summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-01-17 17:33:12 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-01-17 17:33:12 -0500
commit3d3c0f04e26d3f07983601dc91714e3dca447206 (patch)
treeae27f8e3de2c7081c3b896d01228f62a30a0a771
parent29e8e65be7b07515b3f45a67593602d9e4317115 (diff)
code cleanup (FnExpr now contains Location)
-rw-r--r--cgen.c47
-rw-r--r--decls_cgen.c15
-rw-r--r--identifiers.c1
-rw-r--r--infer.c4
-rw-r--r--main.c5
-rw-r--r--package.c8
-rw-r--r--test.toc12
-rw-r--r--types.c19
8 files changed, 51 insertions, 60 deletions
diff --git a/cgen.c b/cgen.c
index 0a6a6b8..1bf233b 100644
--- a/cgen.c
+++ b/cgen.c
@@ -487,7 +487,7 @@ static void cgen_full_fn_name(CGenerator *g, FnExpr *f, U64 instance) {
}
}
-static bool cgen_fn_args(CGenerator *g, FnExpr *f, Location where, U64 instance, U64 which_are_const) {
+static bool cgen_fn_args(CGenerator *g, FnExpr *f, U64 instance, U64 which_are_const) {
(void)instance; /* not needed atm */
bool out_param = cgen_uses_ptr(&f->ret_type);
bool any_params = false;
@@ -504,11 +504,11 @@ static bool cgen_fn_args(CGenerator *g, FnExpr *f, Location where, U64 instance,
any_args = true;
Type *type = d->type.kind == TYPE_TUPLE ? &d->type.tuple[idx++] : &d->type;
any_params = true;
- if (!cgen_type_pre(g, type, where))
+ if (!cgen_type_pre(g, type, f->where))
return false;
cgen_write(g, " ");
cgen_ident(g, *i);
- if (!cgen_type_post(g, type, where))
+ if (!cgen_type_post(g, type, f->where))
return false;
}
}
@@ -521,17 +521,17 @@ static bool cgen_fn_args(CGenerator *g, FnExpr *f, Location where, U64 instance,
Type *x = &f->ret_type.tuple[i];
if (any_params || i > 0)
cgen_write(g, ", ");
- if (!cgen_type_pre(g, x, where)) return false;
+ if (!cgen_type_pre(g, x, f->where)) return false;
cgen_write(g, "(*ret%lu_)", (unsigned long)i);
- if (!cgen_type_post(g, x, where)) return false;
+ if (!cgen_type_post(g, x, f->where)) return false;
}
} else {
if (any_params)
cgen_write(g, ", ");
- if (!cgen_type_pre(g, &f->ret_type, where))
+ if (!cgen_type_pre(g, &f->ret_type, f->where))
return false;
cgen_write(g, " (*ret_)");
- if (!cgen_type_post(g, &f->ret_type, where))
+ if (!cgen_type_post(g, &f->ret_type, f->where))
return false;
}
}
@@ -542,7 +542,7 @@ static bool cgen_fn_args(CGenerator *g, FnExpr *f, Location where, U64 instance,
}
/* 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) {
+static bool cgen_fn_header(CGenerator *g, FnExpr *f, U64 instance, U64 which_are_const) {
bool out_param = cgen_uses_ptr(&f->ret_type);
assert(cgen_should_gen_fn(f));
if (!f->export.id) /* local to this translation unit */
@@ -550,14 +550,14 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where, U64 instanc
if (out_param) {
cgen_write(g, "void ");
} else {
- if (!cgen_type_pre(g, &f->ret_type, where)) return false;
+ if (!cgen_type_pre(g, &f->ret_type, f->where)) return false;
cgen_write(g, " ");
}
cgen_full_fn_name(g, f, instance);
if (!out_param) {
- if (!cgen_type_post(g, &f->ret_type, where)) return false;
+ if (!cgen_type_post(g, &f->ret_type, f->where)) return false;
}
- return cgen_fn_args(g, f, where, instance, which_are_const);
+ return cgen_fn_args(g, f, instance, which_are_const);
}
@@ -1179,10 +1179,13 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
cgen_write(g, U64_FMT, e->intl);
break;
case EXPR_LITERAL_STR: {
- size_t c;
+ char *p = e->strl.str;
cgen_write(g, "mkslice_(\"");
- for (c = 0; c < e->strl.len; ++c) {
- cgen_write(g, "\\x%x", e->strl.str[c]);
+ for (size_t i = 0; i < e->strl.len; ++i, ++p) {
+ if (isprint(*p) && *p != '"')
+ cgen_write(g, "%c", *p);
+ else
+ cgen_write(g, "\\x%x", *p);
}
cgen_write(g, "\", %lu)", (unsigned long)e->strl.len);
} break;
@@ -1547,7 +1550,7 @@ static void cgen_zero_value(CGenerator *g, Type *t) {
}
/* pass 0 for instance and NULL for compile_time_args if there are no compile time arguments. */
-static bool cgen_fn(CGenerator *g, FnExpr *f, Location where, U64 instance, Value *compile_time_args) {
+static bool cgen_fn(CGenerator *g, FnExpr *f, U64 instance, Value *compile_time_args) {
/* see also cgen_defs_expr */
FnExpr *prev_fn = g->fn;
Block *prev_block = g->block;
@@ -1555,7 +1558,7 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, Location where, U64 instance, Valu
if (!cgen_should_gen_fn(f))
return true;
fn_enter(f, 0);
- if (!cgen_fn_header(g, f, where, instance, which_are_const))
+ if (!cgen_fn_header(g, f, instance, which_are_const))
return false;
g->fn = f;
cgen_write(g, " {");
@@ -1576,14 +1579,14 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, Location where, U64 instance, Valu
if (type_is_builtin(type, BUILTIN_TYPE)) {
/* don't need to do anything; we'll just use the type's id */
} else {
- if (!cgen_val_pre(g, arg, type, where))
+ if (!cgen_val_pre(g, arg, type, f->where))
return false;
- if (!cgen_type_pre(g, type, where)) return false;
+ if (!cgen_type_pre(g, type, f->where)) return false;
cgen_write(g, " const ");
cgen_ident(g, *ident);
- if (!cgen_type_post(g, type, where)) return false;
+ if (!cgen_type_post(g, type, f->where)) return false;
cgen_write(g, " = ");
- if (!cgen_val(g, arg, type, where))
+ if (!cgen_val(g, arg, type, f->where))
return false;
cgen_write(g, ";");
cgen_nl(g);
@@ -1928,13 +1931,13 @@ static bool cgen_defs_fn(CGenerator *g, FnExpr *f, Type *t) {
for (U64 i = 0; i < instances->cap; ++i) {
if (instances->occupied[i]) {
/* generate this instance */
- if (!cgen_fn(g, &is[i]->fn, f->where, is[i]->c.id, is[i]->val.tuple))
+ if (!cgen_fn(g, &is[i]->fn, is[i]->c.id, is[i]->val.tuple))
return false;
}
}
}
if (!any_const) {
- if (!cgen_fn(g, f, f->where, 0, NULL))
+ if (!cgen_fn(g, f, 0, NULL))
return false;
}
return true;
diff --git a/decls_cgen.c b/decls_cgen.c
index 1545dca..d9ba325 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -42,11 +42,11 @@ static bool cgen_decls_type(CGenerator *g, Type *type) {
return true;
}
-static bool cgen_single_fn_decl(CGenerator *g, FnExpr *f, Location where, U64 instance, U64 which_are_const) {
+static bool cgen_single_fn_decl(CGenerator *g, FnExpr *f, U64 instance, U64 which_are_const) {
if (cgen_should_gen_fn(f)) {
if (!fn_enter(f, 0))
return false;
- if (!cgen_fn_header(g, f, where, instance, which_are_const))
+ if (!cgen_fn_header(g, f, instance, which_are_const))
return false;
cgen_write(g, ";");
cgen_nl(g);
@@ -56,15 +56,14 @@ static bool cgen_single_fn_decl(CGenerator *g, FnExpr *f, Location where, U64 in
}
-static bool cgen_decls_fn_instances(CGenerator *g, FnExpr *f, Type *type) {
- assert(type->fn.constness);
+static bool cgen_decls_fn_instances(CGenerator *g, FnExpr *f) {
Instance **data = f->instances.data;
for (U64 i = 0; i < f->instances.cap; ++i) {
if (f->instances.occupied[i]) {
if (cgen_should_gen_fn(&(*data)->fn)) {
(*data)->fn.c.name = f->c.name;
(*data)->fn.c.id = f->c.id;
- if (!cgen_single_fn_decl(g, &(*data)->fn, f->where, (*data)->c.id, (*data)->val.tuple[0].u64))
+ if (!cgen_single_fn_decl(g, &(*data)->fn, (*data)->c.id, (*data)->val.tuple[0].u64))
return false;
cgen_write(g, ";");
cgen_nl(g);
@@ -80,10 +79,10 @@ static bool cgen_fn_decl(CGenerator *g, FnExpr *f, Type *t) {
if (f->c.declared) return true;
f->c.declared = true;
if (fn_type->constness) {
- if (!cgen_decls_fn_instances(g, f, t))
+ if (!cgen_decls_fn_instances(g, f))
return false;
} else {
- if (!cgen_single_fn_decl(g, f, f->where, 0, 0))
+ if (!cgen_single_fn_decl(g, f, 0, 0))
return false;
}
return true;
@@ -148,7 +147,7 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) {
if (!cgen_type_post(g, &f->ret_type, e->where))
return false;
}
- if (!cgen_fn_args(g, f, e->where, 0, 0))
+ if (!cgen_fn_args(g, f, 0, 0))
return false;
cgen_write(g, ";");
cgen_nl(g);
diff --git a/identifiers.c b/identifiers.c
index 28989d9..52f09b0 100644
--- a/identifiers.c
+++ b/identifiers.c
@@ -132,6 +132,7 @@ static char *ident_to_str(Identifier i) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#pragma GCC diagnostic ignored "-Wrestrict"
+#pragma GCC diagnostic ignored "-Warray-bounds"
#endif
memcpy(str, i->text, i->len);
diff --git a/infer.c b/infer.c
index 98d5635..f577988 100644
--- a/infer.c
+++ b/infer.c
@@ -1,4 +1,4 @@
-static bool call_arg_param_order(Allocator *allocr, FnExpr *fn, Location fn_where, Type *fn_type, Argument *args, Location where, U16 **param_indices);
+static bool call_arg_param_order(Allocator *allocr, FnExpr *fn, Type *fn_type, Argument *args, Location where, U16 **param_indices);
static bool types_expr(Typer *tr, Expression *e);
/* resolved_to should have the same value as to, but not consist of any identifiers which aren't in scope right now */
@@ -52,7 +52,7 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Expres
if (!types_expr(tr, f))
return false;
FnExpr *fn_decl = idecl->decl->expr.fn;
- if (!call_arg_param_order(tr->allocr, fn_decl, idecl->decl->where, &f->type, m_args, match->where, &order))
+ if (!call_arg_param_order(tr->allocr, fn_decl, &f->type, m_args, match->where, &order))
return false;
}
for (size_t i = 0; i < nargs; ++i) {
diff --git a/main.c b/main.c
index 5940406..3d942be 100644
--- a/main.c
+++ b/main.c
@@ -18,9 +18,10 @@
/*
TODO:
-packages
-clean up anywhere we used FnExpr *f, Location where
make sure (&Package).something works
+C functions (#foreign)
+#include
+variadic fns
---
X ::= newtype(int); or something
don't allow while {3; 5} (once break is added)
diff --git a/package.c b/package.c
index 38f8e26..8147272 100644
--- a/package.c
+++ b/package.c
@@ -402,13 +402,13 @@ static void import_type(Importer *im, Type *type) {
}
}
-static bool export_fn_ptr(Exporter *ex, FnExpr *f, Location where) {
+static bool export_fn_ptr(Exporter *ex, FnExpr *f) {
if (f->export.id == 0) {
FnExpr **fptr = arr_add(&ex->exported_fns);
*fptr = f;
size_t nexported_fns = arr_len(ex->exported_fns);
if (nexported_fns > U32_MAX) {
- err_print(where, "Too many exported functions (the maximum is " STRINGIFY(U32_MAX) ").");
+ err_print(f->where, "Too many exported functions (the maximum is " STRINGIFY(U32_MAX) ").");
return false;
}
f->export.id = (U32)nexported_fns;
@@ -488,7 +488,7 @@ static bool export_val_ptr(Exporter *ex, void *v, Type *type, Location where) {
}
} break;
case TYPE_FN:
- if (!export_fn_ptr(ex, *(FnExpr **)v, where))
+ if (!export_fn_ptr(ex, *(FnExpr **)v))
return false;
break;
case TYPE_UNKNOWN:
@@ -687,7 +687,7 @@ static bool export_expr(Exporter *ex, Expression *e) {
return false;
break;
case EXPR_FN:
- if (!export_fn_ptr(ex, e->fn, e->where))
+ if (!export_fn_ptr(ex, e->fn))
return false;
break;
case EXPR_BLOCK:
diff --git a/test.toc b/test.toc
index 2770b9e..c278703 100644
--- a/test.toc
+++ b/test.toc
@@ -1,17 +1,5 @@
-arr ::= pkg "std/arr";
io ::= pkg "std/io";
-putptri ::= fn(x: &int) {
- io.puti(*x);
-};
-
main ::= fn() {
io.puts("Hello, world!");
- x : arr.Arr(int);
- arr.arr_add(&x, 10);
- arr.arr_add(&x, 20);
- arr.arr_add(&x, 80);
- arr.arr_add(&x, 5430);
- arr.arr_add(&x, -6546);
- arr.arr_foreach(x, putptri);
}; \ No newline at end of file
diff --git a/types.c b/types.c
index c6ab0d3..a6c02ba 100644
--- a/types.c
+++ b/types.c
@@ -764,8 +764,7 @@ static bool arg_is_const(Expression *arg, Constness constness) {
/* MUST be called after type_of_fn. */
/* pass NULL for instance if this isn't an instance */
-static bool types_fn(Typer *tr, FnExpr *f, Type *t, Location where,
- Instance *instance) {
+static bool types_fn(Typer *tr, FnExpr *f, Type *t, Instance *instance) {
FnExpr *prev_fn = tr->fn;
bool success = true;
bool entered_fn = false;
@@ -801,7 +800,7 @@ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Location where,
if (!instance) /* where will only actually be at the function declaration if it isn't
an instance. otherwise, where will be at the calling site, which will already be
printed */
- info_print(where, "Function declaration is here.");
+ info_print(f->where, "Function declaration is here.");
free(got); free(expected);
success = false;
goto ret;
@@ -823,7 +822,7 @@ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Location where,
char *expected = type_to_str(ret_type);
err_print(token_location(f->body.where.end), "No return value in function which returns %s.", expected);
free(expected);
- info_print(where, "Function was declared here:");
+ info_print(f->where, "Function was declared here:");
success = false;
goto ret;
}
@@ -835,7 +834,7 @@ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Location where,
}
/* puts a dynamic array of the parameter indices of the arguments into param_indices. */
-static bool call_arg_param_order(Allocator *allocr, FnExpr *fn, Location fn_where, Type *fn_type, Argument *args, Location where, U16 **param_indices) {
+static bool call_arg_param_order(Allocator *allocr, FnExpr *fn, Type *fn_type, Argument *args, Location where, U16 **param_indices) {
size_t nparams = arr_len(fn_type->fn.types)-1;
size_t nargs = arr_len(args);
if (nargs > nparams) {
@@ -875,14 +874,14 @@ static bool call_arg_param_order(Allocator *allocr, FnExpr *fn, Location fn_wher
char *s = ident_to_str(arg->name);
err_print(arg->where, "Argument '%s' does not appear in declaration of function.", s);
free(s);
- info_print(fn_where, "Declaration is here.");
+ info_print(fn->where, "Declaration is here.");
return false;
}
param_idx = index;
} else {
if (param > (Declaration *)arr_last(fn->params)) {
err_print(arg->where, "Too many arguments to function!");
- info_print(fn_where, "Declaration is here.");
+ info_print(fn->where, "Declaration is here.");
return false;
}
@@ -927,7 +926,7 @@ static bool types_expr(Typer *tr, Expression *e) {
HashTable z = {0};
e->fn->instances = z;
} else {
- if (!types_fn(tr, e->fn, &e->type, e->where, NULL))
+ if (!types_fn(tr, e->fn, &e->type, NULL))
return false;
}
} break;
@@ -1286,7 +1285,7 @@ static bool types_expr(Typer *tr, Expression *e) {
if (fn_decl) {
U16 *order;
- if (!call_arg_param_order(tr->allocr, fn_decl, fn_decl->where, &f->type, c->args, e->where, &order))
+ if (!call_arg_param_order(tr->allocr, fn_decl, &f->type, c->args, e->where, &order))
return false;
size_t arg;
for (arg = 0; arg < nargs; ++arg) {
@@ -1595,7 +1594,7 @@ static bool types_expr(Typer *tr, Expression *e) {
/* if anything happens, make sure we let the user know that this happened while generating a fn */
ErrCtx *err_ctx = e->where.start->pos.ctx;
*(Location *)typer_arr_add(tr, &err_ctx->instance_stack) = e->where;
- bool success = types_fn(tr, &c->instance->fn, &f->type, e->where, c->instance);
+ bool success = types_fn(tr, &c->instance->fn, &f->type, c->instance);
arr_remove_lasta(&err_ctx->instance_stack, tr->allocr);
if (!success) return false;
arr_cleara(&table_index_type.tuple, tr->allocr);