From 8fb6f22fa34497225b94fb6bdcf2a59dae0da6fa Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sun, 6 Oct 2019 20:47:30 -0400 Subject: compile-time idents and tuples --- eval.c | 41 +++++++++++++++++++++++++++++++++++++++++ main.c | 1 + parse.c | 1 - test.toc | 13 +++---------- types.c | 6 +++--- types.h | 40 +++++++++++++++++++++------------------- 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; -- cgit v1.2.3