changeset 176:4a70971df28b

built-ins: groundwork for mkclsr built-in
author Lewin Bormann <lbo@spheniscida.de>
date Thu, 12 Sep 2019 08:24:05 +0200
parents 07ff95760f4a
children e55251d97380
files src/built-ins.c
diffstat 1 files changed, 45 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/built-ins.c	Wed Sep 11 21:37:43 2019 +0200
+++ b/src/built-ins.c	Thu Sep 12 08:24:05 2019 +0200
@@ -25,22 +25,32 @@
 };
 
 static const struct ybuiltin_id_mapping YBUILTIN_ID_MAPPING[] = {
-    {"undef", YBUILTIN_UNDEF},     {"for", YBUILTIN_FOR},
-    {"let", YBUILTIN_LET},         {"defn", YBUILTIN_DEFN},
-    {"+", YBUILTIN_PLUS},          {"-", YBUILTIN_MINUS},
-    {"*", YBUILTIN_MULT},          {"/", YBUILTIN_DIV},
-    {"if", YBUILTIN_IF},           {"print", YBUILTIN_PRINT},
-    {"==", YBUILTIN_EQ},           {"<", YBUILTIN_LT},
-    {"car", YBUILTIN_CAR},         {"cdr", YBUILTIN_CDR},
-    {"push", YBUILTIN_PUSH},       {"raise", YBUILTIN_RAISE},
+    {"undef", YBUILTIN_UNDEF},
+    {"for", YBUILTIN_FOR},
+    {"let", YBUILTIN_LET},
+    {"defn", YBUILTIN_DEFN},
+    {"+", YBUILTIN_PLUS},
+    {"-", YBUILTIN_MINUS},
+    {"*", YBUILTIN_MULT},
+    {"/", YBUILTIN_DIV},
+    {"if", YBUILTIN_IF},
+    {"print", YBUILTIN_PRINT},
+    {"==", YBUILTIN_EQ},
+    {"<", YBUILTIN_LT},
+    {"car", YBUILTIN_CAR},
+    {"cdr", YBUILTIN_CDR},
+    {"push", YBUILTIN_PUSH},
+    {"raise", YBUILTIN_RAISE},
     {"recover", YBUILTIN_RECOVER},
+
+    {"_mkclsr", YBUILTIN_INTERNAL_MKCLSR},
 };
 
 static const char* YBUILTIN_ENUM_STR[] = {
     "BUILTIN:UNDEF", "BUILTIN:FOR",   "BUILTIN:LET",  "BUILTIN:DEFN",
     "BUILTIN:+",     "BUILTIN:-",     "BUILTIN:*",    "BUILTIN:/",
     "BUILTIN:IF",    "BUILTIN:PRINT", "BUILTIN:EQ",   "BUILTIN:LT",
-    "BUILTIN:CAR",   "BUILTIN:CDR",   "BUILTIN:PUSH",
+    "BUILTIN:CAR",   "BUILTIN:CDR",   "BUILTIN:PUSH", "BUILTIN:RAISE", "BUILTIN:RECOVER", "BUILTIN:_MKCLSR",
 };
 
 /// Ownership of msg is transferred to this function, ownership of offending is
@@ -303,7 +313,7 @@
 yexpr_t ybuiltin_fn_if(yeval_state_t* state) {
 #define _pattern \
     "(if condition then-expr/(then-exprs) [else-expr/(else-exprs)])"
-    yexpr_t if_expr = yexpr_new();
+    yexpr_t if_expr;
 
     if (!yvec_pop(&state->call_stack, &if_expr)) NOTENOUGHFAIL(IF);
     if (if_expr.typ != YEXPR_LIST) BADEXPRFAIL(IF, if_expr);
@@ -370,7 +380,7 @@
 
 yexpr_t ybuiltin_fn_eq(yeval_state_t* state) {
 #define _pattern "(== expr expr [expr...])"
-    yexpr_t eq = yexpr_new();
+    yexpr_t eq;
 
     if (!yvec_pop(&state->call_stack, &eq)) NOTENOUGHFAIL(EQ);
     if (eq.typ != YEXPR_LIST) BADEXPRFAIL(EQ, eq);
@@ -393,6 +403,30 @@
 #undef _pattern
 }
 
+yexpr_t ybuiltin_fn_mkclsr(yeval_state_t* state) {
+#define _pattern "(_mkclsr function-ref)" // Returns a yexpr_t of type YEXPR_FUNC, with captured values.
+    yexpr_t mkclsr;
+    yexpr_t closure = yexpr_new();
+
+    if (!yvec_pop(&state->call_stack, &mkclsr)) NOTENOUGHFAIL(INTERNAL_MKCLSR);
+    if (mkclsr.typ != YEXPR_LIST) BADEXPRFAIL(INTERNAL_MKCLSR, mkclsr);
+    if (mkclsr.value.list.len != 2) BADEXPRFAIL(INTERNAL_MKCLSR, mkclsr);
+
+    yexpr_t *head = YVEC_AT(&mkclsr.value.list, 0, yexpr_t), *tail = YVEC_AT(&mkclsr.value.list, 1, yexpr_t);
+    if (head->typ != YEXPR_BUILTIN || head->value.builtin != YBUILTIN_INTERNAL_MKCLSR) BADEXPRFAIL(INTERNAL_MKCLSR, mkclsr);
+    if (tail->typ != YEXPR_REF) BADEXPRFAIL(INTERNAL_MKCLSR, mkclsr);
+
+    yvalue_t *funcval = yvalue_get(tail->value.ref);
+    if (funcval->typ != YVALUE_FUNC) TYPEFAIL(INTERNAL_MKCLSR, mkclsr, _pattern);
+    yfunc_t *func = &funcval->value.func;
+    // Vector of yref_t.
+    yvec_t *to_capture = &func->captured;
+
+    does-not-compile
+    // TODO: continue implementation
+#undef _pattern
+}
+
 /**
  * @brief Table of built-in functions, indexed by YBUILTIN_TYPE.
  *