Worked on parse_statement

This commit is contained in:
Kyler Olsen 2025-06-19 23:50:20 -06:00
parent 35e4b97575
commit f7f9797a4a
2 changed files with 164 additions and 14 deletions

View File

@ -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,

View File

@ -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]);