]> git.mdlowis.com Git - proto/obnc.git/commitdiff
sketched out really rough logic for array indexing
authorMichael D. Lowis <mike.lowis@gentex.com>
Mon, 12 Jul 2021 20:52:37 +0000 (16:52 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Mon, 12 Jul 2021 20:52:37 +0000 (16:52 -0400)
cerise/inc/cerise.h
cerise/src/ast.c
cerise/src/grammar.c

index f986221327a5950bf67e17bd8e066a18222b91ee..221c0bc1bb313c02293696d5216bbaf4d9f4db9b 100644 (file)
@@ -193,19 +193,29 @@ long size_of(Type* type);
 // src/ast.c
 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);
+
 bool ast_asbool(Parser* p, AstNode* node);
 long long ast_asint(Parser* p, AstNode* node);
 double ast_asreal(Parser* p, AstNode* node);
+
 AstNode* ast_binop(int op, AstNode* left, AstNode* right);
 AstNode* ast_unop(int op, AstNode* operand);
+// TODO: Add a store operation handler
+AstNode* ast_fieldref(Parser* p, AstNode* record, char* fname);
+AstNode* ast_index(Parser* p, AstNode* array, AstNode* index);
+
 AstNode* ast_block(void);
+void ast_block_add(AstNode* blk, AstNode* stmt);
 AstNode* ast_call(AstNode* func);
+void ast_call_add(AstNode* func, AstNode* arg);
 AstNode* ast_if(AstNode* cond, AstNode* br1, AstNode* br2);
 AstNode* ast_return(AstNode* expr);
+
 void ast_print(AstNode* expr);
 
 /* Backend Code Generation and Base Type Definitions
index 33ff86e7a91035abb70d6f9ce8b76dea0549c886..0391fee751a1c669ffd4ef0aa0c4a11d67587308 100644 (file)
@@ -291,15 +291,32 @@ AstNode* ast_unop(int op, AstNode* operand)
     return ret;
 }
 
+AstNode* ast_fieldref(Parser* p, AstNode* record, char* fname)
+{
+    /* TODO: actually access the field and check that it exists */
+    return record;
+}
+
+AstNode* ast_index(Parser* p, AstNode* array, AstNode* index)
+{
+    /* TODO: actually access the array index */
+    /*
+        * offset = index * sizeof(base)
+        * array->type = array->type->base;
+        * return new ast(ARRAY, base, offset)
+    */
+    return array;
+}
+
 AstNode* ast_block(void)
 {
     return ast_new(BEGIN, &VoidType, NULL, NULL, NULL);
 }
 
-void ast_block_add(AstNode* func)
+void ast_block_add(AstNode* blk, AstNode* stmt)
 {
     /* TODO: append to linked list */
-    (void)func;
+    (void)blk, (void)stmt;
 }
 
 AstNode* ast_call(AstNode* func)
@@ -307,10 +324,10 @@ AstNode* ast_call(AstNode* func)
     return ast_new(CALL, func->hdr.type, func, NULL, NULL);
 }
 
-void ast_call_add(AstNode* func)
+void ast_call_add(AstNode* func, AstNode* arg)
 {
     /* TODO: append to linked list */
-    (void)func;
+    (void)func, (void)arg;
 }
 
 AstNode* ast_if(AstNode* cond, AstNode* br1, AstNode* br2)
index afcb070d4499bc46b68ffb202e6ced9df8451d01..0c4fd177c4c0100160d278acb509d6279d87a9da 100644 (file)
@@ -76,43 +76,37 @@ static AstNode* designator(Parser* p)
 
     AstNode* expr = qualident(p);
 
-//    /* selector */
-//    for (int done = 0; !done;)
-//    {
-//        switch ((int)peek(p)->type)
-//        {
-//            case '.':
-//            {
-//                expect(p, '.');
-//                char* name = expect_text(p, IDENT);
-//                if (item->type->form == FORM_RECORD)
-//                {
-//                    codegen_field(p, item, name);
-//                }
-//                else
-//                {
-//                    error(p, "attempting to access field of non-array object");
-//                }
-//                break;
-//            }
-//
-//            case '[':
-//            {
-//                Item index = {0};
-//                expect(p, '[');
-//                expression(p, &index);
-//                if (item->type->form == FORM_ARRAY)
-//                {
-//                    codegen_index(p, item, &index);
-//                }
-//                else
-//                {
-//                    error(p, "attempting to index non-array value");
-//                }
-//                expect(p, ']');
-//                break;
-//            }
-//
+    /* selector */
+    for (int done = 0; !done;)
+    {
+        switch ((int)peek(p)->type)
+        {
+            case '.':
+            {
+                expect(p, '.');
+                if (expr->hdr.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);
+                break;
+            }
+
+            case '[':
+            {
+                expect(p, '[');
+                if (expr->hdr.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);
+                expect(p, ']');
+                break;
+            }
+
 //    //        case '^':
 //    //            expect(p, '^');
 //    //            break;
@@ -122,11 +116,11 @@ static AstNode* designator(Parser* p)
 //    //            expect(p, ')');
 //    //            break;
 //
-//            default:
-//                done = 1;
-//                break;
-//        }
-//    }
+            default:
+                done = 1;
+                break;
+        }
+    }
 
     EXIT_RULE();
     assert(expr != NULL);
@@ -393,16 +387,28 @@ static Type* type(Parser* p)
     return ret;
 }
 
-//RULE(statement_seq, Item* item)
-//{
-//    ENTER_RULE();
-//    do
-//    {
-//        if (matches(p, IF))
-//        {
-//            expect(p, IF);
-//            expression(p, item);
-//            check_bool(p, item);
+static AstNode* statement_seq(Parser* p)
+{
+    ENTER_RULE();
+    AstNode* block = ast_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);
+
 //            codegen_if(p, item);
 //            expect(p, THEN);
 //            statement_seq(p, &(Item){0});
@@ -424,23 +430,26 @@ static Type* type(Parser* p)
 //            }
 //            codegen_endif(p, elsifs, item);
 //            expect(p, END);
-//        }
-//        else /* assignments/expressions */
-//        {
-//            expression(p, item);
-//            if (accept(p, '='))
-//            {
-//                Item right = { 0 };
-//                expression(p, &right);
-//                check_types(p, item, &right);
-//                codegen_store(p, item, &right);
-//            }
-//            expect(p, ';');
-//        }
-//    }
-//    while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF) && !matches(p, RETURN));
-//    EXIT_RULE();
-//}
+//            ast_block_add(block, ast_binop('=', left, right));
+        }
+        else /* assignments/expressions */
+        {
+            AstNode* expr = expression(p);
+            if (accept(p, '='))
+            {
+                AstNode* right = expression(p);
+                check_types(p, expr, right);
+                expr = ast_binop('=', expr, right);
+            }
+            expect(p, ';');
+            ast_block_add(block, expr);
+        }
+    }
+    while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF) && !matches(p, RETURN));
+
+    EXIT_RULE();
+    return block;
+}
 
 static void var_decl(Parser* p)
 {
@@ -639,12 +648,14 @@ static void module(Parser* p)
 //    }
 
 //    codegen_startproc(p, NULL);
-//    if (accept(p, BEGIN))
-//    {
+    if (accept(p, BEGIN))
+    {
 //        codegen_imports(p);
-//        statement_seq(p, item);
-//        expect(p, END);
-//    }
+        AstNode* block = statement_seq(p);
+        ast_print(block);
+        puts("");
+        expect(p, END);
+    }
 //    codegen_endproc(p);
 
     if (!matches(p, END_FILE))