feat: parse grouped expressions
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
import "@std/mem"
|
||||
import "@std/testing"
|
||||
|
||||
import "@source/diagnostics"
|
||||
import "@source/strpool"
|
||||
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)
|
||||
diagnostic_store := diagnostics.init(mem.c_allocator)
|
||||
defer diagnostics.deinit(&diagnostic_store)
|
||||
source :: "value :: 1 + 2 * 3\n"
|
||||
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)
|
||||
defer ast.deinit(&tree)
|
||||
|
||||
try testing.expect_equal(1, ast.package_decl_count(&tree))
|
||||
declaration :: ast.package_decl(&tree, 0)
|
||||
statement :: ast.statement_decl(&tree, declaration)
|
||||
try testing.expect_equal("value", ast.source_text(&tree, statement.name))
|
||||
try testing.expect_equal(ast.ExprKind.binary, ast.expr_kind(&tree, statement.initializer))
|
||||
add :: ast.binary_expr(&tree, statement.initializer)
|
||||
try testing.expect_equal(ast.BinaryOperator.add, add.operator)
|
||||
try testing.expect_equal(ast.ExprKind.literal_int, ast.expr_kind(&tree, add.left))
|
||||
try testing.expect_equal(ast.ExprKind.binary, ast.expr_kind(&tree, add.right))
|
||||
multiply :: ast.binary_expr(&tree, add.right)
|
||||
try testing.expect_equal(ast.BinaryOperator.multiply, multiply.operator)
|
||||
try testing.expect_equal(0, diagnostics.count(&diagnostic_store))
|
||||
}
|
||||
|
||||
parses_grouped_expression_precedence test {
|
||||
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"
|
||||
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)
|
||||
defer ast.deinit(&tree)
|
||||
|
||||
try testing.expect_equal(0, diagnostics.count(&diagnostic_store))
|
||||
try testing.expect_equal(1, ast.package_decl_count(&tree))
|
||||
statement :: ast.statement_decl(&tree, ast.package_decl(&tree, 0))
|
||||
add :: ast.binary_expr(&tree, statement.initializer)
|
||||
try testing.expect_equal(ast.BinaryOperator.add, add.operator)
|
||||
try testing.expect_equal("a", ast.source_text(&tree, ast.node_span(&tree, add.left)))
|
||||
divide :: ast.binary_expr(&tree, add.right)
|
||||
try testing.expect_equal(ast.BinaryOperator.divide, divide.operator)
|
||||
try testing.expect_equal("3", ast.source_text(&tree, ast.node_span(&tree, divide.right)))
|
||||
multiply :: ast.binary_expr(&tree, divide.left)
|
||||
try testing.expect_equal(ast.BinaryOperator.multiply, multiply.operator)
|
||||
try testing.expect_equal("2", ast.source_text(&tree, ast.node_span(&tree, multiply.right)))
|
||||
subtract :: ast.binary_expr(&tree, multiply.left)
|
||||
try testing.expect_equal(ast.BinaryOperator.subtract, subtract.operator)
|
||||
try testing.expect_equal("b", ast.source_text(&tree, ast.node_span(&tree, subtract.left)))
|
||||
try testing.expect_equal("c", ast.source_text(&tree, ast.node_span(&tree, subtract.right)))
|
||||
}
|
||||
|
||||
parses_function_structure_through_tree_views test {
|
||||
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 ::
|
||||
`grouped proc(a, b T, c U) void {
|
||||
` value int :: 1
|
||||
`}
|
||||
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)
|
||||
defer ast.deinit(&tree)
|
||||
|
||||
declaration :: ast.package_decl(&tree, 0)
|
||||
try testing.expect_equal(ast.DeclKind.function, ast.decl_kind(&tree, declaration))
|
||||
function :: ast.function_decl(&tree, declaration)
|
||||
try testing.expect_equal("grouped", ast.source_text(&tree, function.name))
|
||||
try testing.expect_equal(3, ast.function_param_count(&tree, declaration))
|
||||
first :: ast.param(&tree, ast.function_param(&tree, declaration, 0))
|
||||
second :: ast.param(&tree, ast.function_param(&tree, declaration, 1))
|
||||
third :: ast.param(&tree, ast.function_param(&tree, declaration, 2))
|
||||
try testing.expect_equal("a", ast.source_text(&tree, first.name))
|
||||
try testing.expect_equal("b", ast.source_text(&tree, second.name))
|
||||
try testing.expect_equal("c", ast.source_text(&tree, third.name))
|
||||
try testing.expect_equal(first.type, second.type)
|
||||
try testing.expect(first.type != third.type)
|
||||
try testing.expect_equal(1, ast.block_statement_count(&tree, function.body))
|
||||
try testing.expect_equal(0, diagnostics.count(&diagnostic_store))
|
||||
}
|
||||
|
||||
recovers_invalid_declaration_and_preserves_sibling test {
|
||||
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"
|
||||
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)
|
||||
defer ast.deinit(&tree)
|
||||
|
||||
try testing.expect_equal(2, ast.package_decl_count(&tree))
|
||||
invalid_decl :: ast.package_decl(&tree, 0)
|
||||
valid_decl :: ast.package_decl(&tree, 1)
|
||||
try testing.expect_equal(ast.DeclKind.invalid, ast.decl_kind(&tree, invalid_decl))
|
||||
try testing.expect_equal(ast.DeclKind.statement, ast.decl_kind(&tree, valid_decl))
|
||||
invalid_view :: ast.invalid(&tree, invalid_decl)
|
||||
try testing.expect(diagnostics.get(&diagnostic_store, invalid_view.diagnostic) != null)
|
||||
valid_statement :: ast.statement_decl(&tree, valid_decl)
|
||||
try testing.expect_equal("valid", ast.source_text(&tree, valid_statement.name))
|
||||
}
|
||||
|
||||
recovers_malformed_groups_and_preserves_following_statements test {
|
||||
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 ::
|
||||
`main proc() void {
|
||||
` empty :: ()
|
||||
` operand :: (1 + )
|
||||
` missing :: (2
|
||||
` valid :: (3)
|
||||
`}
|
||||
`after :: 4
|
||||
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)
|
||||
defer ast.deinit(&tree)
|
||||
|
||||
try testing.expect_equal(3, diagnostics.count(&diagnostic_store))
|
||||
try testing.expect_equal(2, ast.package_decl_count(&tree))
|
||||
function :: ast.function_decl(&tree, ast.package_decl(&tree, 0))
|
||||
try testing.expect_equal(4, ast.block_statement_count(&tree, function.body))
|
||||
empty :: ast.statement_decl(&tree, ast.block_statement(&tree, function.body, 0))
|
||||
try testing.expect_equal(ast.ExprKind.invalid, ast.expr_kind(&tree, empty.initializer))
|
||||
operand :: ast.statement_decl(&tree, ast.block_statement(&tree, function.body, 1))
|
||||
add :: ast.binary_expr(&tree, operand.initializer)
|
||||
try testing.expect_equal(ast.ExprKind.invalid, ast.expr_kind(&tree, add.right))
|
||||
missing :: ast.statement_decl(&tree, ast.block_statement(&tree, function.body, 2))
|
||||
try testing.expect_equal(ast.ExprKind.invalid, ast.expr_kind(&tree, missing.initializer))
|
||||
valid :: ast.statement_decl(&tree, ast.block_statement(&tree, function.body, 3))
|
||||
try testing.expect_equal(ast.ExprKind.literal_int, ast.expr_kind(&tree, valid.initializer))
|
||||
try testing.expect_equal("3", ast.source_text(&tree, ast.node_span(&tree, valid.initializer)))
|
||||
after :: ast.statement_decl(&tree, ast.package_decl(&tree, 1))
|
||||
try testing.expect_equal("after", ast.source_text(&tree, after.name))
|
||||
try testing.expect_equal("4", ast.source_text(&tree, ast.node_span(&tree, after.initializer)))
|
||||
}
|
||||
Reference in New Issue
Block a user