diff options
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 72 |
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 { |