]> git.mdlowis.com Git - proto/obnc.git/commitdiff
got basic expression parsing back up and running. Verified using constant evaluation...
authorMichael D. Lowis <mike.lowis@gentex.com>
Mon, 12 Jul 2021 16:40:17 +0000 (12:40 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Mon, 12 Jul 2021 16:40:17 +0000 (12:40 -0400)
cerise/inc/cerise.h
cerise/src/grammar.c
cerise/src/parse.c
cerise/src/type_checks.c
cerise/tests/Module.m

index 44c7bc75045e9ba4237c26150eb1eab7f9bbef9e..1d02883375ed899a98964b886497aff57d4ebbdd 100644 (file)
@@ -157,7 +157,7 @@ void lexprintpos(Parser* p, FILE* file, Tok* tok);
 Tok* peek(Parser* p);
 void error(Parser* p, const char* fmt, ...);
 bool matches(Parser* p, TokType type);
-bool matches_oneof(Parser* p, TokType types[]);
+bool matches_oneof(Parser* p, const TokType types[]);
 bool accept(Parser* p, TokType type);
 void expect(Parser* p, TokType type);
 Tok* expect_val(Parser* p, TokType type);
index a0eaaba37a8c8b96462327862ac5c2a7c0876e5c..70c97ccfd0606d3b8c6d1493db9cf936b5ee3c55 100644 (file)
@@ -229,30 +229,29 @@ static AstNode* term(Parser* p)
 
     AstNode* expr = factor(p);
 
-//    while (matches_oneof(p, (int[]){'*', '/', '%', AND, 0}))
-//    {
-//        Item right = { 0 };
-//        int op = consume(p);
-//        factor(p, &right);
-//        switch(op)
-//        {
-//            case '*':
-//            case '/':
-//            case '%':
-//                check_nums(p, item, &right);
-//                codegen_binop(p, op, item, &right);
-//                break;
-//
-//            case AND:
-//                check_bools(p, item, &right);
-//                codegen_binop(p, op, item, &right);
-//                break;
-//
-//            default:
-//                assert(!"not supported");
-//                break;
-//        }
-//    }
+    while (matches_oneof(p, (int[]){'*', '/', '%', AND, 0}))
+    {
+        int op = consume(p);
+        AstNode* right = factor(p);
+        switch(op)
+        {
+            case '*':
+            case '/':
+            case '%':
+                check_nums(p, expr, right);
+                expr = ast_binop(op, expr, right);
+                break;
+
+            case AND:
+                check_bools(p, expr, right);
+                expr = ast_binop(op, expr, right);
+                break;
+
+            default:
+                assert(!"not supported");
+                break;
+        }
+    }
 
     EXIT_RULE();
     assert(expr != NULL);
@@ -265,12 +264,12 @@ static AstNode* simple_expr(Parser* p)
 
     AstNode* expr;
 
-    /* first term and +/- */
+    /* first term and +/- unary ops */
     if (matches_oneof(p, (int[]){'+', '-', 0}))
     {
-        int op = consume(p); // OP
+        int op = consume(p);
         AstNode* operand = term(p);
-//        check_num(p, operand);
+        check_num(p, operand);
         expr = ast_unop(op, operand);
     }
     else
@@ -278,22 +277,21 @@ static AstNode* simple_expr(Parser* p)
         expr = term(p);
     }
 
-//    /* optional second term and op */
-//    while (matches_oneof(p, (int[]){'+', '-', OR, 0}))
-//    {
-//        Item right = { 0 };
-//        int op = consume(p);
-//        term(p, &right);
-//        if (op == OR)
-//        {
-//            check_bools(p, item, &right);
-//        }
-//        else
-//        {
-//            check_nums(p, item, &right);
-//        }
-//        codegen_binop(p, op, item, &right);
-//    }
+    /* optional second term and binary ops */
+    while (matches_oneof(p, (int[]){'+', '-', OR, 0}))
+    {
+        int op = consume(p);
+        AstNode* right = term(p);
+        if (op == OR)
+        {
+            check_bools(p, expr, right);
+        }
+        else
+        {
+            check_nums(p, expr, right);
+        }
+        expr = ast_binop(op, expr, right);
+    }
 
     EXIT_RULE();
     assert(expr != NULL);
