From c0ee99fd545b67cf0bfd2111e760aa313d16095c Mon Sep 17 00:00:00 2001 From: William Bell Date: Thu, 5 Jun 2025 15:13:57 +0100 Subject: [PATCH] add multi line support for more stuff --- src/parser/assignable/assign/assign.c | 15 ++++++++++----- src/parser/assignable/call/call.c | 4 ++++ src/parser/declaration/declaration.c | 9 +++++++++ src/parser/parser.c | 25 ++++++++++++++++++------- src/parser/parser.h | 2 ++ test.ar | 24 +++++++++++++++++++++--- 6 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/parser/assignable/assign/assign.c b/src/parser/assignable/assign/assign.c index 8ffb520..5e51e84 100644 --- a/src/parser/assignable/assign/assign.c +++ b/src/parser/assignable/assign/assign.c @@ -18,11 +18,11 @@ ParsedValue *parse_assign(char *file, DArray *tokens, ParsedValue *assign_to, ParsedCall *call = assign_to->data; for (size_t i = 0; i < call->args->size; i++) { if (((ParsedValue *)darray_get(call->args, i))->type != AST_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); + 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); } } @@ -39,6 +39,11 @@ ParsedValue *parse_assign(char *file, DArray *tokens, ParsedValue *assign_to, error_if_finished(file, tokens, index); token = darray_get(tokens, *index); assign->from = parse_token(file, tokens, index, true); + 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; diff --git a/src/parser/assignable/call/call.c b/src/parser/assignable/call/call.c index 2de6570..ff72fbb 100644 --- a/src/parser/assignable/call/call.c +++ b/src/parser/assignable/call/call.c @@ -25,10 +25,14 @@ ParsedValue *parse_call(char *file, DArray *tokens, size_t *index, token = darray_get(tokens, *index); } else { 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); error_if_finished(file, tokens, index); + skip_newlines_and_indents(tokens, index); + error_if_finished(file, tokens, index); token = darray_get(tokens, *index); if (token->type == TOKEN_RPAREN) { (*index)++; diff --git a/src/parser/declaration/declaration.c b/src/parser/declaration/declaration.c index 4296817..64ceaa4 100644 --- a/src/parser/declaration/declaration.c +++ b/src/parser/declaration/declaration.c @@ -65,6 +65,8 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) { darray_push(declaration->parameters, ¶meter_name); (*index)++; error_if_finished(file, tokens, index); + skip_newlines_and_indents(tokens, index); + error_if_finished(file, tokens, index); token = darray_get(tokens, *index); if (token->type == TOKEN_RPAREN) { (*index)++; @@ -89,6 +91,11 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) { free(declaration->from); declaration->from = parse_token(file, tokens, index, true); + if (!declaration->from) { + fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line, + token->column); + exit(EXIT_FAILURE); + } if ((*index) >= tokens->size) break; token = darray_get(tokens, *index); @@ -97,6 +104,8 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) { break; (*index)++; error_if_finished(file, tokens, index); + skip_newlines_and_indents(tokens, index); + error_if_finished(file, tokens, index); token = darray_get(tokens, *index); } return parsedValue; diff --git a/src/parser/parser.c b/src/parser/parser.c index 493689d..a778293 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -29,6 +29,21 @@ void error_if_finished(char *file, DArray *tokens, size_t *index) { } } +void skip_newlines_and_indents(DArray *tokens, size_t *index) { + bool passed = false; + while (!passed && (*index) < tokens->size) { + Token *token = darray_get(tokens, *index); + switch (token->type) { + case TOKEN_NEW_LINE: + case TOKEN_INDENT: + (*index)++; + break; + default: + passed = true; + } + } +} + ParsedValue *parse_token(char *file, DArray *tokens, size_t *index, bool inline_flag) { Token *token = darray_get(tokens, *index); @@ -61,12 +76,8 @@ ParsedValue *parse_token(char *file, DArray *tokens, size_t *index, output = parse_string(*token); break; case TOKEN_NEW_LINE: - while (token->type == TOKEN_NEW_LINE && ++(*index) < tokens->size) { - token = darray_get(tokens, *index); - } - if (token->type == TOKEN_NEW_LINE) - break; - output = parse_token(file, tokens, index, inline_flag); + (*index)++; + return NULL; break; case TOKEN_INDENT: fprintf(stderr, "%s:%zu:%zu error: invalid indentation\n", file, token->line, @@ -101,7 +112,7 @@ ParsedValue *parse_token(char *file, DArray *tokens, size_t *index, case TOKEN_ASSIGN_MODULO: case TOKEN_ASSIGN_PLUS: case TOKEN_ASSIGN_SLASH: - case TOKEN_ASSIGN_STAR:; + case TOKEN_ASSIGN_STAR: output = parse_assign(file, tokens, output, index); break; case TOKEN_LPAREN: diff --git a/src/parser/parser.h b/src/parser/parser.h index 242b0e0..eccd2c4 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -36,4 +36,6 @@ void free_parsed(void *ptr); void error_if_finished(char *file,DArray *tokens, size_t *index); +void skip_newlines_and_indents(DArray *tokens, size_t *index); + #endif // PARSER_H \ No newline at end of file diff --git a/test.ar b/test.ar index e4990ee..24a898e 100644 --- a/test.ar +++ b/test.ar @@ -1,3 +1,21 @@ -let a, b = 1, c, d = 42, temp_result, compute_area(radius) = 3.1415, identity(x) = x, f(x), g(y, z), result, z = 0, extremely_long_variable_name_to_test_limits, cache_value = compute_area(5), placeholder_fn_with_no_body(arg1, arg2, arg3), total = identity(100), deeply_nested_args_function(arg1, arg2, arg3, arg4, arg5), sum = a, another, another_function(), just_null_here -x = 10 -x.epic_test_long_variable_name = "hello world" \ No newline at end of file +let a, + b = 1, + c, + d = 42, + temp_result, + compute_area(radius) = 3.1415, + identity(x) = x, + f(x), + g(y, z), + result, + z = 0, + extremely_long_variable_name_to_test_limits, + cache_value = compute_area(5), + placeholder_fn_with_no_body(arg1, arg2, arg3), + total = identity(100), + deeply_nested_args_function(arg1, arg2, arg3, arg4, arg5), + sum = a, + another, + another_function(), + just_null_here +if (x) term.log("hello world") \ No newline at end of file