From b543b9a80fdb15a03d13c863391dbeff46e804d7 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sat, 15 Feb 2020 22:14:08 -0500 Subject: more struct params & reverted to StructDef *struc; --- cgen.c | 12 ++++++------ copy.c | 23 +++++++--------------- decls_cgen.c | 2 +- eval.c | 14 +++++++------- foreign.c | 2 +- infer.c | 47 +++++++++++++++++++++++--------------------- instance_table.c | 6 +++--- main.c | 4 +++- parse.c | 16 ++------------- sdecls_cgen.c | 2 +- test.toc | 2 +- types.c | 59 +++++++++++++++++++++++++++++++++++++------------------- types.h | 6 +----- 13 files changed, 97 insertions(+), 98 deletions(-) diff --git a/cgen.c b/cgen.c index 5586b6f..7628bd2 100644 --- a/cgen.c +++ b/cgen.c @@ -387,10 +387,10 @@ static bool cgen_type_pre(CGenerator *g, Type *t, Location where) { return false; case TYPE_STRUCT: cgen_write(g, "struct "); - if (t->struc.def->name) { - cgen_ident(g, t->struc.def->name); - } else if (t->struc.def->c.id) { - cgen_ident_id(g, t->struc.def->c.id); + if (t->struc->name) { + cgen_ident(g, t->struc->name); + } else if (t->struc->c.id) { + cgen_ident_id(g, t->struc->c.id); } else { assert(0); } @@ -1832,8 +1832,8 @@ static bool cgen_val_ptr(CGenerator *g, void *v, Type *t, Location where) { break; case TYPE_STRUCT: cgen_write(g, "{"); - arr_foreach(t->struc.def->fields, Field, f) { - if (f != t->struc.def->fields) + arr_foreach(t->struc->fields, Field, f) { + if (f != t->struc->fields) cgen_write(g, ", "); cgen_val_ptr(g, (char *)v + f->offset, &f->type, where); } diff --git a/copy.c b/copy.c index f9b16ec..be82036 100644 --- a/copy.c +++ b/copy.c @@ -126,27 +126,18 @@ static void copy_type(Copier *c, Type *out, Type *in) { it's okay to copy the struct definition here, because before resolving, only one thing can point to a given StructDef */ - StructType *sout = &out->struc, *sin = &in->struc; - - sout->def = allocr_malloc(c->allocr, sizeof *sout->def); - *sout->def = *sin->def; - size_t nfields = arr_len(sin->def->fields); - sout->def->fields = NULL; + out->struc = allocr_malloc(c->allocr, sizeof *out->struc); + *out->struc = *in->struc; + size_t nfields = arr_len(in->struc->fields); + out->struc->fields = NULL; - arr_set_lena(&sout->def->fields, nfields, c->allocr); + arr_set_lena(&out->struc->fields, nfields, c->allocr); for (size_t i = 0; i < nfields; ++i) { - Field *fout = &sout->def->fields[i]; - Field *fin = &sin->def->fields[i]; + Field *fout = &out->struc->fields[i]; + Field *fin = &in->struc->fields[i]; *fout = *fin; copy_type(c, &fout->type, &fin->type); } - - size_t nargs = arr_len(sin->args); - sout->args = NULL; - arr_set_lena(&sout->args, nargs, c->allocr); - for (size_t i = 0; i < nargs; ++i) { - copy_expr(c, &sout->args[i], &sin->args[i]); - } } } break; } diff --git a/decls_cgen.c b/decls_cgen.c index bb72110..61c93e8 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -11,7 +11,7 @@ static bool cgen_decls_type(CGenerator *g, Type *type) { if (!(type->flags & TYPE_IS_RESOLVED)) /* non-instance constant fn parameter type */ return true; if (type->kind == TYPE_STRUCT) { - StructDef *sdef = type->struc.def; + StructDef *sdef = type->struc; if (!(sdef->flags & STRUCT_DEF_CGEN_DEFINED)) { /* generate struct definition */ cgen_write(g, "struct "); diff --git a/eval.c b/eval.c index 489b40f..865d16e 100644 --- a/eval.c +++ b/eval.c @@ -94,8 +94,8 @@ static size_t compiler_alignof(Type *t) { return sizeof(size_t); case TYPE_STRUCT: { /* assume the align of a struct is (at most) the greatest align out of its children's */ - eval_struct_find_offsets(t->struc.def); - return t->struc.def->align; + eval_struct_find_offsets(t->struc); + return t->struc->align; } case TYPE_UNKNOWN: case TYPE_EXPR: @@ -123,8 +123,8 @@ static size_t compiler_sizeof(Type *t) { case TYPE_SLICE: return sizeof v.slice; case TYPE_STRUCT: { - eval_struct_find_offsets(t->struc.def); - return t->struc.def->size; + eval_struct_find_offsets(t->struc); + return t->struc->size; } break; case TYPE_VOID: case TYPE_UNKNOWN: @@ -341,8 +341,8 @@ static void fprint_val_ptr(FILE *f, void *p, Type *t) { } break; case TYPE_STRUCT: fprintf(f, "["); /* TODO: change? when struct initializers are added */ - arr_foreach(t->struc.def->fields, Field, fi) { - if (fi != t->struc.def->fields) + arr_foreach(t->struc->fields, Field, fi) { + if (fi != t->struc->fields) fprintf(f, ", "); fprint_ident_debug(f, fi->name); fprintf(f, ": "); @@ -777,7 +777,7 @@ static bool eval_ptr_to_struct_field(Evaluator *ev, Expression *dot_expr, void * struct_type = struct_type->ptr; } if (struct_type->kind == TYPE_STRUCT) { - eval_struct_find_offsets(struct_type->struc.def); + eval_struct_find_offsets(struct_type->struc); Value struc; if (!eval_expr(ev, dot_expr->binary.lhs, &struc)) diff --git a/foreign.c b/foreign.c index f91d4d7..2c1e54a 100644 --- a/foreign.c +++ b/foreign.c @@ -146,7 +146,7 @@ static bool arg_list_start(av_alist *arg_list, void (*fn)(), Value *return_val, break; case TYPE_STRUCT: { size_t struct_size = compiler_sizeof(return_type); - StructDef *struc = return_type->struc.def; + StructDef *struc = return_type->struc; return_val->struc = err_calloc(1, struct_size); bool splittable; /* hopefully this is right! */ diff --git a/infer.c b/infer.c index b0b5433..e4c8b98 100644 --- a/infer.c +++ b/infer.c @@ -24,6 +24,29 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Expres } break; case EXPR_CALL: { +#if 0 + /* TODO: infer from parameterized structs */ + size_t nargs = arr_len(match->struc.args); + Declaration *param = to->struc->params; + int ident_idx = 0; + for (i = 0; i < nargs; ++i) { + Expression *arg = &match->struc.args[i]; + Value val = *decl_val_at_index(param, ident_idx); + Expression val_expr = {0}; + val_expr.kind = EXPR_VAL; + val_expr.val = val; + val_expr.type = *decl_type_at_index(param, ident_idx); + val_expr.flags = EXPR_FOUND_TYPE; + if (!infer_from_expr(tr, arg, &val_expr, &val_expr, idents, vals, types)) { + return false; + } + ++ident_idx; + if (ident_idx >= (int)arr_len(param->idents)) { + ++param; + ident_idx = 0; + } + } +#endif while (to->kind == EXPR_IDENT) { Identifier i = to->ident; if (i->decl_kind == IDECL_DECL) { @@ -119,34 +142,14 @@ static bool infer_from_type(Typer *tr, Type *match, Type *to, Identifier *idents break; case TYPE_STRUCT: { if (to->kind != TYPE_STRUCT) return true; - Field *fields_m = match->struc.def->fields; - Field *fields_t = to->struc.def->fields; + Field *fields_m = match->struc->fields; + Field *fields_t = to->struc->fields; size_t i, len = arr_len(fields_m); if (len != arr_len(fields_t)) return true; for (i = 0; i < len; ++i) { if (!infer_from_type(tr, &fields_m[i].type, &fields_t[i].type, idents, vals, types)) return false; } - size_t nargs = arr_len(match->struc.args); - Declaration *param = to->struc.def->params; - int ident_idx = 0; - for (i = 0; i < nargs; ++i) { - Expression *arg = &match->struc.args[i]; - Value val = *decl_val_at_index(param, ident_idx); - Expression val_expr = {0}; - val_expr.kind = EXPR_VAL; - val_expr.val = val; - val_expr.type = *decl_type_at_index(param, ident_idx); - val_expr.flags = EXPR_FOUND_TYPE; - if (!infer_from_expr(tr, arg, &val_expr, &val_expr, idents, vals, types)) { - return false; - } - ++ident_idx; - if (ident_idx >= (int)arr_len(param->idents)) { - ++param; - ident_idx = 0; - } - } } break; case TYPE_EXPR: { Expression *to_expr = to->was_expr; diff --git a/instance_table.c b/instance_table.c index 85a2abc..0f8948a 100644 --- a/instance_table.c +++ b/instance_table.c @@ -109,7 +109,7 @@ static U64 type_hash(Type *t) { hash += type_hash(t->slice) * 0x67a571620f9a5d6a + 0xc3f91e92c844ab1f; return hash; case TYPE_STRUCT: - hash += (U64)t->struc.def; + hash += (U64)t->struc; return hash; case TYPE_ARR: hash += type_hash(t->arr.of) * 0x3b6256104800a414 + 0xa901e68bbd8968a1 @@ -183,7 +183,7 @@ static U64 val_ptr_hash(void *v, Type *t) { case TYPE_STRUCT: { U32 x = 1; U64 hash = 0; - arr_foreach(t->struc.def->fields, Field, f) { + arr_foreach(t->struc->fields, Field, f) { hash += (U64)x * val_ptr_hash((char *)v + f->offset, &f->type); x = rand_u32(x); } @@ -265,7 +265,7 @@ static bool val_ptr_eq(void *u, void *v, Type *t) { return true; } case TYPE_STRUCT: - arr_foreach(t->struc.def->fields, Field, f) { + arr_foreach(t->struc->fields, Field, f) { if (!val_ptr_eq((char *)u + f->offset, (char *)v + f->offset, &f->type)) return false; } diff --git a/main.c b/main.c index 6987aa0..7ab8c62 100644 --- a/main.c +++ b/main.c @@ -19,7 +19,9 @@ /* TODO: struct parameters -- make sure you test inference +- check for empty parameter lists +- make sure inference works +--- see infer.c "is resolved_to necessary" (now that ident system has changed) replace is_reference in type_resolve_ with system for checking if type is circularly dependent in a bad way, with compiler_sizeof diff --git a/parse.c b/parse.c index 2527b0f..67a9233 100644 --- a/parse.c +++ b/parse.c @@ -225,7 +225,7 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) { } case TYPE_STRUCT: { size_t written = 0; - StructDef *def = t->struc.def; + StructDef *def = t->struc; Identifier name = def->name; if (name) { char *namestr = ident_to_str(name); @@ -235,17 +235,6 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) { written = str_copy(buffer, bufsize, "anonymous struct"); } if (resolved) { - if (t->struc.args) { - written += str_copy(buffer + written, bufsize - written, "("); - arr_foreach(t->struc.args, Expression, arg) { - /* TODO: print arguments, maybe, but do we even ever call this (for non-debugging purposes) with an unresolved type? */ - if (arg != t->struc.args) - written += str_copy(buffer + written, bufsize - written, ", "); - written += str_copy(buffer + written, bufsize - written, ""); - } - written += str_copy(buffer + written, bufsize - written, ")"); - } - } else { if (def->params) { written += str_copy(buffer + written, bufsize - written, "("); arr_foreach(def->params, Declaration, param) { @@ -601,8 +590,7 @@ static bool parse_type(Parser *p, Type *type) { case KW_STRUCT: { /* struct */ type->kind = TYPE_STRUCT; - type->struc.args = NULL; - StructDef *struc = type->struc.def = parser_malloc(p, sizeof *type->struc.def); + StructDef *struc = type->struc = parser_malloc(p, sizeof *type->struc); struc->flags = 0; struc->name = NULL; /* help cgen out */ diff --git a/sdecls_cgen.c b/sdecls_cgen.c index e84b459..83c978e 100644 --- a/sdecls_cgen.c +++ b/sdecls_cgen.c @@ -13,7 +13,7 @@ static bool cgen_sdecls_type(CGenerator *g, Type *type) { if (!(type->flags & TYPE_IS_RESOLVED)) /* non-instance constant fn parameter type */ return true; if (type->kind == TYPE_STRUCT) { - StructDef *sdef = type->struc.def; + StructDef *sdef = type->struc; /* we'll actually define the struct later; here we can just declare it */ if (sdef->flags & STRUCT_DEF_CGEN_DECLARED) { diff --git a/test.toc b/test.toc index 286e83a..2ded528 100644 --- a/test.toc +++ b/test.toc @@ -7,5 +7,5 @@ foo ::= struct(t::Type) { }; main ::= fn() { - + a:foo(int); }; \ No newline at end of file diff --git a/types.c b/types.c index 42e32da..5b37c1e 100644 --- a/types.c +++ b/types.c @@ -60,7 +60,7 @@ static bool type_eq(Type *a, Type *b) { case TYPE_BUILTIN: return a->builtin == b->builtin; case TYPE_STRUCT: - return a->struc.def == b->struc.def; + return a->struc == b->struc; case TYPE_FN: { if (arr_len(a->fn.types) != arr_len(b->fn.types)) return false; Type *a_types = a->fn.types, *b_types = b->fn.types; @@ -572,12 +572,12 @@ static bool type_resolve_(Typer *tr, Type *t, Location where, bool is_reference) return false; break; case TYPE_STRUCT: - if (t->struc.def->params) { + if (t->struc->params) { err_print(where, "Expected arguments to structure."); - info_print(t->struc.def->where, "Structure was declared here."); + info_print(t->struc->where, "Structure was declared here."); return false; } - arr_foreach(t->struc.def->fields, Field, f) { + arr_foreach(t->struc->fields, Field, f) { if (!type_resolve_(tr, &f->type, where, is_reference)) return false; } @@ -598,10 +598,13 @@ static bool type_resolve_(Typer *tr, Type *t, Location where, bool is_reference) if (!eval_expr(tr->evalr, t->expr, &typeval)) return false; *t = *typeval.type; - if (t->kind == TYPE_STRUCT && !t->struc.args && t->struc.def->params) { - err_print(where, "Expected arguments to structure, but you didn't provide any."); - info_print(t->struc.def->where, "Structure was declared here."); - return false; + if (t->kind == TYPE_STRUCT) { + Declaration *params = t->struc->params; + if (params && !(params[0].flags & DECL_FOUND_VAL)) { + err_print(where, "Expected arguments to structure, but you didn't provide any."); + info_print(t->struc->where, "Structure was declared here."); + return false; + } } t->was_expr = expr; assert(t->flags & TYPE_IS_RESOLVED); @@ -1396,11 +1399,33 @@ static bool types_expr(Typer *tr, Expression *e) { e->type.kind = TYPE_UNKNOWN; return true; } - if (f->type.kind != TYPE_FN) { + if (type_is_builtin(&f->type, BUILTIN_TYPE)) { + /* maybe it's a parameterized type */ + } else if (f->type.kind != TYPE_FN) { char *type = type_to_str(&f->type); err_print(e->where, "Calling non-function (type %s).", type); return false; } + + if (expr_is_definitely_const(f) || type_is_builtin(&f->type, BUILTIN_TYPE)) { + Value val; + if (!eval_expr(tr->evalr, f, &val)) + return false; + if (type_is_builtin(&f->type, BUILTIN_TYPE)) { + Type *base = val.type; + if (base->kind != TYPE_STRUCT) { + err_print(e->where, "Cannot pass arguments to non-struct type."); + return false; + } + if (!base->struc->params) { + int x; + } + return true; + } + fn_decl = val.fn; + + } + Type *ret_type = f->type.fn.types; Type *param_types = ret_type + 1; Argument *args = c->args; @@ -1409,12 +1434,6 @@ static bool types_expr(Typer *tr, Expression *e) { Expression *arg_exprs = NULL; arr_set_lena(&arg_exprs, nparams, tr->allocr); bool *params_set = nparams ? typer_calloc(tr, nparams, sizeof *params_set) : NULL; - if (expr_is_definitely_const(f)) { - Value val; - if (!eval_expr(tr->evalr, f, &val)) - return false; - fn_decl = val.fn; - } if (fn_decl) { U16 *order; @@ -2043,7 +2062,7 @@ static bool types_expr(Typer *tr, Expression *e) { e->binary.op = BINARY_DOT; bool is_field = false; if (!eval_expr(tr->evalr, rhs, &field_name)) return false; - arr_foreach(lhs_type->struc.def->fields, Field, f) { + arr_foreach(lhs_type->struc->fields, Field, f) { if (ident_eq_str(f->name, field_name.slice.data)) { is_field = true; *t = f->type; @@ -2106,7 +2125,7 @@ static bool types_expr(Typer *tr, Expression *e) { } if (struct_type->kind == TYPE_STRUCT) { bool is_field = false; - arr_foreach(struct_type->struc.def->fields, Field, f) { + arr_foreach(struct_type->struc->fields, Field, f) { if (ident_eq(f->name, rhs->ident)) { is_field = true; *t = f->type; @@ -2197,7 +2216,7 @@ static bool types_expr(Typer *tr, Expression *e) { } case EXPR_TYPE: { Type *tval = &e->typeval; - if (tval->kind == TYPE_STRUCT && tval->struc.def->params) { + if (tval->kind == TYPE_STRUCT && tval->struc->params) { /* don't try to resolve this */ t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_TYPE; @@ -2283,7 +2302,7 @@ static bool types_decl(Typer *tr, Declaration *d) { if ((d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_TYPE && d->expr.typeval.kind == TYPE_STRUCT) { - d->expr.typeval.struc.def->name = d->idents[0]; + d->expr.typeval.struc->name = d->idents[0]; } if (d->flags & DECL_INFER) { @@ -2384,7 +2403,7 @@ static bool types_decl(Typer *tr, Declaration *d) { if (type_is_builtin(t, BUILTIN_TYPE)) { if (d->flags & DECL_HAS_EXPR) { Value *val = d->type.kind == TYPE_TUPLE ? &d->val.tuple[i] : &d->val; - if (val->type->kind == TYPE_STRUCT && val->type->struc.def->params) { + if (val->type->kind == TYPE_STRUCT && val->type->struc->params) { /* don't resolve it because it's not really complete */ } else { if (!type_resolve(tr, val->type, d->where)) return false; diff --git a/types.h b/types.h index 6ece6b1..c9e1197 100644 --- a/types.h +++ b/types.h @@ -417,10 +417,6 @@ enum { TYPE_IS_RESOLVED = 0x02, }; typedef U8 TypeFlags; -typedef struct { - struct StructDef *def; /* it's a pointer so that multiple Types can reference the same struct definition */ - struct Expression *args; /* only exists before resolving */ -} StructType; typedef struct Type { Location where; struct Expression *was_expr; /* if non-NULL, indicates that this type used to be an expression (TYPE_EXPR) */ @@ -439,7 +435,7 @@ typedef struct Type { } arr; struct Type *ptr; struct Type *slice; - StructType struc; + struct StructDef *struc; /* multiple resolved types can refer to the same struct */ struct Expression *expr; }; } Type; -- cgit v1.2.3