diff options
-rw-r--r-- | cgen.c | 24 | ||||
-rw-r--r-- | decls_cgen.c | 71 | ||||
-rw-r--r-- | instance_table.c | 69 | ||||
-rw-r--r-- | location.c | 7 | ||||
-rw-r--r-- | test.toc | 8 | ||||
-rw-r--r-- | typedefs_cgen.c | 7 | ||||
-rw-r--r-- | types.h | 2 |
7 files changed, 122 insertions, 66 deletions
@@ -29,10 +29,9 @@ static bool cgen_defs_block(CGenerator *g, Block *b); static bool cgen_defs_decl(CGenerator *g, Declaration *d); #define cgen_recurse_subexprs_fn_simple(fn, decl_f, block_f) \ - if (cgen_should_gen_fn(fn)) { \ if (!fn_enter(fn, 0)) return false; \ FnExpr *prev_fn = g->f##n; \ - g->f##n = fn; \ + g->f##n = fn; \ arr_foreach(fn->params, Declaration, param) \ if (!decl_f(g, param)) \ return false; \ @@ -42,8 +41,7 @@ static bool cgen_defs_decl(CGenerator *g, Declaration *d); if (!block_f(g, &fn->body)) \ return false; \ fn_exit(fn); \ - g->f##n = prev_fn; \ - } + g->f##n = prev_fn; /* calls f on every sub-expression of e, block_f on every sub-block, and decl_f on every sub-declaration. */ #define cgen_recurse_subexprs(g, e, f, block_f, decl_f) \ @@ -136,17 +134,17 @@ static bool cgen_defs_decl(CGenerator *g, Declaration *d); for (U64 i = 0; i < fn->instances.cap; i++) { \ if (fn->instances.occupied[i]) { \ cgen_recurse_subexprs_fn_simple((&(*data)->fn), decl_f, block_f); \ - } \ - data++; \ - } \ - } else { \ - cgen_recurse_subexprs_fn_simple(fn, decl_f, block_f); \ + } \ + data++; \ + } \ + } else { \ + cgen_recurse_subexprs_fn_simple(fn, decl_f, block_f); \ } \ } break; \ - case EXPR_NEW: \ - if (e->new.n && !f(g, e->new.n)) \ - return false; \ - break; \ + case EXPR_NEW: \ + if (e->new.n && !f(g, e->new.n)) \ + return false; \ + break; \ } static bool cgen_block_enter(CGenerator *g, Block *b) { diff --git a/decls_cgen.c b/decls_cgen.c index 82bf56f..ca127db 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -47,7 +47,36 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) { fn_exit(&e->fn); } } - } break; + } break; + case EXPR_TYPE: { + Type *type = &e->typeval; + if (type->kind == TYPE_STRUCT) { + StructDef *sdef = type->struc; + if (!(sdef->flags & STRUCT_DEF_CGENERATED)) { + /* generate struct definition */ + cgen_write(g, "struct "); + if (sdef->c.name) + cgen_ident(g, sdef->c.name); + else + cgen_ident_id(g, sdef->c.id); + cgen_write(g, "{"); + cgen_nl(g); + g->indent_lvl++; + arr_foreach(sdef->fields, Field, f) { + if (!cgen_type_pre(g, f->type, e->where)) return false; + cgen_write(g, " "); + cgen_ident(g, f->name); + if (!cgen_type_post(g, f->type, e->where)) return false; + cgen_write(g, ";"); + cgen_nl(g); + } + g->indent_lvl--; + cgen_write(g, "};"); + cgen_nl(g); + sdef->flags |= STRUCT_DEF_CGENERATED; + } + } + } break; default: break; } @@ -86,44 +115,8 @@ static bool cgen_decls_decl(CGenerator *g, Declaration *d) { } cgen_recurse_subexprs(g, (&d->expr), cgen_decls_expr, cgen_decls_block, cgen_decls_decl); } else if (d->flags & DECL_HAS_EXPR) { - if (d->flags & DECL_IS_CONST) { - for (size_t idx = 0; idx < arr_len(d->idents); idx++) { - Type *type = d->type.kind == TYPE_TUPLE ? &d->type.tuple[idx] : &d->type; - if (type->kind == TYPE_TYPE) { - Value *val = d->type.kind == TYPE_TUPLE ? &d->val.tuple[idx] : &d->val; - if (val->type->kind == TYPE_STRUCT) { - StructDef *sdef = val->type->struc; - if (!(sdef->flags & STRUCT_DEF_CGENERATED)) { - /* generate struct definition */ - cgen_write(g, "struct "); - if (sdef->c.name) - cgen_ident(g, sdef->c.name); - else - cgen_ident_id(g, sdef->c.id); - cgen_write(g, "{"); - cgen_nl(g); - g->indent_lvl++; - arr_foreach(sdef->fields, Field, f) { - if (!cgen_type_pre(g, f->type, d->where)) return false; - cgen_write(g, " "); - cgen_ident(g, f->name); - if (!cgen_type_post(g, f->type, d->where)) return false; - cgen_write(g, ";"); - cgen_nl(g); - } - g->indent_lvl--; - cgen_write(g, "};"); - cgen_nl(g); - sdef->flags |= STRUCT_DEF_CGENERATED; - } - } - } - } - } - if (!(d->flags & DECL_IS_CONST) || (d->expr.kind == EXPR_FN)) { - if (!cgen_decls_expr(g, &d->expr)) - return false; - } + if (!cgen_decls_expr(g, &d->expr)) + return false; } return true; } diff --git a/instance_table.c b/instance_table.c index d370a2a..7c8b61c 100644 --- a/instance_table.c +++ b/instance_table.c @@ -1,3 +1,12 @@ +/* + TODO: better hash functions, especially for integers + (right now, nearby integers are close together in hash + space, which is bad with the way these hash tables + are designed) +*/ + +/* NOTE: any time you see 0x then 16 hexadecimal digits, that's probably a random number for hashing */ + /* hash tables are initialized by setting them to {0}, e.g. HashTable x = {0}; @@ -60,8 +69,55 @@ static U64 f64_hash(F64 f) { return hash; } -static void fprint_val(FILE *f, Value v, Type *t); /* DELME */ -static void fprint_type(FILE *out, Type *t); /* !! */ +static U64 type_hash(Type *t) { + static const U64 starters[TYPE_COUNT] = { + 0x40d8675d0f148df7, + 0xee4db91f31fdf2e1, + 0x94963ca71f7f0df4, + 0x95b9d36f45f27cf2, + 0x68d393d7cade0570, + 0x8191b5178d728e8c, + 0x50da97f1211b2423, + 0xc3977306abd0ae6c, + 0x87ea684427e1c521, + 0xcee5fd6d6cbdfe23, + 0xd80dd2469d6e7c1b + }; + U64 hash = starters[t->kind]; + assert(t->flags & TYPE_IS_RESOLVED); + switch (t->kind) { + case TYPE_BUILTIN: + return hash + (U64)t->builtin * 0x1307787dfff73417; + case TYPE_VOID: + case TYPE_UNKNOWN: + case TYPE_TYPE: + return hash; + case TYPE_TUPLE: + arr_foreach(t->tuple, Type, sub) + hash = hash * type_hash(sub) + 0x16225b0aa9993299; + return hash; + case TYPE_FN: + arr_foreach(t->fn.types, Type, sub) + hash = hash * type_hash(sub) + 0x2092d851ab2008de; + return hash; + case TYPE_PTR: + hash += type_hash(t->ptr) * 0x277caae472151119 + 0xf5c6ae7b4dae3bcf; + return hash; + case TYPE_SLICE: + hash += type_hash(t->slice) * 0x67a571620f9a5d6a + 0xc3f91e92c844ab1f; + return hash; + case TYPE_STRUCT: + hash += (U64)t->struc; + return hash; + case TYPE_ARR: + hash += type_hash(t->arr.of) * 0x3b6256104800a414 + 0xa901e68bbd8968a1 + + 0xbf79c81a3e68e504 * t->arr.n; + return hash; + case TYPE_EXPR: break; + } + assert(0); return 0; +} + /* Note that for these value hashing functions, values of different types may collide */ static U64 val_ptr_hash(void *v, Type *t) { assert(t->flags & TYPE_IS_RESOLVED); @@ -97,7 +153,8 @@ static U64 val_ptr_hash(void *v, Type *t) { return hash; } case TYPE_PTR: return (U64)*(void **)v; - case TYPE_TYPE: return (U64)*(Type **)v; + case TYPE_TYPE: + return type_hash(*(Type **)v); case TYPE_ARR: { U32 x = 1; U64 hash = 0; @@ -165,8 +222,10 @@ static bool val_ptr_eq(void *u, void *v, Type *t) { return *(FnExpr **)u == *(FnExpr **)v; case TYPE_PTR: return *(void **)u == *(void **)v; - case TYPE_TYPE: - return type_eq(*(Type **)u, *(Type **)v); + case TYPE_TYPE: { + bool ret = type_eq(*(Type **)u, *(Type **)v); + return ret; + } case TYPE_TUPLE: { Value *us = *(Value **)u; Value *vs = *(Value **)v; @@ -2,3 +2,10 @@ static bool location_after(Location a, Location b) { /* a is after b? */ assert(a.ctx == b.ctx); return a.code > b.code; } + +static void fprint_location(FILE *out, Location location) { + char *newline = strchr(location.code, '\n'); + if (newline) *newline = 0; + fprintf(out, "Line %ld: %s\n", (long)location.line, location.code); + if (newline) *newline = '\n'; +} @@ -23,11 +23,11 @@ y:s; }; main @= fn() { -// a : pair(int); +a : pair(int); b : pair(int); c : pair(float); -// a.x = 5; -// puti(a.x); +a.x = 5; +puti(a.x); c.x = 13.3; -// putf(c.x); +putf(c.x); }; diff --git a/typedefs_cgen.c b/typedefs_cgen.c index 9da3121..8c2d627 100644 --- a/typedefs_cgen.c +++ b/typedefs_cgen.c @@ -4,7 +4,6 @@ static bool typedefs_expr(CGenerator *g, Expression *e); static bool typedefs_block(CGenerator *g, Block *b) { Block *prev = g->block; - printf("%s\n",b->stmts[0].where.code); if (!cgen_block_enter(g, b)) return false; arr_foreach(b->stmts, Statement, s) @@ -85,10 +84,8 @@ static bool typedefs_decl(CGenerator *g, Declaration *d) { } } if (d->flags & DECL_HAS_EXPR) { - if (!(d->flags & DECL_IS_CONST) || d->expr.kind == EXPR_FN) { - if (!typedefs_expr(g, &d->expr)) - return false; - } + if (!typedefs_expr(g, &d->expr)) + return false; } return true; } @@ -299,8 +299,10 @@ typedef enum { TYPE_TYPE, TYPE_EXPR, /* just use this expression as the type. this kind of type doesn't exist after resolving. */ TYPE_STRUCT +#define TYPE_COUNT (TYPE_STRUCT+1) } TypeKind; + typedef enum { BUILTIN_I8, BUILTIN_I16, |