|
@ -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(Throw) \ |
|
|
|
|
|
|
|
|
_DO(Return) _DO(Break) _DO(Continue) _DO(Throw) _DO(Try) \ |
|
|
_DO(Quasiquote) _DO(Unquote) |
|
|
_DO(Quasiquote) _DO(Unquote) |
|
|
|
|
|
|
|
|
typedef enum { |
|
|
typedef enum { |
|
@ -73,7 +73,9 @@ oop globals= 0; |
|
|
DO_PROTOS() _DO(__proto__) _DO(__name__) _DO(__default__) _DO(__arguments__) \ |
|
|
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(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) \ |
|
|
_DO(lhs) _DO(rhs) _DO(scope) _DO(args) _DO(expression) _DO(labels) _DO(statements) _DO(initialise) \ |
|
|
_DO(update) _DO(this) _DO(fixed) _DO(operator) _DO(map) _DO(func) _DO(__line__) _DO(__file__) |
|
|
|
|
|
|
|
|
_DO(update) _DO(this) _DO(fixed) _DO(operator) _DO(map) _DO(func) \ |
|
|
|
|
|
_DO(try) _DO(catch) _DO(finally) _DO(exception) \ |
|
|
|
|
|
_DO(__line__) _DO(__file__) |
|
|
|
|
|
|
|
|
#define _DO(NAME) oop NAME##_symbol; |
|
|
#define _DO(NAME) oop NAME##_symbol; |
|
|
DO_SYMBOLS() |
|
|
DO_SYMBOLS() |
|
@ -544,6 +546,16 @@ oop newContinue(void) |
|
|
return obj; |
|
|
return obj; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
oop newTry(oop try, oop exception, oop catch, oop finally) |
|
|
|
|
|
{ |
|
|
|
|
|
oop obj = newObject(Try_proto); |
|
|
|
|
|
map_set(obj, try_symbol, try); |
|
|
|
|
|
map_set(obj, exception_symbol, exception); |
|
|
|
|
|
map_set(obj, catch_symbol, catch); |
|
|
|
|
|
map_set(obj, finally_symbol, finally); |
|
|
|
|
|
return obj; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
oop fold(oop ast); |
|
|
oop fold(oop ast); |
|
|
|
|
|
|
|
|
#define YY_INPUT(buf, result, max_size) \ |
|
|
#define YY_INPUT(buf, result, max_size) \ |
|
@ -608,6 +620,7 @@ exp = VAR l:ident ASSIGN e:exp { $$ = newDeclarati |
|
|
| BREAK { $$ = newBreak() } |
|
|
| BREAK { $$ = newBreak() } |
|
|
| CONTINUE { $$ = newContinue() } |
|
|
| CONTINUE { $$ = newContinue() } |
|
|
| THROW e:exp { $$ = newUnary(Throw_proto, e) } |
|
|
| THROW e:exp { $$ = newUnary(Throw_proto, e) } |
|
|
|
|
|
| t:try { $$ = t } |
|
|
| 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) } |
|
@ -620,6 +633,12 @@ ident = l:IDENT { $$ = l } |
|
|
syntax2 = < [a-zA-Z_][a-zA-Z0-9_]* > |
|
|
syntax2 = < [a-zA-Z_][a-zA-Z0-9_]* > |
|
|
&{ null != getSyntaxId(2, intern(yytext)) } - { $$ = getSyntaxId(2, intern(yytext)) } |
|
|
&{ null != getSyntaxId(2, intern(yytext)) } - { $$ = getSyntaxId(2, intern(yytext)) } |
|
|
|
|
|
|
|
|
|
|
|
try = TRY t:stmt i:null c:null f:null |
|
|
|
|
|
( CATCH LPAREN i:IDENT RPAREN c:stmt ) ? |
|
|
|
|
|
( FINALLY f:stmt ) ? { $$ = newTry(t, i, c, f) } |
|
|
|
|
|
|
|
|
|
|
|
null = { $$ = null } |
|
|
|
|
|
|
|
|
assignOp = ASSIGN { $$= null } |
|
|
assignOp = ASSIGN { $$= null } |
|
|
| ASSIGNADD { $$= Add_symbol } |
|
|
| ASSIGNADD { $$= Add_symbol } |
|
|
| ASSIGNSUB { $$= Sub_symbol } |
|
|
| ASSIGNSUB { $$= Sub_symbol } |
|
@ -769,7 +788,8 @@ 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 | THROW |
|
|
|
|
|
|
|
|
keyword = FUN | SYNTAX | VAR | SWITCH | CASE | DEFAULT | DO | FOR | WHILE | IF | ELSE | NULL | RETURN | BREAK | CONTINUE |
|
|
|
|
|
| THROW | TRY | CATCH | FINALLY |
|
|
|
|
|
|
|
|
IDENT = !keyword < [a-zA-Z_][a-zA-Z0-9_]* > - { $$ = intern(yytext) } |
|
|
IDENT = !keyword < [a-zA-Z_][a-zA-Z0-9_]* > - { $$ = intern(yytext) } |
|
|
|
|
|
|
|
@ -795,6 +815,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_] - |
|
|
THROW = 'throw' ![a-zA-Z0-9_] - |
|
|
|
|
|
TRY = 'try' ![a-zA-Z0-9_] - |
|
|
|
|
|
CATCH = 'catch' ![a-zA-Z0-9_] - |
|
|
|
|
|
FINALLY = 'finally' ![a-zA-Z0-9_] - |
|
|
IMPORT = 'import' ![a-zA-Z0-9_] - |
|
|
IMPORT = 'import' ![a-zA-Z0-9_] - |
|
|
HASH = '#' - |
|
|
HASH = '#' - |
|
|
LOGOR = '||' - |
|
|
LOGOR = '||' - |
|
@ -1383,6 +1406,62 @@ oop eval(oop scope, oop ast) |
|
|
jbs->result = eval(scope, map_get(ast, rhs_symbol)); |
|
|
jbs->result = eval(scope, map_get(ast, rhs_symbol)); |
|
|
siglongjmp(jbs->jb, j_throw); |
|
|
siglongjmp(jbs->jb, j_throw); |
|
|
} |
|
|
} |
|
|
|
|
|
case t_Try: { |
|
|
|
|
|
oop try = map_get(ast, try_symbol); |
|
|
|
|
|
oop exception = map_get(ast, exception_symbol); |
|
|
|
|
|
oop catch = map_get(ast, catch_symbol); |
|
|
|
|
|
oop finally = map_get(ast, finally_symbol); |
|
|
|
|
|
|
|
|
|
|
|
jbRecPush(); |
|
|
|
|
|
int 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: { |
|
|
|
|
|
oop e= jbs->result; |
|
|
|
|
|
jbRecPop(); |
|
|
|
|
|
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 res; |
|
|
|
|
|
} |
|
|
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; |
|
@ -1766,6 +1845,13 @@ oop prim_print(oop params) |
|
|
return params; |
|
|
return params; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
oop prim_println(oop params) |
|
|
|
|
|
{ |
|
|
|
|
|
oop res= prim_print(params); |
|
|
|
|
|
printf("\n"); |
|
|
|
|
|
return res; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
oop evalArgs(oop scope, oop args) |
|
|
oop evalArgs(oop scope, oop args) |
|
|
{ |
|
|
{ |
|
|
int i = 0; |
|
|
int i = 0; |
|
@ -1788,7 +1874,7 @@ void readEvalPrint(char *fileName) { |
|
|
|
|
|
|
|
|
if (0 == jbt) { |
|
|
if (0 == jbt) { |
|
|
while (inputStack && yyparse()) { |
|
|
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) { |
|
|
if (!yylval) { |
|
|
fclose(inputStack->file); |
|
|
fclose(inputStack->file); |
|
|
inputStackPop(); |
|
|
inputStackPop(); |
|
@ -1854,16 +1940,17 @@ int main(int argc, char **argv) |
|
|
symbol_table= makeMap(); |
|
|
symbol_table= makeMap(); |
|
|
globals= 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); |
|
|
#define _DO(NAME) NAME##_symbol=intern(#NAME); |
|
|
DO_SYMBOLS() |
|
|
DO_SYMBOLS() |
|
|