aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavian Kaufmann <flavian@flaviankaufmann.ch>2025-05-26 09:33:05 +0200
committerFlavian Kaufmann <flavian@flaviankaufmann.ch>2025-05-26 09:33:05 +0200
commit041fcfd0b17e7a6f654fc155108847aac8293144 (patch)
tree2e2330f73c2911f7f7c03cd38c8370a68a6dc1d0
parent49e4ca2fa0c6de8f50d3f739ce46e8d4c7b75da8 (diff)
downloadimp-041fcfd0b17e7a6f654fc155108847aac8293144.tar.gz
imp-041fcfd0b17e7a6f654fc155108847aac8293144.zip
[feature] only allow procedure declarations on top level
-rw-r--r--examples/gcd.imp4
-rw-r--r--src/driver.c2
-rw-r--r--src/interpreter.c4
-rw-r--r--src/parser.y52
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); }
;
%%