diff --git a/src/parser/assignable/assign/assign.c b/src/parser/assignable/assign/assign.c index 7e5c9a2..1423892 100644 --- a/src/parser/assignable/assign/assign.c +++ b/src/parser/assignable/assign/assign.c @@ -7,8 +7,8 @@ #include #include -ParsedValue *parse_assign(char *file, DArray *tokens, ParsedValue *assign_to, - size_t *index) { +ParsedValueReturn parse_assign(char *file, DArray *tokens, + ParsedValue *assign_to, size_t *index) { Token *token = darray_get(tokens, *index); switch (assign_to->type) { case AST_IDENTIFIER: @@ -24,6 +24,7 @@ ParsedValue *parse_assign(char *file, DArray *tokens, ParsedValue *assign_to, "only use letters, digits, or _, and can't be keywords.\n", file, token->line, token->column); exit(EXIT_FAILURE); + } } break; @@ -35,19 +36,25 @@ ParsedValue *parse_assign(char *file, DArray *tokens, ParsedValue *assign_to, ParsedAssign *assign = checked_malloc(sizeof(ParsedAssign)); assign->to = assign_to; assign->type = token->type; + ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); + parsedValue->type = AST_ASSIGN; + parsedValue->data = assign; (*index)++; error_if_finished(file, tokens, index); token = darray_get(tokens, *index); - assign->from = parse_token(file, tokens, index, true); + ParsedValueReturn from = parse_token(file, tokens, index, true); + if (from.err.exists) { + free_parsed(parsedValue); + free(parsedValue); + return from; + } + assign->from = from.value; if (!assign->from) { fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line, token->column); exit(EXIT_FAILURE); } - ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); - parsedValue->type = AST_ASSIGN; - parsedValue->data = assign; - return parsedValue; + return (ParsedValueReturn){no_err, parsedValue}; } void free_parse_assign(void *ptr) { diff --git a/src/parser/assignable/assign/assign.h b/src/parser/assignable/assign/assign.h index 57c7e9f..f4b62a6 100644 --- a/src/parser/assignable/assign/assign.h +++ b/src/parser/assignable/assign/assign.h @@ -9,8 +9,8 @@ typedef struct { ParsedValue * from; } ParsedAssign; -ParsedValue *parse_assign(char*file, DArray *tokens, - ParsedValue *assign_to, size_t *index); +ParsedValueReturn parse_assign(char *file, DArray *tokens, ParsedValue *assign_to, + size_t *index); void free_parse_assign(void*ptr); diff --git a/src/parser/assignable/identifier/identifier.c b/src/parser/assignable/identifier/identifier.c index 88c4aec..347fef9 100644 --- a/src/parser/assignable/identifier/identifier.c +++ b/src/parser/assignable/identifier/identifier.c @@ -4,9 +4,9 @@ #include #include "../../../memory.h" -ParsedValue *parse_identifier(Token *token) { +ParsedValueReturn parse_identifier(Token *token) { ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); parsedValue->type = AST_IDENTIFIER; parsedValue->data = strcpy(checked_malloc(strlen(token->value) + 1), token->value); - return parsedValue; + return (ParsedValueReturn){no_err, parsedValue}; } \ No newline at end of file diff --git a/src/parser/assignable/identifier/identifier.h b/src/parser/assignable/identifier/identifier.h index 6cbaf49..26f064e 100644 --- a/src/parser/assignable/identifier/identifier.h +++ b/src/parser/assignable/identifier/identifier.h @@ -4,6 +4,6 @@ #include "../../../lexer/token.h" // for Token // Function declaration for parsing an identifier -ParsedValue * parse_identifier(Token * token); +ParsedValueReturn parse_identifier(Token *token); #endif // IDENTIFIER_H \ No newline at end of file diff --git a/src/parser/declaration/declaration.c b/src/parser/declaration/declaration.c index 27431ba..d43272e 100644 --- a/src/parser/declaration/declaration.c +++ b/src/parser/declaration/declaration.c @@ -1,6 +1,6 @@ #include "declaration.h" -#include "../../hashmap/hashmap.h" #include "../../hash_data/hash_data.h" +#include "../../hashmap/hashmap.h" #include "../../lexer/token.h" #include "../../memory.h" #include "../function/function.h" @@ -10,7 +10,7 @@ #include #include -ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) { +ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index) { (*index)++; error_if_finished(file, tokens, index); Token *token = darray_get(tokens, *index); @@ -30,16 +30,19 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) { declaration->from = parse_null(); if (token->type != TOKEN_IDENTIFIER) { - fprintf(stderr, "%s:%zu:%zu error: declaration requires an identifier\n", - file, token->line, token->column); - exit(EXIT_FAILURE); + free_parsed(parsedValue); + free(parsedValue); + return (ParsedValueReturn){ + create_err(token->line, token->column, token->length, file, + "Syntax Error", "declaration requires an identifier"), + NULL}; } declaration->name = strcpy(checked_malloc(strlen(token->value) + 1), token->value); (*index)++; if ((*index) >= tokens->size) - return parsedValue; + return (ParsedValueReturn){no_err, parsedValue}; token = darray_get(tokens, *index); if (token->type == TOKEN_LPAREN) { isFunction = true; @@ -51,7 +54,7 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) { if (token->type == TOKEN_RPAREN) { (*index)++; if ((*index) >= tokens->size) - return parsedValue; + return (ParsedValueReturn){no_err, parsedValue}; token = darray_get(tokens, *index); } else { while ((*index) < tokens->size) { @@ -59,23 +62,32 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) { error_if_finished(file, tokens, index); token = darray_get(tokens, *index); if (token->type != TOKEN_IDENTIFIER) { - fprintf(stderr, - "%s:%zu:%zu error: parameter names need to start with a " - "letter or _, only use letters, digits, or _, and can't be " - "keywords.\n", - file, token->line, token->column); - exit(EXIT_FAILURE); + free_parsed(parsedValue); + free(parsedValue); + return (ParsedValueReturn){ + create_err( + token->line, token->column, token->length, file, + "Syntax Error", + "parameter names need to start with a letter or _, only " + "use letters, digits, or _, and can't be keywords."), + NULL}; } - uint64_t hash = siphash64_bytes(token->value, token->length, siphash_key); + uint64_t hash = + siphash64_bytes(token->value, token->length, siphash_key); if (hashmap_lookup(parameters_hashmap, hash) != NULL) { - fprintf(stderr, - "%s:%zu:%zu error: duplicate argument '%.*s' in function definition\n", - file, token->line, token->column, (int)token->length, token->value); - exit(EXIT_FAILURE); + free_parsed(parsedValue); + free(parsedValue); + return (ParsedValueReturn){ + create_err(token->line, token->column, token->length, file, + "Syntax Error", + "duplicate argument in function " + "definition"), + NULL}; } char *parameter_name = checked_malloc(token->length + 1); strcpy(parameter_name, token->value); - hashmap_insert(parameters_hashmap, hash, parameter_name, (void*)1, 0); + hashmap_insert(parameters_hashmap, hash, parameter_name, (void *)1, + 0); darray_push(¶meters, ¶meter_name); (*index)++; error_if_finished(file, tokens, index); @@ -85,18 +97,22 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) { if (token->type == TOKEN_RPAREN) { (*index)++; if ((*index) >= tokens->size) - return parsedValue; + return (ParsedValueReturn){no_err, parsedValue}; token = darray_get(tokens, *index); break; } else if (token->type != TOKEN_COMMA) { - fprintf(stderr, "%s:%zu:%zu error: expected comma\n", file, - token->line, token->column); - exit(EXIT_FAILURE); + free_parsed(parsedValue); + free(parsedValue); + return (ParsedValueReturn){ + create_err(token->line, token->column, token->length, file, + "Syntax Error", "expected comma"), + NULL}; } (*index)++; error_if_finished(file, tokens, index); } } + hashmap_free(parameters_hashmap, NULL); } if (token->type == TOKEN_ASSIGN) { (*index)++; @@ -104,11 +120,20 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) { free(declaration->from); - declaration->from = parse_token(file, tokens, index, true); + ParsedValueReturn from = parse_token(file, tokens, index, true); + if (from.err.exists) { + free_parsed(parsedValue); + free(parsedValue); + return from; + } + declaration->from = from.value; if (!declaration->from) { - fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line, - token->column); - exit(EXIT_FAILURE); + free_parsed(parsedValue); + free(parsedValue); + return (ParsedValueReturn){create_err(token->line, token->column, + token->length, file, + "Syntax Error", "expected body"), + NULL}; } } if (isFunction) { @@ -133,7 +158,7 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) { error_if_finished(file, tokens, index); token = darray_get(tokens, *index); } - return parsedValue; + return (ParsedValueReturn){no_err, parsedValue}; } void free_string(void *ptr) { @@ -144,9 +169,12 @@ void free_string(void *ptr) { void free_single_declaration(void *ptr) { ParsedSingleDeclaration *declaration = ptr; - free(declaration->name); - free_parsed(declaration->from); - free(declaration->from); + if (declaration->name) + free(declaration->name); + if (declaration->from) { + free_parsed(declaration->from); + free(declaration->from); + } } void free_declaration(void *ptr) { diff --git a/src/parser/declaration/declaration.h b/src/parser/declaration/declaration.h index a8eb9dc..39ceab2 100644 --- a/src/parser/declaration/declaration.h +++ b/src/parser/declaration/declaration.h @@ -9,8 +9,7 @@ typedef struct { } ParsedSingleDeclaration; // Function declaration for parsing an identifier -ParsedValue *parse_declaration(char *file, DArray *tokens, - size_t *index); +ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index); void free_declaration(void *ptr); diff --git a/src/parser/dictionary/dictionary.c b/src/parser/dictionary/dictionary.c index 0d2e862..142729c 100644 --- a/src/parser/dictionary/dictionary.c +++ b/src/parser/dictionary/dictionary.c @@ -7,7 +7,7 @@ #include #include -ParsedValue *parse_dictionary(char *file, DArray *tokens, size_t *index) { +ParsedValueReturn parse_dictionary(char *file, DArray *tokens, size_t *index) { ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); parsedValue->type = AST_DICTIONARY; DArray *dictionary = checked_malloc(sizeof(DArray)); @@ -23,17 +23,29 @@ ParsedValue *parse_dictionary(char *file, DArray *tokens, size_t *index) { error_if_finished(file, tokens, index); size_t keyIndex = *index; Token *keyToken = darray_get(tokens, *index); - ParsedValue *key; + ParsedValueReturn key; if (keyToken->type == TOKEN_IDENTIFIER) { (*index)++; key = parse_string(keyToken, false); } else { key = parse_token(file, tokens, index, true); } + if (key.err.exists) { + free_parsed(parsedValue); + free(parsedValue); + return key; + } else if (!key.value) { + free_parsed(parsedValue); + free(parsedValue); + return (ParsedValueReturn){create_err(token->line, token->column, + token->length, file, + "Syntax Error", "expected key"), + NULL}; + } skip_newlines_and_indents(tokens, index); error_if_finished(file, tokens, index); token = darray_get(tokens, *index); - ParsedValue *value; + ParsedValueReturn value; bool tobreak = false; switch (token->type) { case TOKEN_COLON: @@ -41,6 +53,22 @@ ParsedValue *parse_dictionary(char *file, DArray *tokens, size_t *index) { skip_newlines_and_indents(tokens, index); error_if_finished(file, tokens, index); value = parse_token(file, tokens, index, true); + if (value.err.exists) { + free_parsed(parsedValue); + free(parsedValue); + free_parsed(key.value); + free(key.value); + return value; + } else if (!value.value) { + free_parsed(parsedValue); + free(parsedValue); + free_parsed(key.value); + free(key.value); + return (ParsedValueReturn){ + create_err(token->line, token->column, token->length, file, + "Syntax Error", "expected value"), + NULL}; + } skip_newlines_and_indents(tokens, index); error_if_finished(file, tokens, index); token = darray_get(tokens, *index); @@ -63,7 +91,7 @@ ParsedValue *parse_dictionary(char *file, DArray *tokens, size_t *index) { token->column); exit(EXIT_FAILURE); } - ParsedDictionaryEntry entry = {key, value}; + ParsedDictionaryEntry entry = {key.value, value.value}; darray_push(dictionary, &entry); if (tobreak) { break; @@ -73,7 +101,7 @@ ParsedValue *parse_dictionary(char *file, DArray *tokens, size_t *index) { } } (*index)++; - return parsedValue; + return (ParsedValueReturn){no_err, parsedValue}; } void free_dictionary_entry(void *ptr) { diff --git a/src/parser/dictionary/dictionary.h b/src/parser/dictionary/dictionary.h index 9fe3a07..4d7188e 100644 --- a/src/parser/dictionary/dictionary.h +++ b/src/parser/dictionary/dictionary.h @@ -8,8 +8,7 @@ typedef struct { ParsedValue * value; } ParsedDictionaryEntry; -ParsedValue *parse_dictionary(char *file, DArray *tokens, - size_t *index); +ParsedValueReturn parse_dictionary(char *file, DArray *tokens, size_t *index); void free_parsed_dictionary(void *ptr); diff --git a/src/parser/dowrap/dowrap.c b/src/parser/dowrap/dowrap.c index 6de7101..e920a57 100644 --- a/src/parser/dowrap/dowrap.c +++ b/src/parser/dowrap/dowrap.c @@ -24,7 +24,7 @@ void free_string_dowrap(void *ptr) { free(str); } -ParsedValue *parse_dowrap(char *file, DArray *tokens, size_t *index) { +ParsedValueReturn parse_dowrap(char *file, DArray *tokens, size_t *index) { ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); parsedValue->type = AST_DOWRAP; DArray *dowrap_parsed = checked_malloc(sizeof(DArray)); @@ -32,9 +32,13 @@ ParsedValue *parse_dowrap(char *file, DArray *tokens, size_t *index) { parsedValue->data = dowrap_parsed; (*index)++; if ((*index) >= tokens->size) - return parsedValue; + return (ParsedValueReturn){no_err, parsedValue}; Token *token = darray_get(tokens, *index); if (token->type != TOKEN_NEW_LINE) { + return (ParsedValueReturn){create_err(token->line, token->column, + token->length, file, "Syntax Error", + "expected body"), + NULL}; fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line, token->column); exit(EXIT_FAILURE); @@ -74,7 +78,7 @@ ParsedValue *parse_dowrap(char *file, DArray *tokens, size_t *index) { break; } if (temp_indent_depth > indent_depth) { - size_t indent_amount = temp_indent_depth-indent_depth; + size_t indent_amount = temp_indent_depth - indent_depth; Token indent_token; indent_token.line = token->line; indent_token.column = token->column; @@ -85,21 +89,27 @@ ParsedValue *parse_dowrap(char *file, DArray *tokens, size_t *index) { } temp_indent_depth_toggle = false; temp_indent_depth = 0; - temp_index_count=0; + temp_index_count = 0; darray_push(&dowrap_tokens, token); } } - (*index)-=temp_index_count; - for (size_t i = 0; i #include #include diff --git a/src/parser/if/if.c b/src/parser/if/if.c index 48b5093..162b909 100644 --- a/src/parser/if/if.c +++ b/src/parser/if/if.c @@ -6,7 +6,17 @@ #include #include -ParsedValue *parse_if(char *file, DArray *tokens, size_t *index) { +void free_conditional(void *ptr) { + ParsedConditional *conditional = ptr; + if (conditional->condition) { + free_parsed(conditional->condition); + free(conditional->condition); + } + free_parsed(conditional->content); + free(conditional->content); +} + +ParsedValueReturn parse_if(char *file, DArray *tokens, size_t *index) { (*index)++; error_if_finished(file, tokens, index); @@ -35,28 +45,50 @@ ParsedValue *parse_if(char *file, DArray *tokens, size_t *index) { } } - ParsedValue *condition = NULL; + ParsedValueReturn condition = {no_err, NULL}; if (token->type != TOKEN_ELSE) { // Parse ( condition ) token = darray_get(tokens, *index); if (token->type != TOKEN_LPAREN) { - fprintf(stderr, "%s:%zu:%zu error: expected '(' after if\n", file, - token->line, token->column); - exit(EXIT_FAILURE); + darray_free(parsed_if, free_conditional); + free(parsed_if); + return (ParsedValueReturn){ + create_err(token->line, token->column, token->length, file, + "Syntax Error", "expected '(' after if"), + NULL}; } (*index)++; error_if_finished(file, tokens, index); skip_newlines_and_indents(tokens, index); condition = parse_token(file, tokens, index, true); + if (condition.err.exists) { + darray_free(parsed_if, free_conditional); + free(parsed_if); + return condition; + } else if (!condition.value) { + darray_free(parsed_if, free_conditional); + free(parsed_if); + return (ParsedValueReturn){ + create_err(token->line, token->column, token->length, file, + "Syntax Error", "expected condition"), + NULL}; + } skip_newlines_and_indents(tokens, index); token = darray_get(tokens, *index); if (token->type != TOKEN_RPAREN) { - fprintf(stderr, "%s:%zu:%zu error: missing closing ')' in condition\n", - file, token->line, token->column); - exit(EXIT_FAILURE); + if (condition.value) { + free_parsed(condition.value); + free(condition.value); + } + darray_free(parsed_if, free_conditional); + free(parsed_if); + return (ParsedValueReturn){ + create_err(token->line, token->column, token->length, file, + "Syntax Error", "missing closing ')' in condition"), + NULL}; } (*index)++; @@ -64,15 +96,32 @@ ParsedValue *parse_if(char *file, DArray *tokens, size_t *index) { } // Parse the body - ParsedValue *parsed_content = parse_token(file, tokens, index, false); + ParsedValueReturn parsed_content = parse_token(file, tokens, index, false); - if (!parsed_content) { - fprintf(stderr, "%s:%zu:%zu error: expected body after condition\n", file, - token->line, token->column); - exit(EXIT_FAILURE); + if (parsed_content.err.exists) { + if (condition.value) { + free_parsed(condition.value); + free(condition.value); + } + darray_free(parsed_if, free_conditional); + free(parsed_if); + return parsed_content; } - ParsedConditional conditional = {condition, parsed_content}; + if (!parsed_content.value) { + if (condition.value) { + free_parsed(condition.value); + free(condition.value); + } + darray_free(parsed_if, free_conditional); + free(parsed_if); + return (ParsedValueReturn){create_err(token->line, token->column, + token->length, file, "Syntax Error", + "expected body"), + NULL}; + } + + ParsedConditional conditional = {condition.value, parsed_content.value}; darray_push(parsed_if, &conditional); expect_conditional = @@ -98,17 +147,7 @@ ParsedValue *parse_if(char *file, DArray *tokens, size_t *index) { // printf(" - content value type: %d\n", cond->content->type); // } - return parsedValue; -} - -void free_conditional(void *ptr) { - ParsedConditional *conditional = ptr; - if (conditional->condition) { - free_parsed(conditional->condition); - free(conditional->condition); - } - free_parsed(conditional->content); - free(conditional->content); + return (ParsedValueReturn){no_err, parsedValue}; } void free_parsed_if(void *ptr) { diff --git a/src/parser/if/if.h b/src/parser/if/if.h index 38ef858..344ca64 100644 --- a/src/parser/if/if.h +++ b/src/parser/if/if.h @@ -8,8 +8,7 @@ typedef struct { ParsedValue *content; } ParsedConditional; -ParsedValue *parse_if(char *file, DArray *tokens, - size_t *index); +ParsedValueReturn parse_if(char *file, DArray *tokens, size_t *index); void free_parsed_if(void *ptr); diff --git a/src/parser/list/list.c b/src/parser/list/list.c index 9dc0617..da695b7 100644 --- a/src/parser/list/list.c +++ b/src/parser/list/list.c @@ -6,7 +6,7 @@ #include #include -ParsedValue *parse_list(char *file, DArray *tokens, size_t *index) { +ParsedValueReturn parse_list(char *file, DArray *tokens, size_t *index) { ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); parsedValue->type = AST_LIST; DArray *list = checked_malloc(sizeof(DArray)); @@ -19,9 +19,14 @@ ParsedValue *parse_list(char *file, DArray *tokens, size_t *index) { if (token->type != TOKEN_RBRACKET) { while (true) { skip_newlines_and_indents(tokens, index); - ParsedValue *parsedValue = parse_token(file, tokens, index, true); - darray_push(list, parsedValue); - free(parsedValue); + ParsedValueReturn parsedItem = parse_token(file, tokens, index, true); + if (parsedItem.err.exists) { + free_parsed(parsedValue); + free(parsedValue); + return parsedItem; + } + darray_push(list, parsedItem.value); + free(parsedItem.value); error_if_finished(file, tokens, index); skip_newlines_and_indents(tokens, index); error_if_finished(file, tokens, index); @@ -38,7 +43,7 @@ ParsedValue *parse_list(char *file, DArray *tokens, size_t *index) { } } (*index)++; - return parsedValue; + return (ParsedValueReturn){no_err, parsedValue}; } void free_parsed_list(void *ptr) { diff --git a/src/parser/list/list.h b/src/parser/list/list.h index bd1524c..9bb8c21 100644 --- a/src/parser/list/list.h +++ b/src/parser/list/list.h @@ -3,8 +3,7 @@ #include "../../lexer/token.h" // for Token #include "../parser.h" -ParsedValue *parse_list(char *file, DArray *tokens, - size_t *index); +ParsedValueReturn parse_list(char *file, DArray *tokens, size_t *index); void free_parsed_list(void *ptr); diff --git a/src/parser/number/number.c b/src/parser/number/number.c index 69ccec2..4da45bf 100644 --- a/src/parser/number/number.c +++ b/src/parser/number/number.c @@ -150,9 +150,9 @@ // return 0; // } -ParsedValue *parse_number(Token *token) { +ParsedValueReturn parse_number(Token *token) { ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); parsedValue->type = AST_NUMBER; parsedValue->data = strdup(token->value); - return parsedValue; + return (ParsedValueReturn){no_err, parsedValue}; } \ No newline at end of file diff --git a/src/parser/number/number.h b/src/parser/number/number.h index 230291c..e1528c9 100644 --- a/src/parser/number/number.h +++ b/src/parser/number/number.h @@ -4,6 +4,6 @@ #include "../../lexer/token.h" // for Token // Function declaration for parsing an identifier -ParsedValue * parse_number(Token * token); +ParsedValueReturn parse_number(Token *token); #endif // NUMBER_H \ No newline at end of file diff --git a/src/parser/parser.c b/src/parser/parser.c index d6ff1c0..2faaba3 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -54,11 +54,11 @@ size_t skip_newlines_and_indents(DArray *tokens, size_t *index) { return count; } -ParsedValue *parse_token_full(char *file, DArray *tokens, size_t *index, - bool inline_flag, bool process_operations) { +ParsedValueReturn parse_token_full(char *file, DArray *tokens, size_t *index, + bool inline_flag, bool process_operations) { Token *token = darray_get(tokens, *index); - ParsedValue *output = NULL; + ParsedValueReturn output; if (!inline_flag) { switch (token->type) { @@ -71,15 +71,15 @@ ParsedValue *parse_token_full(char *file, DArray *tokens, size_t *index, switch (token->type) { case TOKEN_TRUE: (*index)++; - output = parse_true(); + output = (ParsedValueReturn){no_err, parse_true()}; break; case TOKEN_FALSE: (*index)++; - output = parse_false(); + output = (ParsedValueReturn){no_err, parse_false()}; break; case TOKEN_NULL: (*index)++; - output = parse_null(); + output = (ParsedValueReturn){no_err, parse_null()}; break; case TOKEN_STRING: (*index)++; @@ -87,18 +87,19 @@ ParsedValue *parse_token_full(char *file, DArray *tokens, size_t *index, break; case TOKEN_NEW_LINE: (*index)++; - return NULL; + return (ParsedValueReturn){no_err, NULL}; case TOKEN_INDENT: if (strlen(token->value) > 0 && (*index + 1) < tokens->size) { token = darray_get(tokens, (*index) + 1); if (token->type != TOKEN_NEW_LINE) { - fprintf(stderr, "%s:%zu:%zu error: invalid indentation\n", file, - token->line, token->column); - exit(EXIT_FAILURE); + return (ParsedValueReturn){ + create_err(token->line, token->column, token->length, file, + "Syntax Error", "unexpected indent"), + NULL}; } } (*index)++; - return NULL; + return (ParsedValueReturn){no_err, NULL}; case TOKEN_IDENTIFIER: (*index)++; output = parse_identifier(token); @@ -128,6 +129,9 @@ ParsedValue *parse_token_full(char *file, DArray *tokens, size_t *index, // LHS required bool passed = false; while (!passed && (*index) < tokens->size) { + if (output.err.exists) { + return output; + } token = darray_get(tokens, *index); switch (token->type) { case TOKEN_ASSIGN: @@ -138,18 +142,18 @@ ParsedValue *parse_token_full(char *file, DArray *tokens, size_t *index, case TOKEN_ASSIGN_PLUS: case TOKEN_ASSIGN_SLASH: case TOKEN_ASSIGN_STAR: - output = parse_assign(file, tokens, output, index); + output = parse_assign(file, tokens, output.value, index); break; case TOKEN_LPAREN: - output = parse_call(file, tokens, index, output); + output = parse_call(file, tokens, index, output.value); break; case TOKEN_DOT: case TOKEN_LBRACKET: - output = parse_access(file, tokens, index, output); + output = parse_access(file, tokens, index, output.value); break; SWITCH_OPERATIONS if (process_operations) { - output = parse_operations(file, tokens, index, output); + output = parse_operations(file, tokens, index, output.value); break; } /* fall through */ @@ -161,18 +165,21 @@ ParsedValue *parse_token_full(char *file, DArray *tokens, size_t *index, return output; } -ParsedValue *parse_token(char *file, DArray *tokens, size_t *index, - bool inline_flag) { +ParsedValueReturn parse_token(char *file, DArray *tokens, size_t *index, + bool inline_flag) { return parse_token_full(file, tokens, index, inline_flag, true); } -void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) { +ArErr parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) { size_t index = 0; bool expecting_new_line = false; while (index < tokens->size) { size_t old_index = index; - ParsedValue *parsed_code = parse_token(file, tokens, &index, inline_flag); - if (parsed_code) { + ParsedValueReturn parsed_code = + parse_token(file, tokens, &index, inline_flag); + if (parsed_code.err.exists) + return parsed_code.err; + else if (parsed_code.value) { if (expecting_new_line) { Token *token = darray_get(tokens, old_index); fprintf(stderr, "%s:%zu:%zu error: expected a new line\n", file, @@ -180,8 +187,8 @@ void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) { exit(EXIT_FAILURE); } expecting_new_line = true; - darray_push(parsed, parsed_code); - free(parsed_code); + darray_push(parsed, parsed_code.value); + free(parsed_code.value); } else { expecting_new_line = false; } diff --git a/src/parser/parser.h b/src/parser/parser.h index 551273a..13c3283 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -2,26 +2,28 @@ #define PARSER_H #include "../dynamic_array/darray.h" +#include "../err.h" #include #include -#define SWITCH_OPERATIONS case TOKEN_AND:\ -case TOKEN_OR:\ -case TOKEN_NOT_IN:\ -case TOKEN_IN:\ -case TOKEN_LE:\ -case TOKEN_GE:\ -case TOKEN_LT:\ -case TOKEN_GT:\ -case TOKEN_NE:\ -case TOKEN_EQ:\ -case TOKEN_PLUS:\ -case TOKEN_MINUS:\ -case TOKEN_MODULO:\ -case TOKEN_STAR:\ -case TOKEN_FLOORDIV:\ -case TOKEN_SLASH:\ -case TOKEN_CARET: +#define SWITCH_OPERATIONS \ + case TOKEN_AND: \ + case TOKEN_OR: \ + case TOKEN_NOT_IN: \ + case TOKEN_IN: \ + case TOKEN_LE: \ + case TOKEN_GE: \ + case TOKEN_LT: \ + case TOKEN_GT: \ + case TOKEN_NE: \ + case TOKEN_EQ: \ + case TOKEN_PLUS: \ + case TOKEN_MINUS: \ + case TOKEN_MODULO: \ + case TOKEN_STAR: \ + case TOKEN_FLOORDIV: \ + case TOKEN_SLASH: \ + case TOKEN_CARET: typedef struct LinkedList LinkedList; @@ -43,24 +45,29 @@ typedef enum { AST_FUNCTION } ValueType; -extern const char* ValueTypeNames[]; +extern const char *ValueTypeNames[]; typedef struct { ValueType type; void *data; } ParsedValue; -void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag); +typedef struct { + ArErr err; + ParsedValue *value; +} ParsedValueReturn; -ParsedValue *parse_token_full(char *file, DArray *tokens, size_t *index, - bool inline_flag, bool process_operations); +ArErr parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag); -ParsedValue *parse_token(char *file, DArray *tokens, size_t *index, +ParsedValueReturn parse_token_full(char *file, DArray *tokens, size_t *index, + bool inline_flag, bool process_operations); + +ParsedValueReturn parse_token(char *file, DArray *tokens, size_t *index, bool inline_flag); void free_parsed(void *ptr); -void error_if_finished(char *file,DArray *tokens, size_t *index); +void error_if_finished(char *file, DArray *tokens, size_t *index); size_t skip_newlines_and_indents(DArray *tokens, size_t *index); diff --git a/src/parser/string/string.c b/src/parser/string/string.c index 51767ce..acca190 100644 --- a/src/parser/string/string.c +++ b/src/parser/string/string.c @@ -245,7 +245,7 @@ char *unquote(char *str, size_t *decoded_len) { return unescaped; } -ParsedValue *parse_string(Token* token, bool to_unquote) { +ParsedValueReturn parse_string(Token* token, bool to_unquote) { ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); parsedValue->type = AST_STRING; ParsedString *parsedString = checked_malloc(sizeof(ParsedString)); @@ -253,11 +253,19 @@ ParsedValue *parse_string(Token* token, bool to_unquote) { if (to_unquote) { parsedString->length = 0; parsedString->string = unquote(token->value, &parsedString->length); + if (!parsedString->string) { + free(parsedValue); + free(parsedString); + return (ParsedValueReturn){create_err(token->line, token->column, + token->length, NULL, "String Error", + "failed to unquote string %s", token->value), + NULL}; + } } else { parsedString->string = strdup(token->value); parsedString->length = token->length; } - return parsedValue; + return (ParsedValueReturn){no_err,parsedValue}; } void free_parsed_string(void *ptr) { diff --git a/src/parser/string/string.h b/src/parser/string/string.h index 17e40db..4c69388 100644 --- a/src/parser/string/string.h +++ b/src/parser/string/string.h @@ -15,7 +15,7 @@ char *swap_quotes(char *input, char quote); char *unquote(char *str, size_t *decoded_len); -ParsedValue *parse_string(Token* token, bool to_unquote); +ParsedValueReturn parse_string(Token* token, bool to_unquote); void free_parsed_string(void *ptr); diff --git a/testing.ar b/testing.ar index 63fc4a5..4977bc6 100644 --- a/testing.ar +++ b/testing.ar @@ -1 +1 @@ -10~10 \ No newline at end of file +~ \ No newline at end of file