Fixed some error handling for invalid if statements. Started if codegen.
This commit is contained in:
81
Parsing.jai
81
Parsing.jai
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user