diff options
-rw-r--r-- | cgen.c | 24 | ||||
-rw-r--r-- | eval.c | 39 | ||||
-rw-r--r-- | main.c | 6 | ||||
-rw-r--r-- | out.c | 19 | ||||
-rwxr-xr-x | runv | 1 | ||||
-rw-r--r-- | test.toc | 16 | ||||
-rw-r--r-- | types.c | 3 |
7 files changed, 60 insertions, 48 deletions
@@ -1,5 +1,7 @@ static bool cgen_stmt(CGenerator *g, Statement *s); -static bool cgen_block(CGenerator *g, Block *b, const char *ret_name, bool enter_and_exit); +#define CGEN_BLOCK_FLAG_NOENTER 0x01 /* should cgen_block actually enter and exit the block? */ +#define CGEN_BLOCK_FLAG_NOBRACES 0x02 /* should it use braces? */ +static bool cgen_block(CGenerator *g, Block *b, const char *ret_name, uint16_t flags); static bool cgen_expr_pre(CGenerator *g, Expression *e); static bool cgen_expr(CGenerator *g, Expression *e); static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, const char *prefix, Expression *to); @@ -598,7 +600,7 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { return false; cgen_write(g, ") "); } - if (!cgen_block(g, &curr->body, ret_name, false)) + if (!cgen_block(g, &curr->body, ret_name, 0)) return false; if (curr->next_elif) { cgen_write(g, " else "); @@ -617,12 +619,12 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { cgen_write(g, "true"); } cgen_write(g, ") "); - if (!cgen_block(g, &w->body, ret_name, false)) + if (!cgen_block(g, &w->body, ret_name, 0)) return false; } break; case EXPR_BLOCK: e->block_ret_id = id; - if (!cgen_block(g, &e->block, ret_name, false)) + if (!cgen_block(g, &e->block, ret_name, 0)) return false; break; case EXPR_CALL: @@ -853,10 +855,11 @@ static bool cgen_expr(CGenerator *g, Expression *e) { functions always call with NULL as ret_name, even if they use out params, for now at least. */ -static bool cgen_block(CGenerator *g, Block *b, const char *ret_name, bool enter_and_exit) { +static bool cgen_block(CGenerator *g, Block *b, const char *ret_name, uint16_t flags) { Block *prev = g->block; - cgen_write(g, "{"); - if (enter_and_exit) + if (!(flags & CGEN_BLOCK_FLAG_NOBRACES)) + cgen_write(g, "{"); + if (!(flags & CGEN_BLOCK_FLAG_NOENTER)) if (!cgen_block_enter(g, b)) return false; cgen_nl(g); @@ -874,9 +877,10 @@ static bool cgen_block(CGenerator *g, Block *b, const char *ret_name, bool enter } cgen_nl(g); } - if (enter_and_exit) + if (!(flags & CGEN_BLOCK_FLAG_NOENTER)) cgen_block_exit(g, prev); - cgen_write(g, "}"); + if (!(flags & CGEN_BLOCK_FLAG_NOBRACES)) + cgen_write(g, "}"); return true; } @@ -920,7 +924,7 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, Location where) { return false; } if (!cgen_block_enter(g, &f->body)) return false; - if (!cgen_block(g, &f->body, NULL, false)) + if (!cgen_block(g, &f->body, NULL, CGEN_BLOCK_FLAG_NOENTER | CGEN_BLOCK_FLAG_NOBRACES)) return false; if (f->ret_decls) { @@ -44,7 +44,7 @@ static size_t compiler_sizeof(Type *t) { case TYPE_PTR: return sizeof t->ptr; case TYPE_ARR: - return compiler_sizeof(t->arr.of) * t->arr.n; + return t->arr.n * compiler_sizeof(t->arr.of); case TYPE_TUPLE: return sizeof t->tuple; case TYPE_SLICE: @@ -343,7 +343,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) { static void eval_deref(Value *v, void *ptr, Type *type) { switch (type->kind) { case TYPE_PTR: v->ptr = *(void **)ptr; break; - case TYPE_ARR: v->arr = *(void **)ptr; break; + case TYPE_ARR: v->arr = ptr; break; /* when we have a pointer to an array, it points directly to the data in that array. */ case TYPE_FN: v->fn = *(FnExpr **)ptr; break; case TYPE_TUPLE: v->tuple = *(Value **)ptr; break; case TYPE_BUILTIN: @@ -449,7 +449,7 @@ static bool eval_set(Evaluator *ev, Expression *set, Value *to) { err_print(set->where, "Array out of bounds (%lu, array size = %lu)\n", (unsigned long)i, (unsigned long)arr_sz); return false; } - eval_deref_set((char *)arr.arr + compiler_sizeof(set->binary.lhs->type.arr.of) * i, to, &set->binary.lhs->type); + eval_deref_set((char *)arr.arr + compiler_sizeof(set->binary.lhs->type.arr.of) * i, to, set->binary.lhs->type.arr.of); } break; default: break; } @@ -504,7 +504,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { #define eval_binary_op_nums_only(op) \ - /* fix casting to bool */ val_cast(&lhs, &e->binary.lhs->type, &lhs, &e->type); \ val_cast(&rhs, &e->binary.rhs->type, &rhs, &e->type); \ assert(e->type.kind == TYPE_BUILTIN); \ @@ -531,15 +530,19 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { eval_binary_bool_op_one(f64, F64, op); #define eval_binary_bool_op_nums_only(op) \ - val_cast(&lhs, &e->binary.lhs->type, &lhs, &e->type); \ - val_cast(&rhs, &e->binary.rhs->type, &rhs, &e->type); \ - assert(e->type.kind == TYPE_BUILTIN); \ - switch (builtin) { \ - eval_binary_bool_op_nums(builtin, op); \ - default:printf("%d\n",(int)builtin); \ - assert(!"Invalid builtin to "#op); break; \ - } - + {Type *ltype=&e->binary.lhs->type, \ + *rtype=&e->binary.rhs->type; \ + Type *cast_to = ltype->flags & TYPE_FLAG_FLEXIBLE ? \ + rtype : ltype; \ + val_cast(&lhs, ltype, &lhs, cast_to); \ + val_cast(&rhs, rtype, &rhs, cast_to); \ + assert(e->type.kind == TYPE_BUILTIN); \ + switch (builtin) { \ + eval_binary_bool_op_nums(builtin, op); \ + default:printf("%d\n",(int)builtin); \ + assert(!"Invalid builtin to "#op); break; \ + }} + switch (e->kind) { @@ -558,7 +561,10 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { err_print(e->where, "Cannot take address of run time variable at compile time."); return false; } - v->ptr = &id->val; + if (o->type.kind == TYPE_ARR) + v->ptr = id->val.arr; /* point directly to data */ + else + v->ptr = &id->val; } break; case EXPR_UNARY_OP: switch (o->unary.op) { @@ -595,7 +601,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { return false; } v->ptr = ((char *)arr.arr) + compiler_sizeof(o->binary.lhs->type.arr.of) * i; - printf("%p\n",v->ptr); } break; default: break; } @@ -637,9 +642,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { case BINARY_ADD: eval_binary_op_nums_only(+); break; case BINARY_SUB: - eval_binary_op_nums_only(-); - printf("%p %p\n", lhs.ptr, rhs.ptr); - break; + eval_binary_op_nums_only(-); break; case BINARY_MUL: eval_binary_op_nums_only(*); break; case BINARY_DIV: @@ -1,10 +1,12 @@ /* TODO: -fix compile time new +compile time return statements +slice at index arr => slice casting del slices -slice at index +run time return statements bf interpreter +error on failed calloc in output unicode variable names make sure initializers for global variables are compile-time constants structs @@ -26,19 +26,18 @@ int main() { } i64 foo(void) { - { - i64 i; { - i64 expr__; expr__ = 0;i = expr__;} - while ((i<100)) { - i = (i+1);; - }; - }return i; + + slice_ X; { + slice_ expr__; slice_ a0_; a0_.data = calloc(5, sizeof(i64([100]))); a0_.n = 5;expr__ = a0_;X = expr__;} + i64( asdf[100]) = {0}; + ((*(&asdf))[5]) = 12;; + return (asdf[5]); } void main__(void) { - { - i64( Ar[1]) = {0}; - }} + + i64( Ar[12]) = {0}; +} @@ -5,3 +5,4 @@ if [ "$1" = "c" ]; then elif [ "$1" = "pc" ]; then cat out.c fi +rm vgcore* 2> /dev/null @@ -6,13 +6,16 @@ // }; foo @= fn() int { - // X := new([100]int); - i := 0; - while i < 100 { + X := new([100]int,5); + asdf : [100]int; + (*(&asdf))[5] = 12; + + + // i := 0; + // while i < 100 { // (*X)[i] = i; - i = i + 1; - } - i + // i = i + 1; + // } // total := 0; // i = 0; // while i < 100 { @@ -20,6 +23,7 @@ foo @= fn() int { // i = i + 1; // } // total + asdf[5] }; main @= fn() { @@ -445,10 +445,9 @@ static Status type_cast_status(Type *from, Type *to) { return STATUS_NONE; if (to->kind == TYPE_FN) return STATUS_WARN; + /* TODO: Cast from ptr to arr */ return STATUS_ERR; case TYPE_ARR: - if (to->kind == TYPE_PTR && type_eq(from->arr.of, to->ptr)) - return STATUS_NONE; return STATUS_ERR; case TYPE_SLICE: if (to->kind == TYPE_PTR && type_eq(from->slice, to->ptr)) |