summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-11-13 12:33:46 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2019-11-13 12:33:46 -0500
commitb1352ae5faada93af4443ec9a0e66c2d08872484 (patch)
tree1c09141ade4b94cf0b9eb359c8b219d0a2250fb9
parent36d01481e735d40df558ef90eadd3c705f8173c7 (diff)
fixed some problems with compile time params
-rw-r--r--cgen.c25
-rw-r--r--main.c5
-rw-r--r--parse.c9
-rw-r--r--test.toc34
-rw-r--r--types.c4
5 files changed, 53 insertions, 24 deletions
diff --git a/cgen.c b/cgen.c
index 2dc187d..956fd83 100644
--- a/cgen.c
+++ b/cgen.c
@@ -1689,6 +1689,9 @@ static bool cgen_decl(CGenerator *g, Declaration *d) {
cgen_write(g, " = ");
if (!cgen_val(g, *val, type, d->where))
return false;
+ } else {
+ cgen_write(g, " = ");
+ cgen_zero_value(g, type);
}
cgen_write(g, ";");
cgen_nl(g);
@@ -1791,18 +1794,20 @@ static bool cgen_stmt(CGenerator *g, Statement *s) {
static bool cgen_defs_expr(CGenerator *g, Expression *e) {
if (e->kind == EXPR_FN) {
FnExpr *f = &e->fn;
- HashTable *instances = f->c.instances;
- if (instances) {
- /* generate each instance */
- ValNumPair *pairs = instances->data;
- for (U64 i = 0; i < instances->cap; i++) {
- if (instances->occupied[i]) {
- /* generate this instance */
- if (!cgen_fn(g, f, e->where, pairs[i].num, pairs[i].val.tuple))
- return false;
+
+ if (e->type.fn.constant) {
+ HashTable *instances = f->c.instances;
+ if (instances) {
+ /* generate each instance */
+ ValNumPair *pairs = instances->data;
+ for (U64 i = 0; i < instances->cap; i++) {
+ if (instances->occupied[i]) {
+ /* generate this instance */
+ if (!cgen_fn(g, f, e->where, pairs[i].num, pairs[i].val.tuple))
+ return false;
+ }
}
}
-
} else {
if (!cgen_fn(g, &e->fn, e->where, 0, NULL))
return false;
diff --git a/main.c b/main.c
index 6676157..1378718 100644
--- a/main.c
+++ b/main.c
@@ -1,9 +1,6 @@
/*
TODO:
-make compile time arguments part of type
-fix local functions
-test direct calling of function with compile time arguments (kind of useless, but test it anyways)
-compile time arguments + out parameters
+compile time arguments + out parameters (in C)
double check that val_get_ptr is being used everywhere it should be
evaluate default arguments
compile-time arguments for out parameter functions
diff --git a/parse.c b/parse.c
index 4fe1f26..cf67805 100644
--- a/parse.c
+++ b/parse.c
@@ -3,6 +3,10 @@ static bool parse_stmt(Parser *p, Statement *s);
#define PARSE_DECL_ALLOW_CONST_WITH_NO_EXPR 0x01
static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, uint16_t flags);
+static bool is_decl(Tokenizer *t);
+static inline bool ends_decl(Token *t, DeclEndKind ends_with);
+
+
static const char *expr_kind_to_str(ExprKind k) {
switch (k) {
case EXPR_LITERAL_FLOAT: return "float literal";
@@ -636,6 +640,8 @@ static bool parser_is_definitely_type(Parser *p, Token **end) {
if (paren_level == 0) {
t->token++;
if (token_is_kw(t->token, KW_LBRACE)) goto end; /* void fn expr */
+ if (is_decl(t)) /* has return declaration */
+ goto end;
Type return_type;
bool prev = t->token->where.ctx->enabled;
t->token->where.ctx->enabled = false;
@@ -744,9 +750,6 @@ static bool parse_block(Parser *p, Block *b) {
return ret;
}
-static bool is_decl(Tokenizer *t);
-static inline bool ends_decl(Token *t, DeclEndKind ends_with);
-
static bool parse_decl_list(Parser *p, Declaration **decls, DeclEndKind decl_end) {
Tokenizer *t = p->tokr;
bool ret = true;
diff --git a/test.toc b/test.toc
index 80e1326..8e52b1b 100644
--- a/test.toc
+++ b/test.toc
@@ -10,13 +10,35 @@ puti @= fn(x: int) {
// };
+// Foo @= struct {
+// x, y: int;
+// z: float;
+// };
+
+
+// bar @= fn() (f: Foo) {
+// f.x = 3;
+// f.y = 123;
+// f.z += 43.2;
+// };
+
+f @= fn(x @ int) i: int {
+ i = x;
+};
main @= fn() {
-f @= fn(x: int, y @ int) int { x + y };
- puti(f(3,5));
-
- puti(f(4, 5));
- puti(f(3, 6));
-puti((fn(x: int, y @ int) int { x + y })(1,2));
+ puti(f(313));
+ puti(f(128));
+ puti(f(231));
+ puti(f(100+213));
};
+// b := bar();
+
+// f @= fn(x: int, y @ int) int { x + y };
+// puti(f(3,5));
+
+// puti(f(4, 5));
+// puti(f(3, 6));
+// puti((fn(x: int, y @ int) int { x + y })(1,2));
+// };
diff --git a/types.c b/types.c
index c39510c..00f72e8 100644
--- a/types.c
+++ b/types.c
@@ -235,6 +235,7 @@ static bool type_of_fn(Typer *tr, Expression *e, Type *t) {
t->kind = TYPE_FN;
t->fn.types = NULL;
t->fn.constant = NULL; /* OPTIM: constant doesn't need to be a dynamic array */
+ bool has_constant_params = false;
Type *ret_type = typer_arr_add(tr, &t->fn.types);
if (!type_resolve(tr, &f->ret_type, e->where))
return false;
@@ -247,6 +248,7 @@ static bool type_of_fn(Typer *tr, Expression *e, Type *t) {
unsigned is_const = decl->flags & DECL_IS_CONST;
if (is_const) {
if (!t->fn.constant) {
+ has_constant_params = true;
for (size_t i = 0; i < idx; i++) {
*(bool *)typer_arr_add(tr, &t->fn.constant) = false;
}
@@ -255,7 +257,7 @@ static bool type_of_fn(Typer *tr, Expression *e, Type *t) {
for (size_t i = 0; i < arr_len(decl->idents); i++) {
Type *param_type = typer_arr_add(tr, &t->fn.types);
*param_type = decl->type;
- if (t->fn.constant) {
+ if (has_constant_params) {
*(bool *)typer_arr_add(tr, &t->fn.constant) = is_const != 0;
}
idx++;