diff --git a/samples/deepfailure.noja b/samples/deepfailure.noja new file mode 100644 index 0000000..7178f7d --- /dev/null +++ b/samples/deepfailure.noja @@ -0,0 +1,24 @@ + +depth = 9; + +fun fail(p) +{ + if p < depth: + fail(p+1, depth, fail); + else + assert(false); +} + +#fail(0); + +fun a() +{ + fun b() + { + print(depth, '\n'); + } + + b(); +} + +a(); \ No newline at end of file diff --git a/samples/list.noja b/samples/list.noja index 84f2c7a..db4cf75 100644 --- a/samples/list.noja +++ b/samples/list.noja @@ -1,17 +1,5 @@ - l = [1, 2, 3, 4]; print('The list contains ', count(l), ' items.\n'); print('The list is: ', l, '.\n'); - - -fun fail(p, fail) -{ - if p == 5: - assert(false); - else - fail(p+1, fail); -} - -fail(0, fail); \ No newline at end of file diff --git a/samples/webservice.noja b/samples/webservice.noja deleted file mode 100644 index 0940026..0000000 --- a/samples/webservice.noja +++ /dev/null @@ -1,10 +0,0 @@ - -fun index(req) - return {code: 200, 'body': 'Hello, world!'}; - -routes = { - '/': index, - '/groups': list_groups -} - -res = serve(8080, routes); \ No newline at end of file diff --git a/src/main.c b/src/main.c index 9ed9750..29903c2 100644 --- a/src/main.c +++ b/src/main.c @@ -233,7 +233,7 @@ int main(int argc, char **argv) Runtime_SetBuiltins(runtime, builtins); - Object *result = run(runtime, (Error*) &error, exe, 0, NULL, 0); + Object *result = run(runtime, (Error*) &error, exe, 0, NULL, 1, NULL, 0); if(result == NULL) { diff --git a/src/runtime/o_func.c b/src/runtime/o_func.c index 704680f..5c58cc9 100644 --- a/src/runtime/o_func.c +++ b/src/runtime/o_func.c @@ -9,6 +9,7 @@ typedef struct { Runtime *runtime; Executable *exe; int index, argc; + Object *globals; } FunctionObject; static Object *call(Object *self, Object **argv, unsigned int argc, Heap *heap, Error *error); @@ -73,7 +74,7 @@ static Object *call(Object *self, Object **argv, unsigned int argc, Heap *heap, // The right amount of arguments was provided. argv2 = argv; - Object *result = run(func->runtime, error, func->exe, func->index, argv2, expected_argc); + Object *result = run(func->runtime, error, func->exe, func->index, func->globals, 0, argv2, expected_argc); if(argv2 != argv) free(argv2); @@ -81,7 +82,7 @@ static Object *call(Object *self, Object **argv, unsigned int argc, Heap *heap, return result; } -Object *Object_FromNojaFunction(Runtime *runtime, Executable *exe, int index, int argc, Heap *heap, Error *error) +Object *Object_FromNojaFunction(Runtime *runtime, Executable *exe, int index, int argc, Object *globals, Heap *heap, Error *error) { assert(runtime != NULL); assert(exe != NULL); @@ -107,6 +108,7 @@ Object *Object_FromNojaFunction(Runtime *runtime, Executable *exe, int index, in func->exe = exe_copy; func->index = index; func->argc = argc; + func->globals = globals; return (Object*) func; } \ No newline at end of file diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index c262c12..19881b8 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -10,7 +10,8 @@ typedef struct Frame Frame; struct Frame { Frame *prev; - Object *vars; + Object *locals; + Object *globals; Executable *exe; int index, used; }; @@ -645,7 +646,7 @@ static _Bool step(Runtime *runtime, Error *error) if(key == NULL) return 0; - if(!Object_Insert(runtime->frame->vars, key, val, runtime->heap, error)) + if(!Object_Insert(runtime->frame->locals, key, val, runtime->heap, error)) return 0; return 1; } @@ -835,28 +836,29 @@ static _Bool step(Runtime *runtime, Error *error) if(key == NULL) return 0; - Object *obj = Object_Select(runtime->frame->vars, key, runtime->heap, error); + Object *locations[] = { + runtime->frame->locals, + runtime->frame->globals, + Runtime_GetBuiltins(runtime), + }; + + Object *obj = NULL; - if(obj == NULL && error->occurred == 0) + for(int p = 0; obj == NULL && (unsigned int) p < sizeof(locations)/sizeof(locations[0]); p += 1) { - // Variable not defined locally. + if(locations[p] == NULL) + continue; - Object *builtins = Runtime_GetBuiltins(runtime); - - if(builtins != NULL) - obj = Object_Select(builtins, key, runtime->heap, error); - - if(obj == NULL) - { - if(error->occurred == 0) - // There's no such variable. - Error_Report(error, 1, "Reference to undefined variable \"%s\"", ops[0].as_string); - return 0; - } + obj = Object_Select(locations[p], key, Runtime_GetHeap(runtime), error); } - else - if(obj == NULL) + + if(obj == NULL) + { + if(error->occurred == 0) + // There's no such variable. + Error_Report(error, 1, "Reference to undefined variable \"%s\"", ops[0].as_string); return 0; + } if(!Runtime_Push(runtime, error, obj)) return 0; @@ -912,7 +914,7 @@ static _Bool step(Runtime *runtime, Error *error) assert(ops[0].type == OPTP_INT); assert(ops[1].type == OPTP_INT); - Object *obj = Object_FromNojaFunction(runtime, runtime->frame->exe, ops[0].as_int, ops[1].as_int, runtime->heap, error); + Object *obj = Object_FromNojaFunction(runtime, runtime->frame->exe, ops[0].as_int, ops[1].as_int, runtime->frame->globals, runtime->heap, error); if(obj == NULL) return 0; @@ -1033,7 +1035,7 @@ static _Bool step(Runtime *runtime, Error *error) return 1; } -Object *run(Runtime *runtime, Error *error, Executable *exe, int index, Object **argv, int argc) +Object *run(Runtime *runtime, Error *error, Executable *exe, int index, Object *globals, _Bool is_global_scope, Object **argv, int argc) { assert(runtime != NULL); assert(error != NULL); @@ -1053,14 +1055,28 @@ Object *run(Runtime *runtime, Error *error, Executable *exe, int index, Object * Frame frame; { frame.prev = NULL; - frame.vars = Object_NewMap(-1, runtime->heap, error); + + if(is_global_scope) + { + if(globals == NULL) + globals = Object_NewMap(-1, runtime->heap, error); + + frame.globals = globals; + frame.locals = frame.globals; + } + else + { + frame.globals = globals; + frame.locals = Object_NewMap(-1, runtime->heap, error); + } + + if(frame.locals == NULL) + return NULL; + frame.exe = Executable_Copy(exe); frame.index = index; frame.used = 0; - if(frame.vars == NULL) - return NULL; - if(frame.exe == NULL) { Error_Report(error, 1, "Failed to copy executable"); diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 406e289..3970934 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -23,9 +23,9 @@ Snapshot *Snapshot_New(Runtime *runtime); void Snapshot_Free(Snapshot *snapshot); void Snapshot_Print(Snapshot *snapshot, FILE *fp); -Object *run(Runtime *runtime, Error *error, Executable *exe, int index, Object **argv, int argc); +Object *run(Runtime *runtime, Error *error, Executable *exe, int index, Object *globals, _Bool is_global_scope, Object **argv, int argc); Object *Object_NewBuiltinsMap(Runtime *runtime, Heap *heap, Error *err); Object* Object_FromNativeFunction(Runtime *runtime, Object *(*callback)(Runtime*, Object**, unsigned int, Error*), int argc, Heap *heap, Error *error); -Object* Object_FromNojaFunction(Runtime *runtime, Executable *exe, int index, int argc, Heap *heap, Error *error); +Object *Object_FromNojaFunction(Runtime *runtime, Executable *exe, int index, int argc, Object *globals, Heap *heap, Error *error); #endif \ No newline at end of file