From 1dd53ce54c2008e3a11a636a496853cf6f9a5d65 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 24 Jan 2020 09:11:53 +0100 Subject: Convert hash map to gc, implement more instructions and call command --- include/bytecode.h | 2 +- include/command.h | 12 ++++++++++++ include/parser.h | 2 +- include/program.h | 29 ++++++++++++++++++++++++----- include/std/buffer.h | 9 +++++++-- include/std/hash_map.h | 25 ------------------------- include/std/string_view.h | 11 ----------- include/std_gc/hash_map.h | 29 +++++++++++++++++++++++++++++ include/string_view.h | 11 +++++++++++ include/tokenizer.h | 6 +++--- include/value.h | 10 +++++++++- 11 files changed, 97 insertions(+), 49 deletions(-) create mode 100644 include/command.h delete mode 100644 include/std/hash_map.h delete mode 100644 include/std/string_view.h create mode 100644 include/std_gc/hash_map.h create mode 100644 include/string_view.h (limited to 'include') diff --git a/include/bytecode.h b/include/bytecode.h index 06ebf19..912da89 100644 --- a/include/bytecode.h +++ b/include/bytecode.h @@ -2,7 +2,7 @@ #define TSL_BYTECODE_H #include "std/buffer.h" -#include "std/string_view.h" +#include "string_view.h" #include "value.h" #include diff --git a/include/command.h b/include/command.h new file mode 100644 index 0000000..6e6490b --- /dev/null +++ b/include/command.h @@ -0,0 +1,12 @@ +#ifndef TSL_COMMAND_H +#define TSL_COMMAND_H + +#include "string_view.h" + +/* Return 1 if you want to continue reading. @data is null-terminated */ +typedef int (*ProgramOutputCallback)(char *data, int size, void *userdata); + +/* Returns the program exit code (a positive value), or a negative value on failure */ +int tsl_command_exec(char **args, ProgramOutputCallback output_callback, void *userdata); + +#endif /* TSL_COMMAND_H */ diff --git a/include/parser.h b/include/parser.h index 440fbac..9fdb9b6 100644 --- a/include/parser.h +++ b/include/parser.h @@ -13,6 +13,6 @@ typedef enum { TODO: Make this function load a file instead of parsing memory. This is needed because when using @import function instead tsl, it will load a file anyways. */ -TslParseResult tsl_parse(const char *code, size_t code_size, TslProgram *program_output); +TslParseResult tsl_parse(char *code, size_t code_size, TslProgram *program_output); #endif /* TSL_PARSER_H */ diff --git a/include/program.h b/include/program.h index c097c7b..5c4737b 100644 --- a/include/program.h +++ b/include/program.h @@ -2,16 +2,35 @@ #define TSL_PROGRAM_H #include "std/buffer.h" -#include "std/hash_map.h" +#include "std_gc/hash_map.h" +#include "string_view.h" #include "value.h" -#define TSL_STACK_MAX_SIZE 255 +typedef enum { + TSL_STACK_VALUE_TYPE_NUMBER, + TSL_STACK_VALUE_TYPE_BOOL, + TSL_STACK_VALUE_TYPE_STRING, + TSL_STACK_VALUE_TYPE_FUNCTION, + TSL_STACK_VALUE_TYPE_VARIABLE, + TSL_STACK_VALUE_TYPE_NULL, + TSL_STACK_VALUE_TYPE_COMMAND_ARG +} TslStackValueType; + +typedef struct { + union { + int integer; + double number; + TslBool boolean; + TslStringView str; + } data; + TslStackValueType type; +} TslStackValue; typedef struct { TslBuffer /*TslBytecode*/ function_bytecode_list; - TslHashMap /*TslStringView, TslValue*/ variables; - TslValue stack_values[TSL_STACK_MAX_SIZE]; - size_t stack_index; + /* Allocated with GC and is the root object of the program. When this is deallocated, the whole program is deallocated */ + TslHashMap /*TslStringView, TslValue*/ *variables; + TslBuffer /*TslStackValue*/ stack_values; } TslProgram; typedef enum { diff --git a/include/std/buffer.h b/include/std/buffer.h index 3aad48b..7253d88 100644 --- a/include/std/buffer.h +++ b/include/std/buffer.h @@ -17,8 +17,13 @@ void tsl_buffer_init(TslBuffer *self); void tsl_buffer_deinit(TslBuffer *self); int tsl_buffer_append(TslBuffer *self, const void *data, size_t size); -/* The buffer has to >= @size */ -void tsl_buffer_pop(TslBuffer *self, size_t size); +/* + This function changes the size of the buffer without changing the capacity + and returns the value at the back of the buffer, which is valid until @tsl_buffer_append or + @tsl_buffer_deinit is called. + The buffer size has to be larger or equal to @size. +*/ +void* tsl_buffer_pop(TslBuffer *self, size_t size); void* tsl_buffer_begin(TslBuffer *self); void* tsl_buffer_end(TslBuffer *self); void tsl_buffer_move(TslBuffer *dst, TslBuffer *src); diff --git a/include/std/hash_map.h b/include/std/hash_map.h deleted file mode 100644 index b430d22..0000000 --- a/include/std/hash_map.h +++ /dev/null @@ -1,25 +0,0 @@ -#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; -} 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, or NULL if it doesn't exist */ -void* tsl_hash_map_get(TslHashMap *self, const TslStringView *key, TslHashFunc hash_func); -/* Get a reference to the value by key @key, or insert a new value for the key with a size of @size */ -int tsl_hash_map_get_or_create(TslHashMap *self, const TslStringView *key, size_t size, TslHashFunc hash_func, void **output); - -#endif /* TSL_HASH_MAP_H */ diff --git a/include/std/string_view.h b/include/std/string_view.h deleted file mode 100644 index 4f9552a..0000000 --- a/include/std/string_view.h +++ /dev/null @@ -1,11 +0,0 @@ -#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/std_gc/hash_map.h b/include/std_gc/hash_map.h new file mode 100644 index 0000000..e67dd75 --- /dev/null +++ b/include/std_gc/hash_map.h @@ -0,0 +1,29 @@ +#ifndef TSL_HASH_MAP_H +#define TSL_HASH_MAP_H + +#include "../value.h" +#include + +/* TODO: Optimize small hash map by using the members of the struct instead of allocating on heap */ +typedef struct { + void *buckets_data; /* value=TslHashMapNode */ + size_t buckets_size; + size_t buckets_capacity; +} TslHashMap; + +void tsl_hash_map_init(TslHashMap *self); + +int tsl_hash_map_insert(TslHashMap *self, const TslValue *key, TslValue *value); +/* + Get a reference to the value by key @key, or NULL if it doesn't exist. + The returned pointer is only valid until until reallocation after after insert inserting a new value into the hash map. +*/ +TslValue* tsl_hash_map_get(TslHashMap *self, const TslValue *key); +/* + Get a reference to the value by key @key, or insert a new value for the key (a TslValue). + Returns NULL on failure. + The returned pointer is only valid until until reallocation after after insert inserting a new value into the hash map. +*/ +TslValue* tsl_hash_map_get_or_create(TslHashMap *self, const TslValue *key); + +#endif /* TSL_HASH_MAP_H */ diff --git a/include/string_view.h b/include/string_view.h new file mode 100644 index 0000000..1209c1a --- /dev/null +++ b/include/string_view.h @@ -0,0 +1,11 @@ +#ifndef TSL_STRING_VIEW_H +#define TSL_STRING_VIEW_H + +#include + +typedef struct { + char *data; + size_t size; +} TslStringView; + +#endif /* TSL_STRING_VIEW_H */ diff --git a/include/tokenizer.h b/include/tokenizer.h index 2e7d42b..875396a 100644 --- a/include/tokenizer.h +++ b/include/tokenizer.h @@ -1,7 +1,7 @@ #ifndef TSL_TOKENIZER_H #define TSL_TOKENIZER_H -#include "std/string_view.h" +#include "string_view.h" typedef enum { TSL_TOKEN_END_OF_FILE, @@ -38,7 +38,7 @@ typedef struct { } TslTokenizerPeek; typedef struct { - const char *code; + char *code; size_t code_size; size_t code_index; size_t prev_code_index; @@ -52,7 +52,7 @@ typedef struct { char arithmetic_symbol; } TslTokenizer; -void tsl_tokenizer_init(TslTokenizer *self, const char *code, size_t code_size); +void tsl_tokenizer_init(TslTokenizer *self, char *code, size_t code_size); TslToken tsl_tokenizer_next(TslTokenizer *self); int tsl_tokenizer_accept(TslTokenizer *self, TslToken expected_token); diff --git a/include/value.h b/include/value.h index 58e57fe..e26cc4a 100644 --- a/include/value.h +++ b/include/value.h @@ -3,11 +3,13 @@ #include #include +#include "string_view.h" typedef enum { TSL_TYPE_NULL, TSL_TYPE_NUMBER, TSL_TYPE_STRING, + TSL_TYPE_STRING_VIEW, TSL_TYPE_BOOL, TSL_TYPE_LIST, TSL_TYPE_MAP, @@ -23,13 +25,14 @@ typedef enum { } TslBool; typedef struct { - char *data; + uint8_t *data; size_t size; } TslString; /* TODO: Implement this */ typedef struct { void *data; + size_t size; } TslList; /* TODO: Implement this */ @@ -41,6 +44,7 @@ typedef struct { union { TslNumber number; TslString *string; + TslStringView string_view; TslBool boolean; TslList *list; TslMap *map; @@ -49,4 +53,8 @@ typedef struct { uint8_t type; } TslValue; +uint64_t tsl_value_hash(const TslValue *value); +/* Returns 1 if equal, otherwise returns 0 */ +int tsl_value_equals(const TslValue *lhs, const TslValue *rhs); + #endif /* TSL_VALUE_H */ -- cgit v1.2.3