diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-02 17:21:54 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-02 17:21:54 -0500 |
commit | 153001dd24eece3aa38b57ae2dced25fc0856d0c (patch) | |
tree | 75ed3689b283f093e6f02a5dbac6f1498ea3801b | |
parent | e12efeebae81d524f96eea33813f57d4b90020bc (diff) |
started #if
-rw-r--r-- | eval.c | 44 | ||||
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | parse.c | 14 | ||||
-rw-r--r-- | test.toc | 71 | ||||
-rw-r--r-- | types.c | 35 | ||||
-rw-r--r-- | types.h | 8 |
6 files changed, 82 insertions, 91 deletions
@@ -26,20 +26,20 @@ static inline void *evalr_calloc(Evaluator *ev, size_t n, size_t bytes) { return allocr_calloc(ev->allocr, n, bytes); } -static bool builtin_truthiness(Value *v, BuiltinType b) { +static bool builtin_truthiness(Value v, BuiltinType b) { switch (b) { - case BUILTIN_I8: return v->i8 != 0; - case BUILTIN_I16: return v->i16 != 0; - case BUILTIN_I32: return v->i32 != 0; - case BUILTIN_I64: return v->i64 != 0; - case BUILTIN_U8: return v->u8 != 0; - case BUILTIN_U16: return v->u16 != 0; - case BUILTIN_U32: return v->u32 != 0; - case BUILTIN_U64: return v->u64 != 0; - case BUILTIN_F32: return v->f32 != 0; - case BUILTIN_F64: return v->f64 != 0; - case BUILTIN_BOOL: return v->boolv; - case BUILTIN_CHAR: return v->charv != 0; + case BUILTIN_I8: return v.i8 != 0; + case BUILTIN_I16: return v.i16 != 0; + case BUILTIN_I32: return v.i32 != 0; + case BUILTIN_I64: return v.i64 != 0; + case BUILTIN_U8: return v.u8 != 0; + case BUILTIN_U16: return v.u16 != 0; + case BUILTIN_U32: return v.u32 != 0; + case BUILTIN_U64: return v.u64 != 0; + case BUILTIN_F32: return v.f32 != 0; + case BUILTIN_F64: return v.f64 != 0; + case BUILTIN_BOOL: return v.boolv; + case BUILTIN_CHAR: return v.charv != 0; case BUILTIN_TYPE: case BUILTIN_NMS: break; @@ -47,16 +47,16 @@ static bool builtin_truthiness(Value *v, BuiltinType b) { assert(0); return false; } -static bool val_truthiness(Value *v, Type *t) { +static bool val_truthiness(Value v, Type *t) { assert(t->flags & TYPE_IS_RESOLVED); switch (t->kind) { case TYPE_VOID: return false; case TYPE_UNKNOWN: assert(0); return false; case TYPE_BUILTIN: return builtin_truthiness(v, t->builtin); - case TYPE_PTR: return v->ptr != NULL; - case TYPE_FN: return v->fn != NULL; + case TYPE_PTR: return v.ptr != NULL; + case TYPE_FN: return v.fn != NULL; case TYPE_ARR: return t->arr.n > 0; - case TYPE_SLICE: return v->slice.n > 0; + case TYPE_SLICE: return v.slice.n > 0; case TYPE_TUPLE: case TYPE_STRUCT: case TYPE_EXPR: @@ -349,7 +349,7 @@ static void val_builtin_cast(Value *vin, BuiltinType from, Value *vout, BuiltinT builtin_float_casts(f32, F32); builtin_float_casts(f64, F64); - case BUILTIN_BOOL: vout->boolv = builtin_truthiness(vin, from); break; + case BUILTIN_BOOL: vout->boolv = builtin_truthiness(*vin, from); break; case BUILTIN_CHAR: switch (to) { builtin_casts_to_int(charv); @@ -374,7 +374,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) { assert(to->flags & TYPE_IS_RESOLVED); if (to->kind == TYPE_BUILTIN && to->builtin == BUILTIN_BOOL) { - vout->boolv = val_truthiness(vin, from); + vout->boolv = val_truthiness(*vin, from); return; } @@ -1083,7 +1083,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { eval_unary_op_nums_only(-); } break; case UNARY_NOT: - v->boolv = !val_truthiness(v, &e->unary.of->type); + v->boolv = !val_truthiness(*v, &e->unary.of->type); break; case UNARY_DEL: if (of_type->kind == TYPE_PTR) @@ -1191,7 +1191,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { if (i->cond) { Value cond; if (!eval_expr(ev, i->cond, &cond)) return false; - if (val_truthiness(&cond, &i->cond->type)) { + if (val_truthiness(cond, &i->cond->type)) { if (!eval_block(ev, &i->body, v)) return false; } else if (i->next_elif) { if (!eval_expr(ev, i->next_elif, v)) return false; @@ -1207,7 +1207,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { if (w->cond) { if (!eval_expr(ev, w->cond, &cond)) return false; Type *cond_type = &w->cond->type; - if (!val_truthiness(&cond, cond_type)) + if (!val_truthiness(cond, cond_type)) break; } if (!eval_block(ev, &w->body, v)) return false; @@ -8,7 +8,6 @@ /* TODO: -fix x ::= fn_that_returns_array(); fn_that_takes_array(x); #if variadic fns #foreign variadic fns @@ -1304,6 +1304,9 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { Token *start = t->token; + if (token_is_direct(t->token, DIRECT_IF)) { + goto if_expr; + } if (t->token->kind == TOKEN_KW) switch (t->token->kw) { case KW_FN: { /* this is a function */ @@ -1327,8 +1330,13 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { return false; goto success; } - case KW_IF: { + case KW_IF: + if_expr: { IfExpr *i = e->if_ = parser_malloc(p, sizeof *i); + i->flags = 0; + if (t->token->kind == TOKEN_DIRECT) { + i->flags |= IF_STATIC; + } e->kind = EXPR_IF; ++t->token; Token *cond_end = expr_find_end(p, EXPR_CAN_END_WITH_LBRACE); @@ -1360,6 +1368,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { next->where.start = t->token; curr->next_elif = next; IfExpr *nexti = next->if_ = parser_malloc(p, sizeof *nexti); + nexti->flags = 0; if (is_else) { ++t->token; nexti->cond = NULL; @@ -1853,6 +1862,9 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { Expression *single_arg = NULL; /* points to an expr if this is a directive with one expression argument */ switch (t->token->direct) { + case DIRECT_IF: + assert(0); /* handled above */ + break; case DIRECT_C: e->kind = EXPR_C; single_arg = e->c.code = parser_new_expr(p); @@ -1,70 +1,9 @@ -puti ::= fn(x: int) { -//tcc's giving me "incompatible types for redefinition of 'printf'" for some reason (even though the declarations have the exact same type) - #C("#ifndef __TINYC__ -extern int printf(const char *fmt, ...); -#endif -"); - #C("printf(\"%ld\\n\", (long)x);"); -}; -putf ::= fn(x: float) { - #C("#ifndef __TINYC__ -extern int printf(const char *fmt, ...); -#endif -"); - #C("printf(\"%f\\n\", (double)x);"); -}; - -// it would be nice if Arr.data.len == Arr.len (: but this will require some C code... -Arr ::= fn (t :: Type) Type { - struct { - data : []t; - len, cap : int; - } -}; - -arr_add ::= fn(t :: Type, a : &Arr(t), x : t) { - if a.len >= a.cap { - a.cap = a.cap * 2 + 2; - new_data := new(t, a.cap); - for i := 0..a.len-1 { - new_data[i] = a.data[i]; - } - a.data = new_data; - } - a.data[a.len] = x; - a.len += 1; -}; - -square ::= fn(t :: Type, x : t) t { - a : Arr(t); - for i := 1,2..2*x-1 { - arr_add(t, &a, i); - }; - sum := 0 as t; - for i := 0..a.len-1 { - sum += a.data[i]; - }; - sum -}; - - -ArrInt ::= Arr(int); - -inc ::= fn(t :: Type, x : t) t { - x + 1 -}; +#include "std/io.toc", io; main ::= fn() { - arr : ArrInt; - farr : Arr(float); - for i := 1..100 { - arr_add(int, &arr, inc(int, square(int, i))); - arr_add(float, &farr, inc(float, square(float, i as float))); - } - for i := 0..arr.len - 1 { - puti(arr.data[i]); - } - for i := 0..farr.len - 1 { - putf(farr.data[i]); + #if 3 > 5 { + io.puts("3 > 5"); + } else { + io.puts("5 >= 3"); } }; @@ -1624,6 +1624,41 @@ static Status types_expr(Typer *tr, Expression *e) { case EXPR_IF: { IfExpr *i = e->if_; IfExpr *curr = i; + if (curr->flags & IF_STATIC) { + while (1) { + Expression *cond = curr->cond; + Expression *next = curr->next_elif; + Value v; + if (cond) { + if (!types_expr(tr, cond)) + return false; + if (!types_block(tr, &curr->body)) + return false; + if (!eval_expr(tr->evalr, cond, &v)) + return false; + } + if (!cond || val_truthiness(v, &cond->type)) { + Block *true_block = typer_malloc(tr, sizeof *true_block); + *true_block = curr->body; + e->kind = EXPR_BLOCK; + e->block = true_block; + break; + } + if (!next) break; + curr = next->if_; + } + if (e->kind == EXPR_IF) { + /* all conds were false */ + e->kind = EXPR_BLOCK; + e->block = typer_calloc(tr, 1, sizeof *e->block); + e->block->where = e->where; + idents_create(&e->block->idents, tr->allocr, e->block); + } + /* re-type */ + if (!types_expr(tr, e)) + return false; + return true; + } Type *curr_type = t; bool has_else = false; if (!types_block(tr, &curr->body)) @@ -242,11 +242,12 @@ typedef enum { DIRECT_BUILTIN, DIRECT_INCLUDE, DIRECT_FORCE, + DIRECT_IF, DIRECT_COUNT } Directive; static const char *directives[DIRECT_COUNT] = - {"C", "sizeof", "alignof", "export", "foreign", "builtin", "include", "force"}; + {"C", "sizeof", "alignof", "export", "foreign", "builtin", "include", "force", "if"}; typedef enum { KW_SEMICOLON, @@ -594,7 +595,12 @@ typedef struct CallExpr { struct Instance *instance; /* NULL = ordinary function, no compile time args */ } CallExpr; +enum { + IF_STATIC = 0x01 +}; + typedef struct IfExpr { + U8 flags; struct Expression *cond; /* NULL = this is an else */ struct Expression *next_elif; /* next elif/else of this statement */ Block body; |