From 18e936f0ad53fd863d6fda5478732bf2f4401486 Mon Sep 17 00:00:00 2001 From: cozis Date: Fri, 12 Aug 2022 05:30:41 +0200 Subject: [PATCH] cleanups and more test cases --- .gitignore | 12 +- coverage.sh | 8 - examples/bubble_sort.njbc | 9 +- makefile | 43 +- report_test_suite_coverage.sh | 4 + src/cli/main.c | 2 +- src/{noja => lib}/README.md | 0 src/lib/assembler/assemble.c | 393 ++++++++++++++++++ src/lib/assembler/assemble.h | 7 + src/{noja => lib}/builtins/README.md | 0 src/{noja => lib}/builtins/basic.c | 0 src/{noja => lib}/builtins/basic.h | 0 src/{noja => lib}/builtins/files.c | 0 src/{noja => lib}/builtins/files.h | 0 src/{noja => lib}/builtins/math.c | 0 src/{noja => lib}/builtins/math.h | 0 src/{noja => lib}/common/executable.c | 2 +- src/{noja => lib}/common/executable.h | 0 src/{noja => lib}/compiler/AST.h | 0 src/{noja => lib}/compiler/ASTi.h | 0 src/{noja => lib}/compiler/compile.c | 0 src/{noja => lib}/compiler/compile.h | 0 src/{noja => lib}/compiler/parse.c | 0 src/{noja => lib}/compiler/parse.h | 0 src/{noja => lib}/noja.c | 0 src/{noja => lib}/noja.h | 0 src/{noja => lib}/noja_internals.c | 0 src/{noja => lib}/noja_internals.h | 0 src/{noja => lib}/objects/heap.c | 0 src/{noja => lib}/objects/o_bool.c | 0 src/{noja => lib}/objects/o_buffer.c | 0 src/{noja => lib}/objects/o_closure.c | 0 src/{noja => lib}/objects/o_dir.c | 0 src/{noja => lib}/objects/o_file.c | 0 src/{noja => lib}/objects/o_float.c | 0 src/{noja => lib}/objects/o_int.c | 0 src/{noja => lib}/objects/o_list.c | 0 src/{noja => lib}/objects/o_map.c | 0 src/{noja => lib}/objects/o_none.c | 0 src/{noja => lib}/objects/o_string.c | 0 src/{noja => lib}/objects/objects.c | 0 src/{noja => lib}/objects/objects.h | 0 src/{noja => lib}/runtime/o_func.c | 0 src/{noja => lib}/runtime/o_nfunc.c | 0 src/{noja => lib}/runtime/o_staticmap.c | 0 src/{noja => lib}/runtime/runtime.c | 0 src/{noja => lib}/runtime/runtime.h | 0 src/{noja => lib}/runtime/runtime_error.c | 0 src/{noja => lib}/utils/bpalloc.c | 0 src/{noja => lib}/utils/bpalloc.h | 0 src/{noja => lib}/utils/bucketlist.c | 0 src/{noja => lib}/utils/bucketlist.h | 0 src/{noja => lib}/utils/defs.h | 0 src/{noja => lib}/utils/error.c | 0 src/{noja => lib}/utils/error.h | 0 src/{noja => lib}/utils/hash.c | 0 src/{noja => lib}/utils/hash.h | 0 src/{noja => lib}/utils/labellist.c | 0 src/{noja => lib}/utils/labellist.h | 0 src/{noja => lib}/utils/promise.c | 0 src/{noja => lib}/utils/promise.h | 0 src/{noja => lib}/utils/source.c | 0 src/{noja => lib}/utils/source.h | 0 src/{noja => lib}/utils/stack.c | 0 src/{noja => lib}/utils/stack.h | 0 src/{noja => lib}/utils/utf8.c | 0 src/{noja => lib}/utils/utf8.h | 0 tests/tester.c => src/test/main.c | 10 +- test | Bin 0 -> 170160 bytes tests/makefile | 8 - tests/randomizer.py | 201 --------- tests/suite/Testcase_000_001 | 10 + tests/suite/Testcase_001_008 | 8 + .../suite/{Testcase_002 => Testcase_002_000} | 0 .../suite/{Testcase_003 => Testcase_002_001} | 0 .../suite/{Testcase_004 => Testcase_002_002} | 0 .../suite/{Testcase_005 => Testcase_002_003} | 0 .../suite/{Testcase_006 => Testcase_002_004} | 0 .../suite/{Testcase_007 => Testcase_002_005} | 0 .../suite/{Testcase_008 => Testcase_002_006} | 0 .../suite/{Testcase_009 => Testcase_002_007} | 0 .../suite/{Testcase_010 => Testcase_002_008} | 0 .../suite/{Testcase_011 => Testcase_002_009} | 0 .../suite/{Testcase_012 => Testcase_002_010} | 0 .../suite/{Testcase_013 => Testcase_002_011} | 0 tests/suite/Testcase_002_012 | 11 + tests/suite/Testcase_002_013 | 11 + tests/suite/Testcase_002_014 | 11 + tests/suite/Testcase_002_015 | 12 + tests/suite/Testcase_002_016 | 12 + tests/suite/Testcase_002_017 | 12 + tests/suite/Testcase_002_018 | 12 + tests/suite/Testcase_002_019 | 12 + tests/suite/Testcase_002_020 | 12 + tests/suite/Testcase_002_021 | 12 + tests/suite/Testcase_002_022 | 12 + tests/suite/Testcase_002_023 | 16 + tests/suite/Testcase_002_024 | 16 + tests/suite/Testcase_002_025 | 16 + tests/suite/Testcase_002_026 | 14 + tests/suite/Testcase_002_027 | 19 + tests/suite/Testcase_002_028 | 16 + tests/suite/Testcase_002_029 | 16 + tests/suite/Testcase_002_030 | 19 + tests/suite/Testcase_002_031 | 23 + tests/suite/Testcase_002_032 | 17 + tests/suite/Testcase_002_033 | 17 + tests/suite/Testcase_002_34 | 46 ++ tests/suite/Testcase_003_000 | 13 + tests/suite/Testcase_003_001 | 19 + tests/suite/Testcase_004_000 | 13 + tests/suite/Testcase_004_001 | 19 + tests/suite/Testcase_004_002 | 13 + tests/suite/Testcase_004_003 | 19 + tests/suite/Testcase_004_004 | 14 + tests/suite/Testcase_004_005 | 14 + tests/suite/Testcase_005_000 | 11 + tests/suite/Testcase_005_001 | 13 + tests/suite/Testcase_005_002 | 17 + tests/suite/Testcase_005_003 | 13 + tests/suite/Testcase_006_000 | 11 + tests/suite/Testcase_006_001 | 12 + tests/suite/Testcase_006_002 | 13 + tests/suite/Testcase_007_000 | 12 + tests/suite/Testcase_007_001 | 25 ++ tests/suite/Testcase_007_002 | 12 + tests/suite/Testcase_008_000 | 12 + tests/suite/Testcase_008_001 | 14 + tests/suite/Testcase_008_002 | 17 + tests/suite/Testcase_008_003 | 20 + tests/suite/Testcase_009_000 | 14 + tests/suite/Testcase_009_001 | 19 + tests/suite/Testcase_009_002 | 23 + tests/suite/Testcase_009_003 | 25 ++ tests/suite/Testcase_009_004 | 18 + tests/suite/Testcase_010_000 | 13 + tests/suite/Testcase_010_001 | 18 + tests/suite/Testcase_010_002 | 21 + tests/suite/Testcase_010_003 | 24 ++ tests/suite/Testcase_010_004 | 18 + tests/suite/Testcase_011_000 | 15 + tests/suite/Testcase_011_001 | 17 + tests/suite/Testcase_011_002 | 22 + tests/suite/Testcase_011_003 | 25 ++ tests/tester | Bin 84864 -> 0 bytes 145 files changed, 1445 insertions(+), 234 deletions(-) delete mode 100755 coverage.sh create mode 100755 report_test_suite_coverage.sh rename src/{noja => lib}/README.md (100%) create mode 100644 src/lib/assembler/assemble.c create mode 100644 src/lib/assembler/assemble.h rename src/{noja => lib}/builtins/README.md (100%) rename src/{noja => lib}/builtins/basic.c (100%) rename src/{noja => lib}/builtins/basic.h (100%) rename src/{noja => lib}/builtins/files.c (100%) rename src/{noja => lib}/builtins/files.h (100%) rename src/{noja => lib}/builtins/math.c (100%) rename src/{noja => lib}/builtins/math.h (100%) rename src/{noja => lib}/common/executable.c (99%) rename src/{noja => lib}/common/executable.h (100%) rename src/{noja => lib}/compiler/AST.h (100%) rename src/{noja => lib}/compiler/ASTi.h (100%) rename src/{noja => lib}/compiler/compile.c (100%) rename src/{noja => lib}/compiler/compile.h (100%) rename src/{noja => lib}/compiler/parse.c (100%) rename src/{noja => lib}/compiler/parse.h (100%) rename src/{noja => lib}/noja.c (100%) rename src/{noja => lib}/noja.h (100%) rename src/{noja => lib}/noja_internals.c (100%) rename src/{noja => lib}/noja_internals.h (100%) rename src/{noja => lib}/objects/heap.c (100%) rename src/{noja => lib}/objects/o_bool.c (100%) rename src/{noja => lib}/objects/o_buffer.c (100%) rename src/{noja => lib}/objects/o_closure.c (100%) rename src/{noja => lib}/objects/o_dir.c (100%) rename src/{noja => lib}/objects/o_file.c (100%) rename src/{noja => lib}/objects/o_float.c (100%) rename src/{noja => lib}/objects/o_int.c (100%) rename src/{noja => lib}/objects/o_list.c (100%) rename src/{noja => lib}/objects/o_map.c (100%) rename src/{noja => lib}/objects/o_none.c (100%) rename src/{noja => lib}/objects/o_string.c (100%) rename src/{noja => lib}/objects/objects.c (100%) rename src/{noja => lib}/objects/objects.h (100%) rename src/{noja => lib}/runtime/o_func.c (100%) rename src/{noja => lib}/runtime/o_nfunc.c (100%) rename src/{noja => lib}/runtime/o_staticmap.c (100%) rename src/{noja => lib}/runtime/runtime.c (100%) rename src/{noja => lib}/runtime/runtime.h (100%) rename src/{noja => lib}/runtime/runtime_error.c (100%) rename src/{noja => lib}/utils/bpalloc.c (100%) rename src/{noja => lib}/utils/bpalloc.h (100%) rename src/{noja => lib}/utils/bucketlist.c (100%) rename src/{noja => lib}/utils/bucketlist.h (100%) rename src/{noja => lib}/utils/defs.h (100%) rename src/{noja => lib}/utils/error.c (100%) rename src/{noja => lib}/utils/error.h (100%) rename src/{noja => lib}/utils/hash.c (100%) rename src/{noja => lib}/utils/hash.h (100%) rename src/{noja => lib}/utils/labellist.c (100%) rename src/{noja => lib}/utils/labellist.h (100%) rename src/{noja => lib}/utils/promise.c (100%) rename src/{noja => lib}/utils/promise.h (100%) rename src/{noja => lib}/utils/source.c (100%) rename src/{noja => lib}/utils/source.h (100%) rename src/{noja => lib}/utils/stack.c (100%) rename src/{noja => lib}/utils/stack.h (100%) rename src/{noja => lib}/utils/utf8.c (100%) rename src/{noja => lib}/utils/utf8.h (100%) rename tests/tester.c => src/test/main.c (98%) create mode 100755 test delete mode 100644 tests/makefile delete mode 100644 tests/randomizer.py create mode 100644 tests/suite/Testcase_000_001 create mode 100644 tests/suite/Testcase_001_008 rename tests/suite/{Testcase_002 => Testcase_002_000} (100%) rename tests/suite/{Testcase_003 => Testcase_002_001} (100%) rename tests/suite/{Testcase_004 => Testcase_002_002} (100%) rename tests/suite/{Testcase_005 => Testcase_002_003} (100%) rename tests/suite/{Testcase_006 => Testcase_002_004} (100%) rename tests/suite/{Testcase_007 => Testcase_002_005} (100%) rename tests/suite/{Testcase_008 => Testcase_002_006} (100%) rename tests/suite/{Testcase_009 => Testcase_002_007} (100%) rename tests/suite/{Testcase_010 => Testcase_002_008} (100%) rename tests/suite/{Testcase_011 => Testcase_002_009} (100%) rename tests/suite/{Testcase_012 => Testcase_002_010} (100%) rename tests/suite/{Testcase_013 => Testcase_002_011} (100%) create mode 100644 tests/suite/Testcase_002_012 create mode 100644 tests/suite/Testcase_002_013 create mode 100644 tests/suite/Testcase_002_014 create mode 100644 tests/suite/Testcase_002_015 create mode 100644 tests/suite/Testcase_002_016 create mode 100644 tests/suite/Testcase_002_017 create mode 100644 tests/suite/Testcase_002_018 create mode 100644 tests/suite/Testcase_002_019 create mode 100644 tests/suite/Testcase_002_020 create mode 100644 tests/suite/Testcase_002_021 create mode 100644 tests/suite/Testcase_002_022 create mode 100644 tests/suite/Testcase_002_023 create mode 100644 tests/suite/Testcase_002_024 create mode 100644 tests/suite/Testcase_002_025 create mode 100644 tests/suite/Testcase_002_026 create mode 100644 tests/suite/Testcase_002_027 create mode 100644 tests/suite/Testcase_002_028 create mode 100644 tests/suite/Testcase_002_029 create mode 100644 tests/suite/Testcase_002_030 create mode 100644 tests/suite/Testcase_002_031 create mode 100644 tests/suite/Testcase_002_032 create mode 100644 tests/suite/Testcase_002_033 create mode 100644 tests/suite/Testcase_002_34 create mode 100644 tests/suite/Testcase_003_000 create mode 100644 tests/suite/Testcase_003_001 create mode 100644 tests/suite/Testcase_004_000 create mode 100644 tests/suite/Testcase_004_001 create mode 100644 tests/suite/Testcase_004_002 create mode 100644 tests/suite/Testcase_004_003 create mode 100644 tests/suite/Testcase_004_004 create mode 100644 tests/suite/Testcase_004_005 create mode 100644 tests/suite/Testcase_005_000 create mode 100644 tests/suite/Testcase_005_001 create mode 100644 tests/suite/Testcase_005_002 create mode 100644 tests/suite/Testcase_005_003 create mode 100644 tests/suite/Testcase_006_000 create mode 100644 tests/suite/Testcase_006_001 create mode 100644 tests/suite/Testcase_006_002 create mode 100644 tests/suite/Testcase_007_000 create mode 100644 tests/suite/Testcase_007_001 create mode 100644 tests/suite/Testcase_007_002 create mode 100644 tests/suite/Testcase_008_000 create mode 100644 tests/suite/Testcase_008_001 create mode 100644 tests/suite/Testcase_008_002 create mode 100644 tests/suite/Testcase_008_003 create mode 100644 tests/suite/Testcase_009_000 create mode 100644 tests/suite/Testcase_009_001 create mode 100644 tests/suite/Testcase_009_002 create mode 100644 tests/suite/Testcase_009_003 create mode 100644 tests/suite/Testcase_009_004 create mode 100644 tests/suite/Testcase_010_000 create mode 100644 tests/suite/Testcase_010_001 create mode 100644 tests/suite/Testcase_010_002 create mode 100644 tests/suite/Testcase_010_003 create mode 100644 tests/suite/Testcase_010_004 create mode 100644 tests/suite/Testcase_011_000 create mode 100644 tests/suite/Testcase_011_001 create mode 100644 tests/suite/Testcase_011_002 create mode 100644 tests/suite/Testcase_011_003 delete mode 100755 tests/tester diff --git a/.gitignore b/.gitignore index ab4e333..1f076b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,9 @@ -cache -vgcore.* -libnoja.a +cache/ +report/ + noja -*.gcov \ No newline at end of file +!noja/ + +vgcore.* +*.gcov +lib*.a \ No newline at end of file diff --git a/coverage.sh b/coverage.sh deleted file mode 100755 index c649d9e..0000000 --- a/coverage.sh +++ /dev/null @@ -1,8 +0,0 @@ -./build.sh --coverage -mkdir temp -export LLVM_PROFILE_FILE="temp/noja.profraw" -./build/noja run examples/json.noja -llvm-profdata merge -sparse temp/noja.profraw -o temp/noja.profdata -llvm-cov show ./build/noja -instr-profile=temp/noja.profdata >> build/coverage.txt -llvm-cov export ./build/noja -instr-profile=temp/noja.profdata >> build/coverage.json -rm -rf temp \ No newline at end of file diff --git a/examples/bubble_sort.njbc b/examples/bubble_sort.njbc index f0009e8..2317ae9 100644 --- a/examples/bubble_sort.njbc +++ b/examples/bubble_sort.njbc @@ -12,12 +12,14 @@ copy: PUSHINT 0; ASS "i"; POP 1; + +loop_start: PUSHVAR "i"; PUSHVAR "L"; PUSHVAR "count"; CALL 1, 1; LSS; - JUMPIFNOTANDPOP 31; + JUMPIFNOTANDPOP loop_end; PUSHVAR "L"; PUSHVAR "i"; SELECT; @@ -30,7 +32,8 @@ copy: ADD; ASS "i"; POP 1; - JUMP 12; + JUMP loop_start; +loop_end: PUSHVAR "L2"; RETURN 1; RETURN 0; @@ -50,7 +53,7 @@ bubble_sort: PUSHNNE; EQL; JUMPIFNOTANDPOP default_less_cb_end; - PUSHFUN 50, 2; + PUSHFUN default_less_cb, 2; ASS "less"; POP 1; JUMP default_less_cb_end; diff --git a/makefile b/makefile index 70a377a..153e8b3 100644 --- a/makefile +++ b/makefile @@ -18,14 +18,22 @@ SRCDIR = src # when doing `make clean`. OBJDIR = cache +# Temporary directory where execution coverage +# reports are stored. If this directory doesn't +# exist, it will be created. This folder is +# deleted by `make clean`. +REPORTDIR = report + # Source directory for each program to be build # They are relative to the SRCDIR folder. -LIB_SUBDIR = noja +LIB_SUBDIR = lib CLI_SUBDIR = cli +TST_SUBDIR = test # Resulting file names LIB_FNAME = libnoja.a CLI_FNAME = noja +TST_FNAME = test # Where the build programs will be moved when # installation occurres. @@ -92,12 +100,14 @@ endif # Absolute path of each program's source tree LIB_SRCDIR = $(SRCDIR)/$(LIB_SUBDIR) CLI_SRCDIR = $(SRCDIR)/$(CLI_SUBDIR) +TST_SRCDIR = $(SRCDIR)/$(TST_SUBDIR) # Each program that is being build uses as object # cache a subfolder of OBJDIR called like the it's # source tree base folder in SRCDIR. LIB_OBJDIR = $(OBJDIR)/$(LIB_SUBDIR) CLI_OBJDIR = $(OBJDIR)/$(CLI_SUBDIR) +TST_OBJDIR = $(OBJDIR)/$(TST_SUBDIR) LIB_CFILES = $(call rwildcard, $(LIB_SRCDIR), *.c) LIB_HFILES = $(call rwildcard, $(LIB_SRCDIR), *.h) @@ -107,15 +117,24 @@ CLI_CFILES = $(call rwildcard, $(CLI_SRCDIR), *.c) CLI_HFILES = $(call rwildcard, $(CLI_SRCDIR), *.h) CLI_OFILES = $(patsubst $(CLI_SRCDIR)/%.c, $(CLI_OBJDIR)/%.o, $(CLI_CFILES)) +TST_CFILES = $(call rwildcard, $(TST_SRCDIR), *.c) +TST_HFILES = $(call rwildcard, $(TST_SRCDIR), *.h) +TST_OFILES = $(patsubst $(TST_SRCDIR)/%.c, $(TST_OBJDIR)/%.o, $(TST_CFILES)) + +ALL_CFILES = $(call rwildcard, $(SRCDIR), *.c) + # Useful abbreviations LIB = $(OUTDIR)/$(LIB_FNAME) CLI = $(OUTDIR)/$(CLI_FNAME) +TST = $(OUTDIR)/$(TST_FNAME) # ===================== # # === Rules =========== # # ===================== # -all: $(LIB) $(CLI) +.PHONY: report install clean all + +all: $(LIB) $(CLI) $(TST) $(OBJDIR)/%.o: $(SRCDIR)/%.c @ mkdir -p $(@D) @@ -128,11 +147,29 @@ $(LIB): $(LIB_OFILES) $(CLI): $(CLI_OFILES) $(LIB) $(CC) $^ -o $@ $(LFLAGS) +$(TST): $(TST_OFILES) $(LIB) + gcc $^ -o $@ $(LFLAGS) + +#$(REPORTDIR)/%.gcov: src/%.c +# @ mkdir -p $(@D) +# gcov --stdout $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.c, $^) > $@ +# +#report: $(patsubst $(SRCDIR)/%.c, $(REPORTDIR)/%.gcov, $(ALL_CFILES)) +# lcov --capture --directory $(OBJDIR) --output-file coverage.info +# genhtml coverage.info --output-directory . +# + +report: + lcov --capture --directory $(OBJDIR) --output-file $(OBJDIR)/coverage.info + @ mkdir -p report + genhtml $(OBJDIR)/coverage.info --output-directory report + install: $(LIB) $(CLI) sudo cp $(LIB) $(LIB_INSTALLDIR) sudo cp $(CLI) $(CLI_INSTALLDIR) clean: rm -rf $(OBJDIR) + rm -rf $(REPORTDIR) rm -f $(LIB) - rm -f $(CLI) + rm -f $(CLI) \ No newline at end of file diff --git a/report_test_suite_coverage.sh b/report_test_suite_coverage.sh new file mode 100755 index 0000000..8331060 --- /dev/null +++ b/report_test_suite_coverage.sh @@ -0,0 +1,4 @@ +make -B BUILD_MODE=COVERAGE CC=gcc +./test tests/suite +make report +firefox report/index.html \ No newline at end of file diff --git a/src/cli/main.c b/src/cli/main.c index b76f92c..e3385fc 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -32,7 +32,7 @@ #include #include #include -#include "../noja/noja.h" +#include "../lib/noja.h" static const char usage[] = "Usage patterns:\n" diff --git a/src/noja/README.md b/src/lib/README.md similarity index 100% rename from src/noja/README.md rename to src/lib/README.md diff --git a/src/lib/assembler/assemble.c b/src/lib/assembler/assemble.c new file mode 100644 index 0000000..2a787c3 --- /dev/null +++ b/src/lib/assembler/assemble.c @@ -0,0 +1,393 @@ +#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 + // + //