Add basic support for -m argument to interpreter
This commit is contained in:
parent
0c59a20bbb
commit
2b02ef457e
27
kuroko.c
27
kuroko.c
@ -303,8 +303,9 @@ static int modulePaths(void) {
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
int flags = 0;
|
||||
int moduleAsMain = 0;
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "dgrstMV-:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "dgm:rstMV-:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
/* Disassemble code blocks after compilation. */
|
||||
@ -322,6 +323,10 @@ int main(int argc, char * argv[]) {
|
||||
/* Disassemble instructions as they are executed. */
|
||||
flags |= KRK_ENABLE_TRACING;
|
||||
break;
|
||||
case 'm':
|
||||
moduleAsMain = 1;
|
||||
optind--; /* to get us back to optarg */
|
||||
goto _finishArgs;
|
||||
case 'r':
|
||||
enableRline = 0;
|
||||
break;
|
||||
@ -338,6 +343,7 @@ int main(int argc, char * argv[]) {
|
||||
"Interpreter options:\n"
|
||||
" -d Debug output from the bytecode compiler.\n"
|
||||
" -g Collect garbage on every allocation.\n"
|
||||
" -m mod Run a module as a script.\n"
|
||||
" -r Disable complex line editing in the REPL.\n"
|
||||
" -s Debug output from the scanner/tokenizer.\n"
|
||||
" -t Disassemble instructions as they are exceuted.\n"
|
||||
@ -357,6 +363,7 @@ int main(int argc, char * argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
_finishArgs:
|
||||
krk_initVM(flags);
|
||||
|
||||
/* Attach kuroko.argv - argv[0] will be set to an empty string for the repl */
|
||||
@ -383,7 +390,23 @@ int main(int argc, char * argv[]) {
|
||||
|
||||
KrkValue result = INTEGER_VAL(0);
|
||||
|
||||
if (optind == argc) {
|
||||
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(
|
||||
AS_STRING(AS_LIST(OBJECT_VAL(AS_INSTANCE(argList)->_internal))->values[0]),
|
||||
&module,
|
||||
AS_STRING(krk_peek(0)));
|
||||
if (vm.flags & KRK_HAS_EXCEPTION) {
|
||||
krk_dumpTraceback();
|
||||
krk_resetStack();
|
||||
}
|
||||
return out;
|
||||
} else if (optind == argc) {
|
||||
/* Add builtins for the repl, but hide them from the globals() list. */
|
||||
krk_defineNative(&vm.builtins->fields, "exit", exitFunc);
|
||||
krk_defineNative(&vm.builtins->fields, "paste", paste);
|
||||
|
5
modules/maindemo.krk
Normal file
5
modules/maindemo.krk
Normal file
@ -0,0 +1,5 @@
|
||||
import kuroko
|
||||
if __name__ == '__main__':
|
||||
print("Run as main with args:", kuroko.argv)
|
||||
else:
|
||||
print("__name__ =", __name__)
|
30
vm.c
30
vm.c
@ -125,15 +125,17 @@ static void dumpStack(CallFrame * frame) {
|
||||
* is not None, it will also be printed using safe methods.
|
||||
*/
|
||||
void krk_dumpTraceback() {
|
||||
fprintf(stderr, "Traceback, most recent last:\n");
|
||||
for (size_t i = 0; i <= vm.frameCount - 1; i++) {
|
||||
CallFrame * frame = &vm.frames[i];
|
||||
KrkFunction * function = frame->closure->function;
|
||||
size_t instruction = frame->ip - function->chunk.code - 1;
|
||||
fprintf(stderr, " File \"%s\", line %d, in %s\n",
|
||||
(function->chunk.filename ? function->chunk.filename->chars : "?"),
|
||||
(int)krk_lineNumber(&function->chunk, instruction),
|
||||
(function->name ? function->name->chars : "(unnamed)"));
|
||||
if (vm.frameCount) {
|
||||
fprintf(stderr, "Traceback, most recent last:\n");
|
||||
for (size_t i = 0; i <= vm.frameCount - 1; i++) {
|
||||
CallFrame * frame = &vm.frames[i];
|
||||
KrkFunction * function = frame->closure->function;
|
||||
size_t instruction = frame->ip - function->chunk.code - 1;
|
||||
fprintf(stderr, " File \"%s\", line %d, in %s\n",
|
||||
(function->chunk.filename ? function->chunk.filename->chars : "?"),
|
||||
(int)krk_lineNumber(&function->chunk, instruction),
|
||||
(function->name ? function->name->chars : "(unnamed)"));
|
||||
}
|
||||
}
|
||||
|
||||
if (!krk_valuesEqual(vm.currentException,NONE_VAL())) {
|
||||
@ -3481,7 +3483,7 @@ static int handleException() {
|
||||
* a later search path has a krk source and an earlier search path has a shared
|
||||
* object module, the later search path will still win.
|
||||
*/
|
||||
int krk_loadModule(KrkString * name, KrkValue * moduleOut) {
|
||||
int krk_loadModule(KrkString * name, KrkValue * moduleOut, KrkString * runAs) {
|
||||
KrkValue modulePaths, modulePathsInternal;
|
||||
|
||||
/* See if the module is already loaded */
|
||||
@ -3544,7 +3546,7 @@ int krk_loadModule(KrkString * name, KrkValue * moduleOut) {
|
||||
* returns to the current call frame; modules should return objects. */
|
||||
int previousExitFrame = vm.exitOnFrame;
|
||||
vm.exitOnFrame = vm.frameCount;
|
||||
*moduleOut = krk_runfile(fileName,1,name->chars,fileName);
|
||||
*moduleOut = krk_runfile(fileName,1,runAs->chars,fileName);
|
||||
vm.exitOnFrame = previousExitFrame;
|
||||
if (!IS_OBJECT(*moduleOut)) {
|
||||
krk_runtimeError(vm.exceptions.importError,
|
||||
@ -3585,7 +3587,7 @@ int krk_loadModule(KrkString * name, KrkValue * moduleOut) {
|
||||
|
||||
char * handlerName = AS_CSTRING(krk_peek(0));
|
||||
|
||||
KrkValue (*moduleOnLoad)();
|
||||
KrkValue (*moduleOnLoad)(KrkString * name);
|
||||
void * out = dlsym(dlRef, handlerName);
|
||||
memcpy(&moduleOnLoad,&out,sizeof(out));
|
||||
|
||||
@ -3599,7 +3601,7 @@ int krk_loadModule(KrkString * name, KrkValue * moduleOut) {
|
||||
|
||||
krk_pop(); /* onload function */
|
||||
|
||||
*moduleOut = moduleOnLoad();
|
||||
*moduleOut = moduleOnLoad(runAs);
|
||||
if (!IS_INSTANCE(*moduleOut)) {
|
||||
krk_runtimeError(vm.exceptions.importError,
|
||||
"Failed to load module '%s' from '%s'", name->chars, fileName);
|
||||
@ -3852,7 +3854,7 @@ static KrkValue run() {
|
||||
case OP_IMPORT: {
|
||||
KrkString * name = READ_STRING(operandWidth);
|
||||
KrkValue module;
|
||||
if (!krk_loadModule(name, &module)) {
|
||||
if (!krk_loadModule(name, &module, name)) {
|
||||
goto _finishException;
|
||||
}
|
||||
break;
|
||||
|
1
vm.h
1
vm.h
@ -151,3 +151,4 @@ extern void krk_finalizeClass(KrkClass * _class);
|
||||
extern void krk_dumpTraceback();
|
||||
extern KrkInstance * krk_startModule(const char * name);
|
||||
extern KrkValue krk_dirObject(int argc, KrkValue argv[]);
|
||||
extern int krk_loadModule(KrkString * name, KrkValue * moduleOut, KrkString * runAs);
|
||||
|
Loading…
Reference in New Issue
Block a user