]> git.mdlowis.com Git - proto/obnc.git/commitdiff
fixed up constants and constant unary ops
authorMichael D. Lowis <mike.lowis@gentex.com>
Fri, 11 Jun 2021 20:45:40 +0000 (16:45 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Fri, 11 Jun 2021 20:45:40 +0000 (16:45 -0400)
cerise/inc/cerise.h
cerise/src/grammar.c
cerise/src/sym.c
cerise/tests/Module.m

index ce835a5f3b008ffb4ed073522197a4f7ef2ea88d..fa1345fce60050e22bc2cc2b3b31c7ed19a5f46f 100644 (file)
@@ -102,7 +102,7 @@ typedef union {
     long long i;
     double f;
     char* s;
-} ImmValue;
+} Operand;
 
 typedef struct Symbol {
     enum{
@@ -112,7 +112,7 @@ typedef struct Symbol {
     Type* type;
     struct Symbol* desc;
     long nargs;
-    ImmValue imm;
+    Operand imm;
     int export : 1;
     int global : 1;
 } Symbol;
@@ -132,7 +132,7 @@ typedef struct Item {
     Symbol* sym;
     Type* type;
     int reg;
-    ImmValue imm;
+    Operand imm;
 } Item;
 
 typedef struct {
@@ -171,6 +171,8 @@ int consume(Parser* p);
 // src/sym.c
 Symbol* symbol_new(Parser* p, size_t scope, char* name, int class, bool export);
 Symbol* symbol_get(Parser* p, char* name, int class);
+size_t symbol_getid(Parser* p, char* name, int class);
+Symbol* symbol_getbyid(Parser* p, size_t id);
 size_t symbol_openscope(Parser* p);
 void symbol_closescope(Parser* p, size_t scope);
 
@@ -230,19 +232,17 @@ void codegen_index(Parser* p, Item* array, Item* index);
 void codegen_field(Parser* p, Item* record, char* name);
 
 enum {
-    IR_CONST
+    IR_MODE_CONST,
+    IR_MODE_VAR,
+    IR_MODE_TYPE,
+    IR_MODE_INFO,
 };
 
-typedef union {
-    long i;
-    double f;
-    char* s;
-} Operand;
-
 typedef struct Operation {
 //    struct Operation* next;
     int code : 28;
     int mode : 4;
+    Type* type;
     union {
         Operand args[3];
         struct {
index 812f8c9a1dcb67844b62232a94e669fb99c98e7b..3554da5895acf6a274465194fb1df39a2dc15fdb 100644 (file)
@@ -29,11 +29,15 @@ static void print_op(Operation* op)
     {
         case INT:
         case BOOL:
-            printf("    $%ld = %ld\n", op->u.args[0].i, op->u.args[1].i);
+            printf("    $%lld = %lld\n", op->u.args[0].i, op->u.args[1].i);
             break;
 
         case REAL:
-            printf("    $%ld = %f\n", op->u.args[0].i, op->u.args[1].f);
+            printf("    $%lld = %f\n", op->u.args[0].i, op->u.args[1].f);
+            break;
+
+        default:
+            printf("    <unprintable op %d >\n", op->code);
             break;
     }
 }
@@ -67,14 +71,25 @@ static void ir_push(Operation* op)
     Ops[NumOps++] = op;
 }
 
+static void ir_bool(Parser* p, bool val)
+{
+    Operation* op = calloc(1, sizeof(Operation));
+    op->code = BOOL;
+    op->mode = IR_MODE_CONST;
+    op->type = &BoolType;
+    op->u.args[0].i = p->curr_reg++;
+    op->u.args[1].i = (long)val;
+    ir_push(op);
+}
+
 static void ir_int(Parser* p, long val)
 {
     Operation* op = calloc(1, sizeof(Operation));
     op->code = INT;
-    op->mode = IR_CONST;
+    op->mode = IR_MODE_CONST;
+    op->type = &IntType;
     op->u.args[0].i = p->curr_reg++;
     op->u.args[1].i = val;
-    print_op(op);
     ir_push(op);
 }
 
@@ -82,35 +97,29 @@ static void ir_real(Parser* p, double val)
 {
     Operation* op = calloc(1, sizeof(Operation));
     op->code = REAL;
-    op->mode = IR_CONST;
+    op->mode = IR_MODE_CONST;
+    op->type = &RealType;
     op->u.args[0].i = p->curr_reg++;
     op->u.args[1].f = val;
-    print_op(op);
     ir_push(op);
 }
 
 static void ir_getconst(Parser* p, Symbol* sym)
 {
     Operation* op = ir_pop();
-    if (op->mode != IR_CONST)
+    print_op(op);
+    if (op->mode != IR_MODE_CONST)
     {
         error(p, "Constant definition is non-constant");
     }
-//    sym->type = op->type;
-    if (op->code == INT)
-    {
-        sym->imm.i = op->u.args[1].i;
-    }
-    else
-    {
-        sym->imm.i = op->u.args[1].f;
-    }
+    sym->type = op->type;
+    sym->imm = op->u.args[1];
 }
 
 static void ir_unop(Parser* p, int op)
 {
     Operation* a = ir_pop();
-    if (a->mode == IR_CONST)
+    if (a->mode == IR_MODE_CONST)
     {
         if (a->code == INT)
         {
@@ -118,7 +127,9 @@ static void ir_unop(Parser* p, int op)
             {
                 case '+': a->u.args[1].i = +a->u.args[1].i; break;
                 case '-': a->u.args[1].i = -a->u.args[1].i; break;
-                default:  assert(!"not a valid op");    break;
+                default:
+                    error(p, "invalid unary operation on integer value");
+                    break;
             }
         }
         else if (a->code == REAL)
@@ -127,7 +138,9 @@ static void ir_unop(Parser* p, int op)
             {
                 case '+': a->u.args[1].f = +a->u.args[1].f; break;
                 case '-': a->u.args[1].f = -a->u.args[1].f; break;
-                default:  assert(!"not a valid op");    break;
+                default:
+                    error(p, "invalid unary operation on real value");
+                    break;
             }
         }
         else if (a->code == BOOL)
@@ -135,18 +148,75 @@ static void ir_unop(Parser* p, int op)
             switch (op)
             {
                 case NOT: a->u.args[1].i = !a->u.args[1].i; break;
-                default:  assert(!"not a valid op");    break;
+                default:
+                    error(p, "invalid unary operation on boolean value");
+                    break;
             }
         }
     }
     else
     {
-        assert(!"unimplemented unary op");
+        error(p, "unimplemented unary operation");
     }
-    print_op(a);
     ir_push(a);
 }
 
+void ir_load(Parser* p, char* name)
+{
+    size_t id = symbol_getid(p, name, -1);
+    Symbol* sym = symbol_getbyid(p, id);
+
+    Operation* op = calloc(1, sizeof(Operation));
+    op->type = sym->type;
+    switch (sym->class)
+    {
+        case SYM_CONST:
+            op->mode = IR_MODE_CONST;
+            op->u.args[0].i = p->curr_reg++;
+            op->u.args[1] = sym->imm;
+            if (sym->type == &IntType)
+            {
+                op->code = INT;
+            }
+            else if (sym->type == &RealType)
+            {
+                op->code = REAL;
+            }
+            else if (sym->type == &BoolType)
+            {
+                op->code = BOOL;
+            }
+            else
+            {
+                error(p, "constant definition has unexpected type");
+            }
+            break;
+
+        case SYM_VAR:
+            op->code = VAR;
+            op->mode = IR_MODE_VAR;
+            op->u.args[0].i = p->curr_reg++;
+            op->u.args[1].i = id;
+            break;
+
+        case SYM_PROC:
+            op->code = VAR;
+            op->mode = IR_MODE_VAR;
+            op->u.args[0].i = p->curr_reg++;
+            op->u.args[1].i = id;
+            break;
+
+        case SYM_TYPE:
+            op->code = TYPE;
+            op->mode = IR_MODE_INFO;
+            break;
+
+        default:
+            break;
+    }
+    ir_push(op);
+}
+
 /* Item Handling
  *****************************************************************************/
 Field* add_field(Parser* p, Type* type, char* name, bool export)
@@ -183,25 +253,25 @@ Field* add_field(Parser* p, Type* type, char* name, bool export)
  *****************************************************************************/
 static void expression(Parser* p);
 
-//RULE(qualident, Item* item)
-//{
-//    ENTER_RULE();
-//    char* name = expect_text(p, IDENT);
-//    Symbol* sym = symbol_get(p, name, -1);
-//    init_item(item, sym);
-//    (void)sym;
-//
-////    if (accept(p, '.'))
-////    {
-////        expect(p, IDENT);
-////    }
-//    EXIT_RULE();
-//}
-//
-//RULE(designator, Item* item)
-//{
-//    ENTER_RULE();
-//    qualident(p, item);
+static void qualident(Parser* p)
+{
+    ENTER_RULE();
+
+    char* name = expect_text(p, IDENT);
+    ir_load(p, name);
+
+//    if (accept(p, '.'))
+//    {
+//        expect(p, IDENT);
+//    }
+
+    EXIT_RULE();
+}
+
+static void designator(Parser* p)
+{
+    ENTER_RULE();
+    qualident(p);
 //    /* selector */
 //    for (int done = 0; !done;)
 //    {
@@ -253,8 +323,8 @@ static void expression(Parser* p);
 //                break;
 //        }
 //    }
-//    EXIT_RULE();
-//}
+    EXIT_RULE();
+}
 
 static void factor(Parser* p)
 {
@@ -277,25 +347,24 @@ static void factor(Parser* p)
 //            break;
 
         case BOOL:
-            ir_int(p, peek(p)->value.integer);
+            ir_bool(p, peek(p)->value.integer);
             consume(p);
             break;
 
-//        case '(':
-//            expect(p, '(');
-//            expression(p, item);
-//            expect(p, ')');
-//            break;
+        case '(':
+            expect(p, '(');
+            expression(p);
+            expect(p, ')');
+            break;
 
-//        case NOT:
-//            consume(p);
-//            factor(p, item);
-//            check_bool(p, item);
-//            codegen_unop(p, NOT, item);
-//            break;
+        case NOT:
+            consume(p);
+            factor(p);
+            ir_unop(p, NOT);
+            break;
 
-//        case IDENT:
-//            designator(p, item);
+        case IDENT:
+            designator(p);
 //            if (accept(p, '('))
 //            {
 //                Symbol* proc = symbol_get(p, item->imm.s, SYM_PROC);
@@ -337,7 +406,7 @@ static void factor(Parser* p)
 //                codegen_call(p, item, arglist.next);
 //                expect(p, ')');
 //            }
-//            break;
+            break;
 
         default:
             printf("unknown factor: %d\n", peek(p)->type);
@@ -391,8 +460,6 @@ static void simple_expr(Parser* p)
         int op = consume(p); // OP
         term(p);
         ir_unop(p, op);
-//        check_num(p, item);
-//        codegen_unop(p, op, item);
     }
     else
     {
index eb42ce4fb5e6b3152a1b9983e24b7503c79eb3c8..2f6e5e0d50532f329f7549041cc0cf8f54ef503a 100644 (file)
@@ -81,21 +81,27 @@ Symbol* symbol_new(Parser* p, size_t scope, char* name, int class, bool export)
     return &(p->syms[p->nsyms-1]);
 }
 
-Symbol* symbol_get(Parser* p, char* name, int class)
+size_t symbol_getid(Parser* p, char* name, int class)
 {
-    Symbol* sym = NULL;
     size_t index = lookup(p, 0, name, class);
 
     if (NIL_SYMBOL == index)
     {
         error(p, "unknown symbol '%s'", name);
     }
-    else
-    {
-        sym = &(p->syms[index]);
-    }
 
-    return sym;
+    return index;
+}
+
+Symbol* symbol_getbyid(Parser* p, size_t id)
+{
+    return &(p->syms[id]);
+}
+
+Symbol* symbol_get(Parser* p, char* name, int class)
+{
+    size_t id = symbol_getid(p, name, class);
+    return symbol_getbyid(p, id);
 }
 
 size_t symbol_openscope(Parser* p)
index b862ea7b4cea3e921d8986ab16ae1ae6a268f2c4..8d026587351c4ee174fb57fd12af9944a86a6150 100644 (file)
@@ -7,6 +7,7 @@ module Module
 const
   A = true
   B = -42
+  C = not A
 
 #type
 #  TypeA = Int