Fixed parsing of negative numbers.

This commit is contained in:
Jacob Signorovitch 2025-01-04 09:53:39 -05:00
parent 4d828500af
commit 9a9e5cd3e0
3 changed files with 33 additions and 70 deletions

View File

@ -22,7 +22,6 @@ ASTNumData exec_call(AST* ast) {
fflush(stdout); fflush(stdout);
ASTCallData* calldata = (ASTCallData*)ast->data; ASTCallData* calldata = (ASTCallData*)ast->data;
if (!strcmp(calldata->to, "sum") && calldata->argc == 2) { if (!strcmp(calldata->to, "sum") && calldata->argc == 2) {
ASTNumData n1 = exec_expr(calldata->argv[0]); ASTNumData n1 = exec_expr(calldata->argv[0]);
ASTNumData n2 = exec_expr(calldata->argv[1]); ASTNumData n2 = exec_expr(calldata->argv[1]);

View File

@ -28,13 +28,19 @@
%token<strval> CALL %token<strval> CALL
%token<fval> NUM %token<fval> NUM
%token NEG %token SUB
%token PLUS %token PLUS
%token MULT %token MULT
%token DIV %token DIV
%token NL %token NL
%type<ast> exp
%left DIV PLUS MULT SUB
%precedence NEG
%type<fval> num;
%type<ast> exp;
%% %%
@ -43,89 +49,47 @@ input:
| exp { root = $1; } | exp { root = $1; }
; ;
exp: num:
NUM { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); } NUM { $$ = $1; }
| NEG NUM { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init(-$2)); } | SUB NUM { $$ = -$2; } %prec NEG
;
| CALL LGROUP NUM SEP NUM RGROUP { exp:
num { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); }
// name(thing, thing)
| CALL LGROUP exp SEP exp RGROUP {
AST** argv = calloc(2, sizeof(AST*)); AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init($3)); argv[0] = $3;
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($5)); argv[1] = $5;
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init($1, 2, argv)); $$ = ast_init(AST_TYPE_CALL, ast_call_data_init($1, 2, argv));
} }
| NUM PLUS NUM { | exp PLUS exp {
AST** argv = calloc(2, sizeof(AST*)); AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); argv[0] = $1;
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($3)); argv[1] = $3;
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("sum", 2, argv)); $$ = ast_init(AST_TYPE_CALL, ast_call_data_init("sum", 2, argv));
} }
| NEG NUM PLUS NUM {
| exp SUB exp {
AST** argv = calloc(2, sizeof(AST*)); AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$2)); argv[0] = $1;
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($4)); argv[1] = $3;
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("sum", 2, argv));
}
| NUM NEG NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init($1));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($3));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("sub", 2, argv));
}
| NEG NUM NEG NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$2));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($4));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("sub", 2, argv)); $$ = ast_init(AST_TYPE_CALL, ast_call_data_init("sub", 2, argv));
} }
| NUM MULT NUM { | exp MULT exp {
AST** argv = calloc(2, sizeof(AST*)); AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); argv[0] = $1;
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($3)); argv[1] = $3;
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("mul", 2, argv));
}
| NEG NUM MULT NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$2));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($4));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("mul", 2, argv));
}
| NEG NUM MULT NEG NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$2));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$5));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("mul", 2, argv));
}
| NUM MULT NEG NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init($1));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$4));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("mul", 2, argv)); $$ = ast_init(AST_TYPE_CALL, ast_call_data_init("mul", 2, argv));
} }
| NUM DIV NUM { | exp DIV exp {
AST** argv = calloc(2, sizeof(AST*)); AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); argv[0] = $1;
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($3)); argv[1] = $3;
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("div", 2, argv));
}
| NEG NUM DIV NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$2));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($4));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("div", 2, argv));
}
| NEG NUM DIV NEG NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$2));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$5));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("div", 2, argv));
}
| NUM DIV NEG NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init($1));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$4));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("div", 2, argv)); $$ = ast_init(AST_TYPE_CALL, ast_call_data_init("div", 2, argv));
} }
%% %%

View File

@ -72,7 +72,7 @@ int yylex() {
switch (c) { switch (c) {
case '+': return PLUS; case '+': return PLUS;
case '\n': return NL; case '\n': return NL;
case '-': return NEG; case '-': return SUB;
case '*': return MULT; case '*': return MULT;
case '/': return DIV; case '/': return DIV;
case '(': return LGROUP; case '(': return LGROUP;