changeset 61:81b4668981e6

built-ins: Implement basic built-ins. Also fix weird bison breakage with _POSIX_C_SOURCE macro.
author Lewin Bormann <lbo@spheniscida.de>
date Sat, 24 Aug 2019 21:26:44 +0200
parents 2144052c96b4
children b4000861eea5
files CMakeLists.txt gen/y.yy src/CMakeLists.txt src/built-ins.c src/built-ins.h src/expr_test.c
diffstat 6 files changed, 82 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Sat Aug 24 21:25:59 2019 +0200
+++ b/CMakeLists.txt	Sat Aug 24 21:26:44 2019 +0200
@@ -4,7 +4,7 @@
 
 PROJECT(ylisp C)
 
-ADD_COMPILE_OPTIONS(-std=c11 -D_XOPEN_SOURCE=500 -D__ISOC99_SOURCE)
+ADD_COMPILE_OPTIONS(-std=c11 -D_XOPEN_SOURCE=500 -D__ISOC99_SOURCE -D_POSIX_C_SOURCE=200809)
 
 # SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)
 
--- a/gen/y.yy	Sat Aug 24 21:25:59 2019 +0200
+++ b/gen/y.yy	Sat Aug 24 21:26:44 2019 +0200
@@ -2,6 +2,7 @@
 typedef void* yyscan_t;
 
 #include <src/expr.h>
+#include <src/value.h>
 #include <src/base/str.h>
 #include <src/base/vec.h>
 }
--- a/src/CMakeLists.txt	Sat Aug 24 21:25:59 2019 +0200
+++ b/src/CMakeLists.txt	Sat Aug 24 21:26:44 2019 +0200
@@ -9,6 +9,7 @@
 
 ADD_LIBRARY(core STATIC
     atom.c
+    built-ins.c
     expr.c
     func.c
     value.c)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/built-ins.c	Sat Aug 24 21:26:44 2019 +0200
@@ -0,0 +1,32 @@
+#include "built-ins.h"
+
+const char* YBUILTIN_ENUM_STR[] = {
+    "BUILTIN:UNDEF",
+    "BUILTIN:FOR",
+    "BUILTIN:LET",
+    "BUILTIN:DEFN",
+    "BUILTIN:+",
+    "BUILTIN:-",
+    "BUILTIN:*",
+    "BUILTIN:/",
+    "BUILTIN:IF",
+    "BUILTIN:SEQ",
+};
+
+/**
+ * @brief Table of built-in functions, indexed by YBUILTIN_TYPE.
+ *
+ * TODO: write built-ins.
+ */
+const ybuiltin_fn YBUILTIN_FNS[0];
+
+
+const char* ybuiltin_name(YBUILTIN_TYPE t) {
+    assert(t * sizeof(const char*) < sizeof(YBUILTIN_ENUM_STR));
+    return YBUILTIN_ENUM_STR[t];
+}
+
+yexpr_t ybuiltin_run(YBUILTIN_TYPE t, yvec_t* call_stack) {
+    assert(t * sizeof(ybuiltin_fn) < sizeof(YBUILTIN_FNS));
+    return YBUILTIN_FNS[t](call_stack);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/built-ins.h	Sat Aug 24 21:26:44 2019 +0200
@@ -0,0 +1,29 @@
+#ifndef src_built_ins_h
+#define src_built_ins_h
+
+#include <src/expr.h>
+#include <src/types.h>
+
+#include <src/base/vec.h>
+
+/**
+ * @file built-ins.h
+ * @addtogroup language
+ * @{
+ */
+
+/**
+ * @brief Return a string representation of a built-in.
+ */
+const char* ybuiltin_name(YBUILTIN_TYPE t);
+
+/**
+ * @brief Run a built-in function. The caller assumes ownership of the returned value.
+ */
+yexpr_t ybuiltin_run(YBUILTIN_TYPE t, yvec_t* call_stack);
+
+/**
+ * @}
+ */
+
+#endif
--- a/src/expr_test.c	Sat Aug 24 21:25:59 2019 +0200
+++ b/src/expr_test.c	Sat Aug 24 21:26:44 2019 +0200
@@ -27,6 +27,10 @@
 void test_expr_set(void) {
     yexpr_t expr = yexpr_new();
 
+    // Test undef.
+    yexpr_debug(&expr);
+    fputs("\n", stderr);
+
     // Test atoms.
     yexpr_set_atom_name(&expr, "myatom");
     assert(0 == strcmp("myatom", yatom_name(expr.value.atom)));
@@ -37,6 +41,13 @@
     yexpr_destroy(&expr);
     expr = yexpr_new();
 
+    // Test builtins.
+    yexpr_set_builtin(&expr, YBUILTIN_DEFN);
+    assert(YEXPR_BUILTIN == expr.typ);
+    assert(YBUILTIN_DEFN == expr.value.builtin);
+    yexpr_debug(&expr);
+    fputs("\n", stderr);
+
     // Test number.
     yexpr_set_number(&expr, 12345);
     assert(12345 == expr.value.n);
@@ -83,7 +94,10 @@
     expr = yexpr_new();
 
     // Test init_or_extend.
-    yexpr_set_number(&expr, 12345);
+    yexpr_set_builtin(&expr, YBUILTIN_MULT);
+    yexpr_t tmp = yexpr_new();
+    yexpr_set_number(&tmp, 12345);
+    yexpr_init_or_extend(&expr, tmp);
 
     yexpr_t src2[3] = {yexpr_new(), yexpr_new(), yexpr_new()};
     yexpr_set_atom_name(&src2[0], "atom1");
@@ -93,10 +107,10 @@
     yexpr_init_or_extend(&expr, src2[2]);
     // Expr now contains list of exprs: 12345, atom1, atom3.
     yvec_t list = expr.value.list;
-    assert(12345 == YVEC_AT(&list, 0, yexpr_t)->value.n);
-    yatom_t got = YVEC_AT(&list, 1, yexpr_t)->value.atom;
+    assert(12345 == YVEC_AT(&list, 1, yexpr_t)->value.n);
+    yatom_t got = YVEC_AT(&list, 2, yexpr_t)->value.atom;
     assert(yatom_get_or_add("atom1") == got);
-    got = YVEC_AT(&list, 2, yexpr_t)->value.atom;
+    got = YVEC_AT(&list, 3, yexpr_t)->value.atom;
     assert(yatom_get_or_add("atom3") == got);
 
     yexpr_debug(&expr);