git » unicorn-sparkle-basic.git » commit bc59cf4

improve ast memory model, add more nodes

author Alan Dipert
2024-01-07 06:23:35 UTC
committer Alan Dipert
2024-01-07 06:23:35 UTC
parent 99beec2dfe7d63cdeab8d4f97d18dcad8f8c8047

improve ast memory model, add more nodes

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;