Add basic support for -m argument to interpreter

This commit is contained in:
K. Lange 2021-01-13 09:08:11 +09:00
parent 0c59a20bbb
commit 2b02ef457e
4 changed files with 47 additions and 16 deletions

View File

@ -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
View 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
View File

@ -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
View File

@ -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);