diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-14 19:01:58 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-14 19:01:58 -0500 |
commit | 62349b1f6d9f5948f856e26e3b0eef19567198fa (patch) | |
tree | 907540e60d2973f4f15e9c7929422e7d24a0477d | |
parent | 2d647644449ead4ab3b477b5c2547bc6da29cc20 (diff) |
named args for imported fns
-rw-r--r-- | cgen.c | 4 | ||||
-rw-r--r-- | identifiers.c | 4 | ||||
-rw-r--r-- | package.c | 11 | ||||
-rw-r--r-- | parse.c | 8 | ||||
-rwxr-xr-x | point.sh | 5 | ||||
-rw-r--r-- | point.toc | 2 | ||||
-rw-r--r-- | test.toc | 4 | ||||
-rw-r--r-- | types.c | 19 | ||||
-rw-r--r-- | types.h | 1 |
9 files changed, 38 insertions, 20 deletions
@@ -288,8 +288,10 @@ static inline void cgen_ident_simple(CGenerator *g, Identifier i) { static void cgen_ident(CGenerator *g, Identifier i) { IdentDecl *idecl = ident_decl(i); - if (idecl && idecl->kind == IDECL_DECL && idecl->decl->flags & DECL_EXPORT) + if (idecl && idecl->kind == IDECL_DECL && idecl->decl->flags & DECL_EXPORT) { + assert(g->pkg_prefix); cgen_write(g, "%s__", g->pkg_prefix); + } if (i == g->main_ident) { /* don't conflict with C's main! */ cgen_write(g, "main__"); diff --git a/identifiers.c b/identifiers.c index 505b565..6d1506d 100644 --- a/identifiers.c +++ b/identifiers.c @@ -148,6 +148,10 @@ static void fprint_ident(FILE *out, Identifier id) { } static void fprint_ident_debug(FILE *out, Identifier id) { + if (id->anonymous) { + fprintf(out, "???"); + return; + } #ifdef TOC_DEBUG if (id->export_id) printf(U64_FMT "-", id->export_id); @@ -959,8 +959,9 @@ static bool export_decl(Exporter *ex, Declaration *d) { } static void import_decl(Importer *im, Declaration *d) { - d->flags = import_u16(im); possibly_static_assert(sizeof d->flags == 2); + d->flags = import_u16(im); + d->flags &= (DeclFlags)~(DeclFlags)DECL_EXPORT; d->where = import_location(im); d->idents = NULL; size_t n_idents = import_arr(im, &d->idents); @@ -1051,10 +1052,15 @@ static void import_block(Importer *im, Block *b) { } static bool export_fn(Exporter *ex, FnExpr *f) { + export_location(ex, f->where); export_len(ex, arr_len(f->params)); - arr_foreach(f->params, Declaration, param) + arr_foreach(f->params, Declaration, param) { if (!export_decl(ex, param)) return false; + arr_foreach(param->idents, Identifier, ident) { + export_ident_name(ex, *ident); + } + } export_len(ex, arr_len(f->ret_decls)); arr_foreach(f->ret_decls, Declaration, ret_decl) if (!export_decl(ex, ret_decl)) @@ -1066,6 +1072,7 @@ static bool export_fn(Exporter *ex, FnExpr *f) { } static void import_fn(Importer *im, FnExpr *f) { + f->where = import_location(im); import_arr(im, &f->params); arr_foreach(f->params, Declaration, param) { import_decl(im, param); @@ -834,7 +834,6 @@ static bool parse_decl_list(Parser *p, Declaration **decls, DeclEndKind decl_end static bool parse_fn_expr(Parser *p, FnExpr *f) { Tokenizer *t = p->tokr; f->ret_decls = NULL; - { /* help types.c */ HashTable z = {0}; @@ -1733,6 +1732,10 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { } success: e->where.end = t->token; + + if (e->kind == EXPR_FN) { + e->fn->where = e->where; + } return true; } @@ -2362,6 +2365,9 @@ static bool expr_is_definitely_const(Expression *e) { case EXPR_UNARY_OP: return expr_is_definitely_const(e->unary.of); case EXPR_BINARY_OP: + if (e->binary.op == BINARY_DOT) { + return expr_is_definitely_const(e->binary.lhs); + } return expr_is_definitely_const(e->binary.lhs) && expr_is_definitely_const(e->binary.rhs); case EXPR_SLICE: diff --git a/point.sh b/point.sh new file mode 100755 index 0000000..4b5f3a5 --- /dev/null +++ b/point.sh @@ -0,0 +1,5 @@ +#!/bin/sh +valgrind -q ./toc point.toc -o point.c +valgrind -q ./toc test.toc +gcc point.c out.c -o a.out +./a.out @@ -16,7 +16,7 @@ bar ::= fn() []int { #export x ::= bar(); -#export mk_point ::= fn(x, y: int) p : Point { +#export mk_point ::= fn(x, y:=0) p : Point { p.x = x; p.y = y; }; @@ -7,11 +7,9 @@ putf ::= fn(x: float) { "); }; - - point ::= pkg "point"; main ::= fn() { - x : point.Point = point.mk_point(13, 14); + x : point.Point = point.mk_point(y = 13, 14); puti(x.x + x.y); };
\ No newline at end of file @@ -863,7 +863,7 @@ static bool call_arg_param_order(Allocator *allocr, FnExpr *fn, Location fn_wher bool found = false; arr_foreach(fn->params, Declaration, pa) { arr_foreach(pa->idents, Identifier, id) { - if (*id == arg->name) { + if (ident_eq(*id, arg->name)) { found = true; break; } @@ -1287,21 +1287,16 @@ 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 (f->kind == EXPR_IDENT) { - IdentDecl *decl = ident_decl(f->ident); - assert(decl); - if (decl->kind == IDECL_DECL) { - if (decl->decl->flags & DECL_HAS_EXPR) { - Expression *expr = &decl->decl->expr; - if (expr->kind == EXPR_FN) - fn_decl = decl->decl->expr.fn; - } - } + 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; - if (!call_arg_param_order(tr->allocr, fn_decl, ident_decl(f->ident)->decl->where, &f->type, c->args, e->where, &order)) + if (!call_arg_param_order(tr->allocr, fn_decl, fn_decl->where, &f->type, c->args, e->where, &order)) return false; size_t arg; for (arg = 0; arg < nargs; ++arg) { @@ -572,6 +572,7 @@ typedef struct EachExpr { typedef struct FnExpr { struct Declaration *params; /* declarations of the parameters to this function */ struct Declaration *ret_decls; /* array of decls, if this has named return values. otherwise, NULL */ + Location where; Type ret_type; Block body; HashTable instances; /* for fns with constant parameters. the key is a tuple where |