Fixed some error handling for invalid if statements. Started if codegen.

This commit is contained in:
2025-01-18 22:22:16 +01:00
parent b4d119230b
commit 45ea54cf93
23 changed files with 344 additions and 11 deletions

View File

@@ -213,6 +213,50 @@ unexpected_token :: (state : *Parse_State, token : Token, message : string) {
record_error(state, token, final_message, false);
}
else_if_without_if :: (state : *Parse_State) {
builder : String_Builder;
init_string_builder(*builder,, temp);
append(*builder, "'else if' without 'if'\n");
token := state.previous;
location : Source_Range = generate_source_location_from_token(state, token);
indent(*builder, 1);
cyan(*builder);
print_to_builder(*builder, "%\n", print_from_source_location(location));
indent(*builder, 1);
print_token_pointer(*builder, token);
white(*builder);
final_message := builder_to_string(*builder);
record_error(state, token, final_message, false);
}
else_without_if :: (state : *Parse_State) {
builder : String_Builder;
init_string_builder(*builder,, temp);
append(*builder, "'else' without 'if'\n");
token := state.previous;
location : Source_Range = generate_source_location_from_token(state, token);
indent(*builder, 1);
cyan(*builder);
print_to_builder(*builder, "%\n", print_from_source_location(location));
indent(*builder, 1);
print_token_pointer(*builder, token);
white(*builder);
final_message := builder_to_string(*builder);
record_error(state, token, final_message, false);
}
expected_expression :: (state : *Parse_State, token : Token, message : string) {
builder : String_Builder;
init_string_builder(*builder,, temp);
@@ -395,7 +439,10 @@ precedence :: (parse_state : *Parse_State, precedence : Precedence) -> *AST_Node
prefix_rule := get_rule(parse_state.previous.kind).prefix;
if prefix_rule == null {
expected_expression(parse_state, parse_state.current, "Expected expression.");
tok_s : string;
tok_s.data = parse_state.previous.source;
tok_s.count = parse_state.previous.length;
expected_expression(parse_state, parse_state.previous, tprint("Expected expression after '%'.", tok_s));
// @Incomplete: Add error node here?
return error_node(parse_state, "Expected expression.");
}
@@ -405,7 +452,11 @@ precedence :: (parse_state : *Parse_State, precedence : Precedence) -> *AST_Node
while precedence <= get_rule(parse_state.current.kind).precedence {
advance(parse_state);
if parse_state.current.kind == .TOKEN_EOF {
expected_expression(parse_state, parse_state.current, "Reached end of file. Expected expression.");
tok_s : string;
tok_s.data = parse_state.previous.source;
tok_s.count = parse_state.previous.length;
expected_expression(parse_state, parse_state.current, tprint("Reached end of file. Expected expression after '%'.", tok_s));
// expected_expression(parse_state, parse_state.current, "Reached end of file. Expected expression.");
// @Incomplete: Add error node here?
return null;
}
@@ -791,15 +842,12 @@ statement :: (parse_state : *Parse_State) -> *AST_Node {
source_location : Source_Range;
source_location.begin = parse_state.previous;
if_expression := expression(parse_state);
add_child(node, if_expression);
// consume(parse_state, .TOKEN_LEFTBRACE, "Expect '{' after if-condition.");
if_cond := expression(parse_state);
add_child(node, if_cond);
source_location.end = parse_state.previous;
if_body := block(parse_state);
if if_body.children.count > 0 {
add_child(node, if_body);
}
add_child(node, if_body);
if match(parse_state, .TOKEN_ELSE) {
else_node := else_statement(parse_state);
@@ -809,6 +857,23 @@ statement :: (parse_state : *Parse_State) -> *AST_Node {
node.source_location = source_location;
return node;
} else if match(parse_state, .TOKEN_ELSE) {
if check(parse_state, .TOKEN_IF) {
else_if_without_if(parse_state);
advance_to_sync_point(parse_state);
if check(parse_state, .TOKEN_LEFTBRACE) {
return block(parse_state);
}
return error_node(parse_state, "'else if' without 'if'.");
} else {
else_without_if(parse_state);
advance_to_sync_point(parse_state);
if check(parse_state, .TOKEN_LEFTBRACE) {
return block(parse_state);
}
return error_node(parse_state, "'else' without 'if'.");
}
} else {
return expression_statement(parse_state);
}