瀏覽代碼

Add Throw mechanism and hierarchy in verbose mode

master
mtardy 4 年之前
父節點
當前提交
d9364885fe
共有 1 個檔案被更改,包括 98 行新增39 行删除
  1. +98
    -39
      parse.leg

+ 98
- 39
parse.leg 查看文件

@ -18,7 +18,7 @@
_DO(PreDecVariable) _DO(PreDecMember) _DO(PreDecIndex) \ _DO(PreDecVariable) _DO(PreDecMember) _DO(PreDecIndex) \
_DO(PostDecVariable) _DO(PostDecMember) _DO(PostDecIndex) \ _DO(PostDecVariable) _DO(PostDecMember) _DO(PostDecIndex) \
_DO(GetVariable) _DO(GetMember) _DO(SetMember) _DO(GetIndex) _DO(SetIndex) \ _DO(GetVariable) _DO(GetMember) _DO(SetMember) _DO(GetIndex) _DO(SetIndex) \
_DO(Return) _DO(Break) _DO(Continue) \
_DO(Return) _DO(Break) _DO(Continue) _DO(Throw) \
_DO(Quasiquote) _DO(Unquote) _DO(Quasiquote) _DO(Unquote)
typedef enum { typedef enum {
@ -38,6 +38,7 @@ enum jb_t {
j_return = 1, j_return = 1,
j_break, j_break,
j_continue, j_continue,
j_throw,
}; };
typedef struct jb_record typedef struct jb_record
@ -49,14 +50,6 @@ typedef struct jb_record
jb_record *jbs= NULL; jb_record *jbs= NULL;
void jbsCheck(char *msg)
{
if (NULL == jbs) {
fprintf(stderr, "\n%s\n", msg);
exit(1);
}
}
jb_record *jbRecPush() { jb_record *jbRecPush() {
jb_record *newJbRec = memcheck(malloc(sizeof(jb_record))); jb_record *newJbRec = memcheck(malloc(sizeof(jb_record)));
newJbRec->result = null; newJbRec->result = null;
@ -607,10 +600,11 @@ exp = VAR l:ident ASSIGN e:exp { $$ = newDeclarati
| DO s:stmt WHILE LPAREN c:exp RPAREN { $$ = newDo(s, c) } | DO s:stmt WHILE LPAREN c:exp RPAREN { $$ = newDo(s, c) }
| FOR LPAREN i:stmt c:stmt u:exp RPAREN s:stmt { $$ = newFor(i, c, u, s) } | FOR LPAREN i:stmt c:stmt u:exp RPAREN s:stmt { $$ = newFor(i, c, u, s) }
| s:switch { $$ = s } | s:switch { $$ = s }
| RETURN e:exp { $$ = newReturn(e) }
| RETURN e:exp { $$ = newReturn(e) }
| RETURN { $$ = newReturn(null) } | RETURN { $$ = newReturn(null) }
| BREAK { $$ = newBreak() } | BREAK { $$ = newBreak() }
| CONTINUE { $$ = newContinue() } | CONTINUE { $$ = newContinue() }
| THROW e:exp { $$ = newUnary(Throw_proto, e) }
| l:IDENT o:assignOp e:exp { $$ = newAssign(Assign_proto, l, o, e) } | l:IDENT o:assignOp e:exp { $$ = newAssign(Assign_proto, l, o, e) }
| l:postfix DOT i:IDENT o:assignOp e:exp { $$ = newSetMap(SetMember_proto, l, i, o, e) } | l:postfix DOT i:IDENT o:assignOp e:exp { $$ = newSetMap(SetMember_proto, l, i, o, e) }
| l:postfix LBRAC i:exp RBRAC o:assignOp e:exp { $$ = newSetMap(SetIndex_proto, l, i, o, e) } | l:postfix LBRAC i:exp RBRAC o:assignOp e:exp { $$ = newSetMap(SetIndex_proto, l, i, o, e) }
@ -772,7 +766,7 @@ eol = ( "\n""\r"*
comment = "//" ( ![\n\r] . )* comment = "//" ( ![\n\r] . )*
| "/*" ( !"*/" . )* "*/" | "/*" ( !"*/" . )* "*/"
keyword = FUN | SYNTAX | VAR | SWITCH | CASE | DEFAULT | DO | FOR | WHILE | IF | ELSE | NULL | RETURN | BREAK | CONTINUE
keyword = FUN | SYNTAX | VAR | SWITCH | CASE | DEFAULT | DO | FOR | WHILE | IF | ELSE | NULL | RETURN | BREAK | CONTINUE | THROW
IDENT = !keyword < [a-zA-Z_][a-zA-Z0-9_]* > - { $$ = intern(yytext) } IDENT = !keyword < [a-zA-Z_][a-zA-Z0-9_]* > - { $$ = intern(yytext) }
@ -797,6 +791,7 @@ NULL = 'null' ![a-zA-Z0-9_] -
RETURN = 'return' ![a-zA-Z0-9_] - RETURN = 'return' ![a-zA-Z0-9_] -
BREAK = 'break' ![a-zA-Z0-9_] - BREAK = 'break' ![a-zA-Z0-9_] -
CONTINUE = 'continue' ![a-zA-Z0-9_] - CONTINUE = 'continue' ![a-zA-Z0-9_] -
THROW = 'throw' ![a-zA-Z0-9_] -
IMPORT = 'import' ![a-zA-Z0-9_] - IMPORT = 'import' ![a-zA-Z0-9_] -
HASH = '#' - HASH = '#' -
LOGOR = '||' - LOGOR = '||' -
@ -1029,7 +1024,7 @@ oop evalArgs(oop scope, oop args);
oop eval(oop scope, oop ast) oop eval(oop scope, oop ast)
{ {
if (opt_v) {
if (opt_v > 3) {
printf("EVAL: "); printf("EVAL: ");
println(ast); println(ast);
} }
@ -1094,12 +1089,13 @@ oop eval(oop scope, oop ast)
jbRecPush(); jbRecPush();
int jbt = sigsetjmp(jbs->jb, 0); int jbt = sigsetjmp(jbs->jb, 0);
switch (jbt) { switch (jbt) {
case j_return: {
case j_return:
case j_throw: {
oop result = jbs->result; oop result = jbs->result;
jbRecPop(); jbRecPop();
jbsCheck("return outside a function");
assert(jbs);
jbs->result = result; jbs->result = result;
siglongjmp(jbs->jb, j_return);
siglongjmp(jbs->jb, jbt);
assert(0); assert(0);
} }
case j_break: { case j_break: {
@ -1123,12 +1119,13 @@ oop eval(oop scope, oop ast)
jbRecPush(); jbRecPush();
int jbt = sigsetjmp(jbs->jb, 0); int jbt = sigsetjmp(jbs->jb, 0);
switch (jbt) { switch (jbt) {
case j_return: {
case j_return:
case j_throw: {
oop result = jbs->result; oop result = jbs->result;
jbRecPop(); jbRecPop();
jbsCheck("return outside a function");
assert(jbs);
jbs->result = result; jbs->result = result;
siglongjmp(jbs->jb, j_return);
siglongjmp(jbs->jb, jbt);
assert(0); assert(0);
} }
case j_break: { case j_break: {
@ -1158,12 +1155,13 @@ oop eval(oop scope, oop ast)
jbRecPush(); jbRecPush();
int jbt = sigsetjmp(jbs->jb, 0); int jbt = sigsetjmp(jbs->jb, 0);
switch (jbt) { switch (jbt) {
case j_return: {
case j_return:
case j_throw: {
oop result = jbs->result; oop result = jbs->result;
jbRecPop(); jbRecPop();
jbsCheck("return outside a function");
assert(jbs);
jbs->result = result; jbs->result = result;
siglongjmp(jbs->jb, j_return);
siglongjmp(jbs->jb, jbt);
assert(0); assert(0);
} }
case j_break: { case j_break: {
@ -1179,6 +1177,7 @@ oop eval(oop scope, oop ast)
result= eval(localScope, body); result= eval(localScope, body);
restart_for:; restart_for:;
} }
jbRecPop();
return result; return result;
} }
case t_Switch: { case t_Switch: {
@ -1195,12 +1194,13 @@ oop eval(oop scope, oop ast)
jbRecPush(); jbRecPush();
int jbt = sigsetjmp(jbs->jb, 0); int jbt = sigsetjmp(jbs->jb, 0);
switch (jbt) { switch (jbt) {
case j_return: {
case j_return:
case j_throw: {
oop result = jbs->result; oop result = jbs->result;
jbRecPop(); jbRecPop();
jbsCheck("return outside a function");
assert(jbs);
jbs->result = result; jbs->result = result;
siglongjmp(jbs->jb, j_return);
siglongjmp(jbs->jb, jbt);
assert(0); assert(0);
} }
case j_break: { case j_break: {
@ -1209,7 +1209,7 @@ oop eval(oop scope, oop ast)
} }
case j_continue: { case j_continue: {
jbRecPop(); jbRecPop();
jbsCheck("continue outside a loop");
assert(jbs);
siglongjmp(jbs->jb, j_continue); siglongjmp(jbs->jb, j_continue);
assert(0); assert(0);
} }
@ -1219,6 +1219,7 @@ oop eval(oop scope, oop ast)
assert(map_hasIntegerKey(statements, i)); assert(map_hasIntegerKey(statements, i));
result= eval(scope, get(statements, Map, elements)[i].value); result= eval(scope, get(statements, Map, elements)[i].value);
} }
jbRecPop();
return result; return result;
} }
case t_Assign: { case t_Assign: {
@ -1238,7 +1239,7 @@ oop eval(oop scope, oop ast)
oop body = map_get(ast, body_symbol); oop body = map_get(ast, body_symbol);
oop fixed = map_get(ast, fixed_symbol); oop fixed = map_get(ast, fixed_symbol);
oop func = makeFunction(NULL, name, param, body, scope, fixed); oop func = makeFunction(NULL, name, param, body, scope, fixed);
if (opt_v) {
if (opt_v > 4) {
printf("funcscope: "); printf("funcscope: ");
println(scope); println(scope);
printf("globalScope: "); printf("globalScope: ");
@ -1264,7 +1265,7 @@ oop eval(oop scope, oop ast)
oop localScope = map_zip(param, args); oop localScope = map_zip(param, args);
map_set(localScope, __arguments___symbol, args); map_set(localScope, __arguments___symbol, args);
map_set(localScope, __proto___symbol, get(func, Function, parentScope)); map_set(localScope, __proto___symbol, get(func, Function, parentScope));
if (opt_v) {
if (opt_v > 4) {
printf("parentScope: "); printf("parentScope: ");
println(get(func, Function, parentScope)); println(get(func, Function, parentScope));
printf("localScope: "); printf("localScope: ");
@ -1287,6 +1288,12 @@ oop eval(oop scope, oop ast)
fprintf(stderr, "\ncontinue outside of a loop\n"); fprintf(stderr, "\ncontinue outside of a loop\n");
exit(1); exit(1);
} }
case j_throw: {
oop res= jbs->result;
jbRecPop();
jbs->result= res;
siglongjmp(jbs->jb, j_throw);
}
} }
oop result = eval(localScope, get(func, Function, body)); oop result = eval(localScope, get(func, Function, body));
@ -1315,7 +1322,7 @@ oop eval(oop scope, oop ast)
map_set(localScope, this_symbol, this); map_set(localScope, this_symbol, this);
map_set(localScope, __arguments___symbol, args); map_set(localScope, __arguments___symbol, args);
map_set(localScope, __proto___symbol, get(func, Function, parentScope)); map_set(localScope, __proto___symbol, get(func, Function, parentScope));
if (opt_v) {
if (opt_v > 4) {
printf("parentScope: "); printf("parentScope: ");
println(get(func, Function, parentScope)); println(get(func, Function, parentScope));
printf("localScope: "); printf("localScope: ");
@ -1338,6 +1345,12 @@ oop eval(oop scope, oop ast)
fprintf(stderr, "\ncontinue outside of a loop\n"); fprintf(stderr, "\ncontinue outside of a loop\n");
exit(1); exit(1);
} }
case j_throw: {
oop res= jbs->result;
jbRecPop();
jbs->result= res;
siglongjmp(jbs->jb, j_throw);
}
} }
oop result = eval(localScope, get(func, Function, body)); oop result = eval(localScope, get(func, Function, body));
@ -1346,18 +1359,23 @@ oop eval(oop scope, oop ast)
} }
case t_Return: { case t_Return: {
jbsCheck("return outside a function");
assert(jbs);
jbs->result = eval(scope, map_get(ast, value_symbol)); jbs->result = eval(scope, map_get(ast, value_symbol));
siglongjmp(jbs->jb, j_return); siglongjmp(jbs->jb, j_return);
} }
case t_Break: { case t_Break: {
jbsCheck("break outside a loop");
assert(jbs);
siglongjmp(jbs->jb, j_break); siglongjmp(jbs->jb, j_break);
} }
case t_Continue: { case t_Continue: {
jbsCheck("continue outside a loop");
assert(jbs);
siglongjmp(jbs->jb, j_continue); siglongjmp(jbs->jb, j_continue);
} }
case t_Throw: {
assert(jbs);
jbs->result = eval(scope, map_get(ast, rhs_symbol));
siglongjmp(jbs->jb, j_throw);
}
case t_Block: { case t_Block: {
oop statements = map_get(ast, statements_symbol); oop statements = map_get(ast, statements_symbol);
int i = 0; int i = 0;
@ -1664,6 +1682,12 @@ oop prim_invoke(oop params)
fprintf(stderr, "\ncontinue outside of a loop\n"); fprintf(stderr, "\ncontinue outside of a loop\n");
exit(1); exit(1);
} }
case j_throw: {
oop res= jbs->result;
jbRecPop();
jbs->result= res;
siglongjmp(jbs->jb, j_throw);
}
} }
oop result= eval(localScope, get(func, Function, body)); oop result= eval(localScope, get(func, Function, body));
jbRecPop(); jbRecPop();
@ -1700,6 +1724,12 @@ oop apply(oop func, oop args)
fprintf(stderr, "\ncontinue outside of a loop\n"); fprintf(stderr, "\ncontinue outside of a loop\n");
exit(1); exit(1);
} }
case j_throw: {
oop res= jbs->result;
jbRecPop();
jbs->result= res;
siglongjmp(jbs->jb, j_throw);
}
} }
oop result= eval(localScope, get(func, Function, body)); oop result= eval(localScope, get(func, Function, body));
jbRecPop(); jbRecPop();
@ -1743,15 +1773,44 @@ oop AST= NULL;
void readEvalPrint(char *fileName) { void readEvalPrint(char *fileName) {
inputStackPush(fileName); inputStackPush(fileName);
jbRecPush();
jb_record *jtop= jbs;
int jbt= sigsetjmp(jbs->jb, 0);
if (0 == jbt) {
while (inputStack && yyparse()) {
if (opt_v > 1) printf("%s:%i: ", inputStack->name, inputStack->lineNumber);
if (!yylval) {
fclose(inputStack->file);
inputStackPop();
continue;
} // EOF
if (opt_v > 1) println(yylval);
oop res = eval(globals, yylval);
if (opt_v > 0) println(res);
assert(jbs == jtop);
}
jbRecPop();
return;
}
while (inputStack && yyparse()) {
if (!yylval) {
fclose(inputStack->file);
inputStackPop();
continue;
} // EOF
if (opt_v) println(yylval);
println(eval(globals, yylval));
assert(jbs == jtop);
oop res = jbs->result;
jbRecPop();
switch (jbt) {
case j_return:
fprintf(stderr, "\nreturn outside of a function\n");
exit(1);
case j_break:
fprintf(stderr, "\nbreak outside of a loop or switch\n");
exit(1);
case j_continue:
fprintf(stderr, "\ncontinue outside of a loop\n");
exit(1);
case j_throw:
printf("\nunhandled exception: ");
println(res);
exit(1);
} }
} }

Loading…
取消
儲存