From f8cd57da4383706a89b753252655d5a05a2c990f Mon Sep 17 00:00:00 2001 From: cozis Date: Thu, 11 Aug 2022 16:26:56 +0200 Subject: [PATCH] the interpreter implementation is now hidden behing the src/libnoja/noja.h facade. Also I wrote a disassembler that lets you build noja executables by specifying the bytecode directly in a text format --- Makefile | 1 + build_tests.sh | 13 + src/libnoja/assembler/assembler.c | 389 ++++++++++++++++++++++ src/libnoja/assembler/assembler.h | 7 + src/{ => libnoja}/builtins/README.md | 0 src/{ => libnoja}/builtins/basic.c | 0 src/{ => libnoja}/builtins/basic.h | 0 src/{ => libnoja}/builtins/files.c | 0 src/{ => libnoja}/builtins/files.h | 0 src/{ => libnoja}/builtins/math.c | 0 src/{ => libnoja}/builtins/math.h | 0 src/{ => libnoja}/common/executable.c | 123 +++++++ src/{ => libnoja}/common/executable.h | 3 + src/{ => libnoja}/compiler/AST.h | 0 src/{ => libnoja}/compiler/ASTi.h | 0 src/{ => libnoja}/compiler/compile.c | 0 src/{ => libnoja}/compiler/compile.h | 0 src/{ => libnoja}/compiler/parse.c | 0 src/{ => libnoja}/compiler/parse.h | 0 src/libnoja/noja.c | 264 +++++++++++++++ src/libnoja/noja.h | 7 + src/{ => libnoja}/objects/heap.c | 0 src/{ => libnoja}/objects/o_bool.c | 0 src/{ => libnoja}/objects/o_buffer.c | 0 src/{ => libnoja}/objects/o_closure.c | 0 src/{ => libnoja}/objects/o_dir.c | 0 src/{ => libnoja}/objects/o_file.c | 0 src/{ => libnoja}/objects/o_float.c | 0 src/{ => libnoja}/objects/o_int.c | 0 src/{ => libnoja}/objects/o_list.c | 0 src/{ => libnoja}/objects/o_map.c | 0 src/{ => libnoja}/objects/o_none.c | 0 src/{ => libnoja}/objects/o_string.c | 0 src/{ => libnoja}/objects/objects.c | 0 src/{ => libnoja}/objects/objects.h | 0 src/{ => libnoja}/runtime/o_func.c | 0 src/{ => libnoja}/runtime/o_nfunc.c | 0 src/{ => libnoja}/runtime/o_staticmap.c | 0 src/{ => libnoja}/runtime/runtime.c | 0 src/{ => libnoja}/runtime/runtime.h | 0 src/{ => libnoja}/runtime/runtime_error.c | 0 src/{ => libnoja}/utils/bpalloc.c | 0 src/{ => libnoja}/utils/bpalloc.h | 0 src/{ => libnoja}/utils/bucketlist.c | 0 src/{ => libnoja}/utils/bucketlist.h | 0 src/{ => libnoja}/utils/defs.h | 0 src/{ => libnoja}/utils/error.c | 0 src/{ => libnoja}/utils/error.h | 0 src/{ => libnoja}/utils/hash.c | 0 src/{ => libnoja}/utils/hash.h | 0 src/libnoja/utils/labellist.c | 99 ++++++ src/libnoja/utils/labellist.h | 13 + src/{ => libnoja}/utils/promise.c | 8 +- src/{ => libnoja}/utils/promise.h | 1 + src/{ => libnoja}/utils/source.c | 0 src/{ => libnoja}/utils/source.h | 0 src/{ => libnoja}/utils/stack.c | 0 src/{ => libnoja}/utils/stack.h | 0 src/{ => libnoja}/utils/utf8.c | 0 src/{ => libnoja}/utils/utf8.h | 0 src/main.c | 271 +-------------- tests/assembler_fuzz.c | 0 tests/assembler_fuzz_seeds/0.njasm | 0 tests/assembler_fuzz_seeds/1.njasm | 1 + tests/assembler_fuzz_seeds/2.njasm | 32 ++ tests/assembler_fuzz_seeds/3.njasm | 1 + tests/assembler_fuzz_seeds/4.njasm | 1 + tests/assembler_test.c | 289 ++++++++++++++++ 68 files changed, 1260 insertions(+), 263 deletions(-) create mode 100755 build_tests.sh create mode 100644 src/libnoja/assembler/assembler.c create mode 100644 src/libnoja/assembler/assembler.h rename src/{ => libnoja}/builtins/README.md (100%) rename src/{ => libnoja}/builtins/basic.c (100%) rename src/{ => libnoja}/builtins/basic.h (100%) rename src/{ => libnoja}/builtins/files.c (100%) rename src/{ => libnoja}/builtins/files.h (100%) rename src/{ => libnoja}/builtins/math.c (100%) rename src/{ => libnoja}/builtins/math.h (100%) rename src/{ => libnoja}/common/executable.c (78%) rename src/{ => libnoja}/common/executable.h (94%) rename src/{ => libnoja}/compiler/AST.h (100%) rename src/{ => libnoja}/compiler/ASTi.h (100%) rename src/{ => libnoja}/compiler/compile.c (100%) rename src/{ => libnoja}/compiler/compile.h (100%) rename src/{ => libnoja}/compiler/parse.c (100%) rename src/{ => libnoja}/compiler/parse.h (100%) create mode 100644 src/libnoja/noja.c create mode 100644 src/libnoja/noja.h rename src/{ => libnoja}/objects/heap.c (100%) rename src/{ => libnoja}/objects/o_bool.c (100%) rename src/{ => libnoja}/objects/o_buffer.c (100%) rename src/{ => libnoja}/objects/o_closure.c (100%) rename src/{ => libnoja}/objects/o_dir.c (100%) rename src/{ => libnoja}/objects/o_file.c (100%) rename src/{ => libnoja}/objects/o_float.c (100%) rename src/{ => libnoja}/objects/o_int.c (100%) rename src/{ => libnoja}/objects/o_list.c (100%) rename src/{ => libnoja}/objects/o_map.c (100%) rename src/{ => libnoja}/objects/o_none.c (100%) rename src/{ => libnoja}/objects/o_string.c (100%) rename src/{ => libnoja}/objects/objects.c (100%) rename src/{ => libnoja}/objects/objects.h (100%) rename src/{ => libnoja}/runtime/o_func.c (100%) rename src/{ => libnoja}/runtime/o_nfunc.c (100%) rename src/{ => libnoja}/runtime/o_staticmap.c (100%) rename src/{ => libnoja}/runtime/runtime.c (100%) rename src/{ => libnoja}/runtime/runtime.h (100%) rename src/{ => libnoja}/runtime/runtime_error.c (100%) rename src/{ => libnoja}/utils/bpalloc.c (100%) rename src/{ => libnoja}/utils/bpalloc.h (100%) rename src/{ => libnoja}/utils/bucketlist.c (100%) rename src/{ => libnoja}/utils/bucketlist.h (100%) rename src/{ => libnoja}/utils/defs.h (100%) rename src/{ => libnoja}/utils/error.c (100%) rename src/{ => libnoja}/utils/error.h (100%) rename src/{ => libnoja}/utils/hash.c (100%) rename src/{ => libnoja}/utils/hash.h (100%) create mode 100644 src/libnoja/utils/labellist.c create mode 100644 src/libnoja/utils/labellist.h rename src/{ => libnoja}/utils/promise.c (97%) rename src/{ => libnoja}/utils/promise.h (97%) rename src/{ => libnoja}/utils/source.c (100%) rename src/{ => libnoja}/utils/source.h (100%) rename src/{ => libnoja}/utils/stack.c (100%) rename src/{ => libnoja}/utils/stack.h (100%) rename src/{ => libnoja}/utils/utf8.c (100%) rename src/{ => libnoja}/utils/utf8.h (100%) create mode 100644 tests/assembler_fuzz.c create mode 100644 tests/assembler_fuzz_seeds/0.njasm create mode 100644 tests/assembler_fuzz_seeds/1.njasm create mode 100644 tests/assembler_fuzz_seeds/2.njasm create mode 100644 tests/assembler_fuzz_seeds/3.njasm create mode 100644 tests/assembler_fuzz_seeds/4.njasm create mode 100644 tests/assembler_test.c diff --git a/Makefile b/Makefile index 503cd83..b89dd4b 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,7 @@ $(OBJDIR)/%.o: $(SRCDIR)/%.c @ $(CC) $(CFLAGS) -c $^ -o $@ + # Clean all artifacts and rebuild the whole thing all: clean $(OBJS) build diff --git a/build_tests.sh b/build_tests.sh new file mode 100755 index 0000000..7e83d90 --- /dev/null +++ b/build_tests.sh @@ -0,0 +1,13 @@ +FILES="tests/assembler_test.c \ + src/assembler/assembler.c \ + src/common/executable.c \ + src/utils/error.c \ + src/utils/source.c \ + src/utils/bpalloc.c \ + src/utils/promise.c \ + src/utils/labellist.c \ + src/utils/bucketlist.c" + +gcc $FILES -o build/assembler_test_cov -Wall -Wextra -g --coverage +gcc $FILES -o build/assembler_test -Wall -Wextra -g + diff --git a/src/libnoja/assembler/assembler.c b/src/libnoja/assembler/assembler.c new file mode 100644 index 0000000..f833e86 --- /dev/null +++ b/src/libnoja/assembler/assembler.c @@ -0,0 +1,389 @@ +#include +#include +#include +#include +#include "../utils/error.h" +#include "../utils/source.h" +#include "../utils/labellist.h" +#include "../common/executable.h" + +typedef struct { + const char *str; + size_t len; + size_t cur; +} Context; + +static void skipIdentifier(Context *ctx) +{ + while(ctx->cur < ctx->len && (isalpha(ctx->str[ctx->cur]) || isdigit(ctx->str[ctx->cur]) || ctx->str[ctx->cur] == '_')) + ctx->cur += 1; +} + +static void skipSpaces(Context *ctx) +{ + while(ctx->cur < ctx->len && isspace(ctx->str[ctx->cur])) + ctx->cur += 1; +} + +typedef struct { + size_t offset; + size_t length; +} Slice; + +static bool parseLabelAndOpcode(Context *ctx, bool *no_label, + Slice *label, Slice *opcode, + Error *error) +{ + assert(ctx != NULL && no_label != NULL + && label != NULL && opcode != NULL); + + // NOTE: This function must start at + // the first byte of the label or + // opcode. All whitespace must be + // consumed by the caller. + + // Now we expect either a label and an + // opcode, or just an opcode + // + //