Files
2026-08-16 00:50:11 +02:00

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)
}
}