From ef425e6df5ac959115d903f9d6fab183ce101114 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Mon, 12 Jul 2021 13:04:27 -0400 Subject: [PATCH] non-record type definitions are working now. --- cerise/inc/cerise.h | 5 ++ cerise/src/ast.c | 28 +++++++++-- cerise/src/grammar.c | 114 +++++++++++++++++++++--------------------- cerise/tests/Module.m | 8 +-- 4 files changed, 90 insertions(+), 65 deletions(-) diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 1d02883..f986221 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -191,10 +191,15 @@ long align_item(long offset, long size); 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); AstNode* ast_block(void); diff --git a/cerise/src/ast.c b/cerise/src/ast.c index 3b3d04c..33ff86e 100644 --- a/cerise/src/ast.c +++ b/cerise/src/ast.c @@ -32,7 +32,7 @@ typedef struct { } val; } AstValue; -static bool is_const(AstNode* node) +bool ast_isconst(AstNode* node) { bool ret; switch (node->hdr.code) @@ -51,9 +51,9 @@ static bool is_const(AstNode* node) return ret; } -static bool both_const(AstNode* left, AstNode* right) +bool ast_areconst(AstNode* left, AstNode* right) { - return is_const(left) && is_const(right); + return ast_isconst(left) && ast_isconst(right); } static AstNode* ast_new(int code, Type* type, AstNode* l0, AstNode* l1, AstNode* l2) @@ -112,12 +112,30 @@ AstNode* ast_real(double val) return (AstNode*)node; } +bool ast_asbool(Parser* p, AstNode* node) +{ + check_bool(p, node); + return (bool)(((AstValue*)node)->val.i); +} + +long long ast_asint(Parser* p, AstNode* node) +{ + check_int(p, node); + return ((AstValue*)node)->val.i; +} + +double ast_asreal(Parser* p, AstNode* node) +{ + check_real(p, node); + return ((AstValue*)node)->val.f; +} + AstNode* ast_binop(int op, AstNode* left, AstNode* right) { assert(left); assert(right); AstNode* ret = NULL; - if (both_const(left,right)) + if (ast_areconst(left,right)) { AstValue* a = (AstValue*)left; AstValue* b = (AstValue*)right; @@ -231,7 +249,7 @@ AstNode* ast_unop(int op, AstNode* operand) { assert(operand); AstNode* ret = NULL; - if (is_const(operand)) + if (ast_isconst(operand)) { AstValue* a = (AstValue*)operand; if (a->hdr.type->form == FORM_INT) diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 70c97cc..2070d3b 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -318,31 +318,32 @@ static AstNode* expression(Parser* p) return expr; } -//RULE(type, Item* item) -//{ -// ENTER_RULE(); -// (void)item; -// if (matches(p, IDENT)) -// { -// char* text = expect_text(p, IDENT); -// Symbol* sym = symbol_get(p, text, SYM_TYPE); -// item->type = sym->type; -// } -// else if (accept(p, ARRAY)) -// { -// expression(p, item); -// if (item->mode != ITEM_CONST) -// { -// error(p, "non-constant array size"); -// } -// expect(p, OF); -// Item base = {0}; -// type(p, &base); -// item->type = calloc(1, sizeof(Type)); -// item->type->form = FORM_ARRAY; -// item->type->size = item->imm.i; -// item->type->base = base.type; -// } +static Type* type(Parser* p) +{ + ENTER_RULE(); + Type* ret = NULL; + + if (matches(p, IDENT)) + { + char* text = expect_text(p, IDENT); + Symbol* sym = symbol_get(p, text, SYM_TYPE); + ret = sym->type; + } + else if (accept(p, ARRAY)) + { + AstNode* lnode = expression(p); + if (!ast_isconst(lnode)) + { + error(p, "non-constant array size"); + } + long long length = ast_asint(p, lnode); + expect(p, OF); + Type* base = type(p); + ret = calloc(1, sizeof(Type)); + ret->form = FORM_ARRAY; + ret->size = length; + ret->base = base; + } // else if (accept(p, RECORD)) // { // long offset = 0; @@ -386,12 +387,13 @@ static AstNode* expression(Parser* p) // // expect(p, END); // } -// else -// { -// error(p, "expected a type"); -// } -// EXIT_RULE(); -//} + else + { + error(p, "expected a type"); + } + EXIT_RULE(); + return ret; +} //RULE(statement_seq, Item* item) //{ @@ -459,26 +461,26 @@ static AstNode* expression(Parser* p) // while (matches(p, IDENT)); // EXIT_RULE(); //} -// -//RULE(type_decl, Item* item) -//{ -// ENTER_RULE(); -// char* name = NULL; -// bool export = false; -// Symbol* sym = NULL; -// -// do -// { -// name = expect_text(p, IDENT); -// export = accept(p, '*'); -// sym = symbol_new(p, 0, name, SYM_TYPE, export); -// expect(p, '='); -// type(p, item); -// sym->type = item->type; -// } -// while (matches(p, IDENT)); -// EXIT_RULE(); -//} + +static void type_decl(Parser* p) +{ + ENTER_RULE(); + char* name = NULL; + bool export = false; + Symbol* sym = NULL; + + do + { + name = expect_text(p, IDENT); + export = accept(p, '*'); + sym = symbol_new(p, 0, name, SYM_TYPE, export); + expect(p, '='); + sym->type = type(p); + } + while (matches(p, IDENT)); + + EXIT_RULE(); +} static void const_decl(Parser* p) { @@ -626,11 +628,11 @@ static void module(Parser* p) const_decl(p); } -// if (accept(p, TYPE)) -// { -// type_decl(p); -// } -// + if (accept(p, TYPE)) + { + type_decl(p); + } + // if (accept(p, VAR)) // { // var_decl(p); diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index e41d143..c934edd 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -14,10 +14,10 @@ const G = B + 2 - 2 * 2 H = false or A -#type -# TypeA = Int -# TypeB = array 5 of Int -# TypeC = array 5 of array 10 of Int +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 -- 2.49.0