From 43ff02231117bacb3cd60af0e654a0b3e8b5678b Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 23 Jan 2020 07:05:01 +0100 Subject: wip... there is a crash in get_or_create hash map --- README.md | 3 ++- include/program.h | 7 ++++++- include/value.h | 5 ++++- src/parser.c | 13 ------------- src/program.c | 31 +++++++++++++++++++++++++++++++ 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index bbf1212..3077b8f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ A tiny scripting language that is designed to be a replacement for small shell/python scripts.\ -Written in ANSI C to allow embedding everywhere and a WTFPL license that allows it to be used anywhere without any restrictions. +Written in ANSI C to allow embedding everywhere and a WTFPL license that allows it to be used anywhere without any restrictions.\ +See example.tsl for an example of what tsl looks like. # TODO * Remove dependency on `gc`. Write our own gc instead. * Implement big int, which numbers should automatically switch to when they are too large to fit into double. diff --git a/include/program.h b/include/program.h index 6135726..c097c7b 100644 --- a/include/program.h +++ b/include/program.h @@ -3,10 +3,15 @@ #include "std/buffer.h" #include "std/hash_map.h" +#include "value.h" + +#define TSL_STACK_MAX_SIZE 255 typedef struct { TslBuffer /*TslBytecode*/ function_bytecode_list; - TslHashMap variables; + TslHashMap /*TslStringView, TslValue*/ variables; + TslValue stack_values[TSL_STACK_MAX_SIZE]; + size_t stack_index; } TslProgram; typedef enum { diff --git a/include/value.h b/include/value.h index 1d053b7..58e57fe 100644 --- a/include/value.h +++ b/include/value.h @@ -14,6 +14,9 @@ typedef enum { TSL_TYPE_USERDATA } TslType; +/* TODO: Support BigInt */ +typedef double TslNumber; + typedef enum { TSL_FALSE, TSL_TRUE @@ -36,7 +39,7 @@ typedef struct { typedef struct { union { - double number; + TslNumber number; TslString *string; TslBool boolean; TslList *list; diff --git a/src/parser.c b/src/parser.c index 608f670..098962a 100644 --- a/src/parser.c +++ b/src/parser.c @@ -65,19 +65,6 @@ static void tsl_parser_pop_function(TslParser *self) { tsl_buffer_pop(&self->function_bytecode_list_index, sizeof(int)); } -#if 0 -static uint64_t hash_string_view(const void *data, size_t size) { - uint64_t result = 0xdec05eba; - const uint8_t *p = data; - while(size) { - result = ((result << 5) + result) + *p; - ++p; - --size; - } - return result; -} -#endif - static TslParseResult tsl_parser_parse_map(TslParser *self, int *num_items) { #define parse_map_element_separator \ return_if_error(tsl_tokenizer_accept(&self->tokenizer, TSL_TOKEN_COLON)); \ diff --git a/src/program.c b/src/program.c index 862931a..3ec6f85 100644 --- a/src/program.c +++ b/src/program.c @@ -1,10 +1,12 @@ #include "../include/program.h" #include "../include/bytecode.h" #include +#include void tsl_program_init(TslProgram *self) { tsl_buffer_init(&self->function_bytecode_list); tsl_hash_map_init(&self->variables); + self->stack_index = 0; } void tsl_program_deinit(TslProgram *self) { @@ -18,7 +20,27 @@ void tsl_program_deinit(TslProgram *self) { tsl_hash_map_deinit(&self->variables); } +static uint64_t hash_string_view(const void *data, size_t size) { + uint64_t result = 0xdec05eba; + const uint8_t *p = data; + while(size) { + result = ((result << 5) + result) + *p; + ++p; + --size; + } + return result; +} + TslProgramResult tsl_program_run(TslProgram *self) { + #define push(value, type_enum, value_field) \ + do { \ + if(self->stack_index == TSL_STACK_MAX_SIZE) \ + return TSL_PROGRAM_RESULT_ERR; \ + self->stack_values[self->stack_index].data.value_field = (value); \ + self->stack_values[self->stack_index].type = (type_enum); \ + ++self->stack_index; \ + } while(0) + TslBytecode *file_scope_bytecode = tsl_buffer_begin(&self->function_bytecode_list); char *instruction = tsl_buffer_begin(&file_scope_bytecode->buffer); char *instruction_end = tsl_buffer_end(&file_scope_bytecode->buffer); @@ -33,11 +55,13 @@ TslProgramResult tsl_program_run(TslProgram *self) { switch(opcode) { case TSL_OPCODE_LOADN: { printf("loadn %f\n", instruction_type2->value); + push(instruction_type2->value, TSL_TYPE_NUMBER, number); instruction += sizeof(TslInstructionType2); break; } case TSL_OPCODE_LOADB: { printf("loadb %s\n", instruction_type3->value ? "true" : "false"); + push(instruction_type3->value, TSL_TYPE_BOOL, boolean); instruction += sizeof(TslInstructionType3); break; } @@ -62,7 +86,14 @@ TslProgramResult tsl_program_run(TslProgram *self) { break; } case TSL_OPCODE_SETV: { + TslValue stack_value; + TslValue *value; printf("setv \"%.*s\"\n", (int)instruction_type4->value.size, instruction_type4->value.data); + assert(self->stack_index > 0); + stack_value = self->stack_values[--self->stack_index]; + if(!tsl_hash_map_get_or_create(&self->variables, &instruction_type4->value, sizeof(TslValue), hash_string_view, (void**)&value)) + return TSL_PROGRAM_RESULT_ERR; + *value = stack_value; instruction += sizeof(TslInstructionType4); break; } -- cgit v1.2.3