diff --git a/README.md b/README.md
index 14a6cbd..664ca54 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# C3 v0.1
C3 is a programming language, inspired by C89, Elixir and Common Lisp.
-It aims to replace C89 with an Elixir syntax.
+It aims to better C89 with an Elixir syntax.
```
defmodule C3 do
diff --git a/libc3/env.c b/libc3/env.c
new file mode 100644
index 0000000..d0affaa
--- /dev/null
+++ b/libc3/env.c
@@ -0,0 +1,32 @@
+/* c3
+ * Copyright 2022 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted
+ * the above copyright notice and this permission paragraph
+ * are included in all copies and substantial portions of this
+ * software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <assert.h>
+#include "env.h"
+#include "error_handler.h"
+#include "frame.h"
+
+s_env * env_init (s_env *env)
+{
+ assert(env);
+ env->frame = NULL;
+ env->error_handler = NULL;
+ return env;
+}
+
+void env_clean (s_env *env)
+{
+ assert(env);
+ frame_delete_all(env->frame);
+ error_handler_delete_all(env->error_handler);
+}
diff --git a/libc3/env.h b/libc3/env.h
index ead8486..6dcc6a2 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -19,4 +19,4 @@
s_env * env_init (s_env *env);
void env_clean (s_env *env);
-#endif /* C3_H */
+#endif /* ENV_H */
diff --git a/libc3/error_handler.h b/libc3/error_handler.h
new file mode 100644
index 0000000..0cf95d1
--- /dev/null
+++ b/libc3/error_handler.h
@@ -0,0 +1,31 @@
+/* c3
+ * Copyright 2022 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted
+ * the above copyright notice and this permission paragraph
+ * are included in all copies and substantial portions of this
+ * software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef ERROR_HANDLER_H
+#define ERROR_HANDLER_H
+
+#include "types.h"
+
+/* stack-allocation compatible functions */
+void error_handler_clean (s_error_handler *error_handler);
+s_error_handler * error_handler_init (s_error_handler *error_handler,
+ s_error_handler *next);
+
+/* constructors */
+s_error_handler * error_handler_new (s_error_handler *next);
+
+/* destructors */
+void error_handler_delete (s_error_handler *error_handler);
+void error_handler_delete_all (s_error_handler *error_handler);
+
+#endif /* ERROR_HANDLER_H */
diff --git a/libc3/eval.h b/libc3/eval.h
new file mode 100644
index 0000000..169ccf0
--- /dev/null
+++ b/libc3/eval.h
@@ -0,0 +1,21 @@
+/* c3
+ * Copyright 2022 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted
+ * the above copyright notice and this permission paragraph
+ * are included in all copies and substantial portions of this
+ * software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef EVAL_H
+#define EVAL_H
+
+#include "types.h"
+
+s_tag * eval_tag (s_env *env, s_tag *tag);
+
+#endif /* EVAL_H */
diff --git a/libc3/facts.c b/libc3/facts.c
index f4f7716..37fe262 100644
--- a/libc3/facts.c
+++ b/libc3/facts.c
@@ -248,6 +248,8 @@ e_bool facts_remove_fact (s_facts *facts, const s_fact *fact)
assert(fact);
found = facts_find_fact(facts, fact);
if (found) {
+ if (facts->log)
+ facts_log_remove(facts->log, found);
skiplist_remove__fact(facts->index_spo, found);
skiplist_remove__fact(facts->index_pos, found);
skiplist_remove__fact(facts->index_osp, found);
diff --git a/libc3/frame.c b/libc3/frame.c
new file mode 100644
index 0000000..903ebbf
--- /dev/null
+++ b/libc3/frame.c
@@ -0,0 +1,56 @@
+/* c3
+ * Copyright 2022 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted
+ * the above copyright notice and this permission paragraph
+ * are included in all copies and substantial portions of this
+ * software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <assert.h>
+#include <err.h>
+#include <stdlib.h>
+#include "frame.h"
+#include "list.h"
+
+void frame_clean (s_frame *frame)
+{
+ assert(frame);
+ list_delete(frame->bindings);
+}
+
+void frame_delete (s_frame *frame)
+{
+ if (frame)
+ frame_clean(frame);
+}
+
+void frame_delete_all (s_frame *frame)
+{
+ s_frame *next;
+ while (frame) {
+ next = frame->next;
+ frame_delete(frame);
+ frame = next;
+ }
+}
+
+s_frame * frame_init (s_frame *frame, s_frame *next)
+{
+ assert(frame);
+ frame->bindings = NULL;
+ frame->next = next;
+ return frame;
+}
+
+s_frame * frame_new (s_frame *next)
+{
+ s_frame *frame;
+ if (! (frame = malloc(sizeof(s_frame))))
+ errx(1, "frame_new: out of memory");
+ return frame_init(frame, next);
+}
diff --git a/libc3/frame.h b/libc3/frame.h
new file mode 100644
index 0000000..882fa0d
--- /dev/null
+++ b/libc3/frame.h
@@ -0,0 +1,30 @@
+/* c3
+ * Copyright 2022 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted
+ * the above copyright notice and this permission paragraph
+ * are included in all copies and substantial portions of this
+ * software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef FRAME_H
+#define FRAME_H
+
+#include "types.h"
+
+/* stack-allocation compatible functions */
+void frame_clean (s_frame *frame);
+s_frame * frame_init (s_frame *frame, s_frame *next);
+
+/* constructors */
+s_frame * frame_new ();
+
+/* destructors */
+void frame_delete (s_frame *frame);
+void frame_delete_all (s_frame *frame);
+
+#endif /* FRAME_H */
diff --git a/libc3/types.h b/libc3/types.h
index 5dd6a90..8175c43 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -14,6 +14,7 @@
#ifndef TYPES_H
#define TYPES_H
+#include <setjmp.h>
#include <stdio.h>
#include "../libtommath/tommath.h"
@@ -307,4 +308,27 @@ typedef struct module {
s_facts *facts;
} s_module;
+/* error_handler */
+typedef struct error_handler s_error_handler;
+
+struct error_handler
+{
+ jmp_buf jmp_buf;
+ s_error_handler *next;
+};
+
+/* frame */
+typedef struct frame s_frame;
+
+struct frame {
+ s_list *bindings;
+ s_frame *next;
+};
+
+/* env */
+typedef struct env {
+ s_frame *frame;
+ s_error_handler *error_handler;
+} s_env;
+
#endif /* TYPES_H */
diff --git a/test/fact_test.c b/test/fact_test.c
index eab833b..0321154 100644
--- a/test/fact_test.c
+++ b/test/fact_test.c
@@ -34,18 +34,6 @@ void fact_test ()
fact_test_inspect();
}
-s_fact * fact_test_1 (s_fact *fact, const s8 *tag)
-{
- return fact_test_3(fact, tag, tag, tag);
-}
-
-s_fact * fact_test_3 (s_fact *fact, const s8 *subject,
- const s8 *predicate, const s8 *object)
-{
- fact_test_clean(fact);
- return fact_test_init_3(fact, subject, predicate, object);
-}
-
s_fact * fact_test_clean (s_fact *fact)
{
assert(fact);
diff --git a/test/fact_test.h b/test/fact_test.h
index 1854962..67e437a 100644
--- a/test/fact_test.h
+++ b/test/fact_test.h
@@ -44,9 +44,6 @@
} \
} while (0)
-s_fact * fact_test_1 (s_fact *fact, const s8 *tag);
-s_fact * fact_test_3 (s_fact *fact, const s8 *subject,
- const s8 *predicate, const s8 *object);
s_fact * fact_test_clean (s_fact *fact);
s_fact * fact_test_init_1 (s_fact *fact, const s8 *tag);
s_fact * fact_test_init_3 (s_fact *fact, const s8 *subject,
diff --git a/test/facts_test.c b/test/facts_test.c
index dacbba7..5d46050 100644
--- a/test/facts_test.c
+++ b/test/facts_test.c
@@ -37,6 +37,7 @@ void facts_test ()
facts_test_find();
facts_test_log_add();
facts_test_log_remove();
+ facts_test_dump();
}
void facts_test_add ()
@@ -296,7 +297,7 @@ void facts_test_log_remove ()
BUF_INIT_ALLOCA(&log, 1024);
fp = fopen("facts_test_log_remove.facts", "w");
buf_file_open_w(&log, fp);
- facts_init(&facts, NULL);
+ facts_init(&facts, &log);
while (p[i]) {
fact_test_init_1(fact + i, p[i]);
facts_add_fact(&facts, fact + i);
@@ -306,6 +307,7 @@ void facts_test_log_remove ()
facts_remove_fact(&facts, fact + i);
}
facts_clean(&facts);
+ buf_file_close(&log);
fclose(fp);
test_file_compare("facts_test_log_remove.facts",
"facts_test_log_remove.facts.expected");
diff --git a/test/facts_test_dump.facts b/test/facts_test_dump.facts
new file mode 100644
index 0000000..bebffb3
--- /dev/null
+++ b/test/facts_test_dump.facts
@@ -0,0 +1,23 @@
+add {a, a, a}
+add {-18446744073709551616, -18446744073709551616, -18446744073709551616}
+add {18446744073709551616, 18446744073709551616, 18446744073709551616}
+add {-4294967296, -4294967296, -4294967296}
+add {-65536, -65536, -65536}
+add {-256, -256, -256}
+add {-10, -10, -10}
+add {-1, -1, -1}
+add {0, 0, 0}
+add {1, 1, 1}
+add {10, 10, 10}
+add {256, 256, 256}
+add {65536, 65536, 65536}
+add {4294967296, 4294967296, 4294967296}
+add {[], [], []}
+add {[[], []], [[], []], [[], []]}
+add {"a", "a", "a"}
+add {A, A, A}
+add {:a, :a, :a}
+add {{a, b}, {a, b}, {a, b}}
+add {{:a, :b}, {:a, :b}, {:a, :b}}
+add {{{a, b}, {c, d}}, {{a, b}, {c, d}}, {{a, b}, {c, d}}}
+add {{{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}}
diff --git a/test/facts_test_dump.facts.expected b/test/facts_test_dump.facts.expected
new file mode 100644
index 0000000..bebffb3
--- /dev/null
+++ b/test/facts_test_dump.facts.expected
@@ -0,0 +1,23 @@
+add {a, a, a}
+add {-18446744073709551616, -18446744073709551616, -18446744073709551616}
+add {18446744073709551616, 18446744073709551616, 18446744073709551616}
+add {-4294967296, -4294967296, -4294967296}
+add {-65536, -65536, -65536}
+add {-256, -256, -256}
+add {-10, -10, -10}
+add {-1, -1, -1}
+add {0, 0, 0}
+add {1, 1, 1}
+add {10, 10, 10}
+add {256, 256, 256}
+add {65536, 65536, 65536}
+add {4294967296, 4294967296, 4294967296}
+add {[], [], []}
+add {[[], []], [[], []], [[], []]}
+add {"a", "a", "a"}
+add {A, A, A}
+add {:a, :a, :a}
+add {{a, b}, {a, b}, {a, b}}
+add {{:a, :b}, {:a, :b}, {:a, :b}}
+add {{{a, b}, {c, d}}, {{a, b}, {c, d}}, {{a, b}, {c, d}}}
+add {{{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}}
diff --git a/test/facts_test_log_add.facts b/test/facts_test_log_add.facts
new file mode 100644
index 0000000..5286f7a
--- /dev/null
+++ b/test/facts_test_log_add.facts
@@ -0,0 +1,23 @@
+add {"a", "a", "a"}
+add {:a, :a, :a}
+add {A, A, A}
+add {a, a, a}
+add {[], [], []}
+add {[[], []], [[], []], [[], []]}
+add {{:a, :b}, {:a, :b}, {:a, :b}}
+add {{{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}}
+add {{a, b}, {a, b}, {a, b}}
+add {{{a, b}, {c, d}}, {{a, b}, {c, d}}, {{a, b}, {c, d}}}
+add {0, 0, 0}
+add {1, 1, 1}
+add {10, 10, 10}
+add {256, 256, 256}
+add {65536, 65536, 65536}
+add {4294967296, 4294967296, 4294967296}
+add {18446744073709551616, 18446744073709551616, 18446744073709551616}
+add {-1, -1, -1}
+add {-10, -10, -10}
+add {-256, -256, -256}
+add {-65536, -65536, -65536}
+add {-4294967296, -4294967296, -4294967296}
+add {-18446744073709551616, -18446744073709551616, -18446744073709551616}
diff --git a/test/facts_test_log_add.facts.expected b/test/facts_test_log_add.facts.expected
index e69de29..5286f7a 100644
--- a/test/facts_test_log_add.facts.expected
+++ b/test/facts_test_log_add.facts.expected
@@ -0,0 +1,23 @@
+add {"a", "a", "a"}
+add {:a, :a, :a}
+add {A, A, A}
+add {a, a, a}
+add {[], [], []}
+add {[[], []], [[], []], [[], []]}
+add {{:a, :b}, {:a, :b}, {:a, :b}}
+add {{{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}}
+add {{a, b}, {a, b}, {a, b}}
+add {{{a, b}, {c, d}}, {{a, b}, {c, d}}, {{a, b}, {c, d}}}
+add {0, 0, 0}
+add {1, 1, 1}
+add {10, 10, 10}
+add {256, 256, 256}
+add {65536, 65536, 65536}
+add {4294967296, 4294967296, 4294967296}
+add {18446744073709551616, 18446744073709551616, 18446744073709551616}
+add {-1, -1, -1}
+add {-10, -10, -10}
+add {-256, -256, -256}
+add {-65536, -65536, -65536}
+add {-4294967296, -4294967296, -4294967296}
+add {-18446744073709551616, -18446744073709551616, -18446744073709551616}
diff --git a/test/facts_test_log_remove.facts b/test/facts_test_log_remove.facts
new file mode 100644
index 0000000..f96c838
--- /dev/null
+++ b/test/facts_test_log_remove.facts
@@ -0,0 +1,46 @@
+add {"a", "a", "a"}
+add {:a, :a, :a}
+add {A, A, A}
+add {a, a, a}
+add {[], [], []}
+add {[[], []], [[], []], [[], []]}
+add {{:a, :b}, {:a, :b}, {:a, :b}}
+add {{{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}}
+add {{a, b}, {a, b}, {a, b}}
+add {{{a, b}, {c, d}}, {{a, b}, {c, d}}, {{a, b}, {c, d}}}
+add {0, 0, 0}
+add {1, 1, 1}
+add {10, 10, 10}
+add {256, 256, 256}
+add {65536, 65536, 65536}
+add {4294967296, 4294967296, 4294967296}
+add {18446744073709551616, 18446744073709551616, 18446744073709551616}
+add {-1, -1, -1}
+add {-10, -10, -10}
+add {-256, -256, -256}
+add {-65536, -65536, -65536}
+add {-4294967296, -4294967296, -4294967296}
+add {-18446744073709551616, -18446744073709551616, -18446744073709551616}
+remove {-18446744073709551616, -18446744073709551616, -18446744073709551616}
+remove {-4294967296, -4294967296, -4294967296}
+remove {-65536, -65536, -65536}
+remove {-256, -256, -256}
+remove {-10, -10, -10}
+remove {-1, -1, -1}
+remove {18446744073709551616, 18446744073709551616, 18446744073709551616}
+remove {4294967296, 4294967296, 4294967296}
+remove {65536, 65536, 65536}
+remove {256, 256, 256}
+remove {10, 10, 10}
+remove {1, 1, 1}
+remove {0, 0, 0}
+remove {{{a, b}, {c, d}}, {{a, b}, {c, d}}, {{a, b}, {c, d}}}
+remove {{a, b}, {a, b}, {a, b}}
+remove {{{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}}
+remove {{:a, :b}, {:a, :b}, {:a, :b}}
+remove {[[], []], [[], []], [[], []]}
+remove {[], [], []}
+remove {a, a, a}
+remove {A, A, A}
+remove {:a, :a, :a}
+remove {"a", "a", "a"}
diff --git a/test/facts_test_log_remove.facts.expected b/test/facts_test_log_remove.facts.expected
new file mode 100644
index 0000000..f96c838
--- /dev/null
+++ b/test/facts_test_log_remove.facts.expected
@@ -0,0 +1,46 @@
+add {"a", "a", "a"}
+add {:a, :a, :a}
+add {A, A, A}
+add {a, a, a}
+add {[], [], []}
+add {[[], []], [[], []], [[], []]}
+add {{:a, :b}, {:a, :b}, {:a, :b}}
+add {{{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}}
+add {{a, b}, {a, b}, {a, b}}
+add {{{a, b}, {c, d}}, {{a, b}, {c, d}}, {{a, b}, {c, d}}}
+add {0, 0, 0}
+add {1, 1, 1}
+add {10, 10, 10}
+add {256, 256, 256}
+add {65536, 65536, 65536}
+add {4294967296, 4294967296, 4294967296}
+add {18446744073709551616, 18446744073709551616, 18446744073709551616}
+add {-1, -1, -1}
+add {-10, -10, -10}
+add {-256, -256, -256}
+add {-65536, -65536, -65536}
+add {-4294967296, -4294967296, -4294967296}
+add {-18446744073709551616, -18446744073709551616, -18446744073709551616}
+remove {-18446744073709551616, -18446744073709551616, -18446744073709551616}
+remove {-4294967296, -4294967296, -4294967296}
+remove {-65536, -65536, -65536}
+remove {-256, -256, -256}
+remove {-10, -10, -10}
+remove {-1, -1, -1}
+remove {18446744073709551616, 18446744073709551616, 18446744073709551616}
+remove {4294967296, 4294967296, 4294967296}
+remove {65536, 65536, 65536}
+remove {256, 256, 256}
+remove {10, 10, 10}
+remove {1, 1, 1}
+remove {0, 0, 0}
+remove {{{a, b}, {c, d}}, {{a, b}, {c, d}}, {{a, b}, {c, d}}}
+remove {{a, b}, {a, b}, {a, b}}
+remove {{{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}, {{:a, :b}, {:c, :d}}}
+remove {{:a, :b}, {:a, :b}, {:a, :b}}
+remove {[[], []], [[], []], [[], []]}
+remove {[], [], []}
+remove {a, a, a}
+remove {A, A, A}
+remove {:a, :a, :a}
+remove {"a", "a", "a"}
diff --git a/test/test.c b/test/test.c
index 102201b..97a015b 100644
--- a/test/test.c
+++ b/test/test.c
@@ -33,7 +33,6 @@ const char **g_test_targets = {NULL};
void test_context (const char *context)
{
g_test_context = context;
- /* printf("test_context(%s)\n", context); */
}
int test_file_compare (const char *path_a, const char *path_b)
@@ -42,7 +41,7 @@ int test_file_compare (const char *path_a, const char *path_b)
FILE *fp_b = fopen(path_b, "rb");
char buf_a[1024];
char buf_b[1024];
- sw r;
+ int r;
if (fp_a == fp_b)
return 0;
if (fp_a == NULL)
@@ -52,15 +51,20 @@ int test_file_compare (const char *path_a, const char *path_b)
/* TODO: use fread and check how many bytes are read */
while (fgets(buf_a, 1024, fp_a) != NULL) {
if (fgets(buf_b, 1024, fp_b) == NULL) {
+ test_ko();
return 1;
}
/* TODO: use memcmp for NUL bytes */
- if ((r = strcmp(buf_a, buf_b)))
+ if ((r = strcmp(buf_a, buf_b))) {
+ test_ko();
return r;
+ }
}
if (fgets(buf_b, 1024, fp_b) != NULL) {
+ test_ko();
return -1;
}
+ test_ok();
return 0;
}