kuroko: Update with upstream

This commit is contained in:
K. Lange 2021-03-06 20:17:58 +09:00
parent 620cfc69d2
commit 9df6e63dbf
4 changed files with 386 additions and 90 deletions

View File

@ -14,15 +14,16 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "bim-core.h"
#define ENABLE_THREADING
#include "bim.h"
#ifdef __toaru__
#include <kuroko.h>
#include "vm.h"
#include "debug.h"
#else
#include "kuroko/src/kuroko.h"
#include "kuroko/src/vm.h"
#include "kuroko/src/debug.h"
#include <kuroko/kuroko.h>
#include <kuroko/vm.h>
#include <kuroko/debug.h>
#endif
global_config_t global_config = {
@ -712,24 +713,7 @@ _done:
return 0;
}
/**
* Close a buffer
*/
buffer_t * buffer_close(buffer_t * buf) {
int i;
/* Locate the buffer in the buffer list */
for (i = 0; i < buffers_len; i++) {
if (buf == buffers[i])
break;
}
/* This buffer doesn't exist? */
if (i == buffers_len) {
return NULL;
}
/* Cancel any background tasks for this env */
void cancel_background_tasks(buffer_t * buf) {
background_task_t * t = global_config.background_task;
background_task_t * last = NULL;
while (t) {
@ -750,6 +734,27 @@ buffer_t * buffer_close(buffer_t * buf) {
t = t->next;
}
}
}
/**
* Close a buffer
*/
buffer_t * buffer_close(buffer_t * buf) {
int i;
/* Locate the buffer in the buffer list */
for (i = 0; i < buffers_len; i++) {
if (buf == buffers[i])
break;
}
/* This buffer doesn't exist? */
if (i == buffers_len) {
return NULL;
}
/* Cancel any background tasks for this env */
cancel_background_tasks(buf);
update_biminfo(buf, 0);
@ -909,6 +914,14 @@ int syntax_space = 0;
struct syntax_definition * syntaxes = NULL;
void add_syntax(struct syntax_definition def) {
/* See if a name match already exists for this def. */
for (struct syntax_definition * s = syntaxes; syntaxes && s->name; ++s) {
if (!strcmp(def.name,s->name)) {
*s = def;
return;
}
}
if (syntax_space == 0) {
syntax_space = 4;
syntaxes = calloc(sizeof(struct syntax_definition), syntax_space);
@ -921,6 +934,8 @@ void add_syntax(struct syntax_definition def) {
syntax_count++;
}
void redraw_all(void);
/**
* Calculate syntax highlighting for the given line, and lines after
* if their initial syntax state has changed by this recalculation.
@ -958,21 +973,15 @@ void recalculate_syntax(line_t * line, int line_no) {
krk_push(OBJECT_VAL(s));
KrkValue result = krk_callSimple(OBJECT_VAL(env->syntax->krkFunc), 1, 0);
krk_currentThread.stackTop = krk_currentThread.stack + before;
if (IS_NONE(result) && (krk_currentThread.flags & KRK_HAS_EXCEPTION)) {
if (IS_NONE(result) && (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) {
render_error("Exception occurred in plugin: %s", AS_INSTANCE(krk_currentThread.currentException)->_class->name->chars);
render_commandline_message("\n");
krk_dumpTraceback();
fprintf(stderr,"\n\nThis syntax highlighter will be disabled in this environment.\n\n");
int key = 0;
while ((key = bim_getkey(DEFAULT_KEY_WAIT)) == KEY_TIMEOUT);
env->syntax = NULL;
return;
goto _syntaxError;
} else if (!IS_NONE(result) && !IS_INTEGER(result)) {
fprintf(stderr, "Instead of an integer, got %s\n", krk_typeName(result));
fprintf(stderr,"\n\nThis syntax highlighter will be disabled in this environment.\n\n");
int key = 0;
while ((key = bim_getkey(DEFAULT_KEY_WAIT)) == KEY_TIMEOUT);
env->syntax = NULL;
return;
render_error("Instead of an integer, got %s", krk_typeName(result));
render_commandline_message("\n");
goto _syntaxError;
}
s->state.state = IS_NONE(result) ? -1 : AS_INTEGER(result);
@ -996,6 +1005,14 @@ void recalculate_syntax(line_t * line, int line_no) {
_next:
(void)0;
}
_syntaxError:
krk_resetStack();
fprintf(stderr,"This syntax highlighter will be disabled in this environment.");
env->syntax = NULL;
cancel_background_tasks(env);
pause_for_key();
redraw_all();
}
/**
@ -3686,8 +3703,6 @@ void run_onload(buffer_t * env) {
static void render_syntax_async(background_task_t * task) {
buffer_t * old_env = env;
env = task->env;
struct syntax_definition * old_syn = env->syntax;
env->syntax = task->_private_p;
int line_no = task->_private_i;
if (env->line_count && line_no < env->line_count) {
@ -3699,8 +3714,6 @@ static void render_syntax_async(background_task_t * task) {
redraw_line(line_no);
}
}
env->syntax = old_syn;
env = old_env;
}
@ -3717,7 +3730,6 @@ static void schedule_complete_recalc(void) {
background_task_t * task = malloc(sizeof(background_task_t));
task->env = env;
task->_private_i = i;
task->_private_p = env->syntax;
task->func = render_syntax_async;
task->next = NULL;
if (global_config.tail_task) {
@ -5480,7 +5492,7 @@ BIM_COMMAND(theme,"theme","Set color theme") {
ptrdiff_t before = krk_currentThread.stackTop - krk_currentThread.stack;
KrkValue result = krk_callSimple(OBJECT_VAL(d->callable), 0, 0);
krk_currentThread.stackTop = krk_currentThread.stack + before;
if (IS_NONE(result) && (krk_currentThread.flags & KRK_HAS_EXCEPTION)) {
if (IS_NONE(result) && (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) {
render_error("Exception occurred in theme: %s", AS_INSTANCE(krk_currentThread.currentException)->_class->name->chars);
krk_dumpTraceback();
int key = 0;
@ -6610,7 +6622,12 @@ void find_match_backwards(int from_line, int from_col, int * out_line, int * out
void rehighlight_search(line_t * line) {
if (!global_config.search) return;
int j = 0;
while (j < line->actual) {
line->text[j].flags &= ~(FLAG_SEARCH);
j++;
}
int ignorecase = smart_case(global_config.search);
j = 0;
while (j < line->actual) {
int matchlen = 0;
if (subsearch_matches(line, j, global_config.search, ignorecase, &matchlen)) {
@ -9932,7 +9949,7 @@ int process_krk_command(const char * cmd, KrkValue * outVal) {
* get printed by the interpreter and we can't catch it here. */
krk_currentThread.frames[0].outSlots = 1;
/* Call the interpreter */
KrkValue out = krk_interpret(cmd,0,"<bim>","<bim>");
KrkValue out = krk_interpret(cmd,"<bim>");
/* If the user typed just a command name, try to execute it. */
if (krk_isInstanceOf(out,CommandDef)) {
krk_push(out);
@ -9942,7 +9959,7 @@ int process_krk_command(const char * cmd, KrkValue * outVal) {
int retval = (IS_INTEGER(out)) ? AS_INTEGER(out) : 0;
int hadOutput = 0;
/* If we got an exception during execution, print it now */
if (krk_currentThread.flags & KRK_HAS_EXCEPTION) {
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
if (krk_isInstanceOf(krk_currentThread.currentException, vm.exceptions->syntaxError)) {
}
set_fg_color(COLOR_RED);
@ -10028,7 +10045,7 @@ BIM_COMMAND(runkrk,"runkrk", "Run a kuroko script") {
/* In case we're running in a weird context? */
int previousExitFrame = krk_currentThread.exitOnFrame;
krk_currentThread.exitOnFrame = krk_currentThread.frameCount;
krk_runfile(argv[1],1,"<bim>",argv[1]);
krk_runfile(argv[1],argv[1]);
krk_currentThread.exitOnFrame = previousExitFrame;
redraw_all();
@ -10175,7 +10192,7 @@ static KrkValue krk_bim_register_syntax(int argc, KrkValue argv[], int hasKw) {
if (!IS_STRING(name))
return krk_runtimeError(vm.exceptions->typeError, "%s.name must be str", AS_CLASS(argv[0])->name->chars);
if (!IS_TUPLE(extensions))
return krk_runtimeError(vm.exceptions->typeError, "%s.extensions must by tuple<str>", AS_CLASS(argv[0])->name->chars);
return krk_runtimeError(vm.exceptions->typeError, "%s.extensions must be tuple<str>", AS_CLASS(argv[0])->name->chars);
if (!IS_BOOLEAN(spaces))
return krk_runtimeError(vm.exceptions->typeError, "%s.spaces must be bool", AS_CLASS(argv[0])->name->chars);
if (!IS_CLOSURE(calculate))
@ -10528,7 +10545,7 @@ void import_directory(char * dirName) {
"if '%s%s' not in kuroko.module_paths:\n"
" kuroko.module_paths.insert(0,'%s%s')\n",
dirpath, extra, dirpath, extra);
krk_interpret(tmp,1,"<bim>","<bim>");
krk_interpret(tmp,"<bim>");
}
if (dirpath) free(dirpath);
@ -10538,7 +10555,7 @@ void import_directory(char * dirName) {
char * tmp = malloc(strlen(dirName) + 1 + strlen(ent->d_name) + 1 + 7);
snprintf(tmp, strlen(dirName) + 1 + strlen(ent->d_name) + 1 + 7, "import %s.%s", dirName, ent->d_name);
tmp[strlen(tmp)-4] = '\0';
krk_interpret(tmp,1,"<bim>",ent->d_name);
krk_interpret(tmp,ent->d_name);
free(tmp);
}
ent = readdir(dirp);
@ -10576,6 +10593,33 @@ static void findBim(char * argv[]) {
} /* Else, give up at this point and just don't attach it at all. */
}
BIM_COMMAND(reload,"reload","Reloads all the Kuroko stuff.") {
/* Unload everything syntax-y */
KrkValue result = krk_interpret(
"if True:\n"
" import kuroko\n"
" for mod in kuroko.modules():\n"
" if mod.startswith('syntax.') or mod.startswith('themes.'):\n"
" kuroko.unload(mod)\n", "<bim>");
if (IS_NONE(result) && (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) {
krk_dumpTraceback();
return 1;
}
/* Reload everything */
krk_resetStack();
krk_startModule("<bim-syntax>");
import_directory("syntax");
krk_startModule("<bim-themes>");
import_directory("themes");
krk_startModule("<bim-repl>");
/* Re-run the RC file */
load_bimrc();
krk_resetStack();
return 0;
}
/**
* Run global initialization tasks
*/
@ -10614,9 +10658,7 @@ void initialize(void) {
global_config.tab_indicator = strdup(">");
global_config.space_indicator = strdup("-");
fprintf(stderr, "init vm\n");
krk_initVM(0); /* no debug flags */
fprintf(stderr, "done\n");
KrkInstance * bimModule = krk_newInstance(vm.baseClasses->moduleClass);
krk_attachNamedObject(&vm.modules, "bim", (KrkObj*)bimModule);
@ -10708,6 +10750,9 @@ void initialize(void) {
load_bimrc();
krk_resetStack();
/* Disable default traceback printing */
vm.globalFlags |= KRK_GLOBAL_CLEAN_OUTPUT;
/* Initialize space for buffers */
buffers_avail = 4;
buffers = malloc(sizeof(buffer_t *) * buffers_avail);

View File

@ -22,6 +22,11 @@
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#ifdef __toaru__
#include "vm.h"
#else
#include <kuroko/vm.h>
#endif
#ifdef __DATE__
# define BIM_BUILD_DATE " built " __DATE__ " at " __TIME__
@ -35,7 +40,7 @@
# define TAG "-alpha"
#endif
#define BIM_VERSION "3.0.0" TAG
#define BIM_VERSION "2.99.0" TAG
#define BIM_COPYRIGHT "Copyright 2012-2021 K. Lange <\033[3mklange@toaruos.org\033[23m>"
#define BLOCK_SIZE 4096

View File

@ -28,6 +28,7 @@
#include "vm.h"
#include "memory.h"
#include "scanner.h"
#include "compiler.h"
#define PROMPT_MAIN ">>> "
#define PROMPT_BLOCK " > "
@ -166,9 +167,10 @@ static void tab_complete_func(rline_context_t * c) {
krk_push(thisValue);
if (IS_CLOSURE(thisValue) || IS_BOUND_METHOD(thisValue) ||
(IS_NATIVE(thisValue) && ((KrkNative*)AS_OBJECT(thisValue))->isMethod != 2)) {
char * tmp = malloc(s->length + 2);
sprintf(tmp, "%s(", s->chars);
s = krk_takeString(tmp, strlen(tmp));
size_t allocSize = s->length + 2;
char * tmp = malloc(allocSize);
size_t len = snprintf(tmp, allocSize, "%s(", s->chars);
s = krk_takeString(tmp, len);
krk_pop();
krk_push(OBJECT_VAL(s));
}
@ -274,9 +276,253 @@ _cleanup:
}
#endif
static char * lastDebugCommand = NULL;
static int debuggerHook(KrkCallFrame * frame) {
/* File information */
fprintf(stderr, "At offset 0x%04lx of function '%s' from '%s' on line %lu:\n",
(unsigned long)(frame->ip - frame->closure->function->chunk.code),
frame->closure->function->name->chars,
frame->closure->function->chunk.filename->chars,
(unsigned long)krk_lineNumber(&frame->closure->function->chunk,
(unsigned long)(frame->ip - frame->closure->function->chunk.code)));
/* Opcode trace */
krk_disassembleInstruction(
stderr,
frame->closure->function,
(size_t)(frame->ip - frame->closure->function->chunk.code));
krk_debug_dumpStack(stderr, frame);
while (1) {
char buf[4096] = {0};
#ifndef NO_RLINE
if (enableRline) {
rline_exit_string="";
rline_exp_set_prompts("(dbg) ", "", 6, 0);
rline_exp_set_syntax("krk-dbg");
rline_exp_set_tab_complete_func(NULL);
if (rline(buf, 4096) == 0) goto _dbgQuit;
} else {
#endif
fprintf(stderr, "(dbg) ");
fflush(stderr);
char * out = fgets(buf, 4096, stdin);
if (!out || !strlen(buf)) {
fprintf(stdout, "^D\n");
goto _dbgQuit;
}
#ifndef NO_RLINE
}
#endif
char * nl = strstr(buf,"\n");
if (nl) *nl = '\0';
if (!strlen(buf)) {
if (lastDebugCommand) {
strcpy(buf, lastDebugCommand);
} else {
continue;
}
} else {
#ifndef NO_RLINE
if (enableRline) rline_history_insert(strdup(buf));
#endif
if (lastDebugCommand) free(lastDebugCommand);
lastDebugCommand = strdup(buf);
}
/* Try to tokenize the first bit */
char * arg = NULL;
char * sp = strstr(buf," ");
if (sp) {
*sp = '\0';
arg = sp + 1;
}
/* Now check commands */
if (!strcmp(buf, "c") || !strcmp(buf,"continue")) {
return KRK_DEBUGGER_CONTINUE;
} else if (!strcmp(buf, "s") || !strcmp(buf, "step")) {
return KRK_DEBUGGER_STEP;
} else if (!strcmp(buf, "abort")) {
return KRK_DEBUGGER_ABORT;
} else if (!strcmp(buf, "q") || !strcmp(buf, "quit")) {
return KRK_DEBUGGER_QUIT;
} else if (!strcmp(buf, "bt") || !strcmp(buf, "backtrace")) {
krk_debug_dumpTraceback();
} else if (!strcmp(buf, "p") || !strcmp(buf, "print")) {
if (!arg) {
fprintf(stderr, "print requires an argument\n");
} else {
size_t frameCount = krk_currentThread.frameCount;
/* Compile statement */
KrkFunction * expression = krk_compile(arg,"<debugger>");
if (expression) {
/* Make sure stepping is disabled first. */
krk_debug_disableSingleStep();
/* Turn our compiled expression into a callable. */
krk_push(OBJECT_VAL(expression));
krk_push(OBJECT_VAL(krk_newClosure(expression)));
/* Stack silliness, don't ask. */
krk_push(NONE_VAL());
krk_pop();
/* Call the compiled expression with no args, but claim 2 method extras. */
krk_push(krk_callSimple(krk_peek(0), 0, 2));
fprintf(stderr, "\033[1;30m=> ");
krk_printValue(stderr, krk_peek(0));
fprintf(stderr, "\033[0m\n");
krk_pop();
}
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
krk_dumpTraceback();
krk_currentThread.flags &= ~(KRK_THREAD_HAS_EXCEPTION);
}
krk_currentThread.frameCount = frameCount;
}
} else if (!strcmp(buf, "break") || !strcmp(buf, "b")) {
char * filename = arg;
if (!filename) {
fprintf(stderr, "usage: break FILE LINE [type]\n");
continue;
}
char * lineno = strstr(filename, " ");
if (!lineno) {
fprintf(stderr, "usage: break FILE LINE [type]\n");
continue;
}
/* Advance whitespace */
*lineno = '\0';
lineno++;
/* collect optional type */
int flags = KRK_BREAKPOINT_NORMAL;
char * type = strstr(lineno, " ");
if (type) {
*type = '\0'; type++;
if (!strcmp(type, "repeat") || !strcmp(type,"r")) {
flags = KRK_BREAKPOINT_REPEAT;
} else if (!strcmp(type, "once") || !strcmp(type,"o")) {
flags = KRK_BREAKPOINT_ONCE;
} else {
fprintf(stderr, "Unrecognized breakpoint type: %s\n", type);
continue;
}
}
int lineInt = atoi(lineno);
int result = krk_debug_addBreakpointFileLine(krk_copyString(filename, strlen(filename)), lineInt, flags);
if (result == -1) {
fprintf(stderr, "Sorry, couldn't add breakpoint.\n");
} else {
fprintf(stderr, "Breakpoint %d enabled.\n", result);
}
} else if (!strcmp(buf, "i") || !strcmp(buf, "info")) {
if (!arg) {
fprintf(stderr, " info breakpoints - Show breakpoints.\n");
continue;
}
if (!strcmp(arg,"breakpoints")) {
KrkFunction * codeObject = NULL;
size_t offset = 0;
int flags = 0;
int enabled = 0;
int breakIndex = 0;
while (1) {
int result = krk_debug_examineBreakpoint(breakIndex, &codeObject, &offset, &flags, &enabled);
if (result == -1) break;
if (result == -2) continue;
fprintf(stderr, "%-4d in %s+%d %s %s\n",
breakIndex,
codeObject->name->chars,
(int)offset,
flags == KRK_BREAKPOINT_NORMAL ? "normal":
flags == KRK_BREAKPOINT_REPEAT ? "repeat" :
flags == KRK_BREAKPOINT_ONCE ? "once" : "?",
enabled ? "enabled" : "disabled");
breakIndex++;
}
} else {
fprintf(stderr, "Unrecognized info object: %s\n", arg);
}
} else if (!strcmp(buf, "e") || !strcmp(buf, "enable")) {
if (!arg) {
fprintf(stderr, "enable requires an argument\n");
continue;
}
int breakIndex = atoi(arg);
if (krk_debug_enableBreakpoint(breakIndex)) {
fprintf(stderr, "Invalid breakpoint handle.\n");
} else {
fprintf(stderr, "Breakpoint %d enabled.\n", breakIndex);
}
} else if (!strcmp(buf, "d") || !strcmp(buf, "disable")) {
if (!arg) {
fprintf(stderr, "disable requires an argument\n");
continue;
}
int breakIndex = atoi(arg);
if (krk_debug_disableBreakpoint(breakIndex)) {
fprintf(stderr, "Invalid breakpoint handle.\n");
} else {
fprintf(stderr, "Breakpoint %d disabled.\n", breakIndex);
}
} else if (!strcmp(buf, "r") || !strcmp(buf, "remove")) {
if (!arg) {
fprintf(stderr, "remove requires an argument\n");
continue;
}
int breakIndex = atoi(arg);
if (krk_debug_removeBreakpoint(breakIndex)) {
fprintf(stderr, "Invalid breakpoint handle.\n");
} else {
fprintf(stderr, "Breakpoint %d removed.\n", breakIndex);
}
} else if (!strcmp(buf, "help")) {
fprintf(stderr,
"Kuroko Interactive Debugger\n"
" c continue - Continue until the next breakpoint.\n"
" s step - Execute this instruction and return to the debugger.\n"
" bt backtrace - Print a backtrace.\n"
" q quit - Exit the interpreter.\n"
" abort - Abort the interpreter (may create a core dump).\n"
" b break ... - Set a breakpoint.\n"
" e enable N - Enable breakpoint 'N'.\n"
" d disable N - Disable breakpoint 'N'.\n"
" r remove N - Remove breakpoint 'N'.\n"
" i info ... - See information about breakpoints.\n"
"\n"
"Empty input lines will repeat the last command.\n"
);
} else {
fprintf(stderr, "Unrecognized command: %s\n", buf);
}
}
return KRK_DEBUGGER_CONTINUE;
_dbgQuit:
return KRK_DEBUGGER_QUIT;
}
static void handleSigint(int sigNum) {
if (krk_currentThread.frameCount) {
krk_runtimeError(vm.exceptions->keyboardInterrupt, "Keyboard interrupt.");
krk_currentThread.flags |= KRK_THREAD_SIGNALLED;
}
signal(sigNum, handleSigint);
@ -287,10 +533,11 @@ static void findInterpreter(char * argv[]) {
vm.binpath = strdup(_pgmptr);
#else
/* Try asking /proc */
char * binpath = realpath("/proc/self/exe", NULL);
char tmp[4096];
char * binpath = realpath("/proc/self/exe", tmp);
if (!binpath || (access(binpath, X_OK) != 0)) {
if (strchr(argv[0], '/')) {
binpath = realpath(argv[0], NULL);
binpath = realpath(argv[0], tmp);
} else {
/* Search PATH for argv[0] */
char * _path = strdup(getenv("PATH"));
@ -299,10 +546,9 @@ static void findInterpreter(char * argv[]) {
char * next = strchr(path,':');
if (next) *next++ = '\0';
char tmp[4096];
sprintf(tmp, "%s/%s", path, argv[0]);
snprintf(tmp, 4096, "%s/%s", path, argv[0]);
if (access(tmp, X_OK) == 0) {
binpath = strdup(tmp);
binpath = tmp;
break;
}
path = next;
@ -320,13 +566,11 @@ static int runString(char * argv[], int flags, char * string) {
findInterpreter(argv);
krk_initVM(flags);
krk_startModule("__main__");
krk_interpret(string, 1, "<stdin>","<stdin>");
krk_interpret(string, "<stdin>");
krk_freeVM();
return 0;
}
/* This isn't normally exposed. */
extern KrkFunction * krk_compile(const char * src, int newScope, char * fileName);
static int compileFile(char * argv[], int flags, char * fileName) {
findInterpreter(argv);
krk_initVM(flags);
@ -351,10 +595,10 @@ static int compileFile(char * argv[], int flags, char * fileName) {
krk_startModule("__main__");
/* Call the compiler directly. */
KrkFunction * func = krk_compile(buf, 0, fileName);
KrkFunction * func = krk_compile(buf, fileName);
/* See if there was an exception. */
if (krk_currentThread.flags & KRK_HAS_EXCEPTION) {
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
krk_dumpTraceback();
}
@ -378,28 +622,35 @@ static int compileFile(char * argv[], int flags, char * fileName) {
#endif
int main(int argc, char * argv[]) {
#ifdef _WIN32
SetConsoleOutputCP(65001);
SetConsoleCP(65001);
#endif
int flags = 0;
int moduleAsMain = 0;
int opt;
while ((opt = getopt(argc, argv, "+c:C:dgm:rstMV-:")) != -1) {
while ((opt = getopt(argc, argv, "+c:C:dgm:rstMSV-:")) != -1) {
switch (opt) {
case 'c':
return runString(argv, flags, optarg);
case 'd':
/* Disassemble code blocks after compilation. */
flags |= KRK_ENABLE_DISASSEMBLY;
flags |= KRK_THREAD_ENABLE_DISASSEMBLY;
break;
case 'g':
/* Always garbage collect during an allocation. */
flags |= KRK_ENABLE_STRESS_GC;
flags |= KRK_GLOBAL_ENABLE_STRESS_GC;
break;
case 's':
/* Print debug information during compilation. */
flags |= KRK_ENABLE_SCAN_TRACING;
flags |= KRK_THREAD_ENABLE_SCAN_TRACING;
break;
case 'S':
flags |= KRK_THREAD_SINGLE_STEP;
break;
case 't':
/* Disassemble instructions as they are executed. */
flags |= KRK_ENABLE_TRACING;
flags |= KRK_THREAD_ENABLE_TRACING;
break;
case 'm':
moduleAsMain = 1;
@ -429,6 +680,7 @@ int main(int argc, char * argv[]) {
" -t Disassemble instructions as they are exceuted.\n"
" -C file Compile 'file', but do not execute it.\n"
" -M Print the default module import paths.\n"
" -S Enable single-step debugging.\n"
" -V Print version information.\n"
"\n"
" --version Print version information.\n"
@ -449,6 +701,8 @@ _finishArgs:
findInterpreter(argv);
krk_initVM(flags);
krk_debug_registerCallback(debuggerHook);
/* Attach kuroko.argv - argv[0] will be set to an empty string for the repl */
if (argc == optind) krk_push(OBJECT_VAL(krk_copyString("",0)));
for (int arg = optind; arg < argc; ++arg) {
@ -471,17 +725,11 @@ _finishArgs:
KrkValue result = INTEGER_VAL(0);
if (moduleAsMain) {
/* This isn't going to do what we want for built-in modules, but I'm not sure
* what we _should_ do for them anyway... let's just leave that as a TODO;
* we do let C modules know they are the __main__ now, so non-built-in
* C modules can still act as scripts if they want... */
KrkValue module;
krk_push(OBJECT_VAL(krk_copyString("__main__",8)));
int out = !krk_loadModule(
int out = !krk_importModule(
AS_STRING(AS_LIST(argList)->values[0]),
&module,
AS_STRING(krk_peek(0)));
if (krk_currentThread.flags & KRK_HAS_EXCEPTION) {
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) {
krk_dumpTraceback();
krk_resetStack();
}
@ -493,18 +741,9 @@ _finishArgs:
/* The repl runs in the context of a top-level module so each input
* line can share a globals state with the others. */
krk_startModule("<module>");
krk_startModule("__main__");
krk_attachNamedValue(&krk_currentThread.module->fields,"__doc__", NONE_VAL());
#ifndef NO_RLINE
/* Set ^D to send EOF */
rline_exit_string="";
/* Enable syntax highlight for Kuroko */
rline_exp_set_syntax("krk");
/* Bind a callback for \t */
rline_exp_set_tab_complete_func(tab_complete_func);
#endif
/**
* Python stores version info in a built-in module called `sys`.
* We are not Python, we'll use `sys` to pretend to be Python
@ -540,6 +779,12 @@ _finishArgs:
#ifndef NO_RLINE
/* Main prompt is >>> like in Python */
rline_exp_set_prompts(PROMPT_MAIN, "", 4, 0);
/* Set ^D to send EOF */
rline_exit_string="";
/* Enable syntax highlight for Kuroko */
rline_exp_set_syntax("krk");
/* Bind a callback for \t */
rline_exp_set_tab_complete_func(tab_complete_func);
#endif
while (1) {
@ -671,7 +916,7 @@ _finishArgs:
FREE_ARRAY(char *, lines, lineCapacity);
if (valid) {
KrkValue result = krk_interpret(allData, 0, "<module>","<stdin>");
KrkValue result = krk_interpret(allData, "<stdin>");
if (!IS_NONE(result)) {
KrkClass * type = krk_getType(result);
const char * formatStr = " \033[1;30m=> %s\033[0m\n";
@ -687,8 +932,8 @@ _finishArgs:
} else {
fprintf(stdout, formatStr, AS_CSTRING(result));
}
krk_resetStack();
}
krk_resetStack();
free(allData);
}
@ -696,7 +941,8 @@ _finishArgs:
}
} else {
krk_startModule("__main__");
result = krk_runfile(argv[optind],1,"__main__",argv[optind]);
result = krk_runfile(argv[optind],argv[optind]);
if (IS_NONE(result) && krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) result = INTEGER_VAL(1);
}
krk_freeVM();

2
kuroko

@ -1 +1 @@
Subproject commit 6a95c4a97921e9aa76fda65e1f289428dd95e4b2
Subproject commit 34c8d68720ea5ee736b49094b8b1836a267604a9