From ee7525251681a3c0ab38e0356bc3733adb3e6566 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Mon, 21 Oct 2019 10:08:40 -0400 Subject: run time slice at index; started compile time --- cgen.c | 46 ++++++++++++++++++++++----- eval.c | 107 ++++++++++++++++++++++++++++++++++++--------------------------- main.c | 2 +- out.c | 34 +++++++++++++++----- test.toc | 54 +++++++++++++++++++------------- types.c | 13 ++++++-- types.h | 1 + 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 // #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 { -- cgit v1.2.3