diff options
-rw-r--r-- | cgen.c | 74 | ||||
-rw-r--r-- | decls_cgen.c | 5 | ||||
-rw-r--r-- | main.c | 8 | ||||
-rw-r--r-- | out.c | 37 | ||||
-rw-r--r-- | test.toc | 22 | ||||
-rw-r--r-- | types.c | 11 | ||||
-rw-r--r-- | types.h | 1 |
7 files changed, 99 insertions, 59 deletions
@@ -18,7 +18,7 @@ static void cgen_create(CGenerator *g, FILE *out, Identifiers *ids, Evaluator *e g->anon_fns = NULL; } -static void cgen_block_enter(CGenerator *g, Block *b) { +static bool cgen_block_enter(CGenerator *g, Block *b) { g->block = b; Statement *stmts; if (b == NULL) { @@ -27,7 +27,7 @@ static void cgen_block_enter(CGenerator *g, Block *b) { stmts = b->stmts; } if (b) g->indent_lvl++; - block_enter(b, stmts); + return block_enter(b, stmts); } static void cgen_block_exit(CGenerator *g, Block *into) { @@ -106,7 +106,12 @@ static void cgen_ident(CGenerator *g, Identifier i) { cgen_write(g, "main__"); } else { cgen_indent(g); + IdentDecl *idecl = ident_decl(i); + if (idecl->flags & IDECL_FLAG_CGEN_PTR) + cgen_write(g, "(*"); fprint_ident(cgen_writing_to(g), i); + if (idecl->flags & IDECL_FLAG_CGEN_PTR) + cgen_write(g, ")"); } } @@ -202,17 +207,33 @@ static bool cgen_type_post(CGenerator *g, Type *t, Location where) { cgen_write(g, ", "); if (!cgen_type_pre(g, &t->fn.types[i], where)) return false; + if (cgen_uses_ptr(&t->fn.types[i])) + cgen_write(g, "(*)"); if (!cgen_type_post(g, &t->fn.types[i], where)) return false; } if (out_param) { + Type *ret_type = &t->fn.types[0]; if (arr_len(t->fn.types) > 1) cgen_write(g, ", "); - if (!cgen_type_pre(g, &t->fn.types[0], where)) - return false; - cgen_write(g, "(*)"); - if (!cgen_type_post(g, &t->fn.types[0], where)) - return false; + if (ret_type->kind == TYPE_TUPLE) { + arr_foreach(ret_type->tuple, Type, x) { + if (!cgen_type_pre(g, x, where)) + return false; + cgen_write(g, "(*)"); + if (!cgen_type_post(g, x, where)) + return false; + if (x != arr_last(ret_type->tuple)) { + cgen_write(g, ", "); + } + } + } else { + if (!cgen_type_pre(g, ret_type, where)) + return false; + cgen_write(g, "(*)"); + if (!cgen_type_post(g, ret_type, where)) + return false; + } } if (arr_len(t->fn.types) == 1 && !out_param) cgen_write(g, "void"); @@ -261,6 +282,14 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where) { if (!cgen_type_pre(g, &d->type, where)) return false; cgen_write(g, " "); + bool ptr = cgen_uses_ptr(&d->type); + if (ptr) { + fprint_type(stdout, &d->type); + puts(""); + IdentDecl *idecl = ident_decl(*i); + assert(idecl); + idecl->flags |= IDECL_FLAG_CGEN_PTR; + } cgen_ident(g, *i); if (!cgen_type_post(g, &d->type, where)) return false; @@ -340,20 +369,20 @@ static bool cgen_set(CGenerator *g, Expression *set_expr, const char *set_str, E cgen_write(g, "(*arr__in)"); if (!cgen_type_post(g, type->arr.of, where)) return false; cgen_write(g, " = "); - if (set_expr) { - if (!cgen_expr(g, set_expr)) return false; + if (to_expr) { + if (!cgen_expr(g, to_expr)) return false; } else { - cgen_write(g, set_str); + cgen_write(g, to_str); } cgen_write(g, "; "); if (!cgen_type_pre(g, type->arr.of, where)) return false; cgen_write(g, "(*arr__out)"); if (!cgen_type_post(g, type->arr.of, where)) return false; cgen_write(g, " = "); - if (to_expr) { - if (!cgen_expr(g, to_expr)) return false; + if (set_expr) { + if (!cgen_expr(g, set_expr)) return false; } else { - cgen_write(g, to_str); + cgen_write(g, set_str); } cgen_write(g, ";"); cgen_nl(g); @@ -404,6 +433,8 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, arr_foreach(to->call.arg_exprs, Expression, arg) { if (arg != to->call.arg_exprs) cgen_write(g, ", "); + if (cgen_uses_ptr(&arg->type)) + cgen_write(g, "&"); if (!cgen_expr(g, arg)) return false; } @@ -720,7 +751,11 @@ static bool cgen_expr(CGenerator *g, Expression *e) { cgen_write(g, ")("); if (!cgen_expr(g, e->cast.expr)) return false; - cgen_write(g, "))"); + cgen_write(g, ")"); + if (e->cast.expr->type.kind == TYPE_SLICE + && e->cast.type.kind != TYPE_SLICE) /* casting from a slice to a non-slice */ + cgen_write(g, ".data"); + cgen_write(g, ")"); break; case EXPR_TUPLE: /* the only time this should happen is if you're stating @@ -747,7 +782,8 @@ static bool cgen_expr(CGenerator *g, Expression *e) { static bool cgen_block(CGenerator *g, Block *b, const char *ret_name) { Block *prev = g->block; cgen_write(g, "{"); - cgen_block_enter(g, b); + if (!cgen_block_enter(g, b)) + return false; cgen_nl(g); arr_foreach(b->stmts, Statement, s) if (!cgen_stmt(g, s)) @@ -794,6 +830,7 @@ static void cgen_zero_value(CGenerator *g, Type *t) { } static bool cgen_fn(CGenerator *g, FnExpr *f, Location where) { + fn_enter(f); if (!cgen_fn_header(g, f, where)) return false; cgen_write(g, " "); @@ -802,7 +839,8 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, Location where) { cgen_write(g, "{"); cgen_nl(g); arr_foreach(f->ret_decls, Declaration, d) { - cgen_decl(g, d); + if (!cgen_decl(g, d)) + return false; } if (!cgen_block(g, &f->body, NULL)) return false; @@ -818,6 +856,7 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, Location where) { } cgen_write(g, "}"); + fn_exit(f); cgen_nl(g); g->fn = prev_fn; cgen_nl(g); @@ -936,6 +975,7 @@ static bool cgen_stmt(CGenerator *g, Statement *s) { static bool cgen_decls_file(CGenerator *g, ParsedFile *f); static bool cgen_file(CGenerator *g, ParsedFile *f) { + g->block = NULL; g->file = f; cgen_write(g, "#include <stdint.h>\n" "#include <stdlib.h>\n" @@ -953,11 +993,9 @@ static bool cgen_file(CGenerator *g, ParsedFile *f) { "typedef struct { void *data; u64 n; } slice_;\n" "#define false ((bool)0)\n" "#define true ((bool)1)\n\n\n"); - cgen_block_enter(g, NULL); if (!cgen_decls_file(g, f)) return false; cgen_write(g, "/* code */\n"); - cgen_block_exit(g, NULL); cgen_write(g, "int main() {\n\tmain__();\n\treturn 0;\n}\n\n"); arr_foreach(f->stmts, Statement, s) diff --git a/decls_cgen.c b/decls_cgen.c index 990a21b..ca29bfc 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -74,7 +74,8 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) { static bool cgen_decls_block(CGenerator *g, Block *b) { Block *prev = g->block; - cgen_block_enter(g, b); + if (!cgen_block_enter(g, b)) + return false; arr_foreach(b->stmts, Statement, s) cgen_decls_stmt(g, s); cgen_block_exit(g, prev); @@ -84,12 +85,14 @@ static bool cgen_decls_block(CGenerator *g, Block *b) { static bool cgen_decls_decl(CGenerator *g, Declaration *d) { if (cgen_fn_is_direct(g, d)) { d->expr.fn.c.name = d->idents[0]; + fn_enter(&d->expr.fn); if (!cgen_fn_header(g, &d->expr.fn, d->where)) return false; cgen_write(g, ";"); cgen_nl(g); if (!cgen_decls_block(g, &d->expr.fn.body)) return false; + fn_exit(&d->expr.fn); } else if (d->flags & DECL_FLAG_HAS_EXPR) { if (!cgen_decls_expr(g, &d->expr)) return false; @@ -1,7 +1,5 @@ /* TODO: -fix casting for slice => ptr/arr -parameters can be passed as pointers new returns a *slice* unicode variable names make sure initializers for global variables are compile-time constants @@ -77,6 +75,10 @@ int main(int argc, char **argv) { Evaluator ev; evalr_create(&ev); typer_create(&tr, &ev); + + if (!block_enter(NULL, f.stmts)) /* enter global scope */ + return false; + if (!types_file(&tr, &f)) { err_fprint(TEXT_IMPORTANT("Errors occured while determining types.\n")); return EXIT_FAILURE; @@ -93,6 +95,8 @@ int main(int argc, char **argv) { cgen_create(&g, out, &file_idents, &ev); cgen_file(&g, &f); + block_exit(NULL, f.stmts); /* exit global scope */ + tokr_free(&t); free(contents); @@ -18,6 +18,7 @@ typedef struct { void *data; u64 n; } slice_; /* declarations */ void puti(i64 x); +void asdf(i64( (*x)[3]), i64 y, i64(*ret0_), i64((*ret1_)[3])); void main__(void); /* code */ int main() { @@ -33,25 +34,27 @@ void puti(i64 x) { }} +void asdf(i64( (*x)[3]), i64 y, i64(*ret0_), i64((*ret1_)[3])) { +{ +}(*ret0_) = y;{ +size_t i;i64(*arr__in) = (*x); i64(*arr__out) = (*ret1_); +for (i = 0; i < 3; i++) arr__out[i] = arr__in[i]; +}return; +} + + void main__(void) { { - i64 a0_0_; i64 a0_1_; if (0) { - (a0_0_) = 3;(a0_1_) = 5; - } else { - (a0_0_) = 4;(a0_1_) = 6; - }i64 A; i64 B; (A) = a0_0_; (B) = a0_1_; - (puti(A)); - (puti(B)); - i64 y = 0; - while ((y<10)) { - i64 a2_; - { - y = (y+1);; - a2_ = y; - }(puti(a2_)); - }; - slice_ foo = {NULL, 0}; - slice_ bar = {NULL, 0}; + i64( a[3]) = {0}; + i64 b = 0; + (a[0]) = 17;; + b = 5489;; + i64 c; i64( d[3]); asdf(&a, b, &c, &d); + + (puti(c)); + (puti((d[0]))); + void (* asdfasdf)(i64((*)[3]), i64, i64(*), i64((*)[3])); { + void (* expr__)(i64((*)[3]), i64, i64(*), i64((*)[3])); expr__ = asdf;asdfasdf = expr__;} }} @@ -4,16 +4,16 @@ puti @= fn(x: int) { #C("printf(\"%ld\\n\", (long)x)"); }; +asdf @= fn(x: [3]int, y : int) (int, [3]int) { + y, x +}; + main @= fn() { - A, B := if 0 { 3, 5 } else { 4, 6 }; - // A, B := 3, 5; - puti(A); - puti(B); - y:int; - while y < 10 { - puti({y = y + 1; y}); - } - foo : []int; - bar : []float; - + a : [3]int; + b : int; + a[0] = 17; + b = 5489; + c, d := asdf(a, b); + puti(c); puti(d[0]); + asdfasdf := asdf; };
\ No newline at end of file @@ -471,22 +471,16 @@ static Status type_cast_status(Type *from, Type *to) { return STATUS_WARN; if (to->kind == TYPE_PTR) return STATUS_NONE; - if (to->kind == TYPE_ARR && type_eq(from->ptr, to->arr.of)) - return STATUS_NONE; if (to->kind == TYPE_FN) return STATUS_WARN; return STATUS_ERR; case TYPE_ARR: if (to->kind == TYPE_PTR && type_eq(from->arr.of, to->ptr)) return STATUS_NONE; - if (to->kind == TYPE_ARR && !type_eq(from, to)) - return STATUS_WARN; return STATUS_ERR; case TYPE_SLICE: if (to->kind == TYPE_PTR && type_eq(from->slice, to->ptr)) return STATUS_NONE; - if (to->kind == TYPE_ARR && type_eq(from->slice, to->arr.of)) - return STATUS_NONE; return STATUS_ERR; } assert(0); @@ -1171,14 +1165,11 @@ static void typer_create(Typer *tr, Evaluator *ev) { static bool types_file(Typer *tr, ParsedFile *f) { bool ret = true; - if (!block_enter(NULL, f->stmts)) /* enter global scope */ - return false; arr_foreach(f->stmts, Statement, s) { if (!types_stmt(tr, s)) { ret = false; } - } - block_exit(NULL, f->stmts); /* exit global scope */ + } return ret; } @@ -84,6 +84,7 @@ typedef union Value { } Value; #define IDECL_FLAG_HAS_VAL 0x01 +#define IDECL_FLAG_CGEN_PTR 0x02 /* is a pointer being used for this identifier? */ typedef struct { struct Declaration *decl; struct Block *scope; /* NULL for file scope */ |