summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c46
-rw-r--r--eval.c107
-rw-r--r--main.c2
-rw-r--r--out.c34
-rw-r--r--test.toc54
-rw-r--r--types.c13
-rw-r--r--types.h1
7 files changed, 171 insertions, 86 deletions
diff --git a/cgen.c b/cgen.c
index c76640d..1266f20 100644
--- a/cgen.c
+++ b/cgen.c
@@ -706,10 +706,7 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
break;
case EXPR_BINARY_OP: {
const char *s = "";
- if (e->binary.op == BINARY_SET) {
- if (!cgen_set(g, e->binary.lhs, NULL, e->binary.rhs, NULL)) return false;
- break;
- }
+ bool handled = false;
switch (e->binary.op) {
case BINARY_SUB:
s = "-"; break;
@@ -719,7 +716,10 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
s = "*"; break;
case BINARY_DIV:
s = "/"; break;
- case BINARY_SET: assert(0); break;
+ case BINARY_SET:
+ if (!cgen_set(g, e->binary.lhs, NULL, e->binary.rhs, NULL)) return false;
+ handled = true;
+ break;
case BINARY_GT:
s = ">"; break;
case BINARY_LT:
@@ -733,16 +733,46 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
case BINARY_NE:
s = "!="; break;
case BINARY_AT_INDEX:
- s = "["; break;
+ cgen_write(g, "(");
+ switch (e->binary.lhs->type.kind) {
+ case TYPE_ARR:
+ if (!cgen_expr(g, e->binary.lhs))
+ return false;
+ cgen_write(g, "[");
+ if (!cgen_expr(g, e->binary.rhs))
+ return false;
+ cgen_write(g, "]");
+ break;
+ case TYPE_SLICE:
+ cgen_write(g, "((");
+ if (!cgen_type_pre(g, &e->type, e->where))
+ return false;
+ cgen_write(g, "(*)");
+ if (!cgen_type_post(g, &e->type, e->where))
+ return false;
+ cgen_write(g, ")(");
+ if (!cgen_expr(g, e->binary.lhs))
+ return false;
+ cgen_write(g, ".data))[");
+ if (!cgen_expr(g, e->binary.rhs))
+ return false;
+ cgen_write(g, "]");
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ cgen_write(g, ")");
+ handled = true;
+ break;
}
+ if (handled) break;
cgen_write(g, "(");
if (!cgen_expr(g, e->binary.lhs))
return false;
cgen_write(g, "%s", s);
if (!cgen_expr(g, e->binary.rhs))
return false;
- if (e->binary.op == BINARY_AT_INDEX)
- cgen_write(g, "]");
cgen_write(g, ")");
} break;
case EXPR_UNARY_OP: {
diff --git a/eval.c b/eval.c
index 3f8b380..c60f05b 100644
--- a/eval.c
+++ b/eval.c
@@ -5,6 +5,7 @@ static void block_exit(Block *b, Statement *stmts);
static void evalr_create(Evaluator *ev) {
allocr_create(&ev->allocr);
+ ev->returning = NULL;
}
static void evalr_free(Evaluator *ev) {
@@ -404,6 +405,49 @@ static void eval_deref_set(void *set, Value *to, Type *type) {
}
}
+static bool eval_pointer_at_index(Evaluator *ev, Expression *e, void **ptr, Type **type) {
+ Value arr;
+ if (!eval_expr(ev, e->binary.lhs, &arr)) return false;
+ Value index;
+ if (!eval_expr(ev, e->binary.rhs, &index)) return false;
+ U64 i;
+ Type *ltype = &e->binary.lhs->type;
+ Type *rtype = &e->binary.rhs->type;
+ assert(rtype->kind == TYPE_BUILTIN);
+ if (rtype->builtin == BUILTIN_U64) {
+ i = index.u64;
+ } else {
+ I64 signed_index = val_to_i64(&index, rtype->builtin);
+ if (signed_index < 0) {
+ err_print(e->where, "Array or slice out of bounds (index = %ld)\n", (long)signed_index);
+ return false;
+ }
+ i = (U64)signed_index;
+ }
+ switch (ltype->kind) {
+ case TYPE_ARR: {
+ U64 arr_sz = ltype->arr.n;
+ if (i >= arr_sz) {
+ err_print(e->where, "Array out of bounds (%lu, array size = %lu)\n", (unsigned long)i, (unsigned long)arr_sz);
+ return false;
+ }
+ *ptr = (char *)arr.arr + compiler_sizeof(ltype->arr.of) * i;
+ *type = ltype->arr.of;
+ } break;
+ case TYPE_SLICE: {
+ U64 slice_sz = arr.slice.n;
+ if (i >= slice_sz) {
+ err_print(e->where, "Slice out of bounds (%lu, slice size = %lu)\n", (unsigned long)i, (unsigned long)slice_sz);
+ return false;
+ }
+ *ptr = (char *)arr.slice.data + compiler_sizeof(ltype->slice) * i;
+ *type = ltype->slice;
+ } break;
+ default: assert(0); break;
+ }
+ return true;
+}
+
static bool eval_set(Evaluator *ev, Expression *set, Value *to) {
switch (set->kind) {
case EXPR_IDENT: {
@@ -427,29 +471,11 @@ static bool eval_set(Evaluator *ev, Expression *set, Value *to) {
case EXPR_BINARY_OP:
switch (set->binary.op) {
case BINARY_AT_INDEX: {
- /* TODO */
- Value arr;
- if (!eval_expr(ev, set->binary.lhs, &arr)) return false;
- Value index;
- if (!eval_expr(ev, set->binary.rhs, &index)) return false;
- U64 i;
- U64 arr_sz = set->binary.lhs->type.arr.n;
- assert(set->binary.rhs->type.kind == TYPE_BUILTIN);
- if (set->binary.rhs->type.builtin == BUILTIN_U64) {
- i = index.u64;
- } else {
- I64 signed_index = val_to_i64(&index, set->binary.rhs->type.builtin);
- if (signed_index < 0) {
- err_print(set->where, "Array out of bounds (%ld, array size = %lu)\n", (long)signed_index, (unsigned long)arr_sz);
- return false;
- }
- i = (U64)signed_index;
- }
- if (i >= arr_sz) {
- err_print(set->where, "Array out of bounds (%lu, array size = %lu)\n", (unsigned long)i, (unsigned long)arr_sz);
+ void *ptr;
+ Type *type;
+ if (!eval_pointer_at_index(ev, set, &ptr, &type))
return false;
- }
- eval_deref_set((char *)arr.arr + compiler_sizeof(set->binary.lhs->type.arr.of) * i, to, set->binary.lhs->type.arr.of);
+ eval_deref_set(ptr, to, type);
} break;
default: break;
}
@@ -579,28 +605,11 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
case EXPR_BINARY_OP:
switch (o->binary.op) {
case BINARY_AT_INDEX: {
- Value arr;
- if (!eval_expr(ev, o->binary.lhs, &arr)) return false;
- Value index;
- if (!eval_expr(ev, o->binary.rhs, &index)) return false;
- U64 i;
- U64 arr_sz = o->binary.lhs->type.arr.n;
- assert(o->binary.rhs->type.kind == TYPE_BUILTIN);
- if (o->binary.rhs->type.builtin == BUILTIN_U64) {
- i = index.u64;
- } else {
- I64 signed_index = val_to_i64(&index, o->binary.rhs->type.builtin);
- if (signed_index < 0) {
- err_print(o->where, "Array out of bounds (%ld, array size = %lu)\n", (long)signed_index, (unsigned long)arr_sz);
- return false;
- }
- i = (U64)signed_index;
- }
- if (i >= arr_sz) {
- err_print(o->where, "Array out of bounds (%lu, array size = %lu)\n", (unsigned long)i, (unsigned long)arr_sz);
+ void *ptr;
+ Type *type;
+ if (!eval_pointer_at_index(ev, o, &ptr, &type))
return false;
- }
- v->ptr = ((char *)arr.arr) + compiler_sizeof(o->binary.lhs->type.arr.of) * i;
+ v->ptr = ptr;
} break;
default: break;
}
@@ -827,6 +836,11 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
fn_exit(fn);
return false;
}
+ if (ev->returning) {
+ *v = *ev->returning;
+ free(ev->returning);
+ ev->returning = NULL;
+ }
fn_exit(fn);
} break;
}
@@ -868,7 +882,9 @@ static bool eval_stmt(Evaluator *ev, Statement *stmt) {
return false;
} break;
case STMT_RET:
- /* TODO */
+ ev->returning = err_malloc(sizeof *ev->returning);
+ if (!eval_expr(ev, &stmt->ret.expr, ev->returning))
+ return false;
break;
}
return true;
@@ -879,8 +895,9 @@ static bool eval_block(Evaluator *ev, Block *b, Value *v) {
arr_foreach(b->stmts, Statement, stmt) {
if (!eval_stmt(ev, stmt))
return false;
+ if (ev->returning) break;
}
- if (b->ret_expr) {
+ if (!ev->returning && b->ret_expr) {
if (!eval_expr(ev, b->ret_expr, v))
return false;
}
diff --git a/main.c b/main.c
index afb8ed5..b8c2997 100644
--- a/main.c
+++ b/main.c
@@ -1,7 +1,7 @@
/*
TODO:
-compile time return statements
slice at index
+fix recursion with block_enter/exit
arr => slice casting
del slices
run time return statements
diff --git a/out.c b/out.c
index a3e2ebb..cc44ba0 100644
--- a/out.c
+++ b/out.c
@@ -17,7 +17,8 @@ typedef struct { void *data; u64 n; } slice_;
/* declarations */
-i64 foo(void);
+void puti(i64 x);
+i64 foo(i64 x);
void main__(void);
/* code */
int main() {
@@ -25,19 +26,36 @@ int main() {
return 0;
}
-i64 foo(void) {
+void puti(i64 x) {
- 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]);
+ printf("%ld\n", (long)x);
+}
+
+
+i64 foo(i64 x) {
+
+ slice_ C; {
+ slice_ expr__; slice_ a0_; a0_.data = calloc(x, sizeof(i64)); a0_.n = x;expr__ = a0_;C = expr__;}
+ i64 i; {
+ i64 expr__; expr__ = 0;i = expr__;}
+ while ((i<x)) {
+ (((i64(*))(C.data))[i]) = i;;
+ i = (i+1);;
+ };
+ i64 total; {
+ i64 expr__; expr__ = 0;total = expr__;}
+ while ((i<x)) {
+ total = (total+(((i64(*))(C.data))[i]));;
+ i = (i+1);;
+ };
+ return total;
}
void main__(void) {
- i64( Ar[12]) = {0};
+ i64( A[0]) = {0};
+ i64( B[0]) = {0};
}
diff --git a/test.toc b/test.toc
index 70c5bd6..b1bcbc8 100644
--- a/test.toc
+++ b/test.toc
@@ -1,31 +1,43 @@
// #C("#include <stdio.h>
// #define kasfdhkjasdfhjk ");
-// puti @= fn(x: int) {
- // #C("printf(\"%ld\\n\", (long)x)");
+puti @= fn(x: int) {
+ #C("printf(\"%ld\\n\", (long)x)");
+};
+
+// foo @= fn(x:int) int {
+// if x < 4 {
+// return 7;
+// } else {
+// return 5;
+// }
+// 4
// };
-foo @= fn() int {
- X := new([100]int,5);
- asdf : [100]int;
- (*(&asdf))[5] = 12;
-
+foo @= fn(x: int) int {
+ C := new(int, x);
+ i := 0;
+ while i < x {
+ C[i] = i;
+ i = i + 1;
+ }
+ total := 0;
+ while i < x {
+ total = total + C[i];
+ i = i + 1;
+ }
+ total
- // i := 0;
- // while i < 100 {
- // (*X)[i] = i;
- // i = i + 1;
- // }
- // total := 0;
- // i = 0;
- // while i < 100 {
- // total = total + (*X)[i];
- // i = i + 1;
- // }
- // total
- asdf[5]
};
main @= fn() {
- Ar : [foo()]int;
+ A : [foo(10)]int;
+ B : [foo(100)]int;
+ // C := new(int, 10);
+ // i := 0;
+ // while i < 10 {
+ // C[i] = 7;
+ // i = i + 1;
+ // }
+ // puti(C[9]);
};
diff --git a/types.c b/types.c
index 1a92427..5612eb3 100644
--- a/types.c
+++ b/types.c
@@ -979,13 +979,20 @@ static bool types_expr(Typer *tr, Expression *e) {
err_print(e->where, "The index of an array must be a builtin numerical type.");
return false;
}
- if (lhs_type->kind != TYPE_ARR) {
- char *s = type_to_str(lhs_type);
+ switch (lhs_type->kind) {
+ case TYPE_ARR:
+ *t = *lhs_type->arr.of;
+ break;
+ case TYPE_SLICE:
+ *t = *lhs_type->slice;
+ break;
+ default: {
+ char *s = type_to_str(lhs_type);
err_print(e->where, "Trying to take index of non-array type %s.", s);
free(s);
return false;
}
- *t = *lhs_type->arr.of;
+ }
break;
} break;
} break;
diff --git a/types.h b/types.h
index 59f1b4e..a73cfa9 100644
--- a/types.h
+++ b/types.h
@@ -498,6 +498,7 @@ typedef enum {
typedef struct {
Allocator allocr;
+ Value *returning; /* NULL = not returning anything */
} Evaluator;
typedef struct Typer {