summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-04-19 18:35:59 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-04-19 18:35:59 -0400
commit606b4078dc2871262455272a56a4ab4d5e90b523 (patch)
tree43fe69f7d1221b5f8e238f8a6c40a7fa9792e5e7
parent1c8c80a7e0014a350da59a8e34e499ec1f241b6d (diff)
new for loop system: eval
-rw-r--r--eval.c49
-rw-r--r--main.c5
-rw-r--r--test.toc13
3 files changed, 29 insertions, 38 deletions
diff --git a/eval.c b/eval.c
index 806a024..55c8db6 100644
--- a/eval.c
+++ b/eval.c
@@ -1250,55 +1250,40 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
}
} break;
case EXPR_FOR: {
- /* TODO */
-#if 0
ForExpr *fo = e->for_;
- Value *index_val;
- Value *value_val;
- Value **for_valpp = arr_add(&fo->val_stack);
+ Declaration *header = &fo->header;
+ Value **for_valpp = arr_add(&header->val_stack);
Value *for_valp = *for_valpp = err_malloc(sizeof *for_valp);
- if (fo->index && fo->value) {
- /* make a tuple */
- for_valp->tuple = err_malloc(2 * sizeof *for_valp->tuple);
- }
- if (fo->index) {
- index_val = fo->value ? &for_valp->tuple[0] : for_valp;
- } else {
- index_val = NULL;
- }
- if (fo->value) {
- value_val = fo->index ? &for_valp->tuple[1] : for_valp;
- } else {
- value_val = NULL;
- }
+ /* make a tuple */
+ Value for_val_tuple[2];
+ for_valp->tuple = for_val_tuple;
+ Value *value_val = &for_val_tuple[0];
+ Value *index_val = &for_val_tuple[1];
+ Type *value_type = &header->type.tuple[0];
if (fo->flags & FOR_IS_RANGE) {
+ assert(value_type->kind == TYPE_BUILTIN);
Value from, to;
Value stepval;
- stepval.i64 = 1;
- Type i64t = {0};
- i64t.flags = TYPE_IS_RESOLVED;
- i64t.kind = TYPE_BUILTIN;
- i64t.builtin = BUILTIN_I64;
+ i64_to_val(&stepval, value_type->builtin, 1);
if (!eval_expr(ev, fo->range.from, &from)) return false;
if (fo->range.to && !eval_expr(ev, fo->range.to, &to)) return false;
if (fo->range.stepval)
stepval = *fo->range.stepval;
Value x = from;
- bool step_is_negative = fo->range.stepval && !val_is_nonnegative(stepval, &fo->type);
+ bool step_is_negative = fo->range.stepval && !val_is_nonnegative(stepval, value_type);
if (index_val) index_val->i64 = 0;
while (1) {
if (fo->range.to) {
/* check if loop has ended */
Value lhs = x;
Value rhs = to;
- assert(fo->type.kind == TYPE_BUILTIN);
Type boolt = {0};
boolt.flags = TYPE_IS_RESOLVED;
boolt.kind = TYPE_BUILTIN;
boolt.builtin = BUILTIN_BOOL;
Value cont;
- eval_numerical_bin_op(lhs, &fo->type, step_is_negative ? BINARY_GE : BINARY_LE, rhs, &fo->range.to->type, &cont, &boolt);
+ eval_numerical_bin_op(lhs, value_type, step_is_negative ? BINARY_GE : BINARY_LE, rhs, &fo->range.to->type, &cont, &boolt);
if (!cont.boolv) break;
}
if (value_val) *value_val = x;
@@ -1315,7 +1300,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
if (index_val) {
++index_val->i64;
}
- eval_numerical_bin_op(x, &fo->type, BINARY_ADD, stepval, fo->range.stepval ? &fo->type : &i64t, &x, &fo->type);
+ eval_numerical_bin_op(x, value_type, BINARY_ADD, stepval, value_type, &x, value_type);
}
} else {
@@ -1355,7 +1340,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
if (uses_ptr)
value_val->ptr = ptr;
else
- eval_deref(value_val, ptr, &fo->type);
+ eval_deref(value_val, ptr, value_type);
if (!eval_block(ev, &fo->body, v))
return false;
if (ev->returning) {
@@ -1368,12 +1353,8 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) {
++index->i64;
}
}
- arr_remove_last(&fo->val_stack);
- if (fo->index && fo->value) {
- free(for_valp->tuple);
- }
+ arr_remove_last(&header->val_stack);
free(for_valp);
-#endif
} break;
case EXPR_BLOCK:
if (!eval_block(ev, e->block, v)) return false;
diff --git a/main.c b/main.c
index cd74872..dba2d94 100644
--- a/main.c
+++ b/main.c
@@ -10,7 +10,6 @@
TODO:
replace weird EXPR_FOR system with just a declaration- would make "for use p := points" easier.
need to fix:
- - eval.c
- copy.c
consider: don't do inference for function calls; get rid of was_expr -- now that we have struct params
EXPR_IDENT should be a string before typing, also struct member accesses
@@ -41,7 +40,9 @@ optional -Wshadow
make sure that floating point literals are exact as possible
have some way of doing Infinity and s/qNaN (you can
have them be in std/math.toc)
-once you have a bunch of test code, try making more Expression members pointers
+once you have a bunch of test code:
+- try making more Expression members pointers
+- branch data: #define if(x) bool join(cond, __LINE__) = x; register_branch(__FILE__, __LINE__, cond); if (join(cond, __LINE__))
error on x ::= {return; 3}
struct param inference
maybe macros are just inline functions
diff --git a/test.toc b/test.toc
index 1ce3f12..33ccd3f 100644
--- a/test.toc
+++ b/test.toc
@@ -1,6 +1,15 @@
#include "std/io.toc";
main ::= fn() {
- for x : 3 = "foo" { a := x; }
-
+ foo : [5][]char;
+ for x := &foo {
+ *x = "hello";
+ }
+ for x := foo {
+ puts(x);
+ }
+ for c := "foobar" {
+ puti(c as int);
+ }
}
+main();