aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--include/program.h7
-rw-r--r--include/value.h5
-rw-r--r--src/parser.c13
-rw-r--r--src/program.c31
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 <stdio.h>
+#include <assert.h>
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;
}