compiler

Unnamed Compiled Systems Language Project
git clone http://frotz.net/git/compiler.git
Log | Files | Refs

commit d88ed58bf9b8a45370f057a87445dc2999f8925f
parent 07224cfd65b66af47614403abb395efc5220c230
Author: Brian Swetland <swetland@frotz.net>
Date:   Tue,  7 Dec 2021 02:46:00 -0800

compiler2: progress

- codegen for INDEXing arrays
- fix typo in ast kind name array
- tidy up SYM_IS_* flags and add _REFERENCE
- set type in AST_NAME nodes

Diffstat:
Msrc/codegen-risc5-simple.c | 46++++++++++++++++++++++++++++++++++++++++++++++
Msrc/compiler2.c | 18++++++++++--------
2 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/src/codegen-risc5-simple.c b/src/codegen-risc5-simple.c @@ -381,6 +381,50 @@ u32 gen_logical_op(Ast node, u32 cc, u32 sc) { return r; } +u32 gen_array_addr(Ast node) { + err_ast = node; + if (node->type->kind != TYPE_ARRAY) { + error("cannot deref non-array type"); + } + if (node->kind == AST_NAME) { + u32 base; + i32 offset; + sym_get_loc(node->sym, &base, &offset); + u32 r = get_reg_tmp(); + if (node->sym->kind == SYM_PARAM) { + // arrays here are ptr-to-array, so deref that + emit_mem(LDW, r, base, offset); + } else { + // arrays elsewhere are inline, so just add offset + emit_opi(ADD, r, base, offset); + } + return r; + } else if (node->kind == AST_INDEX) { + error("not ready for [][]"); + } else { + error("cannot dereference this"); + } + return 0; +} + +u32 gen_array_read(Ast node) { + u32 raddr = gen_array_addr(node->c0); + u32 roff = gen_expr(node->c1); + + u32 sz = node->c0->type->base->size; + if (sz > 1) { + emit_opi(MUL, roff, roff, sz); + } + emit_op(ADD, raddr, raddr, roff); + if (sz == 1) { + emit_mem(LDB, roff, raddr, 0); + } else { + emit_mem(LDW, roff, raddr, 0); + } + put_reg(raddr); + return roff; +} + u32 gen_expr(Ast node) { err_ast = node; gen_src_xref(node); @@ -437,6 +481,8 @@ u32 gen_expr(Ast node) { return r; } else if (node->kind == AST_CALL) { return gen_call(node); + } else if (node->kind == AST_INDEX) { + return gen_array_read(node); } else { error("gen_expr cannot handle %s\n", ast_kind[node->kind]); } diff --git a/src/compiler2.c b/src/compiler2.c @@ -95,8 +95,8 @@ enum { str ast_kind[AST_FIELD + 1] = { "NAME", "U32", "STR", "BINOP", "UNOP", "DEREF", "INDEX", "BLOCK", "EXPR", "CALL", "WHILE", "IF", - "RETURN", "BREAK", "CONTINUE", "IFELSE" - "LOCAL", "PROGRAM", "TYPEDEF", "ENUMDEF", "FUNCDEF", + "RETURN", "BREAK", "CONTINUE", "IFELSE", + "PROGRAM", "TYPEDEF", "ENUMDEF", "FUNCDEF", "GLOBAL", "LOCAL", "FIELD", }; @@ -139,7 +139,7 @@ struct TypeRec { Type base; // pointer-to, func-return-type, array-of Symbol sym; // if not anonymous Symbol first; // list of params or fields - u32 len; // array, params + u32 len; // array elem count, param count u32 size; // in bytes, local stack for funcs }; @@ -158,11 +158,12 @@ str sym_kind[SYM_FIELD + 1] = { }; enum { - SYM_IS_READ_ONLY = 1, - SYM_IS_PUBLIC = 2, - SYM_IS_DEFINED = 4, - SYM_IS_BUILTIN = 8, - SYM_IS_PLACED = 16, // exists at addr in sym->value + SYM_IS_READ_ONLY = 0x01, + SYM_IS_PUBLIC = 0x02, + SYM_IS_DEFINED = 0x04, + SYM_IS_BUILTIN = 0x08, + SYM_IS_PLACED = 0x10, // exists at addr in sym->value + SYM_IS_REFERENCE = 0x20, // stored as pointer-to-type }; struct SymbolRec { @@ -1109,6 +1110,7 @@ Ast parse_operand() { } node = ast_make_name(ctx.ident); node->sym = sym; + node->type = sym->type; } else { error("invalid expression"); }