summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c24
-rw-r--r--eval.c39
-rw-r--r--main.c6
-rw-r--r--out.c19
-rwxr-xr-xrunv1
-rw-r--r--test.toc16
-rw-r--r--types.c3
7 files changed, 60 insertions, 48 deletions
diff --git a/cgen.c b/cgen.c
index c733426..c76640d 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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) {
diff --git a/eval.c b/eval.c
index f171a71..3f8b380 100644
--- a/eval.c
+++ b/eval.c
@@ -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:
diff --git a/main.c b/main.c
index 02309af..afb8ed5 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/out.c b/out.c
index 31f95d2..a3e2ebb 100644
--- a/out.c
+++ b/out.c
@@ -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};
+}
diff --git a/runv b/runv
index e892908..cb14729 100755
--- a/runv
+++ b/runv
@@ -5,3 +5,4 @@ if [ "$1" = "c" ]; then
elif [ "$1" = "pc" ]; then
cat out.c
fi
+rm vgcore* 2> /dev/null
diff --git a/test.toc b/test.toc
index 8b5c7fc..70c5bd6 100644
--- a/test.toc
+++ b/test.toc
@@ -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() {
diff --git a/types.c b/types.c
index fda1afa..1a92427 100644
--- a/types.c
+++ b/types.c
@@ -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))