Skip to content
← Back

src/syntax/trees/node.ghul

1
namespace Syntax.Trees is
2
use IO.Std;
3
4
use System;
5
use Source;
6
7
class Node abstract is
8
_next_node_id: int static;
9
10
// Process-unique, monotonically increasing, never reused.
11
// Node-keyed state stores key on this instead of object
12
// identity. Never-reused is load-bearing: a reused id could
13
// serve one node's stale store entry to a different node, so
14
// the counter is global and never reset.
15
node_id: int public;
16
17
location: LOCATION public;
18
19
is_poisoned: bool;
20
21
init(location: LOCATION) is
22
_next_node_id = _next_node_id + 1;
23
node_id = _next_node_id;
24
25
self.location = location;
26
si
27
28
clone() -> Node is
29
let result = cast Node?(memberwise_clone())!;
30
31
// A memberwise clone copies node_id; the clone must not
32
// answer for the original in node-keyed stores.
33
_next_node_id = _next_node_id + 1;
34
result.node_id = _next_node_id;
35
36
// A memberwise clone also copies the original's scope; the
37
// clone starts unassociated until a declaration pass walks it.
38
if let carrier: ScopeCarrier = result then
39
carrier.scope = null;
40
fi
41
42
return result;
43
si
44
45
accept(visitor: Visitor) is
46
visitor.visit(self);
47
si
48
49
walk(visitor: Visitor) is
50
accept(visitor);
51
si
52
53
// Reset per-build state cached on this node by previous compilation
54
// passes. Non-recursive — clears only this node's own state, never
55
// children. CLEAR_STATE_VISITOR is responsible for traversal and
56
// calling clear() on each node it visits.
57
//
58
// Default is a no-op: most node types have no per-build mutable
59
// state. Subclasses with state (Expression, TypeExpression, ...)
60
// override.
61
//
62
// Run between compile-expressions invocations on the same AST
63
// (analyser COMPILE-after-EDIT, multi-file rebuilds where retained
64
// ASTs already have prior compile-expressions output) — see
65
// project_analysis_mode_workflow.
66
clear() is
67
si
68
69
poison(should_poison: bool) is
70
if should_poison then
71
is_poisoned = true;
72
fi
73
si
74
75
poison() is
76
is_poisoned = true;
77
si
78
79
to_string() -> string is
80
try
81
let printer = Process.Printer.GHUL();
82
accept(printer);
83
return printer.result;
84
catch ex: Exception
85
return "unprintable {get_type()}: {ex}";
86
yrt
87
si
88
si
89
si