diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-04-05 11:09:35 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-04-05 11:09:35 -0400 |
commit | 623ad6fbbdb1ad2e03b104230c307735df01b6d6 (patch) | |
tree | 330631b513557902b688525fc4411fb3a226d7fa | |
parent | 943922ae04fa5194091606ad717ecea91ad2f646 (diff) |
fixed some problems with use
-rw-r--r-- | eval.c | 18 | ||||
-rw-r--r-- | main.c | 6 | ||||
-rw-r--r-- | test.toc | 27 | ||||
-rw-r--r-- | types.c | 50 | ||||
-rw-r--r-- | types.h | 1 |
5 files changed, 57 insertions, 45 deletions
@@ -15,7 +15,6 @@ static Value get_builtin_val(BuiltinVal val); static void evalr_create(Evaluator *ev, Typer *tr, Allocator *allocr) { ev->returning = NULL; ev->typer = tr; - ev->enabled = true; ev->allocr = allocr; ffmgr_create(&ev->ffmgr, ev->allocr); } @@ -654,7 +653,7 @@ static Status eval_expr_ptr_at_index(Evaluator *ev, Expression *e, void **ptr, T return eval_val_ptr_at_index(e->where, &arr, i, ltype, ptr, type); } -static Value *ident_val(Identifier i) { +static Value *ident_val(Evaluator *ev, Identifier i) { switch (i->decl_kind) { case IDECL_FOR: { ForExpr *fo = i->decl_for; @@ -671,6 +670,8 @@ static Value *ident_val(Identifier i) { case IDECL_DECL: { Declaration *decl = i->decl; int idx = decl_ident_index(decl, i); + if (decl->type.kind == TYPE_UNKNOWN && ev->typer->err_ctx->have_errored) + return false; /* silently fail (something went wrong when we typed this decl) */ if (decl->flags & DECL_IS_PARAM) { if (decl->val_stack) { Value *valp = *(Value **)arr_last(decl->val_stack); @@ -706,8 +707,8 @@ static Value *ident_val(Identifier i) { } -static inline bool eval_address_of_ident(Identifier i, Location where, Type *type, void **ptr) { - Value *val = ident_val(i); +static inline bool eval_address_of_ident(Evaluator *ev, Identifier i, Location where, Type *type, void **ptr) { + Value *val = ident_val(ev, i); if (!val) { char *s = ident_to_str(i); err_print(where, "Cannot access value of variable %s at compile time.", s); @@ -749,7 +750,7 @@ static Status eval_ptr_to_struct_field(Evaluator *ev, Expression *dot_expr, void void *ptr; Identifier ident = dot_expr->binary.rhs->ident; assert(type_is_builtin(struct_type, BUILTIN_NMS)); - if (!eval_address_of_ident(ident, dot_expr->where, &dot_expr->type, &ptr)) + if (!eval_address_of_ident(ev, ident, dot_expr->where, &dot_expr->type, &ptr)) return false; *p = ptr; } @@ -759,7 +760,7 @@ static Status eval_ptr_to_struct_field(Evaluator *ev, Expression *dot_expr, void static Status eval_address_of(Evaluator *ev, Expression *e, void **ptr) { switch (e->kind) { case EXPR_IDENT: { - if (!eval_address_of_ident(e->ident, e->where, &e->type, ptr)) + if (!eval_address_of_ident(ev, e->ident, e->where, &e->type, ptr)) return false; } break; case EXPR_UNARY_OP: @@ -804,7 +805,7 @@ static Status eval_set(Evaluator *ev, Expression *set, Value *to) { switch (set->kind) { case EXPR_IDENT: { Identifier i = set->ident; - Value *ival = ident_val(i); + Value *ival = ident_val(ev, i); if (!ival) { err_print(set->where, "Cannot set value of run time variable at compile time."); return false; @@ -1042,7 +1043,7 @@ static Status eval_ident(Evaluator *ev, Identifier ident, Value *v, Location whe assert(d->type.flags & TYPE_IS_RESOLVED); } } - Value *ival = ident_val(ident); + Value *ival = ident_val(ev, ident); if (ival) { *v = *ival; } else { @@ -1097,7 +1098,6 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { eval_unary_op_one(f32, F32, op); \ eval_unary_op_one(f64, F64, op); - if (!ev->enabled) return false; /* silently fail */ switch (e->kind) { case EXPR_UNARY_OP: { Value of; @@ -8,13 +8,13 @@ /* TODO: -for accessing struct members (and other things, potentially) with struct["member"], just replace e with - a BINARY_DOT use - use with a decl, e.g. use p : Point; - make sure use works with functions and for, e.g. for use p := points - exceptions (so that if you accidentally use something but have a function with the same name you can still use the function) +for accessing struct members (and other things, potentially) with struct["member"], just replace e with + a BINARY_DOT local structs should not be named in C for some reason forgetting a ; after #include causes a misleading unrecognized expression simplify eval macros with val_to_u/i64 @@ -36,7 +36,7 @@ once you have a bunch of test code, try making more Expression members pointers error on x ::= {return; 3} #returns_code (struct body is a block, to be evaluated at compile time, which returns the actual statements) - struct varargs -macros +macros (specifically, passing untyped expressions to functions) */ #if defined __unix__ || (defined __APPLE__ && defined __MACH__) @@ -1,19 +1,32 @@ -//#include "std/io.toc"; +#include "std/io.toc"; Point ::= struct { - x, y: int; + x, y: float; } -sqdist ::= fn(p: Point) { +sqrt ::= fn(x: float) a := x/2 { + for _ := 0..20 { + a = (x + a * a) / (2 * a); + } +} + +normalize ::= fn(p: &Point) { use p; - x * x + y * y + sqdist := x * x + y * y; + one_over_dist := 1/sqrt(sqdist); + x *= one_over_dist; + y *= one_over_dist; } +printf ::= #foreign("printf", "libc.so.6") fn(#C &"const char", #C ..); + main ::= fn() { p: Point; use p; - x = 3; - y = 4; - //puti(sqdist(p)); + x = 10; + y = 20; + normalize(&p); + fmt := "%f %f\n\0"; + printf(&fmt[0], p.x, p.y); } @@ -589,23 +589,25 @@ static Status type_of_ident(Typer *tr, Location where, Identifier i, Type *t) { case IDECL_DECL: top: { Declaration *d = i->decl; - /* check for trying to capture a variable into a function */ - bool captured = false; - if (ident_scope(i) != NULL && ident_scope(i)->kind != BLOCK_NMS) { - Block *decl_scope = ident_scope(i); - if (decl_scope->kind != BLOCK_NMS) { - /* go back through scopes */ - for (Block **block = arr_last(tr->blocks); *block && *block != decl_scope; --block) { - if ((*block)->kind == BLOCK_FN) { - captured = true; - break; + if (!(d->flags & DECL_IS_CONST)) { + /* check for trying to capture a variable into a function */ + bool captured = false; + if (ident_scope(i) != NULL && ident_scope(i)->kind != BLOCK_NMS) { + Block *decl_scope = ident_scope(i); + if (decl_scope->kind != BLOCK_NMS) { + /* go back through scopes */ + for (Block **block = arr_last(tr->blocks); *block && *block != decl_scope; --block) { + if ((*block)->kind == BLOCK_FN) { + captured = true; + break; + } } } } - } - if (captured && !(d->flags & DECL_IS_CONST)) { - err_print(where, "Variables cannot be captured into inner functions (but constants can)."); - return false; + if (captured) { + err_print(where, "Variables cannot be captured into inner functions (but constants can)."); + return false; + } } if ((d->flags & DECL_HAS_EXPR) && (d->expr.kind == EXPR_TYPE)) { /* allow using a type before declaring it */ @@ -2437,12 +2439,8 @@ static Status types_expr(Typer *tr, Expression *e) { if (!order || order[i] != -1) { Expression *expr = &arg_exprs[i]; Value arg_val = {0}; - if (!eval_expr(tr->evalr, expr, &arg_val)) { - if (tr->evalr->enabled) { - info_print(arg_exprs[i].where, "(error occured while trying to evaluate compile-time argument, argument #%lu)", 1+(unsigned long)i); - } + if (!eval_expr(tr->evalr, expr, &arg_val)) return false; - } Type *type = &expr->type; arg_exprs[i].kind = EXPR_VAL; arg_exprs[i].flags = EXPR_FOUND_TYPE; @@ -3402,7 +3400,6 @@ static Status types_decl(Typer *tr, Declaration *d) { d->type.flags = TYPE_IS_RESOLVED; d->type.was_expr = NULL; d->type.kind = TYPE_UNKNOWN; - tr->evalr->enabled = false; /* disable evaluator completely so that it doesn't accidentally try to access this declaration */ } arr_remove_lasta(&tr->in_decls, tr->allocr); return success; @@ -3585,13 +3582,16 @@ static Status types_stmt(Typer *tr, Statement *s) { case STMT_USE: { Use *u = s->use; Expression *e = &u->expr; + Type *t = &e->type; if (!types_expr(tr, e)) return false; - if (e->type.kind != TYPE_STRUCT && !type_is_builtin(&e->type, BUILTIN_NMS)) { - char *str = type_to_str(&e->type); - err_print(s->where, "You cannot use something of type %s (only Namespaces and structs).", str); - free(str); - return false; + if (t->kind != TYPE_STRUCT && !type_is_builtin(t, BUILTIN_NMS)) { + if (!(t->kind == TYPE_PTR && t->ptr->kind == TYPE_STRUCT)) { + char *str = type_to_str(&e->type); + err_print(s->where, "You cannot use something of type %s (only Namespaces and structs).", str); + free(str); + return false; + } } if (!expr_is_usable(e)) { err_print(e->where, "You can't use this value. You should probably assign it to a variable."); @@ -1046,7 +1046,6 @@ typedef struct Evaluator { Block *returning; /* function body from which we are returning OR loop body in which we are continuing/breaking */ bool is_break; /* is returning because of a break, as opposed to a continue? */ Value ret_val; - bool enabled; ForeignFnManager ffmgr; } Evaluator; |