summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile25
-rw-r--r--src/bin/fspec-info.c10
-rw-r--r--src/compiler/native.c151
3 files changed, 174 insertions, 12 deletions
diff --git a/Makefile b/Makefile
index fb38610..a63ae06 100644
--- a/Makefile
+++ b/Makefile
@@ -10,10 +10,14 @@ WARNINGS := -Wall -Wextra -Wpedantic -Wformat=2 -Wstrict-aliasing=3 -Wstrict-ove
override CFLAGS ?= -g
override CFLAGS += -std=c11 $(WARNINGS)
override CPPFLAGS += -Isrc
+override COLMFLAGS += -Isrc/compiler
-bins = fspec-dump dec2bin xidec xi2path xils xifile uneaf
+bins = fspec-info dec2bin xidec xi2path xils xifile uneaf
all: $(bins)
+%.c: %.lm
+ colm $(COLMFLAGS) -c $^
+
%.c: %.rl
ragel $^
@@ -23,20 +27,17 @@ all: $(bins)
$(bins): %:
$(LINK.c) $(filter %.c %.a,$^) $(LDLIBS) -o $@
-fspec-membuf.a: src/util/membuf.h src/util/membuf.c
-fspec-ragel.a: src/util/ragel/ragel.h src/util/ragel/ragel.c
-fspec-lexer-stack.a: src/fspec/ragel/lexer-stack.h src/fspec/ragel/lexer-stack.c
-fspec-lexer-expr.a: src/fspec/ragel/lexer-expr.h src/fspec/ragel/lexer-expr.c
-fspec-bcode.a: src/fspec/memory.h src/fspec/private/bcode-types.h src/fspec/bcode.h src/fspec/bcode.c fspec-ragel.a
-fspec-lexer.a: src/fspec/lexer.h src/fspec/ragel/lexer.c fspec-lexer-stack.a fspec-lexer-expr.a fspec-bcode.a
-fspec-validator.a: src/fspec/validator.h src/fspec/ragel/validator.c fspec-ragel.a
+fspec-compiler-native.a: private CFLAGS = -Wno-unusued-parameter
+fspec-compiler-native.a: src/compiler/native.c
+fspec-compiler.a: private CFLAGS = -std=c11
+fspec-compiler.a: src/compiler/compiler.c fspec-compiler-native.a
-fspec-dump: private CPPFLAGS += $(shell pkg-config --cflags-only-I squash-0.8)
-fspec-dump: private LDLIBS += $(shell pkg-config --libs-only-l squash-0.8)
-fspec-dump: src/bin/fspec/dump.c fspec-ragel.a fspec-membuf.a fspec-bcode.a fspec-lexer-stack.a fspec-lexer-expr.a fspec-lexer.a fspec-validator.a
+fspec-info: private LDLIBS += -lcolm
+fspec-info: src/bin/fspec-info.c fspec-compiler.a fspec-compiler-native.a
dec2bin: src/bin/misc/dec2bin.c
+xidec: private CFLAGS += -Wno-strict-overflow
xidec: src/bin/xi/xidec.c
xi2path: src/bin/xi/xi2path.c
xils: src/bin/xi/xils.c
@@ -51,7 +52,7 @@ install-bin: $(bins)
install: install-bin
clean:
- $(RM) src/util/ragel/*.c src/fspec/ragel/*.c
+ $(RM) src/compiler/compiler.c
$(RM) $(bins) *.a
.PHONY: all clean install
diff --git a/src/bin/fspec-info.c b/src/bin/fspec-info.c
new file mode 100644
index 0000000..c65fb6a
--- /dev/null
+++ b/src/bin/fspec-info.c
@@ -0,0 +1,10 @@
+#include <colm/colm.h>
+
+int
+main(int argc, const char **argv)
+{
+ struct colm_program *prg = colm_new_program(&colm_object);
+ colm_set_debug(prg, 0);
+ colm_run_program(prg, argc, argv);
+ return colm_delete_program(prg);
+}
diff --git a/src/compiler/native.c b/src/compiler/native.c
new file mode 100644
index 0000000..c24ba3a
--- /dev/null
+++ b/src/compiler/native.c
@@ -0,0 +1,151 @@
+#include <colm/tree.h>
+#include <colm/bytecode.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+
+static inline void*
+ptr_from_value(value_t ptr)
+{
+ return (void*)(intptr_t)ptr;
+}
+
+static inline value_t
+value_from_ptr(void *ptr)
+{
+ return (value_t)(intptr_t*)ptr;
+}
+
+static inline tree_t*
+upref(program_t *prg, tree_t *tree)
+{
+ colm_tree_upref(prg, tree);
+ return tree;
+}
+
+struct op_stack {
+ uint16_t data[1024], index;
+};
+
+value_t
+c_op_stack_new(program_t *prg, tree_t **sp)
+{
+ assert(sizeof(intptr_t) <= sizeof(value_t));
+ return value_from_ptr(calloc(1, sizeof(struct op_stack)));
+}
+
+void
+c_op_stack_free(program_t *prg, tree_t **sp, value_t a)
+{
+ struct op_stack *stack = ptr_from_value(a);
+ free(stack);
+}
+
+str_t*
+c_op_stack_top(program_t *prg, tree_t **sp, value_t a)
+{
+ struct op_stack *stack = ptr_from_value(a);
+ union { uint16_t v; char op[2]; } convert;
+ assert(sizeof(convert) == sizeof(convert.v));
+
+ if (!stack->index)
+ return NULL;
+
+ convert.v = stack->data[stack->index - 1];
+ tree_t *s = construct_string(prg, string_alloc_full(prg, convert.op, 1 + (convert.op[1] != 0)));
+ return (str_t*)upref(prg, s);
+}
+
+value_t
+c_op_stack_push(program_t *prg, tree_t **sp, value_t a, str_t *b)
+{
+ union { uint16_t v; char op[2]; } convert = {0};
+ assert(sizeof(convert) == sizeof(convert.v));
+ assert((value_t)b->value->length <= sizeof(convert.op));
+ memcpy(convert.op, b->value->data, b->value->length);
+ colm_tree_downref(prg, sp, (tree_t*)b);
+
+ struct op_stack *stack = ptr_from_value(a);
+ if (stack->index >= sizeof(stack->data) / sizeof(stack->data[0]))
+ return 0;
+
+ stack->data[stack->index++] = convert.v;
+ return 1;
+}
+
+str_t*
+c_op_stack_pop(program_t *prg, tree_t **sp, value_t a)
+{
+ struct op_stack *stack = ptr_from_value(a);
+ str_t *r = c_op_stack_top(prg, sp, a);
+ --stack->index;
+ return r;
+}
+
+value_t
+c_strtoull(program_t *prg, tree_t **sp, str_t *a, value_t b)
+{
+ char buf[24] = {0};
+ if ((value_t)a->value->length >= sizeof(buf))
+ return -1;
+
+ memcpy(buf, a->value->data, a->value->length);
+ colm_tree_downref(prg, sp, (tree_t*)a);
+ return strtoull(buf, NULL, b);
+}
+
+value_t
+c_modulo(program_t *prg, tree_t **sp, value_t a, value_t b)
+{
+ assert(b != 0);
+ return (long)a % (long)b;
+}
+
+value_t
+c_bitnot(program_t *prg, tree_t **sp, value_t a)
+{
+ return ~a;
+}
+
+value_t
+c_bitand(program_t *prg, tree_t **sp, value_t a, value_t b)
+{
+ return a & b;
+}
+
+value_t
+c_bitor(program_t *prg, tree_t **sp, value_t a, value_t b)
+{
+ return a | b;
+}
+
+value_t
+c_bitxor(program_t *prg, tree_t **sp, value_t a, value_t b)
+{
+ return a ^ b;
+}
+
+value_t
+c_shiftr(program_t *prg, tree_t **sp, value_t a, value_t b)
+{
+ assert(b < sizeof(a) * CHAR_BIT);
+ return a >> b;
+}
+
+value_t
+c_shiftl(program_t *prg, tree_t **sp, value_t a, value_t b)
+{
+ assert(b < sizeof(a) * CHAR_BIT);
+ return a << b;
+}
+
+value_t
+c_subscript(program_t *prg, tree_t **sp, str_t *a, value_t b)
+{
+ assert((value_t)a->value->length > b);
+ const value_t v = a->value->data[b];
+ colm_tree_downref(prg, sp, (tree_t*)a);
+ return v;
+}