refactor: integrate compilation-owned identifier interning
This commit is contained in:
+37
-6
@@ -16,6 +16,7 @@ import "@std/debug"
|
||||
import "@std/mem"
|
||||
import "@std/arraylist"
|
||||
import "@source/diagnostics"
|
||||
import "@source/strpool"
|
||||
|
||||
Span :: alias diagnostics.Span
|
||||
DiagnosticId :: alias diagnostics.DiagnosticId
|
||||
@@ -114,6 +115,7 @@ NodeKind :: enum {
|
||||
NodeData :: union {
|
||||
node_id NodeId
|
||||
extra u32
|
||||
name_id strpool.StringId
|
||||
diagnostic DiagnosticId
|
||||
mutability Mutability
|
||||
unary_operator UnaryOperator
|
||||
@@ -295,8 +297,15 @@ add_literal proc(builder @mut Builder, kind LiteralKind, span Span) NodeId ! mem
|
||||
return try add_node(builder, Node{ kind = node_kind }, span)
|
||||
}
|
||||
|
||||
add_identifier proc(builder @mut Builder, span Span) NodeId ! mem.AllocError {
|
||||
return try add_node(builder, Node{ kind = .expr_identifier }, span)
|
||||
add_identifier proc(
|
||||
builder @mut Builder,
|
||||
span Span,
|
||||
interned_name strpool.StringId,
|
||||
) NodeId ! mem.AllocError {
|
||||
return try add_node(builder, Node{
|
||||
kind = .expr_identifier,
|
||||
main = NodeData{ name_id = interned_name },
|
||||
}, span)
|
||||
}
|
||||
|
||||
add_unary proc(
|
||||
@@ -475,6 +484,7 @@ add_statement_decl proc(
|
||||
builder @mut Builder,
|
||||
span Span,
|
||||
name Span,
|
||||
interned_name strpool.StringId,
|
||||
type ?NodeId,
|
||||
mutability Mutability,
|
||||
initializer NodeId,
|
||||
@@ -488,16 +498,23 @@ add_statement_decl proc(
|
||||
kind = .stmt_decl,
|
||||
main = NodeData{ extra = extra },
|
||||
data0 = NodeData{ mutability = mutability },
|
||||
data1 = NodeData{ name_id = interned_name },
|
||||
}, span)
|
||||
}
|
||||
|
||||
add_param proc(builder @mut Builder, span, name Span, type NodeId) NodeId ! mem.AllocError {
|
||||
add_param proc(
|
||||
builder @mut Builder,
|
||||
span, name Span,
|
||||
interned_name strpool.StringId,
|
||||
type NodeId,
|
||||
) NodeId ! mem.AllocError {
|
||||
extra :: try add_extra(builder, name.start)
|
||||
_ = try add_extra(builder, name.end)
|
||||
return try add_node(builder, Node{
|
||||
kind = .param_decl,
|
||||
main = NodeData{ extra = extra },
|
||||
data0 = NodeData{ node_id = type },
|
||||
data1 = NodeData{ name_id = interned_name },
|
||||
}, span)
|
||||
}
|
||||
|
||||
@@ -505,6 +522,7 @@ add_function_decl proc(
|
||||
builder @mut Builder,
|
||||
span Span,
|
||||
name Span,
|
||||
interned_name strpool.StringId,
|
||||
return_type NodeId,
|
||||
params []NodeId,
|
||||
body NodeId,
|
||||
@@ -513,6 +531,7 @@ add_function_decl proc(
|
||||
_ = try add_extra(builder, name.start)
|
||||
_ = try add_extra(builder, name.end)
|
||||
_ = try add_extra(builder, u32(return_type))
|
||||
_ = try add_extra(builder, u32(interned_name))
|
||||
for (params) |parameter| _ = try add_extra(builder, u32(parameter))
|
||||
return try add_node(builder, Node{
|
||||
kind = .func_decl,
|
||||
@@ -579,6 +598,18 @@ node_count proc(tree @Tree) usize {
|
||||
return tree.storage.nodes.items.len
|
||||
}
|
||||
|
||||
#! returns the identifier's identity in the compilation-owned string pool.
|
||||
#! accepts identifiers, declarations, and parameters; source spans remain available in typed views.
|
||||
name_id proc(tree @Tree, id NodeId) strpool.StringId {
|
||||
node :: get_node(&tree.storage, id)
|
||||
return match node.kind {
|
||||
.expr_identifier: node.main.name_id
|
||||
.stmt_decl, .param_decl: node.data1.name_id
|
||||
.func_decl: strpool.StringId(tree.storage.extra.items[usize(node.main.extra) + 3])
|
||||
else: unreachable
|
||||
}
|
||||
}
|
||||
|
||||
package_decl_count proc(tree @Tree) usize {
|
||||
root :: get_node(&tree.storage, tree.root)
|
||||
debug.assert(root.kind == .package)
|
||||
@@ -707,14 +738,14 @@ function_decl proc(tree @Tree, id NodeId) FunctionDeclView {
|
||||
function_param_count proc(tree @Tree, id NodeId) usize {
|
||||
node :: get_node(&tree.storage, id)
|
||||
debug.assert(node.kind == .func_decl)
|
||||
return usize(node.data1.extra - node.main.extra - 3)
|
||||
return usize(node.data1.extra - node.main.extra - 4)
|
||||
}
|
||||
|
||||
function_param proc(tree @Tree, id NodeId, index usize) NodeId {
|
||||
node :: get_node(&tree.storage, id)
|
||||
debug.assert(node.kind == .func_decl)
|
||||
debug.assert(index < usize(node.data1.extra - node.main.extra - 3))
|
||||
return NodeId(tree.storage.extra.items[usize(node.main.extra) + 3 + index])
|
||||
debug.assert(index < usize(node.data1.extra - node.main.extra - 4))
|
||||
return NodeId(tree.storage.extra.items[usize(node.main.extra) + 4 + index])
|
||||
}
|
||||
|
||||
param proc(tree @Tree, id NodeId) ParamView {
|
||||
|
||||
+11
-1
@@ -1,7 +1,11 @@
|
||||
import "@std/mem"
|
||||
import "@std/testing"
|
||||
import "@source/strpool"
|
||||
|
||||
exposes_typed_declaration_views test {
|
||||
strings := strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strings)
|
||||
value_id :: try strpool.intern(&strings, "value")
|
||||
builder := init_builder(mem.c_allocator, "value :: 42")
|
||||
defer deinit_builder(&builder)
|
||||
|
||||
@@ -11,6 +15,7 @@ exposes_typed_declaration_views test {
|
||||
&builder,
|
||||
Span{ start = 0, end = 11 },
|
||||
value_name,
|
||||
value_id,
|
||||
null,
|
||||
.constant,
|
||||
value,
|
||||
@@ -23,6 +28,7 @@ exposes_typed_declaration_views test {
|
||||
try testing.expect_equal(1, package_decl_count(&tree))
|
||||
decl :: package_decl(&tree, 0)
|
||||
try testing.expect_equal(DeclKind.statement, decl_kind(&tree, decl))
|
||||
try testing.expect_equal(value_id, name_id(&tree, decl))
|
||||
|
||||
statement :: statement_decl(&tree, decl)
|
||||
try testing.expect_equal(value_name.start, statement.name.start)
|
||||
@@ -34,11 +40,14 @@ exposes_typed_declaration_views test {
|
||||
}
|
||||
|
||||
exposes_array_type_literal_and_index_views test {
|
||||
strings := strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strings)
|
||||
element_id :: try strpool.intern(&strings, "int")
|
||||
builder := init_builder(mem.c_allocator, "")
|
||||
defer deinit_builder(&builder)
|
||||
span :: Span{ start = 0, end = 0 }
|
||||
count :: try add_literal(&builder, .int, span)
|
||||
element :: try add_identifier(&builder, span)
|
||||
element :: try add_identifier(&builder, span, element_id)
|
||||
row :: try add_array_type(&builder, span, count, element, false)
|
||||
matrix :: try add_array_type(&builder, span, null, row, true)
|
||||
elements [2]NodeId :: [count, element]
|
||||
@@ -55,6 +64,7 @@ exposes_array_type_literal_and_index_views test {
|
||||
try testing.expect_equal(count, array_type(&tree, row).count?)
|
||||
try testing.expect(!array_type(&tree, row).mutable)
|
||||
try testing.expect_equal(element, array_type(&tree, row).element)
|
||||
try testing.expect_equal(element_id, name_id(&tree, element))
|
||||
try testing.expect_equal(ExprKind.array_literal, expr_kind(&tree, literal))
|
||||
try testing.expect_equal(2, array_element_count(&tree, literal))
|
||||
try testing.expect_equal(count, array_element(&tree, literal, 0))
|
||||
|
||||
@@ -7,8 +7,8 @@ import "@source/parser"
|
||||
import "@source/ast"
|
||||
|
||||
renders_array_annotations_literals_and_indexed_assignments test {
|
||||
strpool.strings = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.strings)
|
||||
strings := strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strings)
|
||||
diagnostic_store := diagnostics.init(mem.c_allocator)
|
||||
defer diagnostics.deinit(&diagnostic_store)
|
||||
source ::
|
||||
@@ -19,7 +19,7 @@ renders_array_annotations_literals_and_indexed_assignments test {
|
||||
`}
|
||||
scan_state := lexer.init(mem.c_allocator)
|
||||
defer lexer.deinit(&scan_state)
|
||||
try lexer.scan(&scan_state, source, &diagnostic_store)
|
||||
try lexer.scan(&scan_state, source, &strings, &diagnostic_store)
|
||||
tree := try parser.parse(mem.c_allocator, scan_state.tokens.items, source, &diagnostic_store)
|
||||
defer ast.deinit(&tree)
|
||||
renderer := init(mem.c_allocator)
|
||||
|
||||
Reference in New Issue
Block a user