Rename of files, improved for handling, add cb hints

- Rename Test to Ink as main file
- Support more errors for for loops.
- Add hints to cbs
This commit is contained in:
2025-09-02 11:55:27 +02:00
parent 9e0728f952
commit 603b625e21
10 changed files with 114 additions and 35 deletions

View File

@@ -134,6 +134,7 @@ record_error :: (parse_state : *Parse_State, token : Token, message : string, re
source_location.begin.source = source_location.begin.source - source_location.begin.column;
source_location.main_token = token;
snap := snapshot_state(parse_state);
advance_to_sync_point(parse_state);
error.report_source_location = report_source_location;
@@ -142,6 +143,8 @@ record_error :: (parse_state : *Parse_State, token : Token, message : string, re
parse_state.result.had_error = true;
array_add(*parse_state.result.messages, error);
rewind_to_snapshot(parse_state, snap);
}
generate_source_location_from_token :: (state : *Parse_State, token : Token) -> Source_Range {
@@ -241,6 +244,26 @@ else_without_if :: (state : *Parse_State) {
record_error(state, token, final_message, false);
}
unable_to_parse_statement :: (state : *Parse_State, token : Token, message : string = "") {
builder : String_Builder;
init_string_builder(*builder,, temp);
print_to_builder(*builder, "Unable to parse statement here. %\n", message);
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);
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);
@@ -444,9 +467,9 @@ precedence :: (parse_state : *Parse_State, precedence : Precedence, message : st
tok_s.data = prev.source;
tok_s.count = prev.length;
if message {
expected_expression(parse_state, parse_state.previous, tprint("Expected expression after '%'. %", tok_s, message));
expected_expression(parse_state, prev, tprint("Expected expression after '%'. %", tok_s, message));
} else {
expected_expression(parse_state, parse_state.previous, tprint("Expected expression after '%'.", tok_s));
expected_expression(parse_state, prev, tprint("Expected expression after '%'.", tok_s));
}
return error_node(parse_state, "Expected expression.");
@@ -859,9 +882,10 @@ statement :: (parse_state : *Parse_State) -> *AST_Node {
source_location : Source_Range;
source_location.begin = parse_state.previous;
if_cond := expression(parse_state);
if_cond := expression(parse_state, "Expected if condition.");
add_child(node, if_cond);
source_location.end = parse_state.previous;
advance_to_sync_point(parse_state);
if_body := block(parse_state);
add_child(node, if_body);
@@ -903,18 +927,42 @@ statement :: (parse_state : *Parse_State) -> *AST_Node {
advance(parse_state);
consume(parse_state, .TOKEN_COLON, "Expect ':' after for loop iterator.");
snap := snapshot_state(parse_state);
begin_iter := expression(parse_state, "Expected beginning of iterator.");
if begin_iter.kind == .Error {
unable_to_parse_statement(parse_state, source_location.begin);
rewind_to_snapshot(parse_state, snap);
if parse_state.current.kind == .TOKEN_LEFTBRACE {
block(parse_state);
}
return error_node(parse_state, "'for' without well-formed iterator expression.");
}
add_child(node, begin_iter);
consume(parse_state, .TOKEN_DOTDOT, "Expect '..' after for loop iter left hand side.");
end_iter := expression(parse_state, "Expected end of iterator");
snap = snapshot_state(parse_state);
end_iter := expression(parse_state, "Expected end of iterator.");
if end_iter.kind == .Error {
unable_to_parse_statement(parse_state, source_location.begin);
rewind_to_snapshot(parse_state, snap);
if parse_state.current.kind == .TOKEN_LEFTBRACE {
block(parse_state);
}
return error_node(parse_state, "'for' without well-formed iterator expression.");
}
add_child(node, end_iter);
for_body := block(parse_state);
add_child(node, for_body);
// consume(parse_state, .TOKEN_RIGHTBRACE, "Expect '}' after for body.");
if check(parse_state, .TOKEN_LEFTBRACE) {
for_body := block(parse_state);
add_child(node, for_body);
} else {
unable_to_parse_statement(parse_state, source_location.begin, "'for' currently expects a brace-enclosed block as a body.");
return error_node(parse_state, "'for' currently expects a brace-enclosed block as a body.");
}
node.source_location = source_location;