From: Michael D. Lowis Date: Mon, 12 Jul 2021 20:52:37 +0000 (-0400) Subject: sketched out really rough logic for array indexing X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=95c44745f9ba6a5e13e34d3c63f659b7ed5b60c8;p=proto%2Fobnc.git sketched out really rough logic for array indexing --- diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index f986221..221c0bc 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -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 diff --git a/cerise/src/ast.c b/cerise/src/ast.c index 33ff86e..0391fee 100644 --- a/cerise/src/ast.c +++ b/cerise/src/ast.c @@ -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) diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index afcb070..0c4fd17 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -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))