From: Michael D. Lowis Date: Fri, 11 Jun 2021 20:45:40 +0000 (-0400) Subject: fixed up constants and constant unary ops X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=cd972359735a917dba7faaa924f961f3118823d8;p=proto%2Fobnc.git fixed up constants and constant unary ops --- diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index ce835a5..fa1345f 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -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 { diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 812f8c9..3554da5 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -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(" \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 { diff --git a/cerise/src/sym.c b/cerise/src/sym.c index eb42ce4..2f6e5e0 100644 --- a/cerise/src/sym.c +++ b/cerise/src/sym.c @@ -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) diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index b862ea7..8d02658 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -7,6 +7,7 @@ module Module const A = true B = -42 + C = not A #type # TypeA = Int