Skip to content
← Back

src/syntax/trees/expressions/expression.ghul

1
namespace Syntax.Trees.Expressions is
2
use Source;
3
4
use IR.Values.Value;
5
6
use Logging;
7
8
class Expression: Trees.Node, TypeConstrained abstract is
9
// Compile-expressions output; contents owned by that pass.
10
compile_expressions_state: Syntax.Process.EXPRESSION_STATE field;
11
12
value: Value? => compile_expressions_state.value;
13
right_location: LOCATION => location;
14
15
is_identifier: bool => false;
16
is_unqualified_identifier: bool => false;
17
is_member: bool => false;
18
is_tuple_literal: bool => false;
19
20
could_be_formal_argument: bool => false;
21
could_be_nested_function_definition: bool => false;
22
could_be_type_expression: bool => false;
23
must_be_consumed: bool => false;
24
25
description: string => "expression";
26
27
// Storage lives in compile_expressions_state, but it is written only by the
28
// node kinds whose set_expected_type override stores (see below)
29
// — for every other kind this stays null, as before.
30
expected_type: Semantic.Types.Type? => compile_expressions_state.expected_type;
31
expected_type_error_message: string? => compile_expressions_state.expected_type_error_message;
32
33
// Set on a call's callee expression before it is compiled. A callee
34
// that resolves to a reflected TYPE_GROUP (same name at several
35
// generic arities) is a constructor invocation, so it must keep the
36
// group's generic member for constructor inference rather than
37
// collapsing to the arity-0 member the way a plain value-position
38
// reference does. Reset by clear() between compile cycles.
39
is_call_target: bool => compile_expressions_state.is_call_target;
40
mark_call_target() is compile_expressions_state.is_call_target = true; si
41
42
init(location: LOCATION) is
43
super.init(location);
44
si
45
46
accept(visitor: Visitor) is
47
visitor.visit(self);
48
si
49
50
try_copy_as_variables() -> Variables.LIST? => null;
51
try_copy_as_variable() -> VARIABLE? => null;
52
try_copy_as_tuple_element() -> TUPLE_ELEMENT? => null;
53
54
// Reinterpret this expression as one element of a lambda
55
// parameter's destructure pattern. A parenthesised group
56
// parses as a TUPLE and an element name as an IDENTIFIER (or
57
// a VARIABLE once it carries a `: T`), because the parser
58
// can't know it is looking at a pattern until it reaches the
59
// `=>`. Null for any shape that is not a legal pattern
60
// element, which the caller reports.
61
try_copy_as_variable_left() -> Variables.VariableLeft? => null;
62
try_copy_as_type_expression() -> TypeExpressions.TypeExpression? => null;
63
try_copy_as_identifer() -> Identifiers.Identifier? => null;
64
65
rewrite_as_assignment_left() -> AssignmentLeftExpression => SIMPLE_LEFT_EXPRESSION(location, self);
66
rewrite_as_expression() -> Expression => self;
67
68
try_get_string_literal() -> string? => null;
69
70
// Replace `old` with `replacement` in this node's subexpression
71
// slots, if `old` is one of them (reference-equal). Called by
72
// the SPILL_AWAITS pass to wrap subexpressions in SPILL nodes
73
// without exposing the slot fields as publicly writable. Each
74
// composite subclass overrides this to handle its specific
75
// slots; the default is a no-op for non-composite nodes that
76
// have no replaceable children.
77
replace_child(old: Expression, replacement: Expression) is
78
si
79
80
// Deliberately a no-op: node kinds that don't store the constraint
81
// drop it here. Storing kinds override to write compile_expressions_state.
82
set_expected_type(expected_type: Semantic.Types.Type?, error_message: string?) is si
83
84
clear_expected_type() is
85
compile_expressions_state.expected_type = null;
86
compile_expressions_state.expected_type_error_message = null;
87
si
88
89
// Non-recursive clear of per-build state on this expression. See
90
// Node.clear() and CLEAR_STATE_VISITOR for the orchestration.
91
clear() is
92
compile_expressions_state.clear();
93
si
94
95
// Default upgrade: install the new expected_type when there is no
96
// existing one, or when the new one is the same / strictly
97
// narrower than the existing (i.e. existing is_assignable_from
98
// new). Calls back through the polymorphic set_constraint so
99
// subclasses with real storage get the write without needing
100
// to override upgrade themselves.
101
upgrade_expected_type(new_expected_type: Semantic.Types.Type?, new_error_message: string?) is
102
if !new_expected_type? then
103
return;
104
fi
105
106
let existing = self.expected_type;
107
108
if !existing? \/ existing.is_assignable_from(new_expected_type) then
109
set_expected_type(new_expected_type, new_error_message);
110
fi
111
si
112
si
113
si