changeset 105:c8984769f2ac

built-ins: Make `for` work
author Lewin Bormann <lbo@spheniscida.de>
date Wed, 28 Aug 2019 12:39:23 +0200
parents b9ea42b9f3f6
children 81aabf072d16
files src/built-ins.c
diffstat 1 files changed, 16 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/built-ins.c	Wed Aug 28 12:37:25 2019 +0200
+++ b/src/built-ins.c	Wed Aug 28 12:39:23 2019 +0200
@@ -132,24 +132,27 @@
     YVEC_INIT(&result, items, yexpr_t);
 
     yvec_t* for_items_l = &for_items->value.list;
-    yeval_state_t emptystate = {.call_stack = YVEC_NEW(NULL, 0, yexpr_t)};
 
-    // nested loop: once items, then exprs
     // counter now points to the first expression.
-    for (size_t i = 0; i < for_items_l->len; i++) {
-        yexpr_t* expr = YVEC_AT(for_items_l, i, yexpr_t);
-        yexpr_t evald = yeval(&emptystate, expr, false);
+    assert(counter == 3);
+
+    // nested loop: first items, then exprs
+    for (size_t item = 0; item < for_items_l->len; item++) {
+        yexpr_t* expr = YVEC_AT(for_items_l, item, yexpr_t);
+        yexpr_t evald = yeval(state, expr, false);
         yvalue_t value = {.typ = YVALUE_EXPR, .value.expr = evald};
 
         // For each item, bind reference and execute body.
         yvalue_set(for_ref->value.ref, &value);
-        yexpr_t expr_result = yeval(&emptystate, expr, false);
+        yexpr_t exprs_result = yeval_list_return_last(state, for_list, counter);
+
         // Make deep copy of result
-        yexpr_t expr_result_cp = yexpr_copy(&expr_result);
+        yexpr_t expr_result_cp = yexpr_copy(&exprs_result);
 
-        if (expr_result.typ != YEXPR_UNDEF) YVEC_PUSH(&result, &expr_result_cp);
+        if (exprs_result.typ != YEXPR_UNDEF)
+            YVEC_PUSH(&result, &expr_result_cp);
 
-        yexpr_destroy(&expr_result);
+        yexpr_destroy(&exprs_result);
         yvalue_destroy(&value);
     }
 
@@ -192,8 +195,8 @@
 #undef _pattern
 }
 
-/// Expects a list expression starting with built-in "+" on the stack. It is not modified.
-/// Returns a number expression or an exception.
+/// Expects a list expression starting with built-in "+" on the stack. It is not
+/// modified. Returns a number expression or an exception.
 yexpr_t ybuiltin_fn_plus(yeval_state_t* state) {
 #define _pattern "(+ numeric-expr numeric-expr [numeric-expr ...])"
     yexpr_t plus;
@@ -226,7 +229,8 @@
  * TODO: write built-ins.
  */
 static const ybuiltin_fn YBUILTIN_FNS[] = {ybuiltin_fn_undef, ybuiltin_fn_for,
-                                           ybuiltin_fn_let, NULL, ybuiltin_fn_plus};
+                                           ybuiltin_fn_let, NULL,
+                                           ybuiltin_fn_plus};
 
 const char* ybuiltin_name(YBUILTIN_TYPE t) {
     assert(t * sizeof(const char*) < sizeof(YBUILTIN_ENUM_STR));