diff options
-rw-r--r-- | Makefile | 25 | ||||
-rw-r--r-- | src/bin/fspec-info.c | 10 | ||||
-rw-r--r-- | src/compiler/native.c | 151 |
3 files changed, 174 insertions, 12 deletions
@@ -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; +} |