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? pure => 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
// True for a node whose type comes from the context it sits in
21
// rather than from itself, and which carries no explicit type of
22
// its own: a bare `_`, or a `cast(v)` with the target elided.
23
// Such a node has no type to offer on its first walk, so a
24
// consumer that settles a type for it pushes that type in and
25
// re-walks it.
26
awaits_context_type: bool => false
27
28
could_be_formal_argument: bool => false
29
could_be_nested_function_definition: bool => false
30
could_be_type_expression: bool => false
31
must_be_consumed: bool => false
32
33
description: string => "expression"
34
35
// Storage lives in compile_expressions_state, but it is written only by the
36
// node kinds whose set_expected_type override stores (see below)
37
// — for every other kind this stays null, as before.
38
expected_type: Semantic.Types.Type? => compile_expressions_state.expected_type
39
expected_type_error_message: string? => compile_expressions_state.expected_type_error_message
40
41
// Set on a call's callee expression before it is compiled. A callee
42
// that resolves to a reflected TYPE_GROUP (same name at several
43
// generic arities) is a constructor invocation, so it must keep the
44
// group's generic member for constructor inference rather than
45
// collapsing to the arity-0 member the way a plain value-position
46
// reference does. Reset by clear() between compile cycles.
47
is_call_target: bool => compile_expressions_state.is_call_target
48
mark_call_target() is compile_expressions_state.is_call_target = true; si
49
50
init(location: LOCATION) is
51
super.init(location)
52
si
53
54
accept(visitor: Visitor) is
55
visitor.visit(self)
56
si
57
58
try_copy_as_variables() -> Variables.LIST? => null
59
try_copy_as_variable() -> VARIABLE? => null
60
try_copy_as_tuple_element() -> TUPLE_ELEMENT? => null
61
62
// Reinterpret this expression as one element of a lambda
63
// parameter's destructure pattern. A parenthesised group
64
// parses as a TUPLE and an element name as an IDENTIFIER (or
65
// a VARIABLE once it carries a `: T`), because the parser
66
// can't know it is looking at a pattern until it reaches the
67
// `=>`. Null for any shape that is not a legal pattern
68
// element, which the caller reports.
69
try_copy_as_variable_left() -> Variables.VariableLeft? => null
70
try_copy_as_type_expression() -> TypeExpressions.TypeExpression? => null
71
try_copy_as_identifer() -> Identifiers.Identifier? => null
72
73
rewrite_as_assignment_left() -> AssignmentLeftExpression => SIMPLE_LEFT_EXPRESSION(location, self)
74
rewrite_as_expression() -> Expression => self
75
76
try_get_string_literal() -> string? => null
77
78
// Replace `old` with `replacement` in this node's subexpression
79
// slots, if `old` is one of them (reference-equal). Called by
80
// the SPILL_AWAITS pass to wrap subexpressions in SPILL nodes
81
// without exposing the slot fields as publicly writable. Each
82
// composite subclass overrides this to handle its specific
83
// slots; the default is a no-op for non-composite nodes that
84
// have no replaceable children.
85
replace_child(old: Expression, replacement: Expression) is
86
si
87
88
// Deliberately a no-op: node kinds that don't store the constraint
89
// drop it here. Storing kinds override to write compile_expressions_state.
90
set_expected_type(expected_type: Semantic.Types.Type?, error_message: string?) is si
91
92
// Whether the expected type just pushed is a formal declared to
93
// take an argument pack spread out, so that a function of more
94
// parameters than it takes is one written with the pack spread
95
// out. Dropped whenever an expected type is pushed.
96
expects_pack: bool => compile_expressions_state.pack_marker == 1
97
98
// How many returns further in the marker sits, where it was
99
// written past the expected type's own function type -
100
// `f: X -> T.. -> U` - and zero otherwise.
101
nested_pack_depth: int =>
102
if compile_expressions_state.pack_marker > 1 then compile_expressions_state.pack_marker - 1 else 0 fi
103
104
set_expects_pack(depth: int) is
105
compile_expressions_state.pack_marker = depth + 1
106
si
107
108
clear_expected_type() is
109
compile_expressions_state.expected_type = null
110
compile_expressions_state.expected_type_error_message = null
111
si
112
113
// Non-recursive clear of per-build state on this expression. See
114
// Node.clear() and CLEAR_STATE_VISITOR for the orchestration.
115
clear() is
116
compile_expressions_state.clear()
117
si
118
119
clear_outputs() is
120
compile_expressions_state.clear_outputs()
121
si
122
123
// Default upgrade: install the new expected_type when there is no
124
// existing one, or when the new one is the same / strictly
125
// narrower than the existing (i.e. existing is_assignable_from
126
// new). Calls back through the polymorphic set_constraint so
127
// subclasses with real storage get the write without needing
128
// to override upgrade themselves.
129
upgrade_expected_type(new_expected_type: Semantic.Types.Type?, new_error_message: string?) is
130
if !new_expected_type? then
131
return
132
fi
133
134
let existing = self.expected_type
135
136
if !existing? \/ existing.is_assignable_from(new_expected_type) then
137
set_expected_type(new_expected_type, new_error_message)
138
fi
139
si
140
si
141
si