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:
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:
}