#include "../include/parser.h" #include typedef struct { TslTokenizer tokenizer; } TslParser; 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; } static int tsl_parser_parse(TslParser *self) { for(;;) { 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; } if(tsl_parser_parse_rhs(self) != 0) { return -1; } } else if(token == TSL_TOKEN_END_OF_FILE) { break; } else { fprintf(stderr, "Error: Expected identifier, got TODO\n"); return -1; } } return 0; } int tsl_parse(const char *code, size_t code_size) { TslParser parser; tsl_parser_init(&parser, code, code_size); return tsl_parser_parse(&parser); }