diff options
author | Flavian Kaufmann <flavian@flaviankaufmann.ch> | 2025-05-26 09:33:05 +0200 |
---|---|---|
committer | Flavian Kaufmann <flavian@flaviankaufmann.ch> | 2025-05-26 09:33:05 +0200 |
commit | 041fcfd0b17e7a6f654fc155108847aac8293144 (patch) | |
tree | 2e2330f73c2911f7f7c03cd38c8370a68a6dc1d0 | |
parent | 49e4ca2fa0c6de8f50d3f739ce46e8d4c7b75da8 (diff) | |
download | imp-041fcfd0b17e7a6f654fc155108847aac8293144.tar.gz imp-041fcfd0b17e7a6f654fc155108847aac8293144.zip |
[feature] only allow procedure declarations on top level
-rw-r--r-- | examples/gcd.imp | 4 | ||||
-rw-r--r-- | src/driver.c | 2 | ||||
-rw-r--r-- | src/interpreter.c | 4 | ||||
-rw-r--r-- | src/parser.y | 52 |
4 files changed, 38 insertions, 24 deletions
diff --git a/examples/gcd.imp b/examples/gcd.imp index 5ab0bbf..530f347 100644 --- a/examples/gcd.imp +++ b/examples/gcd.imp @@ -11,6 +11,4 @@ procedure gcd(a, b; r) begin end; end; -x := 48; -y := 18; -gcd(x, y; result); +gcd(48, 18; result); diff --git a/src/driver.c b/src/driver.c index 3727f11..c43b899 100644 --- a/src/driver.c +++ b/src/driver.c @@ -170,7 +170,7 @@ static void ast_print (IMP_ASTNode *node, int depth) { printf("%*sCALL %s(", indent, "", node->data.proc_call.name); IMP_ASTNodeList *args = node->data.proc_call.val_args; while (args) { - printf("%s", args->node->data.variable.name); + ast_print(args->node, 0); args = args->next; if (args) printf(", "); } diff --git a/src/interpreter.c b/src/interpreter.c index b04a293..6efebc3 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -69,9 +69,9 @@ static int interpret_proccall(IMP_InterpreterContext *context, const IMP_ASTNode IMP_ASTNodeList *caller_val_args = node->data.proc_call.val_args; IMP_ASTNodeList *callee_val_args = procdecl->data.proc_decl.val_args; while (caller_val_args && callee_val_args) { - const char *caller_arg_name = caller_val_args->node->data.variable.name; + int val = eval_aexpr(context, caller_val_args->node); const char *callee_arg_name = callee_val_args->node->data.variable.name; - imp_interpreter_context_var_set(proc_context, callee_arg_name, imp_interpreter_context_var_get(context, caller_arg_name)); + imp_interpreter_context_var_set(proc_context, callee_arg_name, val); caller_val_args = caller_val_args->next; callee_val_args = callee_val_args->next; } diff --git a/src/parser.y b/src/parser.y index 5952aa9..a758e84 100644 --- a/src/parser.y +++ b/src/parser.y @@ -1,14 +1,14 @@ +%error-verbose %{ #include <stdio.h> #include "ast.h" -extern char *yytext; -extern int yylineno; extern int yylex(); - IMP_ASTNode *ast_root; -void yyerror(const char *s) { +void yyerror(const char *s) { + extern char *yytext; + extern int yylineno; fprintf(stderr, "Parse error at token \"%s\", line %d: %s\n", yytext, yylineno, s); } %} @@ -37,25 +37,36 @@ void yyerror(const char *s) { %token T_ASSIGN %token T_LPAREN T_RPAREN T_COM T_SEM -%type <node> prog stm var aexp bexp procd procc -%type <node_list> args +%type <node> prog tlstm stm var aexp bexp procd procc +%type <node_list> argl, varl %% -prog : stm +prog : tlstm { ast_root = $1; } ; -stm : T_SKIP - { $$ = imp_ast_skip(); } - | var T_ASSIGN aexp - { $$ = imp_ast_assign($1, $3); } - | T_LPAREN stm T_SEM stm T_RPAREN +tlstm : T_LPAREN tlstm T_SEM tlstm T_RPAREN + { $$ = imp_ast_seq($2, $4); } + | tlstm T_SEM tlstm + { $$ = imp_ast_seq($1, $3); } + | tlstm T_SEM + { $$ = $1; } + | stm + { $$ = $1; } + | procd + { $$ = $1; } + +stm : T_LPAREN stm T_SEM stm T_RPAREN { $$ = imp_ast_seq($2, $4); } | stm T_SEM stm { $$ = imp_ast_seq($1, $3); } | stm T_SEM { $$ = $1; } + | T_SKIP + { $$ = imp_ast_skip(); } + | var T_ASSIGN aexp + { $$ = imp_ast_assign($1, $3); } | T_IF bexp T_THEN stm T_ELSE stm T_END { $$ = imp_ast_if($2, $4, $6); } | T_IF bexp T_THEN stm T_END @@ -64,10 +75,9 @@ stm : T_SKIP { $$ = imp_ast_while($2, $4); } | T_VAR var T_ASSIGN aexp T_IN stm T_END { $$ = imp_ast_let($2, $4, $6); } - | procd - { $$ = $1; } | procc { $$ = $1; } + ; var : T_ID @@ -116,17 +126,23 @@ bexp : bexp T_OR bexp { $$ = imp_ast_rop(IMP_AST_ROP_EQ, imp_ast_int(0), imp_ast_int(1)); } ; -args : var +argl : aexp + { $$ = imp_ast_list($1, NULL); } + | argl T_COM aexp + { $$ = imp_ast_list($3, $1); } + ; + +varl : var { $$ = imp_ast_list($1, NULL); } - | args T_COM var + | argl T_COM var { $$ = imp_ast_list($3, $1); } ; -procd : T_PROC T_ID T_LPAREN args T_SEM args T_RPAREN T_BEGIN stm T_END +procd : T_PROC T_ID T_LPAREN varl T_SEM varl T_RPAREN T_BEGIN stm T_END { $$ = imp_ast_procdecl($2, $4, $6, $9); } ; -procc : T_ID T_LPAREN args T_SEM args T_RPAREN +procc : T_ID T_LPAREN argl T_SEM varl T_RPAREN { $$ = imp_ast_proccall($1, $3, $5); } ; %% |