]> git.mdlowis.com Git - proto/obnc.git/commitdiff
much scaffolding for SSA
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 21 Jul 2021 02:51:47 +0000 (22:51 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 21 Jul 2021 02:51:47 +0000 (22:51 -0400)
cerise/inc/cerise.h
cerise/src/ast.c
cerise/src/grammar.c
cerise/src/ssa.c [new file with mode: 0644]
cerise/src/sym.c
cerise/tests/Module.m

index 40b55a6ccb50c7624ed3b21bceb2711a04a3b08a..94182e877341d9acca5418f8c55dc4c6278e2185 100644 (file)
@@ -111,6 +111,51 @@ typedef struct AstNode {
     struct AstNode* links[3];
 } AstNode;
 
+
+
+typedef struct {
+    size_t symid;
+    size_t symver;
+} SsaVar;
+
+typedef union {
+    long long i;
+    double f;
+    char* s;
+} SsaConst;
+
+typedef union {
+    SsaVar var;
+    SsaConst val;
+} SsaValue;
+
+typedef struct SsaNode {
+    struct SsaNode* next;
+    int code : 27;
+    int mode : 4;
+    int loaded : 1;
+    Type* type;
+    SsaVar dest;
+    SsaValue left;
+    SsaValue right;
+} SsaNode;
+
+typedef struct {
+    size_t id;
+    SsaNode* head;
+    SsaNode* tail;
+} SsaBlock;
+
+enum {
+    MODE_CONST   = 0,
+    MODE_VAR     = 1,
+    MODE_OP      = 2,
+    MODE_CONTROL = 3,
+};
+
+
+
+
 typedef struct Symbol {
     enum{
         SYM_MODULE, SYM_CONST, SYM_VAR, SYM_TYPE, SYM_PROC
@@ -118,8 +163,9 @@ typedef struct Symbol {
     char* name;
     Type* type;
     struct Symbol* desc;
-    AstNode* value;
+    SsaNode* value;
     long nargs;
+    long version;
     size_t module;
     int export : 1;
     int global : 1;
@@ -133,6 +179,10 @@ typedef struct {
     long curr_reg;
     size_t scope;
 
+    SsaBlock* curr_block;
+    SsaBlock* curr_join;
+
+
     size_t msyms;
     size_t nsyms;
     Symbol* syms;
@@ -197,15 +247,15 @@ bool ast_isconst(AstNode* node);
 bool ast_areconst(AstNode* left, AstNode* right);
 
 AstNode* ast_ident(Parser* p, long long index);
-AstNode* ast_bool(bool val);
-AstNode* ast_int(long long val);
-AstNode* ast_real(double val);
+AstNode* ast_bool(Parser* p, bool val);
+AstNode* ast_int(Parser* p, long long val);
+AstNode* ast_real(Parser* p, double val);
 
 bool ast_asbool(AstNode* node);
 long long ast_asint(AstNode* node);
 double ast_asreal(AstNode* node);
 
-AstNode* ast_op(int op, AstNode* left, AstNode* right);
+AstNode* ast_op(Parser* p, int op, AstNode* left, AstNode* right);
 AstNode* ast_store(AstNode* dest, AstNode* value);
 AstNode* ast_fieldref(Parser* p, AstNode* record, char* fname);
 AstNode* ast_index(Parser* p, AstNode* array, AstNode* index);
@@ -219,6 +269,38 @@ AstNode* ast_return(AstNode* expr);
 
 void ast_print(Parser* p, AstNode* expr);
 
+
+
+
+
+bool ssa_asbool(SsaNode* node);
+long long ssa_asint(SsaNode* node);
+double ssa_asreal(SsaNode* node);
+
+SsaNode* ssa_ident(Parser* p, long long index);
+SsaNode* ssa_bool(Parser* p, bool val);
+SsaNode* ssa_int(Parser* p, long long val);
+SsaNode* ssa_real(Parser* p, double val);
+SsaNode* ssa_op(Parser* p, int op, SsaNode* left, SsaNode* right);
+
+SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value);
+SsaNode* ssa_fieldref(Parser* p, SsaNode* record, char* fname);
+SsaNode* ssa_index(Parser* p, SsaNode* array, SsaNode* index);
+
+SsaBlock* ssa_block(void);
+void ssa_block_add(SsaBlock* blk, SsaNode* stmt);
+
+SsaNode* ssa_if(SsaNode* cond, SsaBlock* br1, SsaBlock* br2);
+SsaNode* ssa_return(SsaNode* expr);
+
+SsaNode* ssa_call(SsaNode* func);
+void ssa_call_add(SsaBlock* call, SsaNode* arg);
+
+void ssa_print(Parser* p, SsaNode* expr);
+void ssa_print_block(Parser* p, SsaBlock* block);
+
+
+
 /* Backend Code Generation and Base Type Definitions
  *****************************************************************************/
 extern Type VoidType, BoolType, IntType, RealType, StringType;
index 559b7663e6750a34b2ac2e1a1b54c4a6eec27625..403445f08b96569ec2d0068b568b28ba79446104 100644 (file)
@@ -145,22 +145,25 @@ AstNode* ast_ident(Parser* p, long long index)
     return (AstNode*)node;
 }
 
-AstNode* ast_bool(bool val)
+AstNode* ast_bool(Parser* p, bool val)
 {
+    (void)p;
     AstValue* node = (AstValue*)ast_new(BOOL, &BoolType, NULL, NULL, NULL);
     node->val.i = val;
     return (AstNode*)node;
 }
 
-AstNode* ast_int(long long val)
+AstNode* ast_int(Parser* p, long long val)
 {
+    (void)p;
     AstValue* node = (AstValue*)ast_new(INT, &IntType, NULL, NULL, NULL);
     node->val.i = val;
     return (AstNode*)node;
 }
 
-AstNode* ast_real(double val)
+AstNode* ast_real(Parser* p, double val)
 {
+    (void)p;
     AstValue* node = (AstValue*)ast_new(REAL, &RealType, NULL, NULL, NULL);
     node->val.f = val;
     return (AstNode*)node;
@@ -357,8 +360,9 @@ static AstNode* ast_unop(int op, AstNode* operand)
     return ret;
 }
 
-AstNode* ast_op(int op, AstNode* left, AstNode* right)
+AstNode* ast_op(Parser* p, int op, AstNode* left, AstNode* right)
 {
+    (void)p;
     return (right
         ? ast_binop(op, left, right)
         : ast_unop(op, left));
@@ -391,7 +395,7 @@ static Field* get_field(Parser* p, Type* type, char* name)
 AstNode* ast_fieldref(Parser* p, AstNode* record, char* fname)
 {
     Field* field = get_field(p, record->hdr.type, fname);
-    AstNode* offset = ast_int(field->offset);
+    AstNode* offset = ast_int(p, field->offset);
     if (record->hdr.code == '.')
     {
         /* accumulate the offset into an existing record access */
index 14300cb28c3a92a26a2fc8705b1a6cd2105c09af..29cdc2112e4be6d055715cf4103923c7671be193 100644 (file)
@@ -52,13 +52,13 @@ static Field* add_field(Parser* p, Type* type, char* name, bool export)
 
 /* Grammar Definition
  *****************************************************************************/
-static AstNode* expression(Parser* p);
+static SsaNode* expression(Parser* p);
 
-static AstNode* qualident(Parser* p)
+static SsaNode* qualident(Parser* p)
 {
     ENTER_RULE();
 
-    AstNode* expr;
+    SsaNode* expr;
     char* name = expect_text(p, IDENT);
     size_t symid = symbol_getid(p, 0, name, -1);
     Symbol* sym = symbol_getbyid(p, symid);
@@ -72,17 +72,17 @@ static AstNode* qualident(Parser* p)
     }
 
     /* make the identifier with the final index */
-    expr = ast_ident(p, symid);
+    expr = ssa_ident(p, symid);
 
     EXIT_RULE();
     return expr;
 }
 
-static AstNode* designator(Parser* p)
+static SsaNode* designator(Parser* p)
 {
     ENTER_RULE();
 
-    AstNode* expr = qualident(p);
+    SsaNode* expr = qualident(p);
 
     /* selector */
     for (int done = 0; !done;)
@@ -92,25 +92,25 @@ static AstNode* designator(Parser* p)
             case '.':
             {
                 expect(p, '.');
-                if (expr->hdr.type->form != FORM_RECORD)
+                if (expr->type->form != FORM_RECORD)
                 {
                     error(p, "attempting to access field of non-array object");
                 }
                 char* name = expect_text(p, IDENT);
-                expr = ast_fieldref(p, expr, name);
+                expr = ssa_fieldref(p, expr, name);
                 break;
             }
 
             case '[':
             {
                 expect(p, '[');
-                if (expr->hdr.type->form != FORM_ARRAY)
+                if (expr->type->form != FORM_ARRAY)
                 {
                     error(p, "attempting to index non-array value");
                 }
-                AstNode* index = expression(p);
-                check_int(p, index);
-                expr = ast_index(p, expr, index);
+                SsaNode* index = expression(p);
+//                check_int(p, index);
+                expr = ssa_index(p, expr, index);
                 expect(p, ']');
                 break;
             }
@@ -135,26 +135,26 @@ static AstNode* designator(Parser* p)
     return expr;
 }
 
-static AstNode* factor(Parser* p)
+static SsaNode* factor(Parser* p)
 {
     ENTER_RULE();
 
-    AstNode* expr = NULL;
+    SsaNode* expr = NULL;
 
     switch ((int)peek(p)->type)
     {
         case INT:
-            expr = ast_int(peek(p)->value.integer);
+            expr = ssa_int(p, peek(p)->value.integer);
             consume(p);
             break;
 
         case REAL:
-            expr = ast_real(peek(p)->value.floating);
+            expr = ssa_real(p, peek(p)->value.floating);
             consume(p);
             break;
 
         case BOOL:
-            expr = ast_bool(peek(p)->value.integer);
+            expr = ssa_bool(p, peek(p)->value.integer);
             consume(p);
             break;
 
@@ -166,49 +166,49 @@ static AstNode* factor(Parser* p)
 
         case NOT:
             consume(p);
-            expr = ast_op(NOT, factor(p), NULL);
+            expr = ssa_op(p, NOT, factor(p), NULL);
             break;
 
         case IDENT:
             expr = designator(p);
-            if (accept(p, '('))
-            {
-                expr = ast_call(expr);
-                if (expr->hdr.type->form != FORM_PROC)
-                {
-                    error(p, "attempting to call a non-procedural value");
-                }
-
-                Field* args = expr->hdr.type->fields;
-                while (args && !matches(p, ')'))
-                {
-                    AstNode* val = expression(p);
-                    check_type(p, args->type, val);
-                    ast_call_add(expr, val);
-                    args = args->next;
-                    if (args)
-                    {
-                        expect(p, ',');
-                    }
-                }
-                if (args)
-                {
-                    error(p, "too few arguments to function");
-                }
-                else if (!matches(p, ')'))
-                {
-                    bool comma = accept(p, ',');
-                    if (comma && matches(p, ')'))
-                    {
-                        error(p, "trailing comma in argument list");
-                    }
-                    else
-                    {
-                        error(p, "too many arguments to function");
-                    }
-                }
-                expect(p, ')');
-            }
+//            if (accept(p, '('))
+//            {
+//                expr = ssa_call(expr);
+//                if (expr->type->form != FORM_PROC)
+//                {
+//                    error(p, "attempting to call a non-procedural value");
+//                }
+//
+//                Field* args = expr->type->fields;
+//                while (args && !matches(p, ')'))
+//                {
+//                    SsaNode* val = expression(p);
+//                    check_type(p, args->type, val);
+//                    ssa_call_add(expr, val);
+//                    args = args->next;
+//                    if (args)
+//                    {
+//                        expect(p, ',');
+//                    }
+//                }
+//                if (args)
+//                {
+//                    error(p, "too few arguments to function");
+//                }
+//                else if (!matches(p, ')'))
+//                {
+//                    bool comma = accept(p, ',');
+//                    if (comma && matches(p, ')'))
+//                    {
+//                        error(p, "trailing comma in argument list");
+//                    }
+//                    else
+//                    {
+//                        error(p, "too many arguments to function");
+//                    }
+//                }
+//                expect(p, ')');
+//            }
             break;
 
         default:
@@ -221,29 +221,28 @@ static AstNode* factor(Parser* p)
     return expr;
 }
 
-
-static AstNode* term(Parser* p)
+static SsaNode* term(Parser* p)
 {
     ENTER_RULE();
 
-    AstNode* expr = factor(p);
+    SsaNode* expr = factor(p);
 
     while (matches_oneof(p, (int[]){'*', '/', '%', AND, 0}))
     {
         int op = consume(p);
-        AstNode* right = factor(p);
+        SsaNode* right = factor(p);
         switch(op)
         {
             case '*':
             case '/':
             case '%':
-                check_nums(p, expr, right);
-                expr = ast_op(op, expr, right);
+//                check_nums(p, expr, right);
+                expr = ssa_op(p, op, expr, right);
                 break;
 
             case AND:
-                check_bools(p, expr, right);
-                expr = ast_op(op, expr, right);
+//                check_bools(p, expr, right);
+                expr = ssa_op(p, op, expr, right);
                 break;
 
             default:
@@ -257,19 +256,19 @@ static AstNode* term(Parser* p)
     return expr;
 }
 
-static AstNode* simple_expr(Parser* p)
+static SsaNode* simple_expr(Parser* p)
 {
     ENTER_RULE();
 
-    AstNode* expr;
+    SsaNode* expr;
 
     /* first term and +/- unary ops */
     if (matches_oneof(p, (int[]){'+', '-', 0}))
     {
         int op = consume(p);
-        AstNode* operand = term(p);
-        check_num(p, operand);
-        expr = ast_op(op, operand, NULL);
+        SsaNode* operand = term(p);
+//        check_num(p, operand);
+        expr = ssa_op(p, op, operand, NULL);
     }
     else
     {
@@ -280,16 +279,16 @@ static AstNode* simple_expr(Parser* p)
     while (matches_oneof(p, (int[]){'+', '-', OR, 0}))
     {
         int op = consume(p);
-        AstNode* right = term(p);
+        SsaNode* right = term(p);
         if (op == OR)
         {
-            check_bools(p, expr, right);
+//            check_bools(p, expr, right);
         }
         else
         {
-            check_nums(p, expr, right);
+//            check_nums(p, expr, right);
         }
-        expr = ast_op(op, expr, right);
+        expr = ssa_op(p, op, expr, right);
     }
 
     EXIT_RULE();
@@ -297,19 +296,19 @@ static AstNode* simple_expr(Parser* p)
     return expr;
 }
 
-static AstNode* expression(Parser* p)
+static SsaNode* expression(Parser* p)
 {
     const int ops[] = { EQ, NEQ, '<', LTEQ, '>', GTEQ, 0 };
     ENTER_RULE();
 
-    AstNode* expr = simple_expr(p);
+    SsaNode* expr = simple_expr(p);
 
     if (matches_oneof(p, ops))
     {
         int op = consume(p);
-        AstNode* right = simple_expr(p);
-        check_nums(p, expr, right);
-        expr = ast_op(op, expr, right);
+        SsaNode* right = simple_expr(p);
+//        check_nums(p, expr, right);
+        expr = ssa_op(p, op, expr, right);
     }
 
     EXIT_RULE();
@@ -329,13 +328,13 @@ static Type* type(Parser* p)
     }
     else if (accept(p, ARRAY))
     {
-        AstNode* lnode = expression(p);
-        if (!ast_isconst(lnode))
+        SsaNode* lnode = expression(p);
+        if (lnode->mode != MODE_CONST)
         {
             error(p, "non-constant array size");
         }
-        check_int(p, lnode);
-        long long length = ast_asint(lnode);
+//        check_int(p, lnode);
+        long long length = ssa_asint(lnode);
         expect(p, OF);
         Type* base = type(p);
         ret = symbol_newtype(p);
@@ -393,39 +392,39 @@ static Type* type(Parser* p)
     return ret;
 }
 
-static AstNode* statement_seq(Parser* p)
+static SsaBlock* statement_seq(Parser* p)
 {
     ENTER_RULE();
-    AstNode* block = ast_block();
+    SsaBlock* block = ssa_block();
 
     do
     {
-        if (matches(p, IF))
-        {
-            expect(p, IF);
-            AstNode* cond = expression(p);
-            check_bool(p, cond);
-            expect(p, THEN);
-            AstNode* blk1 = statement_seq(p);
-            AstNode* blk2 = NULL;
-            if (accept(p, ELSE))
-            {
-                blk2 = statement_seq(p);
-            }
-            ast_block_add(block, ast_if(cond, blk1, blk2));
-            expect(p, END);
-        }
-        else /* assignments/expressions */
+//        if (matches(p, IF))
+//        {
+//            expect(p, IF);
+//            SsaNode* cond = expression(p);
+////            check_bool(p, cond);
+//            expect(p, THEN);
+//            SsaNode* blk1 = statement_seq(p);
+//            SsaNode* blk2 = NULL;
+//            if (accept(p, ELSE))
+//            {
+//                blk2 = statement_seq(p);
+//            }
+//            ssa_block_add(block, ssa_if(cond, blk1, blk2));
+//            expect(p, END);
+//        }
+//        else /* assignments/expressions */
         {
-            AstNode* expr = expression(p);
+            SsaNode* expr = expression(p);
             if (accept(p, '='))
             {
-                AstNode* right = expression(p);
-                check_types(p, expr, right);
-                expr = ast_store(expr, right);
+                SsaNode* right = expression(p);
+//                check_types(p, expr, right);
+                expr = ssa_store(p, expr, right);
             }
             expect(p, ';');
-            ast_block_add(block, expr);
+            ssa_block_add(block, expr);
         }
     }
     while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF) && !matches(p, RETURN));
@@ -482,12 +481,9 @@ static void const_decl(Parser* p)
         export = accept(p, '*');
         sym = symbol_new(p, 0, name, SYM_CONST, export);
         expect(p, '=');
-//        AstNode* block = ast_block();
-//        expression(p, block);
-//        sym->value = ast_lastval(block);
-//        check_const(sym->value);
         sym->value = expression(p);
-        sym->type = sym->value->hdr.type;
+        sym->type = sym->value->type;
+        printf("%p\n", sym->value);
     }
     while (matches(p, IDENT));
 
@@ -529,6 +525,7 @@ void proc_decl(Parser* p)
     /* parse the private declarations */
     if (accept(p, CONST))
     {
+        p->curr_block = ssa_block();
         const_decl(p);
     }
 
@@ -542,26 +539,26 @@ void proc_decl(Parser* p)
         var_decl(p);
     }
 
-    /* parse the body of the procedure */
-    expect(p, BEGIN);
-    proc->value = ast_block();
-    if (!matches(p, RETURN) && !matches(p, END))
-    {
-        ast_block_add(proc->value, statement_seq(p));
-    }
-    if (proctype->base != &VoidType)
-    {
-        expect(p, RETURN);
-        AstNode* retval = expression(p);
-        check_type(p, proctype->base, retval);
-        ast_block_add(proc->value, ast_return(retval));
-        expect(p, ';');
-    }
-    expect(p, END);
-    symbol_closescope(p, scope);
-
-    ast_print(p, proc->value);
-    (void)proc->value;
+//    /* parse the body of the procedure */
+//    expect(p, BEGIN);
+//    proc->value = ast_block();
+//    if (!matches(p, RETURN) && !matches(p, END))
+//    {
+//        ast_block_add(proc->value, statement_seq(p));
+//    }
+//    if (proctype->base != &VoidType)
+//    {
+//        expect(p, RETURN);
+//        AstNode* retval = expression(p);
+//        check_type(p, proctype->base, retval);
+//        ast_block_add(proc->value, ast_return(retval));
+//        expect(p, ';');
+//    }
+//    expect(p, END);
+//    symbol_closescope(p, scope);
+//
+//    ast_print(p, proc->value);
+//    (void)proc->value;
 
     EXIT_RULE();
 }
@@ -632,8 +629,8 @@ static void module(Parser* p)
 //        }
         if (!matches(p, END))
         {
-            AstNode* block = statement_seq(p);
-            ast_print(p, block);
+            SsaBlock* block = statement_seq(p);
+//            ast_print(p, block);
             (void)block;
         }
         expect(p, END);
@@ -684,6 +681,7 @@ void compile(char* fname)
 
     p->mtypes = 8;
     p->types = calloc(p->mtypes, sizeof(Type*));
+    symbol_new(p, 0, "$",  SYM_VAR, 0);
     symbol_new(p, 0, "Bool",   SYM_TYPE, 0)->type = &BoolType;
     p->types[p->ntypes++] = &BoolType;
     symbol_new(p, 0, "Int",    SYM_TYPE, 0)->type = &IntType;
diff --git a/cerise/src/ssa.c b/cerise/src/ssa.c
new file mode 100644 (file)
index 0000000..0884cd3
--- /dev/null
@@ -0,0 +1,360 @@
+#include <cerise.h>
+
+static SsaNode* ssa_node(int code, int mode);
+static SsaNode* binop(Parser* p, int op, SsaNode* left, SsaNode* right);
+static SsaNode* unop(Parser* p, int op, SsaNode* operand);
+static SsaNode* const_binop(Parser* p, int op, SsaNode* left, SsaNode* right);
+static SsaNode* const_unop(Parser* p, int op, SsaNode* operand);
+static SsaNode* load(Parser* p, SsaNode* node);
+
+bool ssa_asbool(SsaNode* node)
+{
+    assert(node->code == BOOL);
+    return (bool)(node->left.val.i);
+}
+
+long long ssa_asint(SsaNode* node)
+{
+    assert(node->code == INT);
+    return (bool)(node->left.val.i);
+}
+
+double ssa_asreal(SsaNode* node)
+{
+    assert(node->code == REAL);
+    return (bool)(node->left.val.f);
+}
+
+static SsaNode* ssa_node(int code, int mode)
+{
+    SsaNode* node = calloc(1, sizeof(SsaNode));
+    node->code = code;
+    node->mode = mode;
+    node->dest.symid = 0;
+    node->dest.symver = 0; /* TODO: increment temp ver */
+    return node;
+}
+
+SsaNode* ssa_ident(Parser* p, long long index)
+{
+    Symbol* sym = symbol_getbyid(p, index);
+    SsaNode* node = ssa_node(IDENT, MODE_VAR);
+    node->left.var.symid = index;
+    node->left.var.symver = sym->version;
+    return node;
+}
+
+SsaNode* ssa_bool(Parser* p, bool val)
+{
+    (void)p;
+    SsaNode* node = ssa_node(BOOL, MODE_CONST);
+    node->type = &BoolType;
+    node->left.val.i = val;
+    return node;
+}
+
+SsaNode* ssa_int(Parser* p, long long val)
+{
+    (void)p;
+    SsaNode* node = ssa_node(INT, MODE_CONST);
+    node->type = &IntType;
+    node->left.val.i = val;
+    return node;
+}
+
+SsaNode* ssa_real(Parser* p, double val)
+{
+    (void)p;
+    SsaNode* node = ssa_node(REAL, MODE_CONST);
+    node->type = &RealType;
+    node->left.val.f = val;
+    return node;
+}
+
+SsaNode* ssa_op(Parser* p, int op, SsaNode* left, SsaNode* right)
+{
+    return (right != NULL)
+        ? binop(p, op, left, right)
+        : unop(p, op, left);
+}
+
+SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value)
+{
+    assert("!stores are not implemented");
+    load(p, value);
+    load(p, dest);
+    return NULL;
+}
+
+SsaNode* ssa_fieldref(Parser* p, SsaNode* record, char* fname)
+{
+    assert("!record field references unimplemented");
+    return NULL;
+}
+
+SsaNode* ssa_index(Parser* p, SsaNode* array, SsaNode* index)
+{
+    load(p, array);
+    load(p, index);
+    assert(!"array indexing unimplemented");
+    return NULL;
+}
+
+SsaBlock* ssa_block(void)
+{
+    return calloc(1, sizeof(SsaBlock));
+}
+
+void ssa_block_add(SsaBlock* blk, SsaNode* node)
+{
+    if (blk->head == 0)
+    {
+        blk->head = node;
+        blk->tail = node;
+    }
+    else
+    {
+        blk->tail->next = node;
+        blk->tail = node;
+    }
+}
+
+SsaNode* ssa_if(SsaNode* cond, SsaBlock* br1, SsaBlock* br2);
+SsaNode* ssa_return(SsaNode* expr);
+
+SsaNode* ssa_call(SsaNode* func);
+void ssa_call_add(SsaBlock* call, SsaNode* arg);
+
+
+
+
+
+void ssa_print_block(Parser* p, SsaBlock* block);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+static SsaNode* binop(Parser* p, int op, SsaNode* left, SsaNode* right)
+{
+    SsaNode* node = NULL;
+    if (left->mode == MODE_CONST && right->mode == MODE_CONST)
+    {
+        node = const_binop(p, op, left, right);
+    }
+    else
+    {
+        left = load(p, left);
+        right = load(p, right);
+        node = ssa_node(op, MODE_OP);
+        node->type = left->type;
+        node->left.var = left->dest;
+        node->right.var = right->dest;
+    }
+    return node;
+}
+
+static SsaNode* unop(Parser* p, int op, SsaNode* operand)
+{
+    SsaNode* node = NULL;
+    if (operand->mode == MODE_CONST)
+    {
+        node = const_unop(p, op, operand);
+    }
+    else
+    {
+        operand = load(p, operand);
+        node = ssa_node(op, MODE_OP);
+        node->type = operand->type;
+        node->left.var = operand->dest;
+    }
+    return node;
+}
+
+static SsaNode* const_binop(Parser* p, int op, SsaNode* left, SsaNode* right)
+{
+    (void)p, (void)op, (void)left, (void)right;
+    /* perform the operation based on type and operator */
+    return NULL;
+}
+
+static SsaNode* const_unop(Parser* p, int op, SsaNode* operand)
+{
+    (void)p, (void)op, (void)operand;
+    /* perform the operation based on type and operator */
+    return NULL;
+}
+
+static SsaNode* load(Parser* p, SsaNode* node)
+{
+    if (!node->loaded)
+    {
+        ssa_block_add(p->curr_block, node);
+        node->loaded = 1;
+    }
+    return node;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//static void print_indent(int indent, char* str)
+//{
+//    /* print the indent */
+//    for (int i = 0; i < indent; i++)
+//    {
+//        printf("  ");
+//    }
+//    if (str)
+//    {
+//        printf("%s", str);
+//    }
+//}
+//
+//static void print_opcode(SsaNode* node)
+//{
+//    int op = node->code;
+//    if (op < 256)
+//    {
+//        printf(" %c ", op);
+//    }
+//    else if (op == RETURN)
+//    {
+//        printf(" return ");
+//    }
+//    else if (op == IF)
+//    {
+//        printf("if ");
+//    }
+//    else
+//    {
+//        printf("(%d\n", op);
+//    }
+//}
+//
+//static void print(Parser* p, AstNode* node, int indent)
+//{
+//    assert(node);
+//    print_indent(indent, NULL);
+//
+//    /* now print the data */
+//    switch(node->hdr.code)
+//    {
+//        case BOOL:
+//            printf("B:%lld", ((AstValue*)node)->val.i);
+//            break;
+//
+//        case INT:
+//            printf("I:%lld", ((AstValue*)node)->val.i);
+//            break;
+//
+//        case REAL:
+//            printf("R:%f", ((AstValue*)node)->val.f);
+//            break;
+//
+//        case IDENT:
+//            {
+//                Symbol* s = symbol_getbyid(p, ((AstValue*)node)->val.i);
+//                printf("%s.%lld", s->name, ((AstValue*)node)->tag);
+//            }
+//            break;
+//
+//        case '.':
+//            printf("(field-ref\n");
+//            print(p, node->links[0], indent+1);
+//            print(p, node->links[1], indent+1);
+//            print_indent(indent, ")");
+//            break;
+//
+//        case '[':
+//            printf("(array-index\n");
+//            print(p, node->links[0], indent+1);
+//            print(p, node->links[1], indent+1);
+//            print_indent(indent, ")");
+//            break;
+//
+//        case BEGIN:
+//            printf("(begin\n");
+//            for (AstNode* curr = node->links[0]; curr; curr = curr->hdr.next)
+//            {
+//                print(p, curr, indent+1);
+//            }
+//            print_indent(indent, ")");
+//            break;
+//
+//        case CALL:
+//            printf("(call\n");
+//            print(p, node->links[0], indent+1);
+//            for (AstNode* curr = node->links[1]; curr; curr = curr->hdr.next)
+//            {
+//                print(p, curr, indent+1);
+//            }
+//            print_indent(indent, ")");
+//            break;
+//
+//        case IF:
+//            printf("(if\n");
+//            print(p, node->links[0], indent+1);
+//            print(p, node->links[1], indent+1);
+//            if (node->links[2])
+//            {
+//                print(p, node->links[2], indent+1);
+//            }
+//            print_indent(indent, ")");
+//            break;
+//
+//        default:
+//            if (node->links[1])
+//            {
+//                print_opcode(node);
+//                print(p, node->links[0], indent+1);
+//                print(p, node->links[1], indent+1);
+//                print_indent(indent, ")");
+//            }
+//            else
+//            {
+//                print_opcode(node);
+//                print(p, node->links[0], indent+1);
+//                print_indent(indent, ")");
+//            }
+//            break;
+//    }
+//    puts("");
+//}
+//
+//void ast_print(Parser* p, AstNode* node)
+//{
+//    print(p, node, 0);
+//}
+//
+void ssa_print(Parser* p, SsaNode* expr)
+{
+//    switch (expr->code)
+//    {
+//        case
+//    }
+}
index 41b986cf3a1419381de14c87a9458b7df4ddde51..75c1cc7d3ae9535c9fa7d657c77f13582d1b9491 100644 (file)
@@ -242,9 +242,8 @@ void symbol_import(Parser* p, char* name, char* alias)
     /* TODO: read symbols from real symbol file */
     // All of these should set ->module = modid
 
-    Symbol* sym = symbol_new(p, 0, "testint", SYM_CONST, true);
+    Symbol* sym = symbol_new(p, 0, "testint", SYM_VAR, true);
     sym->module = modid;
-    sym->value = ast_int(42);
 }
 
 /* Symbol Table Unit Tests
index 87490956181166c659dad0ca4507f57175e38bc0..995f67b18513991d955639db8c5cdb499fa3c7d2 100644 (file)
@@ -9,37 +9,37 @@ const
   B* = 42
   C* = 42.0
   D = -B
-  E = -C
-  F = not A
-  G = B + 2 - 2 * 2
-  H = false or A
+#  E = -C
+#  F = not A
+#  G = B + 2 - 2 * 2
+#  H = false or A
 
-type
-  TypeA* = Int
-  TypeB* = array 5*B of Int
-  TypeC* = array 5 of array 10 of Int
-  TypeD* = record
-    x,y : Int
-    label : array 10 of Int
-    dim : record
-      w,h : Int
-    end
-  end
-  TypeE* = record
-    i : Int
-    a : array 5 of Int
-  end
-  TypeF* = array 5 of TypeE
+#type
+#  TypeA* = Int
+#  TypeB* = array 5*B of Int
+#  TypeC* = array 5 of array 10 of Int
+#  TypeD* = record
+#    x,y : Int
+#    label : array 10 of Int
+#    dim : record
+#      w,h : Int
+#    end
+#  end
+#  TypeE* = record
+#    i : Int
+#    a : array 5 of Int
+#  end
+#  TypeF* = array 5 of TypeE
 
-var
-  a* : Bool
-  b* : Int
-  c : Int
-  d : Real
-  e : array 5 of array 10 of Int
-  f : TypeD
-  g : array 5 of Int
-  h : TypeF
+#var
+#  a* : Bool
+#  b* : Int
+#  c : Int
+#  d : Real
+#  e : array 5 of array 10 of Int
+#  f : TypeD
+#  g : array 5 of Int
+#  h : TypeF
 
 #procedure Foo*(e : Int, z : Int, q1 : TypeD, q2 : array 5 of Int) : Int
 #  const FOO = 2
@@ -68,7 +68,7 @@ var
 #    end
 #end
 
-begin
+#begin
 #    h[1].i = 42;
 #  a = true;
 #  a = A;
@@ -155,4 +155,4 @@ begin
 #    Bar(Foo.testint);
 #    Bar(Bar2.testint);
 #    Bar(Bar3.testint);
-end
+#end