From f7f9797a4a3e57f0c09c9479248569fac937c553 Mon Sep 17 00:00:00 2001 From: Kyler Date: Thu, 19 Jun 2025 23:50:20 -0600 Subject: [PATCH] Worked on parse_statement --- include/sync/syntax.h | 22 ++++++ src/syntax.c | 156 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 164 insertions(+), 14 deletions(-) diff --git a/include/sync/syntax.h b/include/sync/syntax.h index 438bfb4..898ed53 100644 --- a/include/sync/syntax.h +++ b/include/sync/syntax.h @@ -12,7 +12,29 @@ typedef enum { NODE_FILE, NODE_BLOCK, + NODE_STATEMENT, + // Definitions and Declarations + NODE_ENUM_DEFINITION, + NODE_FN_DEFINITION, + NODE_LET_STATEMENT, + NODE_STRUCT_DEFINITION, + NODE_UNION_DEFINITION, + // Flow Control + NODE_BREAK_STATEMENT, + NODE_CASE_STATEMENT, + NODE_CONTINUE_STATEMENT, + NODE_DEFAULT_STATEMENT, + NODE_DO_WHILE_LOOP, + NODE_ELSE_STATEMENT, + NODE_FOR_LOOP, + NODE_IF_STATEMENT, + NODE_MATCH_STATEMENT, + NODE_RETURN_STATEMENT, + NODE_SWITCH_STATEMENT, + NODE_WHILE_LOOP, + // Modules + NODE_IMPORT_STATEMENT, NODE_IDENTIFIER, NODE_NUMBER, diff --git a/src/syntax.c b/src/syntax.c index f6a1951..6c43f70 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -20,7 +20,7 @@ typedef struct Child { SyntaxNode node; } Child; -typedef struct ChildrenResult { +typedef struct { SyncResultType type; union { Children result; @@ -28,6 +28,14 @@ typedef struct ChildrenResult { }; } ChildrenResult; +typedef struct { + SyncResultType type; + union { + Parser result; + SyncError error; + }; +} ParserResult; + static GeneralError add_child(Child* list, SyntaxNode node) { if (list == NULL) return (GeneralError){"Headless linked list.", 1}; Child* new_child = (Child*)malloc(sizeof(Child)); @@ -96,6 +104,19 @@ static SyntaxResult syntax_result(NodeType type, Child* list) { return aggregate_children(type, result.result); } +// static SyntaxResult syntax_simple_result(NodeType type, Token token) { +// return (SyntaxResult){SYNC_RESULT, .result = (NodeResult){ +// .type = SYNC_RESULT, +// .result = (SyntaxNode){ +// .type = type, +// .start = token.start, +// .length = token.length, +// .file_info = token.file_info, +// .children = NULL +// } +// }}; +// } + static SyntaxResult syntax_error(const char* message, Token token) { return (SyntaxResult){SYNC_RESULT, .result = (NodeResult){ .type = SYNC_ERROR, @@ -105,29 +126,136 @@ static SyntaxResult syntax_error(const char* message, Token token) { }}; } +static ParserResult get_to_token(Parser* parser, TokenType type, const char* string, char include_end) { + size_t i = parser->pos; + while (parser->tokens.tokens[i].type != TOKEN_EOF) { + if (parser->tokens.tokens[i].type == type) + if (string == NULL || strcmp(parser->tokens.tokens[i].start, string) == 0) + return (ParserResult){SYNC_RESULT, .result = (Parser){ + .tokens.length = i - parser->pos + include_end, + .tokens.tokens = parser->tokens.tokens + parser->pos, + .pos = 0 + }}; + i++; + } + return (ParserResult){SYNC_ERROR, .error = (SyncError){ + .type = SYNC_SYNTACTICAL_ERROR, + .message = "Unexpected end of file.", + .file_info = parser->tokens.tokens[i].file_info + }}; +} + static SyntaxResult parse_expression(Parser* parser) { } -static SyntaxResult parse_statement(Parser* parser) { - Child* children = NULL; +static SyntaxResult parse_enum_definition(Parser* parser) { +} +static SyntaxResult parse_function_definition(Parser* parser) { +} + +static SyntaxResult parse_let_statement(Parser* parser) { +} + +static SyntaxResult parse_struct_definition(Parser* parser) { +} + +static SyntaxResult parse_union_definition(Parser* parser) { +} + +static SyntaxResult parse_do_while_loop(Parser* parser) { +} + +static SyntaxResult parse_else_statement(Parser* parser) { +} + +static SyntaxResult parse_for_loop(Parser* parser) { +} + +static SyntaxResult parse_if_statement(Parser* parser) { +} + +static SyntaxResult parse_return_statement(Parser* parser) { +} + +static SyntaxResult parse_while_loop(Parser* parser) { +} + +static SyntaxResult parse_import_statement(Parser* parser) { +} + +static SyntaxResult parse_statement(Parser* parser) { if ( parser->tokens.tokens[parser->pos].type == TOKEN_EOF || parser->tokens.tokens[parser->pos].type == TOKEN_RBRACE ) return syntax_error("Expected statement", parser->tokens.tokens[parser->pos]); - SyntaxResult result = parse_expression(parser); + + // Definitions and Declarations + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_CONST) + return syntax_error("const must be in a let statement", parser->tokens.tokens[parser->pos]); + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_ENUM) + return parse_enum_definition(parser); + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_FN) + return parse_function_definition(parser); + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_LET) + return parse_let_statement(parser); + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_MUT) + return syntax_error("mut must be in a let statement", parser->tokens.tokens[parser->pos]); + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_PUBLIC) + return syntax_error("public must be in a definition", parser->tokens.tokens[parser->pos]); + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_STATIC) + return syntax_error("static must be in a definition", parser->tokens.tokens[parser->pos]); + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_STRUCT) + return parse_struct_definition(parser); + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_UNION) + return parse_union_definition(parser); + + // Control Flow + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_DO) + return parse_do_while_loop(parser); + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_ELSE) + return parse_else_statement(parser); + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_FOR) + return parse_for_loop(parser); + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_IF) + return parse_if_statement(parser); + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_WHILE) + return parse_while_loop(parser); + + // Types + // if ( + // parser->tokens.tokens[parser->pos].type == TOKEN_KW_BOOL || + // parser->tokens.tokens[parser->pos].type == TOKEN_KW_F32 || + // parser->tokens.tokens[parser->pos].type == TOKEN_KW_F64 || + // parser->tokens.tokens[parser->pos].type == TOKEN_KW_I8 || + // parser->tokens.tokens[parser->pos].type == TOKEN_KW_I16 || + // parser->tokens.tokens[parser->pos].type == TOKEN_KW_I32 || + // parser->tokens.tokens[parser->pos].type == TOKEN_KW_I64 || + // parser->tokens.tokens[parser->pos].type == TOKEN_KW_U8 || + // parser->tokens.tokens[parser->pos].type == TOKEN_KW_U16 || + // parser->tokens.tokens[parser->pos].type == TOKEN_KW_U32 || + // parser->tokens.tokens[parser->pos].type == TOKEN_KW_U64 || + // parser->tokens.tokens[parser->pos].type == TOKEN_KW_VOID + // ) return syntax_error("unexpected built in type reference", parser->tokens.tokens[parser->pos]); + + // Modules + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_AS) + return syntax_error("as must be in an import statement", parser->tokens.tokens[parser->pos]); + if (parser->tokens.tokens[parser->pos].type == TOKEN_KW_IMPORT) + return parse_import_statement(parser); + + Child* children = NULL; + ParserResult expression_parser = get_to_token(parser, TOKEN_SEMICOLON, NULL, 0); + if (expression_parser.type == SYNC_ERROR) + return (SyntaxResult){SYNC_RESULT, .result = (NodeResult){SYNC_ERROR, .error = expression_parser.error}}; + SyntaxResult result = parse_expression(&expression_parser.result); if (result.type == SYNC_ERROR) return result; if (result.result.type == SYNC_ERROR) return result; - if (children == NULL) { - children = (Child*)malloc(sizeof(Child)); - if (children == NULL) - return (SyntaxResult){SYNC_ERROR, .error = (GeneralError){"Failed to allocate memory.", 1}}; - children->next = NULL; - children->node = result.result.result; - } else { - GeneralError error = add_child(children, result.result.result); - if (error.message != NULL) return (SyntaxResult){SYNC_ERROR, .error = error}; - } + children = (Child*)malloc(sizeof(Child)); + if (children == NULL) + return (SyntaxResult){SYNC_ERROR, .error = (GeneralError){"Failed to allocate memory.", 1}}; + children->next = NULL; + children->node = result.result.result; if (parser->tokens.tokens[parser->pos].type != TOKEN_SEMICOLON) return syntax_error("Expected statement", parser->tokens.tokens[parser->pos]);