diff --git a/src/err.c b/src/err.c index 4bb550b..72ba599 100644 --- a/src/err.c +++ b/src/err.c @@ -92,20 +92,21 @@ void output_err(ArErr err) { getline(&buffer, &size, file); char *line_starts = buffer; - while (*line_starts && isspace((unsigned char)*line_starts)) { + char line_column = err.column; + while (*line_starts && isspace((unsigned char)*line_starts) && line_starts-buffer < err.column) { line_starts++; - err.column--; + line_column--; } fprintf(stderr, " %zu | ", err.line); if (err.length) { - fprintf(stderr, "%.*s", (int)err.column - 1, line_starts); + fprintf(stderr, "%.*s", (int)line_column - 1, line_starts); dyefg(stderr, DYE_RED); dye_style(stderr, DYE_STYLE_BOLD); - fprintf(stderr, "%.*s", err.length, line_starts + err.column - 1); + fprintf(stderr, "%.*s", err.length, line_starts + line_column - 1); dye_style(stderr, DYE_STYLE_RESET); dyefg(stderr, DYE_RESET); - fprintf(stderr, "%s", line_starts + (int)err.column + err.length - 1); - for (int64_t i = 0; i < err.column - 1; i++) { + fprintf(stderr, "%s", line_starts + (int)line_column + err.length - 1); + for (int64_t i = 0; i < line_column - 1; i++) { fprintf(stderr, " "); } } else { @@ -118,7 +119,7 @@ void output_err(ArErr err) { } fprintf(stderr, "| "); - for (int i = 1; i < err.column; i++) { + for (int i = 1; i < line_column; i++) { fprintf(stderr, " "); } dyefg(stderr, DYE_RED); diff --git a/src/main.c b/src/main.c index 5da036d..5256b24 100644 --- a/src/main.c +++ b/src/main.c @@ -170,7 +170,7 @@ Execution execute(char *absolute_path) { cwk_path_get_basename(absolute_path, &basename_ptr, &basename_length); if (!basename_ptr) - return (Execution){create_err(0, 0 ,0 , NULL, "Path Error", + return (Execution){create_err(0, 0, 0, NULL, "Path Error", "path has no basename '%s'", absolute_path), (Stack){NULL, NULL}}; @@ -196,8 +196,8 @@ Execution execute(char *absolute_path) { FILE *file = fopen(absolute_path, "r"); if (!file) { - return (Execution){create_err(0, 0, 0, NULL, "File Error", "Unable to open file '%s'", - absolute_path), + return (Execution){create_err(0, 0, 0, NULL, "File Error", + "Unable to open file '%s'", absolute_path), (Stack){NULL, NULL}}; } @@ -228,8 +228,7 @@ Execution execute(char *absolute_path) { if (err.exists) { free_translator(&translated); darray_free(&tokens, free_token); - return (Execution){err, - (Stack){NULL, NULL}}; + return (Execution){err, (Stack){NULL, NULL}}; } end = clock(); time_spent = (double)(end - start) / CLOCKS_PER_SEC; @@ -242,7 +241,13 @@ Execution execute(char *absolute_path) { darray_init(&ast, sizeof(ParsedValue)); start = clock(); - parser(absolute_path, &ast, &tokens, false); + err = parser(absolute_path, &ast, &tokens, false); + if (err.exists) { + free_translator(&translated); + darray_free(&tokens, free_token); + darray_free(&ast, free_parsed); + return (Execution){err, (Stack){NULL, NULL}}; + } end = clock(); time_spent = (double)(end - start) / CLOCKS_PER_SEC; total_time_spent += time_spent; @@ -310,7 +315,7 @@ int main(int argc, char *argv[]) { cwk_path_get_absolute(CWD, path_non_absolute, path, sizeof(path)); free(CWD); Execution resp = execute(path); - if (resp.err.exists){ + if (resp.err.exists) { output_err(resp.err); return -1; } diff --git a/src/parser/assignable/access/access.c b/src/parser/assignable/access/access.c index 713699e..de97378 100644 --- a/src/parser/assignable/access/access.c +++ b/src/parser/assignable/access/access.c @@ -1,53 +1,72 @@ #include "access.h" #include "../../../lexer/token.h" #include "../../../memory.h" -#include "../../string/string.h" #include "../../parser.h" +#include "../../string/string.h" #include #include #include -ParsedValue *parse_access(char *file, DArray *tokens, size_t *index, - ParsedValue *to_access) { +ParsedValueReturn parse_access(char *file, DArray *tokens, size_t *index, + ParsedValue *to_access) { Token *first_token = darray_get(tokens, *index); (*index)++; ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); ParsedAccess *parsedAccess = checked_malloc(sizeof(ParsedAccess)); parsedAccess->to_access = *to_access; + parsedValue->type = AST_ACCESS; + parsedValue->data = parsedAccess; free(to_access); darray_init(&parsedAccess->access, sizeof(ParsedValue)); if (first_token->type == TOKEN_DOT) { error_if_finished(file, tokens, index); Token *token = darray_get(tokens, *index); - ParsedValue *parsedString = parse_string(token, false); - darray_push(&parsedAccess->access, parsedString); - free(parsedString); + ParsedValueReturn parsedString = parse_string(token, false); + if (parsedString.err.exists) { + free_parsed(parsedValue); + free(parsedValue); + return parsedString; + } + darray_push(&parsedAccess->access, parsedString.value); + free(parsedString.value); parsedAccess->access_fields = true; } else { parsedAccess->access_fields = false; + Token *token = first_token; while (true) { skip_newlines_and_indents(tokens, index); error_if_finished(file, tokens, index); - ParsedValue *parsedValue = parse_token(file, tokens, index, true); + ParsedValueReturn parsedAccessValue = + parse_token(file, tokens, index, true); + if (parsedAccessValue.err.exists) { + free_parsed(parsedValue); + free(parsedValue); + return parsedAccessValue; + } else if (!parsedAccessValue.value) { + free_parsed(parsedValue); + free(parsedValue); + return (ParsedValueReturn){ + create_err(token->line, token->column, token->length, file, + "Syntax Error", "expected value"), + NULL}; + } darray_push(&parsedAccess->access, parsedValue); free(parsedValue); skip_newlines_and_indents(tokens, index); error_if_finished(file, tokens, index); - Token *token = darray_get(tokens, *index); + token = darray_get(tokens, *index); if (token->type == TOKEN_RBRACKET) { break; } else if (token->type != TOKEN_COLON) { - fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, - token->line, token->column); + fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line, + token->column); exit(EXIT_FAILURE); } (*index)++; } } - parsedValue->type = AST_ACCESS; - parsedValue->data = parsedAccess; (*index)++; - return parsedValue; + return (ParsedValueReturn){no_err, parsedValue}; } void free_parse_access(void *ptr) { diff --git a/src/parser/assignable/access/access.h b/src/parser/assignable/access/access.h index 2237213..24abc02 100644 --- a/src/parser/assignable/access/access.h +++ b/src/parser/assignable/access/access.h @@ -10,7 +10,8 @@ typedef struct { } ParsedAccess; // Function declaration for parsing an identifier -ParsedValue *parse_access(char*file,DArray *tokens, size_t * index, ParsedValue * to_access); +ParsedValueReturn parse_access(char *file, DArray *tokens, size_t *index, + ParsedValue *to_access); void free_parse_access(void *ptr); diff --git a/src/parser/assignable/assign/assign.c b/src/parser/assignable/assign/assign.c index 78df89f..fe2b399 100644 --- a/src/parser/assignable/assign/assign.c +++ b/src/parser/assignable/assign/assign.c @@ -30,13 +30,14 @@ ParsedValueReturn parse_assign(char *file, DArray *tokens, } } break; - default: - free_parsed(assign_to); - free(assign_to); - return (ParsedValueReturn){create_err(token->line, token->column, + default:; + ArErr err = create_err(token->line, token->column, token->length, file, "Syntax Error", "can't assign to %s", - ValueTypeNames[assign_to->type]), + ValueTypeNames[assign_to->type]); + free_parsed(assign_to); + free(assign_to); + return (ParsedValueReturn){err, NULL}; } ParsedAssign *assign = checked_malloc(sizeof(ParsedAssign)); diff --git a/src/parser/assignable/call/call.c b/src/parser/assignable/call/call.c index b26df81..a6c661d 100644 --- a/src/parser/assignable/call/call.c +++ b/src/parser/assignable/call/call.c @@ -6,8 +6,8 @@ #include #include -ParsedValue *parse_call(char *file, DArray *tokens, size_t *index, - ParsedValue *to_call) { +ParsedValueReturn parse_call(char *file, DArray *tokens, size_t *index, + ParsedValue *to_call) { ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); ParsedCall *call = checked_malloc(sizeof(ParsedCall)); call->to_call = to_call; @@ -21,9 +21,26 @@ ParsedValue *parse_call(char *file, DArray *tokens, size_t *index, while ((*index) < tokens->size) { skip_newlines_and_indents(tokens, index); error_if_finished(file, tokens, index); - ParsedValue *parsedArg = parse_token(file, tokens, index, true); - darray_push(&call->args, parsedArg); - free(parsedArg); + ParsedValueReturn parsedArg = parse_token(file, tokens, index, true); + if (parsedArg.err.exists) { + free_parsed(to_call); + free(to_call); + free_parsed(parsedValue); + free(parsedValue); + return parsedArg; + } else if (!parsedArg.value) { + free_parsed(to_call); + free(to_call); + free_parsed(parsedValue); + free(parsedValue); + + return (ParsedValueReturn){ + create_err(token->line, token->column, token->length, file, + "Syntax Error", "expected argument"), + NULL}; + } + darray_push(&call->args, parsedArg.value); + free(parsedArg.value); error_if_finished(file, tokens, index); skip_newlines_and_indents(tokens, index); error_if_finished(file, tokens, index); @@ -40,7 +57,7 @@ ParsedValue *parse_call(char *file, DArray *tokens, size_t *index, } } (*index)++; - return parsedValue; + return (ParsedValueReturn){no_err, parsedValue}; } void free_parse_call(void *ptr) { diff --git a/src/parser/assignable/call/call.h b/src/parser/assignable/call/call.h index 3675c9a..9407277 100644 --- a/src/parser/assignable/call/call.h +++ b/src/parser/assignable/call/call.h @@ -9,7 +9,7 @@ typedef struct { } ParsedCall; // Function declaration for parsing an identifier -ParsedValue *parse_call(char *file, DArray *tokens, size_t *index, +ParsedValueReturn parse_call(char *file, DArray *tokens, size_t *index, ParsedValue *to_call); void free_parse_call(void *ptr); diff --git a/src/parser/operations/operations.c b/src/parser/operations/operations.c index a50db4b..ac936be 100644 --- a/src/parser/operations/operations.c +++ b/src/parser/operations/operations.c @@ -8,7 +8,7 @@ ParsedValue convert_to_operation(DArray *to_operate_on, DArray *operations) { if (to_operate_on->size == 1) { - return *((ParsedValue*)darray_get(to_operate_on, 0)); + return *((ParsedValue *)darray_get(to_operate_on, 0)); } TokenType operation = 0; DArray positions; @@ -37,23 +37,24 @@ ParsedValue convert_to_operation(DArray *to_operate_on, DArray *operations) { to_operate_on, to_operate_on_last_position, (*position) + 1); DArray operations_slice = darray_slice(operations, last_position, *position); - ParsedValue result = convert_to_operation(&to_operate_on_slice, &operations_slice); - darray_push(&operationStruct->to_operate_on, - &result); + ParsedValue result = + convert_to_operation(&to_operate_on_slice, &operations_slice); + darray_push(&operationStruct->to_operate_on, &result); last_position = (*position); to_operate_on_last_position = (*position) + 1; } - DArray to_operate_on_slice = - darray_slice(to_operate_on, to_operate_on_last_position, to_operate_on->size); - DArray operations_slice = darray_slice(operations, last_position, operations->size); - ParsedValue result =convert_to_operation(&to_operate_on_slice, &operations_slice); - darray_push(&operationStruct->to_operate_on, - &result); + DArray to_operate_on_slice = darray_slice( + to_operate_on, to_operate_on_last_position, to_operate_on->size); + DArray operations_slice = + darray_slice(operations, last_position, operations->size); + ParsedValue result = + convert_to_operation(&to_operate_on_slice, &operations_slice); + darray_push(&operationStruct->to_operate_on, &result); darray_free(&positions, NULL); return parsedValue; } -ParsedValue *parse_operations(char *file, DArray *tokens, size_t *index, +ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index, ParsedValue *first_parsed_value) { DArray to_operate_on; darray_init(&to_operate_on, sizeof(ParsedValue)); @@ -77,17 +78,29 @@ ParsedValue *parse_operations(char *file, DArray *tokens, size_t *index, darray_push(&operations, &token->type); (*index)++; error_if_finished(file, tokens, index); - ParsedValue *parsedValue = + ParsedValueReturn parsedValue = parse_token_full(file, tokens, index, true, false); - darray_push(&to_operate_on, parsedValue); - free(parsedValue); + if (parsedValue.err.exists) { + darray_free(&to_operate_on, free_parsed); + darray_free(&operations, NULL); + return parsedValue; + } else if (!parsedValue.value) { + darray_free(&to_operate_on, free_parsed); + darray_free(&operations, NULL); + return (ParsedValueReturn){ + create_err(token->line, token->column, token->length, file, + "Syntax Error", "expected value"), + NULL}; + } + darray_push(&to_operate_on, parsedValue.value); + free(parsedValue.value); } ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); ParsedValue output = convert_to_operation(&to_operate_on, &operations); - memcpy(parsedValue, &output,sizeof(ParsedValue)); + memcpy(parsedValue, &output, sizeof(ParsedValue)); darray_free(&to_operate_on, NULL); darray_free(&operations, NULL); - return parsedValue; + return (ParsedValueReturn){no_err,parsedValue}; } void free_operation(void *ptr) { diff --git a/src/parser/operations/operations.h b/src/parser/operations/operations.h index 1a3b16b..93f0aff 100644 --- a/src/parser/operations/operations.h +++ b/src/parser/operations/operations.h @@ -8,7 +8,8 @@ typedef struct { DArray to_operate_on; // ParsedValue[] } ParsedOperation; -ParsedValue *parse_operations(char*file,DArray *tokens, size_t * index, ParsedValue * first_parsed_value); +ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index, + ParsedValue *first_parsed_value); void free_operation(void *ptr); diff --git a/src/parser/parser.c b/src/parser/parser.c index 2faaba3..a52e42d 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -177,9 +177,9 @@ ArErr parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) { size_t old_index = index; ParsedValueReturn parsed_code = parse_token(file, tokens, &index, inline_flag); - if (parsed_code.err.exists) + if (parsed_code.err.exists) { return parsed_code.err; - else if (parsed_code.value) { + } 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, diff --git a/testing.ar b/testing.ar index 4977bc6..1eeac2b 100644 --- a/testing.ar +++ b/testing.ar @@ -1 +1 @@ -~ \ No newline at end of file + term.log("hello world") \ No newline at end of file