summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eval.c18
-rw-r--r--main.c6
-rw-r--r--test.toc27
-rw-r--r--types.c50
-rw-r--r--types.h1
5 files changed, 57 insertions, 45 deletions
diff --git a/eval.c b/eval.c
index edbd46d..08417de 100644
--- a/eval.c
+++ b/eval.c
@@ -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;
diff --git a/main.c b/main.c
index 0986f5a..caf8d61 100644
--- a/main.c
+++ b/main.c
@@ -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__)
diff --git a/test.toc b/test.toc
index 41c91ce..a233fed 100644
--- a/test.toc
+++ b/test.toc
@@ -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);
}
diff --git a/types.c b/types.c
index 8bb23a6..0dcd4d1 100644
--- a/types.c
+++ b/types.c
@@ -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.");
diff --git a/types.h b/types.h
index e3d59d2..e347cad 100644
--- a/types.h
+++ b/types.h
@@ -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;