nooc

nooc programming language compiler
git clone git://git.nihaljere.xyz/nooc
Log | Files | Refs | LICENSE

commit da9d21d34fa4f9e474e59a9b77faf7622e3619cd
parent d342f5e873937e6eada0c0b3ef39efad685935a0
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Thu, 30 Dec 2021 14:49:03 -0600

add fixed size global arrays

Diffstat:
Mlex.c | 6++++++
Mmain.c | 16++++++++++++----
Mnooc.h | 9+++++++++
Mparse.c | 30+++++++++++++++++++++++++++---
Atest/array.pass.nooc | 6++++++
Atest/array_size.fail.nooc | 2++
Mtype.c | 4++++
7 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/lex.c b/lex.c @@ -68,6 +68,12 @@ lex(struct slice start) } else if (*start.data == ')') { cur->type = TOK_RPAREN; ADVANCE(1); + } else if (*start.data == '[') { + cur->type = TOK_LSQUARE; + ADVANCE(1); + } else if (*start.data == ']') { + cur->type = TOK_RSQUARE; + ADVANCE(1); } else if (*start.data == '{') { cur->type = TOK_LCURLY; ADVANCE(1); diff --git a/main.c b/main.c @@ -63,7 +63,12 @@ decl_alloc(struct block *block, struct decl *decl) decl->place.size = type->size; switch (decl->place.kind) { case PLACE_ABS: - decl->place.l.addr = data_pushzero(type->size); + if (type->class == TYPE_ARRAY) { + struct type *subtype = &types.data[type->d.arr.subtype]; + decl->place.l.addr = data_pushzero(subtype->size * type->d.arr.len); + } else { + decl->place.l.addr = data_pushzero(type->size); + } break; case PLACE_FRAME: decl->place.l.off = block->datasize; @@ -77,6 +82,8 @@ decl_alloc(struct block *block, struct decl *decl) size_t place_move(char *buf, struct place *dest, struct place *src) { + assert(dest->size != 0); + assert(src->size != 0); size_t total = 0; switch (src->kind) { case PLACE_REG: @@ -280,6 +287,7 @@ typecheck(struct block *block) col = assgn->start->col; goto check; case ITEM_DECL: + // FIXME: typecheck procedure parameters decl = &block->decls.data[item->idx]; type = &types.data[decl->type]; expr = &exprs.data[decl->val]; @@ -292,10 +300,10 @@ check: error(line, col, "expected integer expression for integer declaration"); break; case TYPE_STR: + case TYPE_ARRAY: if (expr->class != C_STR) - error(line, col, "expected string expression for string declaration"); + error(line, col, "expected string expression for array declaration"); break; - case TYPE_PROC: if (expr->class != C_PROC) error(line, col, "expected proc expression for proc declaration"); @@ -529,7 +537,7 @@ evalexpr(struct decl *decl) break; case C_STR: { uint64_t addr = data_push(expr->d.v.v.s.data, expr->d.v.v.s.len); - decl_set(decl, &addr); + decl->place.l.addr = addr; break; } default: diff --git a/nooc.h b/nooc.h @@ -11,6 +11,8 @@ enum tokentype { TOK_RPAREN, TOK_LCURLY, TOK_RCURLY, + TOK_LSQUARE, + TOK_RSQUARE, TOK_PLUS, TOK_MINUS, @@ -64,6 +66,8 @@ struct typelist { enum typeclass { TYPE_INT = 1, TYPE_STR, + TYPE_ARRAY, + TYPE_REF, TYPE_PROC, }; @@ -75,6 +79,11 @@ struct type { struct typelist in; struct typelist out; } params; + struct { + size_t len; + size_t subtype; // struct types + } arr; + size_t subtype; // struct types } d; }; diff --git a/parse.c b/parse.c @@ -115,7 +115,10 @@ typetoclass(struct type *type) case TYPE_INT: return C_INT; case TYPE_STR: + case TYPE_ARRAY: return C_STR; + case TYPE_REF: + return C_REF; default: die("unknown type class"); } @@ -287,8 +290,6 @@ parsetypelist(struct typelist *list) size_t type; while (tok->type != TOK_RPAREN) { - expect(TOK_NAME); - type = parsetype(); array_add(list, type); @@ -309,13 +310,36 @@ parsetype() struct mapkey key; union mapval val; - if (slice_cmplit(&tok->slice, "proc") == 0) { + if (tok->type == TOK_NAME && slice_cmplit(&tok->slice, "proc") == 0) { type.class = TYPE_PROC; tok = tok->next; parsetypelist(&type.d.params.in); if (tok->type == TOK_LPAREN) parsetypelist(&type.d.params.out); + } else if (tok->type == TOK_DOLLAR) { + type.class = TYPE_REF; + type.size = 8; + tok = tok->next; + + type.d.subtype = parsetype(); + } else if (tok->type == TOK_LSQUARE) { + struct expr len = { 0 }; + type.class = TYPE_ARRAY; + type.size = 0; + tok = tok->next; + + expect(TOK_NUM); + parsenum(&len); + + if (len.d.v.v.i64 <= 0) + error(tok->line, tok->col, "expected positive integer for array size"); + type.d.arr.len = len.d.v.v.i64; + + expect(TOK_RSQUARE); + tok = tok->next; + + type.d.arr.subtype = parsetype(); } else { mapkey(&key, tok->slice.data, tok->slice.len); val = mapget(typesmap, &key); diff --git a/test/array.pass.nooc b/test/array.pass.nooc @@ -0,0 +1,6 @@ +let arr [5]i8 = "sup!\n" + +let main proc() = proc() { + syscall(1, 1, $arr, 5) + syscall(60, 0) +} diff --git a/test/array_size.fail.nooc b/test/array_size.fail.nooc @@ -0,0 +1 @@ +let arr [0]i8 = 0+ \ No newline at end of file diff --git a/type.c b/type.c @@ -83,6 +83,10 @@ hashtype(struct type *type, uint8_t *out) case TYPE_PROC: blake3_update(&b3, type->d.params.in.data, type->d.params.in.len * sizeof(*type->d.params.in.data)); blake3_update(&b3, type->d.params.out.data, type->d.params.out.len * sizeof(*type->d.params.out.data)); + break; + case TYPE_ARRAY: + blake3_update(&b3, &type->d.arr, sizeof(type->d.arr)); + break; default: }