From 108018e3e7326dabbbef568ab08bc5cebf5d427b Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 20 Jan 2020 23:00:39 +0100 Subject: Add arithmetic, implement hash map --- include/bytecode.h | 35 +++++++++++++++++---------------- include/std/buffer.h | 4 +++- include/std/hash_map.h | 24 +++++++++++++++++++++++ include/std/string_view.h | 11 +++++++++++ include/tokenizer.h | 19 +++++++++--------- include/value.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 116 insertions(+), 26 deletions(-) create mode 100644 include/std/hash_map.h create mode 100644 include/std/string_view.h create mode 100644 include/value.h (limited to 'include') diff --git a/include/bytecode.h b/include/bytecode.h index 4a14b8d..4a9d49c 100644 --- a/include/bytecode.h +++ b/include/bytecode.h @@ -4,37 +4,40 @@ #include "std/buffer.h" #include -/* - All instructions are 4 bytes in size. -*/ - typedef uint8_t TslOpcodeType; -typedef uint8_t TslRegister; +/* Registers are positive if they refer to local variables and negative when they refer to parameters */ +typedef int16_t TslRegister; typedef uint16_t TslValueIndex; typedef enum { - TSL_OPCODE_ASSIGN + TSL_OPCODE_LOAD_NUMBER, + TSL_OPCODE_MOV_REG } TslOpcode; typedef struct { TslBuffer buffer; + TslRegister register_counter; } TslBytecodeWriter; typedef struct { + TslRegister dst_reg; + double number; + TslOpcodeType opcode; +} TslInstructionType1; + +typedef struct { + TslRegister dst_reg; + TslRegister src_reg; TslOpcodeType opcode; - union { - TslRegister dst_reg; - TslRegister src_reg; - } type1; - union { - TslRegister dst_reg; - TslValueIndex value_index; - } type2; -} TslInstruction; +} TslInstructionType2; void tsl_bytecode_writer_init(TslBytecodeWriter *self); void tsl_bytecode_writer_deinit(TslBytecodeWriter *self); +void tsl_bytecode_writer_reset_register_counter(TslBytecodeWriter *self); +/* Returns -1 on error (too many registers used (more than 2^15)) */ +TslRegister tsl_bytecode_writer_get_unique_register(TslBytecodeWriter *self); -int tsl_bytecode_writer_assign(TslBytecodeWriter *self, TslRegister reg, double value); +int tsl_bytecode_writer_load_number(TslBytecodeWriter *self, TslRegister dst, double number); +int tsl_bytecode_writer_mov_reg(TslBytecodeWriter *self, TslRegister dst, TslRegister src); #endif /* TSL_BYTECODE_H */ diff --git a/include/std/buffer.h b/include/std/buffer.h index dea7dbd..db6474e 100644 --- a/include/std/buffer.h +++ b/include/std/buffer.h @@ -16,6 +16,8 @@ typedef struct { void tsl_buffer_init(TslBuffer *self); void tsl_buffer_deinit(TslBuffer *self); -int tsl_buffer_append(TslBuffer *self, void *data, size_t size); +int tsl_buffer_append(TslBuffer *self, const void *data, size_t size); +void* tsl_buffer_begin(TslBuffer *self); +void* tsl_buffer_end(TslBuffer *self); #endif /* TSL_BUFFER_H */ diff --git a/include/std/hash_map.h b/include/std/hash_map.h new file mode 100644 index 0000000..f3a3a6d --- /dev/null +++ b/include/std/hash_map.h @@ -0,0 +1,24 @@ +#ifndef TSL_HASH_MAP_H +#define TSL_HASH_MAP_H + +#include "string_view.h" +#include + +typedef uint64_t (*TslHashFunc)(const void *data, size_t size); + +/* TODO: Optimize small hash map by using the members of the struct instead of allocating on heap */ +typedef struct { + void *buckets_data; /* value=TslHashMapNode, data=|hash(uint64_t) + key_size(size_t) + key_data(...) data_size(size_t) + data_data(...)| */ + size_t buckets_size; + size_t buckets_capacity; + size_t num_items; +} TslHashMap; + +void tsl_hash_map_init(TslHashMap *self); +void tsl_hash_map_deinit(TslHashMap *self); + +int tsl_hash_map_insert(TslHashMap *self, const TslStringView *key, const void *data, size_t size, TslHashFunc hash_func); +/* Get a reference to the value by key @key */ +void* tsl_hash_map_get(TslHashMap *self, const TslStringView *key, TslHashFunc hash_func); + +#endif /* TSL_HASH_MAP_H */ diff --git a/include/std/string_view.h b/include/std/string_view.h new file mode 100644 index 0000000..4f9552a --- /dev/null +++ b/include/std/string_view.h @@ -0,0 +1,11 @@ +#ifndef TSL_STRING_VIEW_H +#define TSL_STRING_VIEW_H + +#include + +typedef struct { + const char *data; + size_t size; +} TslStringView; + +#endif /* TSL_STRING_VIEW_H */ diff --git a/include/tokenizer.h b/include/tokenizer.h index 98491c7..2e7d42b 100644 --- a/include/tokenizer.h +++ b/include/tokenizer.h @@ -1,13 +1,7 @@ #ifndef TSL_TOKENIZER_H #define TSL_TOKENIZER_H -#include -#include - -typedef struct { - const char *data; - size_t size; -} TslStringView; +#include "std/string_view.h" typedef enum { TSL_TOKEN_END_OF_FILE, @@ -27,7 +21,8 @@ typedef enum { TSL_TOKEN_COLON, TSL_TOKEN_COMMA, TSL_TOKEN_FN, - TSL_TOKEN_DOLLAR_SIGN + TSL_TOKEN_DOLLAR_SIGN, + TSL_TOKEN_ARITHMETIC } TslToken; typedef enum { @@ -53,14 +48,20 @@ typedef struct { TslStringView identifier; TslStringView string; int bool_value; - int64_t number_value; + double number_value; + char arithmetic_symbol; } TslTokenizer; void tsl_tokenizer_init(TslTokenizer *self, const char *code, size_t code_size); TslToken tsl_tokenizer_next(TslTokenizer *self); int tsl_tokenizer_accept(TslTokenizer *self, TslToken expected_token); +/* + If peek was previously called without consuming the token, then the previous value peek token is returned. + In other words, calling tsl_tokenizer_peek twice in a row will return the same token without progressing. +*/ TslToken tsl_tokenizer_peek(TslTokenizer *self); +TslToken tsl_tokenizer_consume_peek(TslTokenizer *self); TslCommandToken tsl_tokenizer_next_command_arg(TslTokenizer *self, TslStringView *arg); diff --git a/include/value.h b/include/value.h new file mode 100644 index 0000000..1d053b7 --- /dev/null +++ b/include/value.h @@ -0,0 +1,49 @@ +#ifndef TSL_VALUE_H +#define TSL_VALUE_H + +#include +#include + +typedef enum { + TSL_TYPE_NULL, + TSL_TYPE_NUMBER, + TSL_TYPE_STRING, + TSL_TYPE_BOOL, + TSL_TYPE_LIST, + TSL_TYPE_MAP, + TSL_TYPE_USERDATA +} TslType; + +typedef enum { + TSL_FALSE, + TSL_TRUE +} TslBool; + +typedef struct { + char *data; + size_t size; +} TslString; + +/* TODO: Implement this */ +typedef struct { + void *data; +} TslList; + +/* TODO: Implement this */ +typedef struct { + void *data; +} TslMap; + +typedef struct { + union { + double number; + TslString *string; + TslBool boolean; + TslList *list; + TslMap *map; + void *userdata; + } data; + uint8_t type; +} TslValue; + +#endif /* TSL_VALUE_H */ -- cgit v1.2.3