@@ -302,20 +300,18 @@ static AstNode* simple_expr(Parser* p)
 
 static AstNode* expression(Parser* p)
 {
+    const int ops[] = { EQ, NEQ, '<', LTEQ, '>', GTEQ, 0 };
     ENTER_RULE();
 
-//    int ops[] = { EQ, NEQ, '<', LTEQ, '>', GTEQ, IS, 0 };
-
     AstNode* expr = simple_expr(p);
 
-//    if (matches_oneof(p, ops))
-//    {
-//        Item right = { 0 };
-//        int op = consume(p);
-//        simple_expr(p, &right);
-//        check_nums(p, item, &right);
-//        codegen_binop(p, op, item, &right);
-//    }
+    if (matches_oneof(p, ops))
+    {
+        int op = consume(p);
+        AstNode* right = simple_expr(p);
+        check_nums(p, expr, right);
+        expr = ast_binop(op, expr, right);
+    }
 
     EXIT_RULE();
     assert(expr != NULL);
@@ -486,7 +482,7 @@ static AstNode* expression(Parser* p)
 
 static void const_decl(Parser* p)
 {
-//    ENTER_RULE();
+    ENTER_RULE();
     char* name = NULL;
     bool export = false;
     Symbol* sym = NULL;
@@ -500,13 +496,9 @@ static void const_decl(Parser* p)
         sym->value = expression(p);
         ast_print(sym->value);
         puts("");
-        (void)sym; /* TODO: put const value into symbol table */
-//        ir_getconst(p, sym);
-//        sym->imm = item->imm;
-//        sym->type = item->type;
     }
     while (matches(p, IDENT));
-//    EXIT_RULE();
+    EXIT_RULE();
 }
 
 //RULE(proc_decl, Item* item)
@@ -586,7 +578,7 @@ static void const_decl(Parser* p)
 
 static void import_list(Parser* p)
 {
-//    ENTER_RULE();
+    ENTER_RULE();
     expect(p, IMPORT);
     do
     {
@@ -612,7 +604,7 @@ static void import_list(Parser* p)
         m->next = p->imports;
         p->imports = m;
     }
-//    EXIT_RULE();
+    EXIT_RULE();
 }
 
 static void module(Parser* p)
index c4e5d0613df6b142fa55396aac84390d5ed30cf7..098986dcbeb4c17592183997e43bcd4f6fbe1202 100644 (file)
@@ -28,7 +28,7 @@ bool matches(Parser* p, TokType type)
     return (peek(p)->type == type);
 }
 
-bool matches_oneof(Parser* p, TokType types[])
+bool matches_oneof(Parser* p, const TokType types[])
 {
     for (int i = 0; types[i] != NONE; i++)
     {
index 60d54accbc201c344925abdca5bd4ec4bdd2d28d..ff98ddade2a0d7d2901f6754e49431b04c602805 100644 (file)
@@ -34,10 +34,14 @@ void check_num(Parser* p, AstNode* a)
     {
         check_real(p, a);
     }
-    else
+    else if (a->hdr.type->form == FORM_INT)
     {
         check_int(p, a);
     }
+    else
+    {
+        error(p, "numeric operation on non-numeric value");
+    }
 }
 
 void check_nums(Parser* p, AstNode* a, AstNode* b)
index 192d9dae87ee04d00ccb6500071f8ef420db84a6..e41d143c6bab339b059a0d7e57d902e4f1d037ba 100644 (file)
@@ -8,9 +8,11 @@ const
   A = true
   B = 42
   C = 42.0
-  D = -42
-  E = not A
-#  F = B + 1 - 1
+  D = -B
+  E = -C
+  F = not A
+  G = B + 2 - 2 * 2
+  H = false or A
 
 #type
 #  TypeA = Int