From 50c928d224bff0af322f23a7d2b842cd54aa2e68 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 18 Jan 2020 10:01:27 +0100 Subject: Start on bytecode, move object files to build directory --- .gitignore | 4 ++-- Makefile | 29 +++++++++++++++++++---------- include/bytecode.h | 40 ++++++++++++++++++++++++++++++++++++++++ include/std/buffer.h | 21 +++++++++++++++++++++ src/bytecode.c | 19 +++++++++++++++++++ src/parser.c | 4 +++- src/std/buffer.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 146 insertions(+), 13 deletions(-) create mode 100644 include/bytecode.h create mode 100644 include/std/buffer.h create mode 100644 src/bytecode.c create mode 100644 src/std/buffer.c diff --git a/.gitignore b/.gitignore index c6275a9..5d6847a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -*.o -tsl +build/* +compile_commands.json \ No newline at end of file diff --git a/Makefile b/Makefile index 9ab88c1..e19c75e 100644 --- a/Makefile +++ b/Makefile @@ -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 + +/* + 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 + +/* + 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 + +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 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 +#include + +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; +} -- cgit v1.2.3