commit f830eda935ab2c8f7917eb263196e16982a26d68
parent f1ed7f827e39132f6ee67d9c16b92af2a0193a6b
Author: Nihal Jere <nihal@nihaljere.xyz>
Date: Sun, 28 Nov 2021 18:58:21 -0600
types and typechecking
Diffstat:
3 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/main.c b/main.c
@@ -304,9 +304,17 @@ parse(struct token *tok)
item = (struct item){ 0 };
expect(tok, TOK_NAME);
name = tok;
- if (tok->next && tok->next->type == TOK_EQUAL) {
+ if (tok->next && tok->next->type == TOK_NAME && tok->next->next && tok->next->next->type == TOK_EQUAL) {
struct decl decl;
item.kind = ITEM_DECL;
+ tok = tok->next;
+
+ if (strncmp(tok->slice.ptr, "i64", 3) == 0) {
+ decl.type = TYPE_I64;
+ } else {
+ error("unknown type");
+ }
+
tok = tok->next->next;
decl.val = parseexpr(&tok);
@@ -325,6 +333,31 @@ parse(struct token *tok)
return items;
}
+void
+typecheck(struct items items)
+{
+ for (size_t i = 0; i < items.len; i++) {
+ switch (items.data[i].kind) {
+ case ITEM_DECL:
+ struct decl *decl = &decls.data[items.data[i].idx];
+ switch (decl->type) {
+ case TYPE_I64:
+ struct expr *expr = &exprs.data[decl->val];
+ // FIXME: we should be able to deal with binary, ident or fcalls
+ if (expr->kind != EXPR_LIT || expr->d.v.type != P_INT) error("expected integer value for integer declaration");
+ break;
+ default:
+ error("unknown decl type");
+ }
+ break;
+ case ITEM_EXPR:
+ break;
+ default:
+ error("unknown item type");
+ }
+ }
+}
+
size_t
genexpr(char *buf, size_t idx, enum reg reg)
{
@@ -431,6 +464,7 @@ main(int argc, char *argv[])
struct token *head = lex((struct slice){addr, statbuf.st_size});
struct items items = parse(head);
+ typecheck(items);
curitems = &items;
FILE *out = fopen(argv[2], "w");
diff --git a/nooc.h b/nooc.h
@@ -39,8 +39,14 @@ struct fcall {
struct fparams params;
};
+// FIXME: make a struct for more complex types
+enum type {
+ TYPE_I64
+};
+
struct decl {
struct slice s;
+ enum type type;
size_t val; // struct exprs
size_t addr;
};
diff --git a/prog.nc b/prog.nc
@@ -1,8 +1,8 @@
-write = 1
-stdout = 0
-exit = 60
-len1 = 11
-len2 = 6
+write i64 = 1
+stdout i64 = 0
+exit i64 = 60
+len1 i64 = 11
+len2 i64 = 6
syscall(write, stdout, "hello world", (+ 1 (+ 5 5)))
syscall(write, stdout, " world", len2)
syscall(exit, 0)