203 lines
7.4 KiB
Plaintext
203 lines
7.4 KiB
Plaintext
import "@std/mem"
|
|
import "@std/testing"
|
|
|
|
import "@source/strpool"
|
|
import "@source/lexer"
|
|
import "@source/ast"
|
|
|
|
ast_renderer :: import "@source/ast/renderer"
|
|
|
|
handles_package_declarations test {
|
|
strpool.STRINGS = strpool.init(mem.c_allocator)
|
|
defer strpool.deinit(&strpool.STRINGS)
|
|
|
|
source ::
|
|
`first int :: 42
|
|
`second float :: 2.15 + 3
|
|
`message :: "hello"
|
|
|
|
scan_state := lexer.init(mem.c_allocator)
|
|
defer lexer.deinit(&scan_state)
|
|
try lexer.scan(&scan_state, source)
|
|
|
|
parse_state := init(mem.c_allocator)
|
|
defer deinit(&parse_state)
|
|
root :: try parse(&parse_state, scan_state.tokens.items)
|
|
|
|
renderer := ast_renderer.init(mem.c_allocator)
|
|
defer ast_renderer.deinit(&renderer)
|
|
try ast_renderer.render_token_stream(&renderer, root, &parse_state, scan_state.tokens.items)
|
|
|
|
try testing.expect_equal(scan_state.tokens.items.len, renderer.tokens.items.len)
|
|
for scan_state.tokens.items |expected, i| {
|
|
actual :: renderer.tokens.items[i]
|
|
try testing.expect_equal(expected.kind, actual.kind)
|
|
try testing.expect_equal(expected.start, actual.start)
|
|
try testing.expect_equal(expected.str_id, actual.str_id)
|
|
}
|
|
}
|
|
|
|
handles_unary_arithmetic_prefix_expression test {
|
|
strpool.STRINGS = strpool.init(mem.c_allocator)
|
|
defer strpool.deinit(&strpool.STRINGS)
|
|
|
|
source ::
|
|
`first :: -42 + 1
|
|
|
|
scan_state := lexer.init(mem.c_allocator)
|
|
defer lexer.deinit(&scan_state)
|
|
try lexer.scan(&scan_state, source)
|
|
|
|
parse_state := init(mem.c_allocator)
|
|
defer deinit(&parse_state)
|
|
root :: try parse(&parse_state, scan_state.tokens.items)
|
|
|
|
renderer := ast_renderer.init(mem.c_allocator)
|
|
defer ast_renderer.deinit(&renderer)
|
|
try ast_renderer.render_token_stream(&renderer, root, &parse_state, scan_state.tokens.items)
|
|
|
|
try testing.expect_equal(scan_state.tokens.items.len, renderer.tokens.items.len)
|
|
for scan_state.tokens.items |expected, i| {
|
|
actual :: renderer.tokens.items[i]
|
|
try testing.expect_equal(expected.kind, actual.kind)
|
|
try testing.expect_equal(expected.start, actual.start)
|
|
try testing.expect_equal(expected.str_id, actual.str_id)
|
|
}
|
|
}
|
|
|
|
handles_binary_arithmetic_expression test {
|
|
strpool.STRINGS = strpool.init(mem.c_allocator)
|
|
defer strpool.deinit(&strpool.STRINGS)
|
|
|
|
source ::
|
|
`first int :: 42 + 3
|
|
`second :: 134 + 5
|
|
`third float :: 1.35 + 2
|
|
`fourth :: first + second
|
|
|
|
scan_state := lexer.init(mem.c_allocator)
|
|
defer lexer.deinit(&scan_state)
|
|
try lexer.scan(&scan_state, source)
|
|
|
|
parse_state := init(mem.c_allocator)
|
|
defer deinit(&parse_state)
|
|
root :: try parse(&parse_state, scan_state.tokens.items)
|
|
|
|
renderer := ast_renderer.init(mem.c_allocator)
|
|
defer ast_renderer.deinit(&renderer)
|
|
try ast_renderer.render_token_stream(&renderer, root, &parse_state, scan_state.tokens.items)
|
|
|
|
try testing.expect_equal(scan_state.tokens.items.len, renderer.tokens.items.len)
|
|
for scan_state.tokens.items |expected, i| {
|
|
actual :: renderer.tokens.items[i]
|
|
try testing.expect_equal(expected.kind, actual.kind)
|
|
try testing.expect_equal(expected.start, actual.start)
|
|
try testing.expect_equal(expected.str_id, actual.str_id)
|
|
}
|
|
}
|
|
|
|
handles_statement_declaration test {
|
|
strpool.STRINGS = strpool.init(mem.c_allocator)
|
|
defer strpool.deinit(&strpool.STRINGS)
|
|
|
|
source ::
|
|
`value int :: 42
|
|
|
|
scan_state := lexer.init(mem.c_allocator)
|
|
defer lexer.deinit(&scan_state)
|
|
try lexer.scan(&scan_state, source)
|
|
|
|
parse_state := init(mem.c_allocator)
|
|
defer deinit(&parse_state)
|
|
root :: try parse(&parse_state, scan_state.tokens.items)
|
|
|
|
renderer := ast_renderer.init(mem.c_allocator)
|
|
defer ast_renderer.deinit(&renderer)
|
|
try ast_renderer.render_token_stream(&renderer, root, &parse_state, scan_state.tokens.items)
|
|
|
|
try testing.expect_equal(scan_state.tokens.items.len, renderer.tokens.items.len)
|
|
for scan_state.tokens.items |expected, i| {
|
|
actual :: renderer.tokens.items[i]
|
|
try testing.expect_equal(expected.kind, actual.kind)
|
|
try testing.expect_equal(expected.start, actual.start)
|
|
try testing.expect_equal(expected.str_id, actual.str_id)
|
|
}
|
|
}
|
|
|
|
handles_function_declarations test {
|
|
strpool.STRINGS = strpool.init(mem.c_allocator)
|
|
defer strpool.deinit(&strpool.STRINGS)
|
|
|
|
source ::
|
|
`empty proc() void {}
|
|
`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)
|
|
|
|
parse_state := init(mem.c_allocator)
|
|
defer deinit(&parse_state)
|
|
root_id :: try parse(&parse_state, scan_state.tokens.items)
|
|
root :: parse_state.nodes.items[usize(root_id)]
|
|
|
|
package_start :: usize(root.data0.extra_id)
|
|
package_end :: usize(root.data1.extra_id)
|
|
try testing.expect_equal(usize(2), package_end - package_start)
|
|
|
|
empty_id :: ast.node_id(parse_state.extra.items[package_start])
|
|
empty :: parse_state.nodes.items[usize(empty_id)]
|
|
empty_payload :: usize(empty.data1.extra_id)
|
|
empty_block :: parse_state.nodes.items[usize(empty.data0.node_id)]
|
|
try testing.expect_equal(ast.NodeKind.func_decl, empty.kind)
|
|
try testing.expect_equal(u32(0), parse_state.extra.items[empty_payload + 1])
|
|
try testing.expect_equal(
|
|
usize(empty_block.data0.extra_id),
|
|
usize(empty_block.data1.extra_id),
|
|
)
|
|
|
|
grouped_id :: ast.node_id(parse_state.extra.items[package_start + 1])
|
|
grouped :: parse_state.nodes.items[usize(grouped_id)]
|
|
grouped_payload :: usize(grouped.data1.extra_id)
|
|
try testing.expect_equal(ast.NodeKind.func_decl, grouped.kind)
|
|
try testing.expect_equal(u32(3), parse_state.extra.items[grouped_payload + 1])
|
|
|
|
param_a_id :: ast.node_id(parse_state.extra.items[grouped_payload + 2])
|
|
param_b_id :: ast.node_id(parse_state.extra.items[grouped_payload + 3])
|
|
param_c_id :: ast.node_id(parse_state.extra.items[grouped_payload + 4])
|
|
param_a :: parse_state.nodes.items[usize(param_a_id)]
|
|
param_b :: parse_state.nodes.items[usize(param_b_id)]
|
|
param_c :: parse_state.nodes.items[usize(param_c_id)]
|
|
try testing.expect_equal(ast.NodeKind.param_decl, param_a.kind)
|
|
try testing.expect_equal(ast.NodeKind.param_decl, param_b.kind)
|
|
try testing.expect_equal(ast.NodeKind.param_decl, param_c.kind)
|
|
try testing.expect(param_a.data0.node_id == param_b.data0.node_id)
|
|
try testing.expect(param_a.data0.node_id != param_c.data0.node_id)
|
|
|
|
grouped_block :: parse_state.nodes.items[usize(grouped.data0.node_id)]
|
|
try testing.expect_equal(ast.NodeKind.block, grouped_block.kind)
|
|
try testing.expect_equal(
|
|
usize(1),
|
|
usize(grouped_block.data1.extra_id) - usize(grouped_block.data0.extra_id),
|
|
)
|
|
|
|
renderer := ast_renderer.init(mem.c_allocator)
|
|
defer ast_renderer.deinit(&renderer)
|
|
try ast_renderer.render_token_stream(
|
|
&renderer,
|
|
root_id,
|
|
&parse_state,
|
|
scan_state.tokens.items,
|
|
)
|
|
|
|
try testing.expect_equal(scan_state.tokens.items.len, renderer.tokens.items.len)
|
|
for scan_state.tokens.items |expected, i| {
|
|
actual :: renderer.tokens.items[i]
|
|
try testing.expect_equal(expected.kind, actual.kind)
|
|
try testing.expect_equal(expected.start, actual.start)
|
|
try testing.expect_equal(expected.str_id, actual.str_id)
|
|
}
|
|
}
|