Bladeren bron

Add throw, try, catch, finally mechanism in the interpreter

pull/13/head
mtardy 4 jaren geleden
bovenliggende
commit
639eb7fae0
3 gewijzigde bestanden met toevoegingen van 74 en 35 verwijderingen
  1. +56
    -28
      parse.leg
  2. +18
    -0
      test-try-catch.txt
  3. +0
    -7
      test3.txt

+ 56
- 28
parse.leg Bestand weergeven

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

+ 18
- 0
test-try-catch.txt Bestand weergeven

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

+ 0
- 7
test3.txt Bestand weergeven

@ -1,7 +0,0 @@
try {
print("hello")
} catch (e) {
print("catch!")
} finally {
print("finally...")
}

Laden…
Annuleren
Opslaan