summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-10-06 20:47:30 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-10-06 20:47:30 -0400
commit8fb6f22fa34497225b94fb6bdcf2a59dae0da6fa (patch)
tree8081efbf04af1407b607a4aab993a5c3554cd1d6
parent2977dbc96fdb948e2543aad758a12bc31c450557 (diff)
compile-time idents and tuples
-rw-r--r--eval.c41
-rw-r--r--main.c1
-rw-r--r--parse.c1
-rw-r--r--test.toc13
-rw-r--r--types.c6
-rw-r--r--types.h40
6 files changed, 69 insertions, 33 deletions
diff --git a/eval.c b/eval.c
index 96a7a2c..7951f70 100644
--- a/eval.c
+++ b/eval.c
@@ -452,6 +452,47 @@ static void eval_expr(Evaluator *ev, Expression *e, Value *v) {
eval_expr(ev, e->cast.expr, &casted);
val_cast(&casted, &e->cast.expr->type, v, &e->cast.type);
} break;
+ case EXPR_FN:
+ v->fn = &e->fn;
+ break;
+ case EXPR_IDENT: {
+ IdentDecl *idecl = ident_decl(e->ident);
+ Declaration *d = idecl->decl;
+ if (d->flags & DECL_FLAG_CONST) {
+ if (!(d->flags & DECL_FLAG_FOUND_VAL)) {
+ eval_expr(ev, &d->expr, &d->val);
+ d->flags |= DECL_FLAG_FOUND_VAL;
+ }
+ if (d->type.kind == TYPE_TUPLE) {
+ long index = 0;
+ arr_foreach(d->idents, Identifier, decl_i) {
+ if (*decl_i == e->ident) {
+ break;
+ }
+ index++;
+ assert(index < (long)arr_len(d->idents)); /* identifier got its declaration set to here, but it's not here */
+ }
+ *v = d->val.tuple[index];
+ } else {
+ *v = d->val;
+ }
+ }
+ } break;
+ case EXPR_TUPLE: {
+ size_t i, n = arr_len(e->tuple);
+ v->tuple = evalr_malloc(ev, n * sizeof *v->tuple);
+ for (i = 0; i < n; i++) {
+ eval_expr(ev, &e->tuple[i], &v->tuple[i]);
+ }
+ } break;
+ case EXPR_DIRECT: {
+ DirectExpr *d = &e->direct;
+ switch (d->which) {
+ case DIRECT_C:
+ /* TODO: return error? */
+ break;
+ }
+ }
}
}
diff --git a/main.c b/main.c
index e77b6cb..34e44b0 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,6 @@
/*
TODO:
+compile-time tuples
call fns at compile time
finish evaluator
improve casting: do you really need "as"?
diff --git a/parse.c b/parse.c
index cd2c939..6db62d1 100644
--- a/parse.c
+++ b/parse.c
@@ -1155,7 +1155,6 @@ static inline bool ends_decl(Token *t, DeclEndKind ends_with) {
}
static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, uint16_t flags) {
- d->val = NULL;
d->where = p->tokr->token->where;
d->idents = NULL;
Tokenizer *t = p->tokr;
diff --git a/test.toc b/test.toc
index 639cfcf..c608fc8 100644
--- a/test.toc
+++ b/test.toc
@@ -1,12 +1,5 @@
main @= fn() {
- x : [{ 3; 5 }] int;
- foo, bar := 3, 5;
- asjdfh, asdfkjh := 3.2, 91;
- if foo {
- bar;
- } else {
- foo;
- }
-
- test, test2 := (fn() {}), asjdfh * 2;
+ foo @= true;
+ N, M @= 8 * if foo { 8 } else { 3} - 3, 894;
+ x : [N + M]int;
}; \ No newline at end of file
diff --git a/types.c b/types.c
index e6b7cdc..e619225 100644
--- a/types.c
+++ b/types.c
@@ -1028,9 +1028,9 @@ static bool types_decl(Typer *tr, Declaration *d) {
d->type.flags &= ~TYPE_FLAG_FLEXIBLE; /* x := 5; => x is not flexible */
}
if (d->flags & DECL_FLAG_CONST) {
- if (!d->val) {
- d->val = typer_malloc(tr, sizeof *d->val); /* OPTIM */
- eval_expr(tr->evalr, &d->expr, d->val);
+ if (!(d->flags & DECL_FLAG_FOUND_VAL)) {
+ eval_expr(tr->evalr, &d->expr, &d->val);
+ d->flags |= DECL_FLAG_FOUND_VAL;
}
}
}
diff --git a/types.h b/types.h
index 30b898a..ccb074f 100644
--- a/types.h
+++ b/types.h
@@ -386,11 +386,31 @@ typedef struct Argument {
Expression val;
} Argument;
+typedef union Value {
+ U8 u8;
+ U16 u16;
+ U32 u32;
+ U64 u64;
+ I8 i8;
+ I16 i16;
+ I32 i32;
+ I64 i64;
+ bool boolv;
+ char charv;
+ float f32;
+ double f64;
+ FnExpr *fn;
+ void *arr;
+ void *ptr;
+ union Value *tuple;
+} Value;
+
#define DECL_FLAG_ANNOTATES_TYPE 0x01
#define DECL_FLAG_CONST 0x02
#define DECL_FLAG_HAS_EXPR 0x04
#define DECL_FLAG_FOUND_TYPE 0x08
#define DECL_FLAG_ERRORED_ABOUT_SELF_REFERENCE 0x10 /* has there been an error about this decl referencing itself? */
+#define DECL_FLAG_FOUND_VAL 0x20
/* OPTIM: Instead of using dynamic arrays, do two passes. */
typedef struct Declaration {
@@ -399,7 +419,7 @@ typedef struct Declaration {
Type type;
uint16_t flags;
Expression expr;
- union Value *val; /* only for constant decls. set to NULL here, and to actual value by types.c. */
+ Value val; /* only for constant decls. */
} Declaration;
typedef enum {
@@ -445,21 +465,3 @@ typedef enum {
typedef struct {
Allocator allocr;
} Evaluator;
-
-typedef union Value {
- U8 u8;
- U16 u16;
- U32 u32;
- U64 u64;
- I8 i8;
- I16 i16;
- I32 i32;
- I64 i64;
- bool boolv;
- char charv;
- float f32;
- double f64;
- FnExpr *fn;
- void *arr;
- void *ptr;
-} Value;