summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-02-15 22:14:08 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-02-15 22:14:08 -0500
commitb543b9a80fdb15a03d13c863391dbeff46e804d7 (patch)
tree66c56bbd0654dce8959503e48ba5a1bd7cda4fbb
parentaaf9c614aa1930ccd8df9c08ab9cb9776df4453f (diff)
more struct params & reverted to StructDef *struc;
-rw-r--r--cgen.c12
-rw-r--r--copy.c23
-rw-r--r--decls_cgen.c2
-rw-r--r--eval.c14
-rw-r--r--foreign.c2
-rw-r--r--infer.c47
-rw-r--r--instance_table.c6
-rw-r--r--main.c4
-rw-r--r--parse.c16
-rw-r--r--sdecls_cgen.c2
-rw-r--r--test.toc2
-rw-r--r--types.c59
-rw-r--r--types.h6
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, "<argument>");
- }
- 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;