aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bamboo.c22
-rw-r--r--src/bamboo.h32
-rw-r--r--src/main.c3
-rw-r--r--src/parser.c38
-rw-r--r--src/parser.h35
-rw-r--r--src/sexp.c8
-rw-r--r--src/sexp.h80
7 files changed, 218 insertions, 0 deletions
diff --git a/src/bamboo.c b/src/bamboo.c
new file mode 100644
index 0000000..70a84f5
--- /dev/null
+++ b/src/bamboo.c
@@ -0,0 +1,22 @@
+#include "bamboo.h"
+
+SExpRef new_list1(Bamboo *ctx, SExpRef e1) {
+ return cons(ctx, e1, nil(ctx));
+}
+
+SExpRef new_list2(Bamboo *ctx, SExpRef e1, SExpRef e2) {
+ return cons(ctx, e1, new_list1(ctx, e2));
+}
+
+SExpRef new_list3(Bamboo *ctx, SExpRef e1, SExpRef e2, SExpRef e3) {
+ return cons(ctx, e1, new_list2(ctx, e2, e3));
+}
+
+SExpRef new_list4(Bamboo *ctx, SExpRef e1, SExpRef e2, SExpRef e3, SExpRef e4) {
+ return cons(ctx, e1, new_list3(ctx, e2, e3, e4));
+}
+
+SExpRef new_list5(Bamboo *ctx, SExpRef e1, SExpRef e2, SExpRef e3, SExpRef e4, SExpRef e5) {
+ return cons(ctx, e1, new_list4(ctx, e2, e3, e4, e5));
+}
+
diff --git a/src/bamboo.h b/src/bamboo.h
new file mode 100644
index 0000000..a424be6
--- /dev/null
+++ b/src/bamboo.h
@@ -0,0 +1,32 @@
+#ifndef BAMBOO_LISP_BAMBOO_H_
+#define BAMBOO_LISP_BAMBOO_H_
+
+#include <algds/hash_table.h>
+
+#include "sexp.h"
+
+typedef struct {
+ SExpVector objs;
+ String2IntHashTable symbols;
+} Bamboo;
+
+void Bamboo_init(Bamboo *self);
+SExp* Bamboo_ref(Bamboo *self, SExpRef ref);
+// TODO: Heap_gc()
+
+SExpRef new_integer(Bamboo *ctx, int64_t val);
+SExpRef new_real(Bamboo *ctx, double val);
+SExpRef new_string(Bamboo *ctx, const char *val);
+SExpRef new_symbol(Bamboo *ctx, const char *val);
+SExpRef cons(Bamboo *ctx, SExpRef car, SExpRef cdr);
+SExpRef nil(Bamboo *ctx);
+SExpRef new_list1(Bamboo *ctx, SExpRef e1);
+SExpRef new_list2(Bamboo *ctx, SExpRef e1, SExpRef e2);
+SExpRef new_list3(Bamboo *ctx, SExpRef e1, SExpRef e2, SExpRef e3);
+SExpRef new_list4(Bamboo *ctx, SExpRef e1, SExpRef e2, SExpRef e3, SExpRef e4);
+SExpRef new_list5(Bamboo *ctx, SExpRef e1, SExpRef e2, SExpRef e3, SExpRef e4, SExpRef e5);
+SExpRef new_list6(Bamboo *ctx, SExpRef e1, SExpRef e2, SExpRef e3, SExpRef e4, SExpRef e5, SExpRef e6);
+SExpRef new_list7(Bamboo *ctx, SExpRef e1, SExpRef e2, SExpRef e3, SExpRef e4, SExpRef e5, SExpRef e6, SExpRef e7);
+
+#endif
+
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..33c14ce
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,3 @@
+int main() {
+ return 0;
+}
diff --git a/src/parser.c b/src/parser.c
new file mode 100644
index 0000000..d164186
--- /dev/null
+++ b/src/parser.c
@@ -0,0 +1,38 @@
+#include "parser.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+
+static void skip_spaces(Parser *ctx) {
+ while (isspace(parser_peek(ctx))) {
+ parser_getchar(ctx);
+ }
+}
+
+ParseResult ParseOk(SExpRef ref) {
+ return (ParseResult){ .val = ref, .errmsg = NULL };
+}
+
+ParseResult ParseErr(const char *msg) {
+ return (ParseResult){ .val = {-1}, .errmsg = msg };
+}
+
+ParseResult parse_sexp(Parser *ctx) {
+ skip_spaces(ctx);
+ int next = parser_peek(ctx);
+ if (next == '(') {
+ return parse_list(ctx);
+ } else if (next == ',') {
+ parser_getchar(ctx);
+ if (parser_peek(ctx) == '@') {
+ return parse_slicing_unquote(ctx);
+ }
+ return parse_unquote(ctx);
+ } else if (next == '`') {
+ return parse_quasi(ctx);
+ } else if (next == '\'') {
+ return parse_quote(ctx);
+ }
+ return parse_atom(ctx);
+}
+
diff --git a/src/parser.h b/src/parser.h
new file mode 100644
index 0000000..3f159b8
--- /dev/null
+++ b/src/parser.h
@@ -0,0 +1,35 @@
+#ifndef BAMBOO_LISP_PARSER_H_
+#define BAMBOO_LISP_PARSER_H_
+
+#include <stdbool.h>
+
+#include "sexp.h"
+
+typedef struct {
+
+} Parser;
+
+typedef struct {
+ SExpRef val;
+ const char *errmsg;
+} ParseResult;
+
+int parser_getchar(Parser *ctx);
+int parser_peek(Parser *ctx);
+
+ParseResult parse_sexp(Parser *ctx);
+ParseResult parse_list(Parser *ctx);
+ParseResult parse_quote(Parser *ctx);
+ParseResult parse_unquote(Parser *ctx);
+ParseResult parse_slicing_unquote(Parser *ctx);
+ParseResult parse_quasi(Parser *ctx);
+ParseResult parse_atom(Parser *ctx);
+ParseResult parse_number(Parser *ctx);
+ParseResult parse_integer(Parser *ctx);
+ParseResult parse_real(Parser *ctx);
+ParseResult parse_symbol(Parser *ctx);
+ParseResult parse_string(Parser *ctx);
+ParseResult parse_char(Parser *ctx);
+
+#endif
+
diff --git a/src/sexp.c b/src/sexp.c
new file mode 100644
index 0000000..b268414
--- /dev/null
+++ b/src/sexp.c
@@ -0,0 +1,8 @@
+#include "sexp.h"
+#include "algds/vec.h"
+
+void SExp_show(SExp self, FILE* fp) {
+ fprintf(fp, "{SEXP}");
+}
+
+VECTOR_IMPL(SExp);
diff --git a/src/sexp.h b/src/sexp.h
new file mode 100644
index 0000000..dfbc4d9
--- /dev/null
+++ b/src/sexp.h
@@ -0,0 +1,80 @@
+#ifndef BAMBOO_LISP_SEXP_H_
+#define BAMBOO_LISP_SEXP_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <algds/vec.h>
+
+struct sexp;
+typedef struct sexp SExp;
+
+typedef struct {
+ int idx;
+} SExpRef;
+
+typedef struct {
+ SExpRef car;
+ SExpRef cdr;
+} SExpPair;
+
+typedef struct {
+ SExpRef args;
+ SExpRef body;
+} SExpFunc;
+
+typedef struct {
+ SExpRef args;
+ SExpRef body;
+} SExpMacro;
+
+typedef struct {
+ SExpRef parent;
+ SExpRef child;
+ SExpRef bindings;
+} SExpEnv;
+
+typedef struct {
+ SExpRef name;
+ SExpRef value;
+ SExpRef func;
+ SExpRef next;
+} SExpBinding;
+
+typedef enum {
+ kIntegerSExp,
+ kRealSExp,
+ kBooleanSExp,
+ kNumberSExp,
+ kCharSExp,
+ kStringSExp,
+ kSymbolSExp,
+ kUserDataSExp,
+ kPairSExp,
+ kFuncSExp,
+ kEnvSExp,
+ kBindingSExp,
+ kMacroSExp,
+} SExpType;
+
+struct sexp {
+ SExpType type;
+ union {
+ int64_t integer;
+ double real;
+ bool boolean;
+ char character;
+ const char *str;
+ const void *userdata;
+ SExpPair pair;
+ SExpFunc func;
+ SExpEnv env;
+ };
+};
+
+void SExp_show(SExp self, FILE* fp);
+
+VECTOR_DEF(SExp);
+
+#endif
+