diff --git a/parse.leg b/parse.leg index 0e4ab8d..2499f07 100644 --- a/parse.leg +++ b/parse.leg @@ -73,12 +73,9 @@ oop globals= 0; DO_PROTOS() _DO(__proto__) _DO(__name__) _DO(__default__) _DO(__arguments__) \ _DO(name) _DO(body) _DO(param) _DO(key) _DO(value) _DO(condition) _DO(consequent) _DO(alternate) \ _DO(lhs) _DO(rhs) _DO(scope) _DO(args) _DO(expression) _DO(labels) _DO(statements) _DO(initialise) \ -<<<<<<< HEAD _DO(update) _DO(this) _DO(fixed) _DO(operator) _DO(map) _DO(func) \ - _DO(try) _DO(catch) _DO(finally) _DO(exception) -======= - _DO(update) _DO(this) _DO(fixed) _DO(operator) _DO(map) _DO(func) _DO(__line__) _DO(__file__) ->>>>>>> master + _DO(try) _DO(catch) _DO(finally) _DO(exception) \ + _DO(__line__) _DO(__file__) #define _DO(NAME) oop NAME##_symbol; DO_SYMBOLS() @@ -1419,28 +1416,51 @@ oop eval(oop scope, oop ast) int jbt = sigsetjmp(jbs->jb, 0); switch (jbt) { case j_return: { - oop result = jbs->result; - jbRecPop(); - return result; + runtimeError(ast, "return outside of a function"); } case j_break: { - fprintf(stderr, "\nbreak outside of a loop\n"); - exit(1); + runtimeError(ast, "break outside of a loop or switch"); } case j_continue: { - fprintf(stderr, "\ncontinue outside of a loop\n"); - exit(1); + runtimeError(ast, "continue outside of a loop"); } case j_throw: { - oop res= jbs->result; + oop e= jbs->result; jbRecPop(); - jbs->result= res; - siglongjmp(jbs->jb, j_throw); + jbs->result= e; + // that should only be set in the catch local scope + setVariable(scope, exception, e); + jbRecPush(); + jbt = sigsetjmp(jbs->jb, 0); + switch (jbt) { + case j_return: { + runtimeError(ast, "return outside of a function"); + } + case j_break: { + runtimeError(ast, "break outside of a loop or switch"); + } + case j_continue: { + runtimeError(ast, "continue outside of a loop"); + } + case j_throw: { + // transfer exception + oop e= jbs->result; + jbRecPop(); + jbs->result= e; + + eval(scope, finally); + siglongjmp(jbs->jb, j_throw); + } + } + oop catchRes= eval(scope, catch); + eval(scope, finally); + jbRecPop(); + return catchRes; } } - + oop res = eval(scope, try); jbRecPop(); - return; + return res; } case t_Block: { oop statements = map_get(ast, statements_symbol); @@ -1825,6 +1845,13 @@ oop prim_print(oop params) return params; } +oop prim_println(oop params) +{ + oop res= prim_print(params); + printf("\n"); + return res; +} + oop evalArgs(oop scope, oop args) { int i = 0; @@ -1847,7 +1874,7 @@ void readEvalPrint(char *fileName) { if (0 == jbt) { while (inputStack && yyparse()) { - if (opt_v > 1) printf("%s:%i: ", inputStack->name, inputStack->lineNumber); + if (opt_v > 1) printf("%s:%i: ", get(inputStack->name, String, value), inputStack->lineNumber); if (!yylval) { fclose(inputStack->file); inputStackPop(); @@ -1913,16 +1940,17 @@ int main(int argc, char **argv) symbol_table= makeMap(); globals= makeMap(); - map_set(globals, intern("exit") , makeFunction(prim_exit, intern("exit"), null, null, globals, null)); - map_set(globals, intern("keys") , makeFunction(prim_keys, intern("keys"), null, null, globals, null)); - map_set(globals, intern("values"), makeFunction(prim_values, intern("values"), null, null, globals, null)); - map_set(globals, intern("length"), makeFunction(prim_length, intern("length"), null, null, globals, null)); - map_set(globals, intern("print") , makeFunction(prim_print, intern("print"), null, null, globals, null)); - map_set(globals, intern("invoke"), makeFunction(prim_invoke, intern("invoke"), null, null, globals, null)); - map_set(globals, intern("apply") , makeFunction(prim_apply, intern("apply"), null, null, globals, null)); - map_set(globals, intern("clone") , makeFunction(prim_clone, intern("clone"), null, null, globals, null)); - map_set(globals, intern("import"), makeFunction(prim_import, intern("import"), null, null, globals, null)); - map_set(globals, intern("millis"), makeFunction(prim_millis, intern("millis"), null, null, globals, null)); + map_set(globals, intern("exit") , makeFunction(prim_exit, intern("exit"), null, null, globals, null)); + map_set(globals, intern("keys") , makeFunction(prim_keys, intern("keys"), null, null, globals, null)); + map_set(globals, intern("values") , makeFunction(prim_values, intern("values"), null, null, globals, null)); + map_set(globals, intern("length") , makeFunction(prim_length, intern("length"), null, null, globals, null)); + map_set(globals, intern("print") , makeFunction(prim_print, intern("print"), null, null, globals, null)); + map_set(globals, intern("println"), makeFunction(prim_println, intern("println"), null, null, globals, null)); + map_set(globals, intern("invoke") , makeFunction(prim_invoke, intern("invoke"), null, null, globals, null)); + map_set(globals, intern("apply") , makeFunction(prim_apply, intern("apply"), null, null, globals, null)); + map_set(globals, intern("clone") , makeFunction(prim_clone, intern("clone"), null, null, globals, null)); + map_set(globals, intern("import") , makeFunction(prim_import, intern("import"), null, null, globals, null)); + map_set(globals, intern("millis") , makeFunction(prim_millis, intern("millis"), null, null, globals, null)); #define _DO(NAME) NAME##_symbol=intern(#NAME); DO_SYMBOLS() diff --git a/test-try-catch.txt b/test-try-catch.txt new file mode 100644 index 0000000..08438fc --- /dev/null +++ b/test-try-catch.txt @@ -0,0 +1,18 @@ +try { + try { + println("hello") + throw "ERROR 12"; + println("that should not be executed"); + } catch (e) { + println("catch!") + println("inner: ", e) + throw "pizza" + print("after pizza") + } finally { + println("finally...") + throw "oh no" + println("after oh no") + } +} catch (e) { + println("outer: ", e); +} \ No newline at end of file diff --git a/test3.txt b/test3.txt deleted file mode 100644 index 1562f01..0000000 --- a/test3.txt +++ /dev/null @@ -1,7 +0,0 @@ -try { - print("hello") -} catch (e) { - print("catch!") -} finally { - print("finally...") -} \ No newline at end of file