diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-09 14:58:51 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-09 14:58:51 -0400 |
commit | 5edaca6cf2ea681c01c7ee0ef5daa041ed185640 (patch) | |
tree | ddeaf59400efb5ed68cb7bb4a62bb43d8e54d940 | |
parent | e2d31615fcf2e3d02d5ff75e98524885c66e49b6 (diff) |
more varargs and bugfixes
-rw-r--r-- | cgen.c | 6 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | test.toc | 55 | ||||
-rw-r--r-- | types.c | 14 |
4 files changed, 61 insertions, 16 deletions
@@ -433,7 +433,7 @@ static void cgen_full_fn_name(CGenerator *g, FnExpr *f, U64 instance) { } } -static void cgen_fn_args(CGenerator *g, FnExpr *f, U64 instance, U64 which_are_const) { +static void cgen_fn_params(CGenerator *g, FnExpr *f, U64 instance, U64 which_are_const) { (void)instance; /* not needed atm */ bool out_param = cgen_uses_ptr(&f->ret_type); cgen_write(g, "("); @@ -456,6 +456,8 @@ static void cgen_fn_args(CGenerator *g, FnExpr *f, U64 instance, U64 which_are_c } } else if ((d->flags & DECL_SEMI_CONST) && (which_are_const & (((U64)1) << semi_const_idx++))) { + /* semi constant argument is constant */ + } else { int idx = 0; arr_foreach(d->idents, Identifier, i) { if (any_params) @@ -534,7 +536,7 @@ static void cgen_fn_header(CGenerator *g, FnExpr *f, U64 instance, U64 which_are cgen_write(g, " "); } cgen_full_fn_name(g, f, instance); - cgen_fn_args(g, f, instance, which_are_const); + cgen_fn_params(g, f, instance, which_are_const); if (!out_param) { cgen_type_post(g, &f->ret_type); } @@ -10,9 +10,11 @@ TODO: variadic fns const varargs +varargs only exist in decls. not a type of its own don't allow default varargs don't allow semiconst varargs make sure you can't have a variadic function pointer +make sure varargs works with inference #foreign variadic fns where #returns_code (function/struct body is a block, to be evaluated at compile time, which returns the actual statements -- you can use this for implementation of printf) @@ -1,9 +1,54 @@ -f ::= fn(x: ..) int { - 3 +#include "io.toc"; + +Arr ::= struct (t :: Type) { + data: []t; + len, cap: int; }; -main ::= fn() { - f(1,2,3); + +arr_add ::= fn(t ::=, a : &Arr(t), x : t) { + if a.len >= a.cap { + a.cap = a.cap * 2 + 2; + new_data := new(t, a.cap); + for i := 0..a.len-1 { + new_data[i] = a.data[i]; + } + a.data = new_data; + } + a.data[a.len] = x; + a.len += 1; }; -main();
\ No newline at end of file +square ::= fn(t ::=, x : t) t { + a : Arr(t); + for i := 1,2..2*x-1 { + arr_add(&a, i); + }; + sum := 0 as t; + for i := 0..a.len-1 { + sum += a.data[i]; + }; + sum +}; + + +// ArrInt ::= Arr(int); + +inc ::= fn(t ::=, x : t) t { + x + 1 +}; + +main ::= fn() { + arr : Arr(int); + farr : Arr(float); + for i := 1..100 { + arr_add(&arr, inc(square(i))); + arr_add(&farr, inc(square(i as float))); + } + for i := 0..arr.len - 1 { + puti(arr.data[i]); + } + for i := 0..farr.len - 1 { + puti(farr.data[i] as int); + } +}; @@ -489,12 +489,7 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { } for (size_t i = 0; i < arr_len(param->idents); ++i) { Type *param_type = typer_arr_add(tr, &t->fn.types); - if (!generic) { - *param_type = param->type; - } else { - param_type->flags = 0; - param_type->kind = TYPE_UNKNOWN; - } + *param_type = param->type; if (has_constant_params) { Constness constn; if (param->flags & DECL_IS_CONST) { @@ -1807,7 +1802,7 @@ static Status types_expr(Typer *tr, Expression *e) { err_print(e->where, "Calling non-function (type %s).", type); return false; } - bool has_varargs = fn_type_has_varargs(&f->type.fn); + bool has_varargs = f->type.kind == TYPE_FN && fn_type_has_varargs(&f->type.fn); if (expr_is_definitely_const(f) || type_is_builtin(&f->type, BUILTIN_TYPE) || has_varargs) { Value val; @@ -1958,7 +1953,7 @@ static Status types_expr(Typer *tr, Expression *e) { } } - size_t nvarargs; + size_t nvarargs = 0; if (has_varargs) { assert(fn_decl); nvarargs = nargs - (size_t)order[nparams-1]; @@ -1972,8 +1967,9 @@ static Status types_expr(Typer *tr, Expression *e) { if (fn_decl && !(fn_decl->flags & FN_EXPR_FOREIGN)) { size_t i = 0; + Declaration *last_param = arr_last(fn_decl->params); arr_foreach(fn_decl->params, Declaration, param) { - if (type_is_builtin(¶m->type, BUILTIN_VARARGS)) continue; + if (has_varargs && param == last_param) continue; arr_foreach(param->idents, Identifier, ident) { I16 arg_idx = order[i]; if (arg_idx == -1) { |