author | Alan Dipert
<alan@dipert.org> 2024-01-07 06:23:35 UTC |
committer | Alan Dipert
<alan@dipert.org> 2024-01-07 06:23:35 UTC |
parent | 99beec2dfe7d63cdeab8d4f97d18dcad8f8c8047 |
ast.c | +46 | -14 |
ast.h | +42 | -6 |
bbasic.y | +25 | -15 |
main.c | +1 | -1 |
diff --git a/ast.c b/ast.c index d05d567..9e203a4 100644 --- a/ast.c +++ b/ast.c @@ -1,21 +1,53 @@ +#include <stdio.h> #include "ast.h" -struct node_tag* ast_last_line; +struct node_tag* ast_last_numbered_line; + +static struct node_tag* ast_alloc(enum NODE_TYPE node_type) { + struct node_tag *new_node = malloc(sizeof(struct node_tag)); + if ((new_node) == NULL) { + fprintf(stderr, "Memory allocation failed at %s:%d\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } + new_node->type = node_type; + return new_node; +} struct node_tag* ast_make_string(char *s) { - struct node_tag *n = malloc(sizeof(struct node_tag)); - n->type = NODE_STRING; - n->node0 = s; - return n; + struct node_tag *new_node = ast_alloc(NODE_STRING); + new_node->data.string.str = s; + return new_node; +} + +struct node_tag* ast_make_numbered_line(int line, struct node_tag* stmt) { + struct node_tag *new_node = ast_alloc(NODE_NUMBERED_LINE); + new_node->data.line.linum = line; + new_node->data.line.stmt = stmt; + ast_last_numbered_line = new_node; + return new_node; +} + +struct node_tag* ast_make_print(struct node_tag* expr) { + struct node_tag *new_node = ast_alloc(NODE_PRINT); + new_node->data.print.expr = expr; + return new_node; +} + +struct node_tag* ast_make_if(struct node_tag* pred, struct node_tag* stmt) { + struct node_tag *new_node = ast_alloc(NODE_IF); + new_node->data.iff.pred = pred; + new_node->data.iff.stmt = stmt; + return new_node; +} + +struct node_tag* ast_make_id(char *name) { + struct node_tag *new_node = ast_alloc(NODE_ID); + new_node->data.id.name = name; + return new_node; } -struct node_tag* ast_make_line(int line, struct node_tag* stmt) { - struct node_tag *n = malloc(sizeof(struct node_tag)); - int *i = malloc(sizeof(int)); - *i = line; - n->type = NODE_LINE; - n->node0 = i; - n->node1 = stmt; - ast_last_line = n; - return n; +struct node_tag* ast_make_number_integer(int val) { + struct node_tag *new_node = ast_alloc(NODE_NUMBER_INTEGER); + new_node->data.number_integer.val = val; + return new_node; } diff --git a/ast.h b/ast.h index 9f388ff..f45ea76 100644 --- a/ast.h +++ b/ast.h @@ -1,7 +1,8 @@ +#include <stdio.h> #include <stdlib.h> enum NODE_TYPE { - NODE_LINE, + NODE_NUMBERED_LINE, NODE_PRINT, NODE_IF, NODE_ADD, @@ -18,13 +19,48 @@ enum NODE_TYPE { NODE_ID }; +struct node_line_data { + int linum; + struct node_tag* stmt; +}; + +struct node_string_data { + char *str; +}; + +struct node_print_data { + struct node_tag* expr; +}; + +struct node_iff_data { + struct node_tag* pred; + struct node_tag* stmt; +}; + +struct node_id_data { + char *name; +}; + +struct node_number_integer_data { + int val; +}; + struct node_tag { enum NODE_TYPE type; - void *node0; - void *node1; + union { + struct node_line_data line; + struct node_string_data string; + struct node_print_data print; + struct node_iff_data iff; + struct node_id_data id; + struct node_number_integer_data number_integer; + } data; }; struct node_tag* ast_make_string(char *s); -struct node_tag* ast_make_line(int linum, struct node_tag* stmt); - -extern struct node_tag* ast_last_line; +struct node_tag* ast_make_numbered_line(int linum, struct node_tag* stmt); +struct node_tag* ast_make_print(struct node_tag* expr); +struct node_tag* ast_make_if(struct node_tag* pred, struct node_tag* stmt); +struct node_tag* ast_make_id(char *name); +struct node_tag* ast_make_number_integer(int val); +extern struct node_tag* ast_last_numbered_line; diff --git a/bbasic.y b/bbasic.y index 77c73c5..f633697 100644 --- a/bbasic.y +++ b/bbasic.y @@ -15,7 +15,7 @@ void yyerror(const char *s) { int num_int; char *id; char *str; - struct type_node *node; + struct node_tag *node; } %token <num_int> NUMBER_INTEGER @@ -23,7 +23,9 @@ void yyerror(const char *s) { %token <str> STRING %token PRINT IF THEN GOTO LT LTE GT GTE EQ -%type <node> line expression statement +%type <node> line +%type <node> expression +%type <node> statement %define parse.error verbose @@ -33,28 +35,36 @@ void yyerror(const char *s) { %% line: NUMBER_INTEGER statement { - $$ = ast_make_line($1, $2); + $$ = ast_make_numbered_line($1, $2); } ; statement: - PRINT expression - | IF expression THEN statement + PRINT expression { + $$ = ast_make_print($2); + } + | IF expression THEN statement { + $$ = ast_make_if($2, $4); + } ; expression: - IDENTIFIER + IDENTIFIER { + $$ = ast_make_id($1); + } | STRING { $$ = ast_make_string($1); } - | NUMBER_INTEGER - | expression '+' expression - | expression '-' expression - | expression '*' expression - | expression '/' expression - | expression LT expression - | expression LTE expression - | expression GT expression - | expression GTE expression + | NUMBER_INTEGER { + $$ = ast_make_number_integer($1); + } + /* | expression '+' expression */ + /* | expression '-' expression */ + /* | expression '*' expression */ + /* | expression '/' expression */ + /* | expression LT expression */ + /* | expression LTE expression */ + /* | expression GT expression */ + /* | expression GTE expression */ ; %% diff --git a/main.c b/main.c index 4f0583a..eccf205 100644 --- a/main.c +++ b/main.c @@ -9,7 +9,7 @@ int main() { while (1) { if(!yyparse()) { printf("It parsed :-)\n"); - printf("linum: %d\n", *(int *)ast_last_line->node0); + printf("linum: %d\n", ast_last_numbered_line->data.line.linum); } } return 0;