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 + // + //