aboutsummaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/src/parser.c b/src/parser.c
index 35a4abb..90c5a24 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -9,7 +9,74 @@ static void tsl_parser_init(TslParser *self, const char *code, size_t code_size)
tsl_tokenizer_init(&self->tokenizer, code, code_size);
}
+typedef enum {
+ MAP_TYPE_UNKNOWN,
+ MAP_TYPE_LIST,
+ MAP_TYPE_MAP
+} MapType;
+
+static int tsl_parser_parse_map(TslParser *self) {
+ MapType map_type = MAP_TYPE_UNKNOWN;
+ for(;;) {
+ TslToken token = tsl_tokenizer_next(&self->tokenizer);
+ if(token == TSL_TOKEN_NUM) {
+ printf("rhs num: %ld\n", self->tokenizer.number_value);
+ } else if(token == TSL_TOKEN_BOOL) {
+ printf("rhs bool: %s\n", self->tokenizer.bool_value ? "true" : "false");
+ } else if(token == TSL_TOKEN_NULL) {
+ printf("rhs null\n");
+ } else if(token == TSL_TOKEN_STRING) {
+ printf("rhs string: |%.*s|\n", self->tokenizer.string.size, self->tokenizer.string.data);
+ token = tsl_tokenizer_next(&self->tokenizer);
+ if(token == TSL_TOKEN_COMMA) {
+ if(map_type == MAP_TYPE_MAP) {
+ /* TODO: Show which lines have mismatching element types */
+ fprintf(stderr, "Error: You can't mix list elements and map elements in the same map\n");
+ return -1;
+ }
+ map_type = MAP_TYPE_LIST;
+ } else if(token == TSL_TOKEN_COLON) {
+ if(map_type == MAP_TYPE_LIST) {
+ /* TODO: Show which lines have mismatching element types */
+ fprintf(stderr, "Error: You can't mix list elements and map elements in the same map\n");
+ return -1;
+ }
+ map_type = MAP_TYPE_LIST;
+ } else if(token == TSL_TOKEN_RBRACE) {
+ if(map_type == MAP_TYPE_MAP) {
+ /* TODO: Show why ':' is needed (because other elements in the map are map types) */
+ fprintf(stderr, "Error: Expected ':', got '}'\n");
+ return -1;
+ }
+ return 0;
+ } else {
+ /* TODO: Show only "expects '}' when not using key-value pair" */
+ fprintf(stderr, "Error: Expected ',', ':' or '}', got TODO\n");
+ return -1;
+ }
+ } else if(token == TSL_TOKEN_RBRACE) {
+ return 0;
+ } else {
+ fprintf(stderr, "Error: Expected '}', got TODO\n");
+ return -1;
+ }
+ }
+}
+
static int tsl_parser_parse_rhs(TslParser *self) {
+ TslToken token = tsl_tokenizer_next(&self->tokenizer);
+ if(token == TSL_TOKEN_NUM) {
+ printf("rhs num: %ld\n", self->tokenizer.number_value);
+ } else if(token == TSL_TOKEN_BOOL) {
+ printf("rhs bool: %s\n", self->tokenizer.bool_value ? "true" : "false");
+ } else if(token == TSL_TOKEN_NULL) {
+ printf("rhs null\n");
+ } else if(token == TSL_TOKEN_STRING) {
+ printf("rhs string: |%.*s|\n", self->tokenizer.string.size, self->tokenizer.string.data);
+ } else {
+ fprintf(stderr, "Error: Expected number, bool or null, got TODO\n");
+ return -1;
+ }
return 0;
}
@@ -18,10 +85,13 @@ static int tsl_parser_parse(TslParser *self) {
TslToken token = tsl_tokenizer_next(&self->tokenizer);
if(token == TSL_TOKEN_IDENTIFIER) {
TslStringView identifier = self->tokenizer.identifier;
+ printf("identifier: %.*s\n", identifier.size, identifier.data);
if(!tsl_tokenizer_accept(&self->tokenizer, TSL_TOKEN_EQUAL)) {
return -1;
}
- tsl_parser_parse_rhs(self);
+ if(tsl_parser_parse_rhs(self) != 0) {
+ return -1;
+ }
} else if(token == TSL_TOKEN_END_OF_FILE) {
break;
} else {