summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-01-14 19:01:58 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-01-14 19:01:58 -0500
commit62349b1f6d9f5948f856e26e3b0eef19567198fa (patch)
tree907540e60d2973f4f15e9c7929422e7d24a0477d
parent2d647644449ead4ab3b477b5c2547bc6da29cc20 (diff)
named args for imported fns
-rw-r--r--cgen.c4
-rw-r--r--identifiers.c4
-rw-r--r--package.c11
-rw-r--r--parse.c8
-rwxr-xr-xpoint.sh5
-rw-r--r--point.toc2
-rw-r--r--test.toc4
-rw-r--r--types.c19
-rw-r--r--types.h1
9 files changed, 38 insertions, 20 deletions
diff --git a/cgen.c b/cgen.c
index 13c4adc..0c955e0 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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);
diff --git a/package.c b/package.c
index bf0ae54..fbb59be 100644
--- a/package.c
+++ b/package.c
@@ -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);
diff --git a/parse.c b/parse.c
index 2ed7473..288087c 100644
--- a/parse.c
+++ b/parse.c
@@ -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
diff --git a/point.toc b/point.toc
index 643a9f8..80506e1 100644
--- a/point.toc
+++ b/point.toc
@@ -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;
};
diff --git a/test.toc b/test.toc
index aa5fee8..168d124 100644
--- a/test.toc
+++ b/test.toc
@@ -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
diff --git a/types.c b/types.c
index de78d56..dba9820 100644
--- a/types.c
+++ b/types.c
@@ -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) {
diff --git a/types.h b/types.h
index 4ee9a44..ba48e59 100644
--- a/types.h
+++ b/types.h
@@ -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