From e8cd3b66a9bf20e5a68147a9882685299d40f495 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sat, 30 Nov 2019 18:30:50 -0500 Subject: basic type returning --- cgen.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ decls_cgen.c | 30 ++++++++++++++++++------------ main.c | 4 +--- test.toc | 11 +++-------- types.c | 2 -- 5 files changed, 74 insertions(+), 25 deletions(-) diff --git a/cgen.c b/cgen.c index db44b76..2e227bf 100644 --- a/cgen.c +++ b/cgen.c @@ -429,10 +429,60 @@ static inline void cgen_fn_instance_number(CGenerator *g, U64 instance) { cgen_write(g, "%"PRIu64"_", instance); } +/* does this type have a type type in it? (e.g. [5]Type, &&Type) */ +static bool type_contains_type(Type *t) { + assert(t->flags & TYPE_IS_RESOLVED); + switch (t->kind) { + case TYPE_BUILTIN: + case TYPE_VOID: + case TYPE_UNKNOWN: + return false; + case TYPE_TYPE: + return true; + case TYPE_PTR: + return type_contains_type(t->ptr); + case TYPE_SLICE: + return type_contains_type(t->slice); + case TYPE_ARR: + return type_contains_type(t->arr.of); + case TYPE_FN: + arr_foreach(t->fn.types, Type, sub) + if (type_contains_type(sub)) + return true; + return false; + case TYPE_TUPLE: + arr_foreach(t->tuple, Type, sub) + if (type_contains_type(sub)) + return true; + return false; + case TYPE_STRUCT: + arr_foreach(t->struc->fields, Field, f) + if (type_contains_type(f->type)) + return true; + return false; + case TYPE_EXPR: break; + } + assert(0); + return false; +} + +/* should we generate this function? (or is it just meant for compile time) */ +static bool cgen_should_gen_fn(FnExpr *f) { + if (f->ret_decls) { + arr_foreach(f->ret_decls, Declaration, decl) + if (type_contains_type(&decl->type)) + return false; + return true; + } else { + return !type_contains_type(&f->ret_type); + } +} + /* unless f has const/semi-const args, instance and which_are_const can be set to 0 */ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where, U64 instance, U64 which_are_const) { bool out_param = cgen_uses_ptr(&f->ret_type); bool any_params = false; + assert(cgen_should_gen_fn(f)); if (!f->c.name) /* anonymous fn */ cgen_write(g, "static "); if (out_param) { @@ -1478,6 +1528,8 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, Location where, U64 instance, Valu FnExpr *prev_fn = g->fn; Block *prev_block = g->block; U64 which_are_const = compile_time_args ? compile_time_args->u64 : 0; + if (!cgen_should_gen_fn(f)) + return true; fn_enter(f, 0); if (!cgen_fn_header(g, f, where, instance, which_are_const)) return false; diff --git a/decls_cgen.c b/decls_cgen.c index 35ef2b5..593bf5d 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -5,6 +5,8 @@ static bool cgen_decls_decl(CGenerator *g, Declaration *d); static bool cgen_decls_fn_instances(CGenerator *g, Expression *e) { assert(e->kind == EXPR_FN); FnExpr *f = &e->fn; + if (!cgen_should_gen_fn(f)) + return true; FnType *type = &e->type.fn; assert(type->constness); Instance **data = f->instances.data; @@ -36,12 +38,14 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) { if (!cgen_decls_fn_instances(g, e)) return false; } else { - fn_enter(&e->fn, 0); - if (!cgen_fn_header(g, &e->fn, e->where, 0, 0)) - return false; - cgen_write(g, ";"); - cgen_nl(g); - fn_exit(&e->fn); + if (cgen_should_gen_fn(&e->fn)) { + fn_enter(&e->fn, 0); + if (!cgen_fn_header(g, &e->fn, e->where, 0, 0)) + return false; + cgen_write(g, ";"); + cgen_nl(g); + fn_exit(&e->fn); + } } } break; default: @@ -69,12 +73,14 @@ static bool cgen_decls_decl(CGenerator *g, Declaration *d) { if (!cgen_decls_fn_instances(g, &d->expr)) return false; } else { - fn_enter(&d->expr.fn, 0); - if (!cgen_fn_header(g, &d->expr.fn, d->where, 0, 0)) - return false; - cgen_write(g, ";"); - cgen_nl(g); - fn_exit(&d->expr.fn); + if (cgen_should_gen_fn(&d->expr.fn)) { + fn_enter(&d->expr.fn, 0); + if (!cgen_fn_header(g, &d->expr.fn, d->where, 0, 0)) + return false; + cgen_write(g, ";"); + cgen_nl(g); + fn_exit(&d->expr.fn); + } } cgen_recurse_subexprs(g, (&d->expr), cgen_decls_expr, cgen_decls_block, cgen_decls_decl); } else if (d->flags & DECL_HAS_EXPR) { diff --git a/main.c b/main.c index e07c049..8f1b25e 100644 --- a/main.c +++ b/main.c @@ -1,12 +1,10 @@ /* TODO: -get rid of TYPE_USER -- don't do automatic type conversion - functions returning Types test ArrInt @= Arr(int); packages +X @= newtype(int); or something don't allow while {3; 5} (once break is added) any odd number of "s for a string make sure futurely/currently-declared types are only used by pointer/slice diff --git a/test.toc b/test.toc index 91c14b9..75c471f 100644 --- a/test.toc +++ b/test.toc @@ -15,16 +15,11 @@ -t @= struct { - A: int; - b: int; +f @= fn() Type { +int }; -f @= fn() {}; main @= fn() { - -u @= t; -x : t; - y : u = x; +x : f(); }; \ No newline at end of file diff --git a/types.c b/types.c index 2384f32..ab186d1 100644 --- a/types.c +++ b/types.c @@ -27,8 +27,6 @@ static bool type_eq(Type *a, Type *b) { return true; /* allow things such as 3 + #C("5") */ assert(a->flags & TYPE_IS_RESOLVED); assert(b->flags & TYPE_IS_RESOLVED); - - /* TODO: deal with was_expr */ if (a->kind != b->kind) return false; if (b->flags & TYPE_IS_FLEXIBLE) { -- cgit v1.2.3