From e7c8a04078261b331b00490ffbffd9ff05d1e0d0 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 22 Jul 2020 23:49:52 +0200 Subject: Add variable to list value and map key --- Makefile | 3 ++- README.md | 6 +++++- example.tsl | 13 +++++++++++-- src/bytecode.c | 2 +- src/parser.c | 22 ++++++++++++++++------ 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 095856f..505778f 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ CFLAGS = -Wall -Wextra -Werror -g3 -std=c89 -pedantic -fPIE -DDEBUG +#CFLAGS = -O3 -flto -static -s LIBS = -lgc OBJ = build/main.o build/tokenizer.o build/parser.o build/program.o build/bytecode.o build/value.o build/command.o build/buffer.o build/hash_map.o build/list.o CC = cc @@ -16,7 +17,7 @@ compiledb: make clean; bear make install: build - install -m +x -s build/tsl /usr/local/bin/tsl + install -Dm755 build/tsl /usr/local/bin/tsl build/main.o: src/main.c include/tokenizer.h $(CC) -c src/main.c -o build/main.o $(CFLAGS) diff --git a/README.md b/README.md index 1426b2e..df43dc2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ +# tsl 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.\ -See example.tsl for an example of what tsl looks like. +See example.tsl for an example of what tsl looks like.\ +The language and implementation is designed to be very simple. + +** Note: tsl is not usable yet ** # Installation Run: `sudo make install`. The tsl binary will be installed in /usr/bin/local. # TODO diff --git a/example.tsl b/example.tsl index eb92e0e..861db41 100755 --- a/example.tsl +++ b/example.tsl @@ -41,9 +41,10 @@ list_index_value = value5[0] # loadn 1 # loadn 2 -# list 2 +# loadv "list_index_value" +# list 3 # setv "list1" -list1 = [1, 2] +list1 = [1, 2, list_index_value] # loadn 3 # loadn 4 @@ -65,6 +66,14 @@ list3 = list1 + list2 # setv "value6" value6 = {"hello": "world", "value": 23} +# loads "hello" +# loads "world" +# loads "value" +# loadn 23 +# map 4 +# setv "value6_1" +value6_1 = {hello: "world", value: 23} + # loadf 1 // loadf1 begins at once, because the file body itself is function 0 # setv "value7" value7 = fn () {} diff --git a/src/bytecode.c b/src/bytecode.c index b7c0364..9cf32a6 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -44,7 +44,7 @@ int tsl_bytecode_add_ins2(TslBytecode *self, TslOpcode opcode, double value) { TslInstructionType2 instruction; instruction.opcode = opcode; instruction.value = value; - fprintf(stderr, "%s %f\n", tsl_opcode_to_string(opcode), value); + fprintf(stderr, "%s %g\n", tsl_opcode_to_string(opcode), value); return tsl_buffer_append(&self->buffer, &instruction, sizeof(instruction)); } diff --git a/src/parser.c b/src/parser.c index e7fa99c..0c46f42 100644 --- a/src/parser.c +++ b/src/parser.c @@ -83,7 +83,17 @@ static TslParseResult tsl_parser_parse_map(TslParser *self, int *num_items) { *num_items = 0; for(;;) { TslToken token = tsl_tokenizer_next(&self->tokenizer); - if(token == TSL_TOKEN_NUM) { + if(token == TSL_TOKEN_STRING) { + ++*num_items; + return_if_error(tsl_bytecode_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADS, &self->tokenizer.string)); + parse_map_element_separator + } else if(token == TSL_TOKEN_IDENTIFIER) { + /* Use the identifier as a key for the map. This is not a variable, but a key (string) without spaces */ + /* This allows syntax like: variable = { key: "value" } */ + ++*num_items; + return_if_error(tsl_bytecode_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADS, &self->tokenizer.identifier)); + parse_map_element_separator + } else if(token == TSL_TOKEN_NUM) { ++*num_items; return_if_error(tsl_bytecode_add_ins2(get_function_bytecode(self), TSL_OPCODE_LOADN, self->tokenizer.number_value)); parse_map_element_separator @@ -95,10 +105,6 @@ static TslParseResult tsl_parser_parse_map(TslParser *self, int *num_items) { ++*num_items; return_if_error(tsl_bytecode_add_ins5(get_function_bytecode(self), TSL_OPCODE_LOADNULL)); parse_map_element_separator - } else if(token == TSL_TOKEN_STRING) { - ++*num_items; - return_if_error(tsl_bytecode_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADS, &self->tokenizer.string)); - parse_map_element_separator } else if(token == TSL_TOKEN_RBRACE) { /* '}' after trailing ',' or an empty map */ return TSL_PARSE_RESULT_OK; @@ -125,7 +131,11 @@ static TslParseResult tsl_parser_parse_list(TslParser *self, int *num_items) { for(;;) { /* TODO: Use tsl_parser_parse_rhs instead */ TslToken token = tsl_tokenizer_next(&self->tokenizer); - if(token == TSL_TOKEN_NUM) { + if(token == TSL_TOKEN_IDENTIFIER) { + ++*num_items; + return_if_error(tsl_bytecode_add_ins4(get_function_bytecode(self), TSL_OPCODE_LOADV, &self->tokenizer.identifier)); + parse_list_element_separator + } else if(token == TSL_TOKEN_NUM) { ++*num_items; return_if_error(tsl_bytecode_add_ins2(get_function_bytecode(self), TSL_OPCODE_LOADN, self->tokenizer.number_value)); parse_list_element_separator -- cgit v1.2.3