aboutsummaryrefslogtreecommitdiff
path: root/src/builtin.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/builtin.h')
-rw-r--r--src/builtin.h98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/builtin.h b/src/builtin.h
new file mode 100644
index 0000000..144ed4c
--- /dev/null
+++ b/src/builtin.h
@@ -0,0 +1,98 @@
+#include "value.h"
+
+#define PROCEDURES(X) \
+/* X(symbol, name, argc) */ \
+ X(plus, "+", 2) \
+ X(minus, "-", 2) \
+ X(cons, "cons", 2) \
+ X(car, "car", 1) \
+ X(cdr, "cdr", 1) \
+
+// Number of builtin procedures
+#define PLUS_ONE(_symbol, _name, _argc) 1 +
+#define BUILTIN_PROCEDURES PROCEDURES(PLUS_ONE) 0
+
+// Forward decalration of the procedures
+#define DECLARE_PROCEDURE(proc) value_t proc(value_t *args)
+#define FORWARD_DECLARATION(symbol, _name, _argc) \
+ DECLARE_PROCEDURE(symbol);
+
+PROCEDURES(FORWARD_DECLARATION)
+
+// Fill procedure struct for the value_t
+#define PROC_DESCRIPTION(symbol, _name, argc) \
+ {argc, symbol},
+
+struct proc_builtin builtin_proc_descriptions[] = {
+ PROCEDURES(PROC_DESCRIPTION)
+};
+
+// List of ordered names of procedures
+#define PROC_NAME(symbol, name, _argc) \
+ name,
+
+const char *builtin_proc_name_list[] = {
+ PROCEDURES(PROC_NAME)
+};
+
+// ----- Definitions -----
+
+#define ASSERT_TYPE(proc, args, pos, vtype, fail) \
+ if(args[pos]->type != vtype) { \
+ err("Expected arg %d of %s to be %s instead of %s", \
+ pos, #proc, "", ""); \
+ fail; \
+ }
+
+#define PROC_ASSERT_TYPE(pos, vtype, fail) \
+ ASSERT_TYPE(P, args, pos, vtype, fail)
+
+#define P plus
+DECLARE_PROCEDURE(P)
+{
+ PROC_ASSERT_TYPE(0, VALUE_INT, return VALUE_EMPTY);
+ PROC_ASSERT_TYPE(1, VALUE_INT, return VALUE_EMPTY);
+
+ int sum = args[0]->value.num + args[1]->value.num;
+ return value_create(VALUE_INT, &sum);
+}
+#undef P
+
+#define P minus
+DECLARE_PROCEDURE(P)
+{
+ PROC_ASSERT_TYPE(0, VALUE_INT, return VALUE_EMPTY);
+ PROC_ASSERT_TYPE(1, VALUE_INT, return VALUE_EMPTY);
+
+ int difference = args[0]->value.num - args[1]->value.num;
+ return value_create(VALUE_INT, &difference);
+}
+#undef P
+
+#define P cons
+DECLARE_PROCEDURE(P)
+{
+ struct cons cons = {value_copy(args[0]), value_copy(args[1])};
+ return value_create(VALUE_CONS, &cons);
+}
+#undef P
+
+#define P car
+DECLARE_PROCEDURE(P)
+{
+ PROC_ASSERT_TYPE(0, VALUE_CONS, return VALUE_EMPTY);
+
+ value_t left = value_copy(args[0]->value.cons.left);
+ return left;
+}
+#undef P
+
+#define P cdr
+DECLARE_PROCEDURE(P)
+{
+ PROC_ASSERT_TYPE(0, VALUE_CONS, return VALUE_EMPTY);
+
+ value_t right = value_copy(args[0]->value.cons.right);
+ return right;
+}
+#undef P