refactor: apply project style guidelines
This commit is contained in:
+29
-16
@@ -29,11 +29,14 @@ State :: struct {
|
||||
next_token usize
|
||||
}
|
||||
|
||||
#! borrows tokens and source while parsing; the returned Tree borrows source until ast.deinit.
|
||||
#! allocator supplies returned node storage and temporary lists released before return.
|
||||
#! the caller owns the Tree and must release it with ast.deinit.
|
||||
parse proc(
|
||||
allocator mem.Allocator,
|
||||
tokens []lexer.Token,
|
||||
source []u8,
|
||||
diagnostic_store @mut diagnostics.Store,
|
||||
allocator mem.Allocator,
|
||||
) ast.Tree ! (mem.AllocError | diagnostics.CapacityError) {
|
||||
state := State{
|
||||
builder = ast.init_builder(allocator, source),
|
||||
@@ -55,7 +58,7 @@ parse_package proc(state @mut State) ast.NodeId ! (mem.AllocError | diagnostics.
|
||||
skip_newlines(state)
|
||||
while !next_is(state, .eof) {
|
||||
start :: state.next_token
|
||||
declaration := parse_decl(state) catch |err| {
|
||||
declaration :: parse_decl(state) catch |err| {
|
||||
match err {
|
||||
.unexpected_token: {
|
||||
recovered :: try recover_decl(state, start)
|
||||
@@ -79,9 +82,7 @@ parse_package proc(state @mut State) ast.NodeId ! (mem.AllocError | diagnostics.
|
||||
|
||||
@hide:file
|
||||
parse_decl proc(state @mut State) ast.NodeId ! ParseError {
|
||||
if next_is(state, .ident) and next_n_is(state, 1, .proc) {
|
||||
return try parse_func_decl(state)
|
||||
}
|
||||
if (next_is(state, .ident) and next_n_is(state, 1, .proc)) return try parse_func_decl(state)
|
||||
return try parse_statement_decl(state)
|
||||
}
|
||||
|
||||
@@ -142,7 +143,7 @@ parse_block proc(state @mut State) ast.NodeId ! ParseError {
|
||||
skip_newlines(state)
|
||||
while !next_is(state, .close_curly) and !next_is(state, .eof) {
|
||||
start :: state.next_token
|
||||
statement := parse_statement(state) catch |err| {
|
||||
statement :: parse_statement(state) catch |err| {
|
||||
match err {
|
||||
.unexpected_token: {
|
||||
recovered :: try recover_statement(state, start)
|
||||
@@ -184,7 +185,7 @@ parse_statement proc(state @mut State) ast.NodeId ! ParseError {
|
||||
@hide:file
|
||||
parse_statement_decl proc(state @mut State) ast.NodeId ! ParseError {
|
||||
name :: try consume(state, .ident)
|
||||
type_id ?ast.NodeId := if next_is(state, .ident)
|
||||
type_id ?ast.NodeId :: if next_is(state, .ident)
|
||||
try parse_type(state)
|
||||
else
|
||||
null
|
||||
@@ -266,8 +267,7 @@ parse_call proc(state @mut State, callee ast.NodeId) ast.NodeId ! ParseError {
|
||||
defer arraylist.deinit(&arguments)
|
||||
|
||||
while !next_is(state, .close_paren) and !next_is(state, .newline) and
|
||||
!next_is(state, .close_curly) and !next_is(state, .eof)
|
||||
{
|
||||
!next_is(state, .close_curly) and !next_is(state, .eof) {
|
||||
argument :: try parse_expr(state)
|
||||
try arraylist.append(&arguments, argument)
|
||||
if (!next_is(state, .comma)) break
|
||||
@@ -276,7 +276,10 @@ parse_call proc(state @mut State, callee ast.NodeId) ast.NodeId ! ParseError {
|
||||
close :: try consume(state, .close_paren)
|
||||
return try ast.add_call(
|
||||
&state.builder,
|
||||
ast.Span{ start = ast.builder_span(&state.builder, callee).start, end = close.span.end },
|
||||
ast.Span{
|
||||
start = ast.builder_span(&state.builder, callee).start,
|
||||
end = close.span.end,
|
||||
},
|
||||
callee,
|
||||
arguments.items,
|
||||
)
|
||||
@@ -293,7 +296,11 @@ parse_primary proc(state @mut State) ast.NodeId ! ParseError {
|
||||
state.next_token += 1
|
||||
return expression
|
||||
}
|
||||
diagnostic :: try diagnostics.add(state.diagnostics, .unexpected_token, current(state).span)
|
||||
diagnostic :: try diagnostics.add(
|
||||
state.diagnostics,
|
||||
.unexpected_token,
|
||||
current(state).span,
|
||||
)
|
||||
return try ast.add_invalid_expr(&state.builder, ast.Span{
|
||||
start = token.span.start,
|
||||
end = ast.builder_span(&state.builder, expression).end,
|
||||
@@ -321,9 +328,9 @@ parse_primary proc(state @mut State) ast.NodeId ! ParseError {
|
||||
else
|
||||
try diagnostics.add(state.diagnostics, .unexpected_token, token.span)
|
||||
|
||||
if (token.kind != .newline and token.kind != .comma and token.kind != .close_paren and token.kind != .close_curly and token.kind != .eof) {
|
||||
state.next_token += 1
|
||||
}
|
||||
if (token.kind != .newline and token.kind != .comma and
|
||||
token.kind != .close_paren and token.kind != .close_curly and
|
||||
token.kind != .eof) state.next_token += 1
|
||||
|
||||
return try ast.add_invalid_expr(&state.builder, token.span, diagnostic)
|
||||
}
|
||||
@@ -331,14 +338,20 @@ parse_primary proc(state @mut State) ast.NodeId ! ParseError {
|
||||
}
|
||||
|
||||
@hide:file
|
||||
recover_decl proc(state @mut State, start usize) ast.NodeId ! (mem.AllocError | diagnostics.CapacityError) {
|
||||
recover_decl proc(
|
||||
state @mut State,
|
||||
start usize,
|
||||
) ast.NodeId ! (mem.AllocError | diagnostics.CapacityError) {
|
||||
diagnostic :: try diagnostics.add(state.diagnostics, .unexpected_token, current(state).span)
|
||||
span :: synchronize(state, start, false)
|
||||
return try ast.add_invalid_decl(&state.builder, span, diagnostic)
|
||||
}
|
||||
|
||||
@hide:file
|
||||
recover_statement proc(state @mut State, start usize) ast.NodeId ! (mem.AllocError | diagnostics.CapacityError) {
|
||||
recover_statement proc(
|
||||
state @mut State,
|
||||
start usize,
|
||||
) ast.NodeId ! (mem.AllocError | diagnostics.CapacityError) {
|
||||
diagnostic :: try diagnostics.add(state.diagnostics, .unexpected_token, current(state).span)
|
||||
span :: synchronize(state, start, true)
|
||||
return try ast.add_invalid_stmt(&state.builder, span, diagnostic)
|
||||
|
||||
@@ -7,8 +7,8 @@ import "@source/lexer"
|
||||
import "@source/ast"
|
||||
|
||||
parses_expression_precedence_through_tree_views test {
|
||||
strpool.STRINGS = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.STRINGS)
|
||||
strpool.strings = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.strings)
|
||||
diagnostic_store := diagnostics.init(mem.c_allocator)
|
||||
defer diagnostics.deinit(&diagnostic_store)
|
||||
source :: "value :: 1 + 2 * 3\n"
|
||||
@@ -16,7 +16,7 @@ parses_expression_precedence_through_tree_views test {
|
||||
defer lexer.deinit(&scan_state)
|
||||
try lexer.scan(&scan_state, source, &diagnostic_store)
|
||||
|
||||
tree := try parse(scan_state.tokens.items, source, &diagnostic_store, mem.c_allocator)
|
||||
tree := try parse(mem.c_allocator, scan_state.tokens.items, source, &diagnostic_store)
|
||||
defer ast.deinit(&tree)
|
||||
|
||||
try testing.expect_equal(1, ast.package_decl_count(&tree))
|
||||
@@ -34,8 +34,8 @@ parses_expression_precedence_through_tree_views test {
|
||||
}
|
||||
|
||||
parses_grouped_expression_precedence test {
|
||||
strpool.STRINGS = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.STRINGS)
|
||||
strpool.strings = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.strings)
|
||||
diagnostic_store := diagnostics.init(mem.c_allocator)
|
||||
defer diagnostics.deinit(&diagnostic_store)
|
||||
source :: "value :: a + ((b - c)) * 2 / 3\n"
|
||||
@@ -43,7 +43,7 @@ parses_grouped_expression_precedence test {
|
||||
defer lexer.deinit(&scan_state)
|
||||
try lexer.scan(&scan_state, source, &diagnostic_store)
|
||||
|
||||
tree := try parse(scan_state.tokens.items, source, &diagnostic_store, mem.c_allocator)
|
||||
tree := try parse(mem.c_allocator, scan_state.tokens.items, source, &diagnostic_store)
|
||||
defer ast.deinit(&tree)
|
||||
|
||||
try testing.expect_equal(0, diagnostics.count(&diagnostic_store))
|
||||
@@ -65,8 +65,8 @@ parses_grouped_expression_precedence test {
|
||||
}
|
||||
|
||||
parses_function_structure_through_tree_views test {
|
||||
strpool.STRINGS = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.STRINGS)
|
||||
strpool.strings = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.strings)
|
||||
diagnostic_store := diagnostics.init(mem.c_allocator)
|
||||
defer diagnostics.deinit(&diagnostic_store)
|
||||
source ::
|
||||
@@ -77,7 +77,7 @@ parses_function_structure_through_tree_views test {
|
||||
defer lexer.deinit(&scan_state)
|
||||
try lexer.scan(&scan_state, source, &diagnostic_store)
|
||||
|
||||
tree := try parse(scan_state.tokens.items, source, &diagnostic_store, mem.c_allocator)
|
||||
tree := try parse(mem.c_allocator, scan_state.tokens.items, source, &diagnostic_store)
|
||||
defer ast.deinit(&tree)
|
||||
|
||||
declaration :: ast.package_decl(&tree, 0)
|
||||
@@ -98,8 +98,8 @@ parses_function_structure_through_tree_views test {
|
||||
}
|
||||
|
||||
recovers_invalid_declaration_and_preserves_sibling test {
|
||||
strpool.STRINGS = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.STRINGS)
|
||||
strpool.strings = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.strings)
|
||||
diagnostic_store := diagnostics.init(mem.c_allocator)
|
||||
defer diagnostics.deinit(&diagnostic_store)
|
||||
source :: "@ broken\nvalid :: 1\n"
|
||||
@@ -107,7 +107,7 @@ recovers_invalid_declaration_and_preserves_sibling test {
|
||||
defer lexer.deinit(&scan_state)
|
||||
try lexer.scan(&scan_state, source, &diagnostic_store)
|
||||
|
||||
tree := try parse(scan_state.tokens.items, source, &diagnostic_store, mem.c_allocator)
|
||||
tree := try parse(mem.c_allocator, scan_state.tokens.items, source, &diagnostic_store)
|
||||
defer ast.deinit(&tree)
|
||||
|
||||
try testing.expect_equal(2, ast.package_decl_count(&tree))
|
||||
@@ -122,8 +122,8 @@ recovers_invalid_declaration_and_preserves_sibling test {
|
||||
}
|
||||
|
||||
recovers_malformed_groups_and_preserves_following_statements test {
|
||||
strpool.STRINGS = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.STRINGS)
|
||||
strpool.strings = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.strings)
|
||||
diagnostic_store := diagnostics.init(mem.c_allocator)
|
||||
defer diagnostics.deinit(&diagnostic_store)
|
||||
source ::
|
||||
@@ -138,7 +138,7 @@ recovers_malformed_groups_and_preserves_following_statements test {
|
||||
defer lexer.deinit(&scan_state)
|
||||
try lexer.scan(&scan_state, source, &diagnostic_store)
|
||||
|
||||
tree := try parse(scan_state.tokens.items, source, &diagnostic_store, mem.c_allocator)
|
||||
tree := try parse(mem.c_allocator, scan_state.tokens.items, source, &diagnostic_store)
|
||||
defer ast.deinit(&tree)
|
||||
|
||||
try testing.expect_equal(3, diagnostics.count(&diagnostic_store))
|
||||
@@ -161,8 +161,8 @@ recovers_malformed_groups_and_preserves_following_statements test {
|
||||
}
|
||||
|
||||
parses_call_statements_and_postfix_precedence test {
|
||||
strpool.STRINGS = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.STRINGS)
|
||||
strpool.strings = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.strings)
|
||||
diagnostic_store := diagnostics.init(mem.c_allocator)
|
||||
defer diagnostics.deinit(&diagnostic_store)
|
||||
source ::
|
||||
@@ -174,7 +174,7 @@ parses_call_statements_and_postfix_precedence test {
|
||||
scan_state := lexer.init(mem.c_allocator)
|
||||
defer lexer.deinit(&scan_state)
|
||||
try lexer.scan(&scan_state, source, &diagnostic_store)
|
||||
tree := try parse(scan_state.tokens.items, source, &diagnostic_store, mem.c_allocator)
|
||||
tree := try parse(mem.c_allocator, scan_state.tokens.items, source, &diagnostic_store)
|
||||
defer ast.deinit(&tree)
|
||||
|
||||
try testing.expect_equal(0, diagnostics.count(&diagnostic_store))
|
||||
@@ -185,7 +185,10 @@ parses_call_statements_and_postfix_precedence test {
|
||||
ping :: ast.statement_expr(&tree, ping_stmt)
|
||||
try testing.expect_equal(ast.ExprKind.call, ast.expr_kind(&tree, ping))
|
||||
try testing.expect_equal(0, ast.call_arg_count(&tree, ping))
|
||||
try testing.expect_equal("ping", ast.source_text(&tree, ast.node_span(&tree, ast.call_expr(&tree, ping).callee)))
|
||||
try testing.expect_equal(
|
||||
"ping",
|
||||
ast.source_text(&tree, ast.node_span(&tree, ast.call_expr(&tree, ping).callee)),
|
||||
)
|
||||
try testing.expect_equal("ping()", ast.source_text(&tree, ast.call_expr(&tree, ping).span))
|
||||
|
||||
result :: ast.statement_decl(&tree, ast.block_statement(&tree, function.body, 1))
|
||||
@@ -198,11 +201,20 @@ parses_call_statements_and_postfix_precedence test {
|
||||
try testing.expect_equal(2, ast.call_arg_count(&tree, call))
|
||||
factory :: ast.call_expr(&tree, call).callee
|
||||
try testing.expect_equal(0, ast.call_arg_count(&tree, factory))
|
||||
try testing.expect_equal("factory", ast.source_text(&tree, ast.node_span(&tree, ast.call_expr(&tree, factory).callee)))
|
||||
try testing.expect_equal(
|
||||
"factory",
|
||||
ast.source_text(&tree, ast.node_span(&tree, ast.call_expr(&tree, factory).callee)),
|
||||
)
|
||||
nested :: ast.call_arg(&tree, call, 0)
|
||||
try testing.expect_equal(2, ast.call_arg_count(&tree, nested))
|
||||
try testing.expect_equal("add", ast.source_text(&tree, ast.node_span(&tree, ast.call_expr(&tree, nested).callee)))
|
||||
try testing.expect_equal("1", ast.source_text(&tree, ast.node_span(&tree, ast.call_arg(&tree, nested, 0))))
|
||||
try testing.expect_equal(
|
||||
"add",
|
||||
ast.source_text(&tree, ast.node_span(&tree, ast.call_expr(&tree, nested).callee)),
|
||||
)
|
||||
try testing.expect_equal(
|
||||
"1",
|
||||
ast.source_text(&tree, ast.node_span(&tree, ast.call_arg(&tree, nested, 0))),
|
||||
)
|
||||
multiply :: ast.binary_expr(&tree, ast.call_arg(&tree, nested, 1))
|
||||
try testing.expect_equal(ast.BinaryOperator.multiply, multiply.operator)
|
||||
try testing.expect_equal("2", ast.source_text(&tree, ast.node_span(&tree, multiply.left)))
|
||||
@@ -213,14 +225,20 @@ parses_call_statements_and_postfix_precedence test {
|
||||
try testing.expect_equal("5", ast.source_text(&tree, ast.node_span(&tree, grouped.right)))
|
||||
|
||||
handler :: ast.statement_expr(&tree, ast.block_statement(&tree, function.body, 2))
|
||||
try testing.expect_equal("handler", ast.source_text(&tree, ast.node_span(&tree, ast.call_expr(&tree, handler).callee)))
|
||||
try testing.expect_equal(
|
||||
"handler",
|
||||
ast.source_text(&tree, ast.node_span(&tree, ast.call_expr(&tree, handler).callee)),
|
||||
)
|
||||
try testing.expect_equal(1, ast.call_arg_count(&tree, handler))
|
||||
try testing.expect_equal("result", ast.source_text(&tree, ast.node_span(&tree, ast.call_arg(&tree, handler, 0))))
|
||||
try testing.expect_equal(
|
||||
"result",
|
||||
ast.source_text(&tree, ast.node_span(&tree, ast.call_arg(&tree, handler, 0))),
|
||||
)
|
||||
}
|
||||
|
||||
recovers_malformed_calls_and_preserves_siblings test {
|
||||
strpool.STRINGS = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.STRINGS)
|
||||
strpool.strings = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.strings)
|
||||
diagnostic_store := diagnostics.init(mem.c_allocator)
|
||||
defer diagnostics.deinit(&diagnostic_store)
|
||||
source ::
|
||||
@@ -235,7 +253,7 @@ recovers_malformed_calls_and_preserves_siblings test {
|
||||
scan_state := lexer.init(mem.c_allocator)
|
||||
defer lexer.deinit(&scan_state)
|
||||
try lexer.scan(&scan_state, source, &diagnostic_store)
|
||||
tree := try parse(scan_state.tokens.items, source, &diagnostic_store, mem.c_allocator)
|
||||
tree := try parse(mem.c_allocator, scan_state.tokens.items, source, &diagnostic_store)
|
||||
defer ast.deinit(&tree)
|
||||
|
||||
try testing.expect_equal(3, diagnostics.count(&diagnostic_store))
|
||||
@@ -245,16 +263,24 @@ recovers_malformed_calls_and_preserves_siblings test {
|
||||
for ([0, 2]) |index| {
|
||||
statement :: ast.block_statement(&tree, function.body, usize(index))
|
||||
try testing.expect_equal(ast.StmtKind.invalid, ast.stmt_kind(&tree, statement))
|
||||
try testing.expect(diagnostics.get(&diagnostic_store, ast.invalid(&tree, statement).diagnostic) != null)
|
||||
try testing.expect(
|
||||
diagnostics.get(&diagnostic_store, ast.invalid(&tree, statement).diagnostic) != null,
|
||||
)
|
||||
}
|
||||
good :: ast.statement_expr(&tree, ast.block_statement(&tree, function.body, 1))
|
||||
try testing.expect_equal("good", ast.source_text(&tree, ast.node_span(&tree, ast.call_expr(&tree, good).callee)))
|
||||
try testing.expect_equal(
|
||||
"good",
|
||||
ast.source_text(&tree, ast.node_span(&tree, ast.call_expr(&tree, good).callee)),
|
||||
)
|
||||
after :: ast.statement_decl(&tree, ast.block_statement(&tree, function.body, 3))
|
||||
try testing.expect_equal("after", ast.source_text(&tree, after.name))
|
||||
holes :: ast.statement_expr(&tree, ast.block_statement(&tree, function.body, 4))
|
||||
try testing.expect_equal(2, ast.call_arg_count(&tree, holes))
|
||||
try testing.expect_equal(ast.ExprKind.invalid, ast.expr_kind(&tree, ast.call_arg(&tree, holes, 0)))
|
||||
try testing.expect_equal("2", ast.source_text(&tree, ast.node_span(&tree, ast.call_arg(&tree, holes, 1))))
|
||||
try testing.expect_equal(
|
||||
"2",
|
||||
ast.source_text(&tree, ast.node_span(&tree, ast.call_arg(&tree, holes, 1))),
|
||||
)
|
||||
tail :: ast.statement_decl(&tree, ast.package_decl(&tree, 1))
|
||||
try testing.expect_equal("tail", ast.source_text(&tree, tail.name))
|
||||
try testing.expect_equal(0, ast.call_arg_count(&tree, tail.initializer))
|
||||
|
||||
Reference in New Issue
Block a user