summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arr.c4
-rw-r--r--cgen.c44
-rw-r--r--out.cbin818 -> 775 bytes
-rwxr-xr-xrunv2
-rw-r--r--test.toc18
-rw-r--r--tokenizer.c4
6 files changed, 57 insertions, 15 deletions
diff --git a/arr.c b/arr.c
index ae34ebc..f21790b 100644
--- a/arr.c
+++ b/arr.c
@@ -47,11 +47,11 @@ static void arr_resva_(void **arr, size_t n, size_t item_sz, Allocator *a) {
static void arr_set_len_(void **arr, size_t n, size_t item_sz) {
arr_resv_(arr, n, item_sz);
- arr_hdr(arr)->len = n;
+ arr_hdr(*arr)->len = n;
}
static void arr_set_lena_(void **arr, size_t n, size_t item_sz, Allocator *a) {
arr_resva_(arr, n, item_sz, a);
- arr_hdr(arr)->len = n;
+ arr_hdr(*arr)->len = n;
}
static void *arr_add_(void **arr, size_t item_sz) {
diff --git a/cgen.c b/cgen.c
index ad31274..be9bdb1 100644
--- a/cgen.c
+++ b/cgen.c
@@ -8,6 +8,7 @@ typedef struct {
} CGenerator;
static bool cgen_stmt(CGenerator *g, Statement *s);
+static bool cgen_block(CGenerator *g, Block *b);
static void cgen_create(CGenerator *g, FILE *out, Identifiers *ids, Evaluator *ev) {
g->outc = out;
@@ -264,18 +265,54 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
cgen_write(g, ")");
} break;
case EXPR_NEW:
- cgen_write(g, "calloc(1, sizeof(");
+ cgen_write(g, "((");
+ if (!cgen_type_pre(g, &e->type, e->where))
+ return false;
+ if (!cgen_type_post(g, &e->type, e->where))
+ return false;
+ cgen_write(g, ")calloc(1, sizeof(");
if (!cgen_type_pre(g, &e->new.type, e->where))
return false;
if (!cgen_type_post(g, &e->new.type, e->where))
return false;
+ cgen_write(g, ")))");
+ break;
+ case EXPR_IF: {
+ IfExpr *curr = &e->if_;
+ while (1) {
+ if (curr->cond) {
+ cgen_write(g, "if (");
+ if (!cgen_expr(g, curr->cond))
+ return false;
+ cgen_write(g, ") ");
+ }
+ if (!cgen_block(g, &curr->body))
+ return false;
+ if (curr->next_elif) {
+ cgen_write(g, " else ");
+ curr = &curr->next_elif->if_;
+ } else break;
+ }
+ } break;
+ case EXPR_CALL:
+ cgen_write(g, "(");
+ if (!cgen_expr(g, e->call.fn))
+ return false;
+ cgen_write(g, "(");
+ arr_foreach(e->call.arg_exprs, Expression, arg) {
+ if (arg != e->call.arg_exprs)
+ cgen_write(g, ", ");
+ if (!cgen_expr(g, arg))
+ return false;
+ }
cgen_write(g, "))");
break;
case EXPR_DIRECT:
switch (e->direct.which) {
case DIRECT_C: {
Value val;
- eval_expr(g->evalr, &e->direct.args[0], &val);
+ if (!eval_expr(g->evalr, &e->direct.args[0], &val))
+ return false;
fwrite(val.arr, 1, e->direct.args[0].type.arr.n, cgen_writing_to(g));
} break;
case DIRECT_COUNT: assert(0); break;
@@ -376,7 +413,8 @@ static bool cgen_stmt(CGenerator *g, Statement *s) {
cgen_nl(g);
break;
case STMT_RET:
- /* TODO */
+ cgen_write(g, "return ");
+ if (!cgen_expr(g, &s->ret.expr)) return false;
break;
}
return true;
diff --git a/out.c b/out.c
index 1c9afa1..1e45b85 100644
--- a/out.c
+++ b/out.c
Binary files differ
diff --git a/runv b/runv
index fe4912a..bf00c4f 100755
--- a/runv
+++ b/runv
@@ -1,2 +1,2 @@
#!/bin/bash
-valgrind -q --track-origins=yes ./toc test.toc && cat out.c
+valgrind -q --track-origins=yes ./toc test.toc
diff --git a/test.toc b/test.toc
index 20f0d35..c4f76db 100644
--- a/test.toc
+++ b/test.toc
@@ -1,12 +1,16 @@
+puti @= fn(i: int) {
+ #C("printf(\"%ld\\n\", i)");
+};
+
main @= fn() {
- adsf @= fn(x,asdf,sadf,sdf,fds : i64, y,zdfsadf,sd: &&f32) u8 {
- 0
- };
x := new int;
- *x = 1+2+3-5/62;
- adsfklk : [5]int;
- adsfklk[0] = 521;
- #C("printf(\"%ld %ld\\n\", *x, adsfklk[0]);");
+ *x = 17;
+ if *x == 0 {
+ *x = 1+2+3-5/62;
+ } else {
+ *x = 4+5+6;
+ }
+ puti(*x);
del x;
};
diff --git a/tokenizer.c b/tokenizer.c
index 2f1c145..a665ca5 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -427,7 +427,7 @@ static bool tokenize_string(Tokenizer *t, char *str) {
Token *token = tokr_add(t);
tokr_put_location(t, token);
tokr_nextchar(t);
- size_t len = 0;
+ size_t len = 0; /* counts \n as 2 chars */
size_t backslashes = 0;
while (*t->s != '"' || backslashes % 2 == 1) {
if (*t->s == '\\') {
@@ -464,7 +464,7 @@ static bool tokenize_string(Tokenizer *t, char *str) {
}
*strptr = 0;
token->kind = TOKEN_STR_LITERAL;
- token->str.len = len;
+ token->str.len = strptr - strlit;
token->str.str = strlit;
tokr_nextchar(t); /* move past closing " */
continue;