diff options
author | dec05eba <dec05eba@protonmail.com> | 2020-01-18 10:01:27 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2020-01-18 10:05:55 +0100 |
commit | 50c928d224bff0af322f23a7d2b842cd54aa2e68 (patch) | |
tree | 4e02b167c89c2ff109f6dfd1d2734309ea0192db | |
parent | 1dbef1bfdefe8d7967a360f00d350db307d344e2 (diff) |
Start on bytecode, move object files to build directory
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | Makefile | 29 | ||||
-rw-r--r-- | include/bytecode.h | 40 | ||||
-rw-r--r-- | include/std/buffer.h | 21 | ||||
-rw-r--r-- | src/bytecode.c | 19 | ||||
-rw-r--r-- | src/parser.c | 4 | ||||
-rw-r--r-- | src/std/buffer.c | 42 |
7 files changed, 146 insertions, 13 deletions
@@ -1,2 +1,2 @@ -*.o -tsl +build/* +compile_commands.json
\ No newline at end of file @@ -1,20 +1,29 @@ CFLAGS = -Wall -Wextra -g3 -ansi -pedantic -OBJ = main.o tokenizer.o parser.o +OBJ = build/main.o build/tokenizer.o build/parser.o build/bytecode.o build/buffer.o -all: $(OBJ) - cc -o tsl $(OBJ) -fPIE +all: build_dir $(OBJ) + cc -o build/tsl $(OBJ) -fPIE clean: - rm $(OBJ) tsl + rm $(OBJ) build/tsl + +build_dir: + mkdir -p build compiledb: make clean; bear make -main.o: src/main.c include/tokenizer.h - cc -c src/main.c $(CFLAGS) +build/main.o: src/main.c include/tokenizer.h + cc -c src/main.c -o build/main.o $(CFLAGS) + +build/tokenizer.o: src/tokenizer.c include/tokenizer.h + cc -c src/tokenizer.c -o build/tokenizer.o $(CFLAGS) + +build/parser.o: src/parser.c include/parser.h + cc -c src/parser.c -o build/parser.o $(CFLAGS) -tokenizer.o: src/tokenizer.c include/tokenizer.h - cc -c src/tokenizer.c $(CFLAGS) +build/bytecode.o: src/bytecode.c include/bytecode.h + cc -c src/bytecode.c -o build/bytecode.o $(CFLAGS) -parser.o: src/parser.c include/parser.h - cc -c src/parser.c $(CFLAGS) +build/buffer.o: src/std/buffer.c include/std/buffer.h + cc -c src/std/buffer.c -o build/buffer.o $(CFLAGS) diff --git a/include/bytecode.h b/include/bytecode.h new file mode 100644 index 0000000..4a14b8d --- /dev/null +++ b/include/bytecode.h @@ -0,0 +1,40 @@ +#ifndef TSL_BYTECODE_H +#define TSL_BYTECODE_H + +#include "std/buffer.h" +#include <stdint.h> + +/* + All instructions are 4 bytes in size. +*/ + +typedef uint8_t TslOpcodeType; +typedef uint8_t TslRegister; +typedef uint16_t TslValueIndex; + +typedef enum { + TSL_OPCODE_ASSIGN +} TslOpcode; + +typedef struct { + TslBuffer buffer; +} TslBytecodeWriter; + +typedef struct { + TslOpcodeType opcode; + union { + TslRegister dst_reg; + TslRegister src_reg; + } type1; + union { + TslRegister dst_reg; + TslValueIndex value_index; + } type2; +} TslInstruction; + +void tsl_bytecode_writer_init(TslBytecodeWriter *self); +void tsl_bytecode_writer_deinit(TslBytecodeWriter *self); + +int tsl_bytecode_writer_assign(TslBytecodeWriter *self, TslRegister reg, double value); + +#endif /* TSL_BYTECODE_H */ diff --git a/include/std/buffer.h b/include/std/buffer.h new file mode 100644 index 0000000..dea7dbd --- /dev/null +++ b/include/std/buffer.h @@ -0,0 +1,21 @@ +#ifndef TSL_BUFFER_H +#define TSL_BUFFER_H + +#include <stddef.h> + +/* + TODO: Optimize small size buffers by using data and size members (16 bytes on x86) + instead of heap allocation +*/ +typedef struct { + void *data; + size_t size; + size_t capacity; +} TslBuffer; + +void tsl_buffer_init(TslBuffer *self); +void tsl_buffer_deinit(TslBuffer *self); + +int tsl_buffer_append(TslBuffer *self, void *data, size_t size); + +#endif /* TSL_BUFFER_H */ diff --git a/src/bytecode.c b/src/bytecode.c new file mode 100644 index 0000000..3e9a6e8 --- /dev/null +++ b/src/bytecode.c @@ -0,0 +1,19 @@ +#include "../include/bytecode.h" +#include <assert.h> + +void tsl_bytecode_writer_init(TslBytecodeWriter *self) { + assert(sizeof(TslInstruction) == 4); + tsl_buffer_init(&self->buffer); +} + +void tsl_bytecode_writer_deinit(TslBytecodeWriter *self) { + tsl_buffer_deinit(&self->buffer); +} + +int tsl_bytecode_writer_assign(TslBytecodeWriter *self, TslRegister reg, double value) { + TslInstruction instruction; + instruction.opcode = TSL_OPCODE_ASSIGN; + instruction.type2.dst_reg = reg; + instruction.type2.value_index = value; + return tsl_buffer_append(&self->buffer, &instruction, sizeof(instruction)); +} diff --git a/src/parser.c b/src/parser.c index 1324305..176be63 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,8 +1,10 @@ #include "../include/parser.h" +#include "../include/bytecode.h" #include <stdio.h> typedef struct { TslTokenizer tokenizer; + TslBytecodeWriter bytecode_writer; } TslParser; static int tsl_parser_parse_rhs(TslParser *self); @@ -10,6 +12,7 @@ static int tsl_parser_parse_expressions(TslParser *self, TslToken end_token); static void tsl_parser_init(TslParser *self, const char *code, size_t code_size) { tsl_tokenizer_init(&self->tokenizer, code, code_size); + tsl_bytecode_writer_init(&self->bytecode_writer); } static int tsl_parser_parse_map(TslParser *self) { @@ -263,7 +266,6 @@ int tsl_parser_parse_expressions(TslParser *self, TslToken end_token) { return 0; } -/* EXPRS */ int tsl_parse(const char *code, size_t code_size) { TslParser parser; tsl_parser_init(&parser, code, code_size); diff --git a/src/std/buffer.c b/src/std/buffer.c new file mode 100644 index 0000000..3fc5184 --- /dev/null +++ b/src/std/buffer.c @@ -0,0 +1,42 @@ +#include "../../include/std/buffer.h" +#include <stdlib.h> +#include <string.h> + +void tsl_buffer_init(TslBuffer *self) { + self->data = NULL; + self->size = 0; + self->capacity = 0; +} + +void tsl_buffer_deinit(TslBuffer *self) { + free(self->data); +} + +static int tsl_buffer_ensure_capacity(TslBuffer *self, size_t new_size) { + void *new_ptr; + if(new_size <= self->capacity) + return 1; + + if(self->capacity != 0) { + size_t new_capacity = self->capacity; + while(new_capacity < new_size) { + new_capacity *= 2; + } + new_size = new_capacity; + } + new_ptr = realloc(self->data, new_size); + if(!new_ptr) + return 0; + + self->data = new_ptr; + self->capacity = new_size; + return 1; +} + +int tsl_buffer_append(TslBuffer *self, void *data, size_t size) { + if(!tsl_buffer_ensure_capacity(self, self->size + size)) + return 1; + memcpy((char*)self->data + self->size, data, size); + self->size += size; + return 0; +} |