From 8b01407374f63ae1bd7d1467b633e2b9c5bab2b3 Mon Sep 17 00:00:00 2001 From: Jacob Signorovitch Date: Mon, 20 Jan 2025 14:47:58 -0500 Subject: [PATCH 1/2] Added initial support for variables. They are now parsed correctly, though they cannot be defined manually and all have a value of 42.42. --- src/ast.c | 14 ++++++++++++-- src/exec.c | 5 +++++ src/grammar.y | 4 +++- src/include/exec.h | 1 + 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/ast.c b/src/ast.c index 3fa9e4d..c923630 100644 --- a/src/ast.c +++ b/src/ast.c @@ -27,6 +27,7 @@ void ast_destroy(AST* ast) { switch (ast->type) { case AST_TYPE_NUM: ast_num_data_destroy(ast->data); break; case AST_TYPE_CALL: ast_call_data_destroy(ast->data); break; + case AST_TYPE_VREF: ast_vref_data_destroy(ast->data); break; default: log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX); } @@ -103,9 +104,18 @@ void ast_call_print(ASTCallData* data, int i) { INDENT_END; } -ASTVrefData* ast_vref_data_init(char* to) {} +ASTVrefData* ast_vref_data_init(char* to) { + talloc(ASTVrefData, vref); -void ast_vref_data_destroy(ASTVrefData* vref) {} + vref->to = to; + + return vref; +} + +void ast_vref_data_destroy(ASTVrefData* vref) { + free(vref->to); + free(vref); +} void ast_vref_print(ASTVrefData* data, int i) { INDENT_BEGIN(i); diff --git a/src/exec.c b/src/exec.c index d20d32a..a34f74b 100644 --- a/src/exec.c +++ b/src/exec.c @@ -13,6 +13,7 @@ ASTNumData exec_exp(AST* ast) { switch (ast->type) { case AST_TYPE_CALL: return exec_call(ast); case AST_TYPE_NUM: return *(ASTNumData*)ast->data; + case AST_TYPE_VREF: return exec_vref(ast); default: printf("what\n"); exit(1); } @@ -67,4 +68,8 @@ ASTNumData exec_call(AST* ast) { return -1000; } +ASTNumData exec_vref(AST* ast) { + return *ast_num_data_init(42.42); +} + void exec_print(double n) { printf("= %lf\n", n); } diff --git a/src/grammar.y b/src/grammar.y index 8d19bcc..df7ddcc 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -84,7 +84,9 @@ exp: | LGROUP exp RGROUP { $$ = $2; } // Variable reference. - //| WORD + | WORD { + $$ = ast_init(AST_TYPE_VREF, ast_vref_data_init($1)); + } | WORD LGROUP arg RGROUP { size_t argc = $3->ln; diff --git a/src/include/exec.h b/src/include/exec.h index 53ee7df..cbf1353 100644 --- a/src/include/exec.h +++ b/src/include/exec.h @@ -5,6 +5,7 @@ ASTNumData exec_exp(AST* ast); ASTNumData exec_call(AST* ast); +ASTNumData exec_vref(AST* ast); void exec_print(double n); #endif From 27e61471a89ca98021d9e0b6c9d92afacfd0025b Mon Sep 17 00:00:00 2001 From: Jacob Date: Sat, 25 Jan 2025 10:12:15 -0500 Subject: [PATCH 2/2] Fixed some things. --- src/grammar.y | 3 +++ src/lexer.c | 1 + test/validation/test.bats | 13 +++++++++++++ 3 files changed, 17 insertions(+) diff --git a/src/grammar.y b/src/grammar.y index df7ddcc..f3f6890 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -27,6 +27,8 @@ %token RGROUP %token SEP +%token EXPSEP + %token WORD %token NUM @@ -50,6 +52,7 @@ input: %empty | exp { root = $1; } + | input EXPSEP exp { root = $3; } ; diff --git a/src/lexer.c b/src/lexer.c index 6ac70cb..874a22d 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -112,6 +112,7 @@ int yylex() { case '(': return LGROUP; case ')': return RGROUP; case ',': return SEP; + case ';': return EXPSEP; default: fprintf(stderr, "Unexpected character: %c\n", c); } diff --git a/test/validation/test.bats b/test/validation/test.bats index 24ae0a0..313d21c 100644 --- a/test/validation/test.bats +++ b/test/validation/test.bats @@ -82,3 +82,16 @@ bin() { ./scl.out $1 | tail -n1; } run bin "-(-(1+2)*3)" [ "$output" = "= 9.000000" ] } + +@test "multiple expressions per line" { + run bin "1+1;2" + [ "$output" = "= 2.000000" ] +} + +@test "variable definition" { + run bin "x = 1" + [ "$output" = "= 1.000000" ] + + run bin "x = 1; x + 1" + [ "$output" = "= 2.000000" ] +}