@@ -33,6 +33,165 @@ def untyped_literal_expr(expr_str, operands=[]):
33
33
return LiteralExpr (expr_str , no_compiled_type , operands )
34
34
35
35
36
+ class BindExpr (CallExpr ):
37
+ """
38
+ Base class for resolved expressions that create Assign/Propagate/Unify
39
+ equations.
40
+ """
41
+
42
+ def __init__ (self ,
43
+ constructor_name : str ,
44
+ constructor_args : List [Union [str , ResolvedExpression ]],
45
+ abstract_expr : Optional [AbstractExpression ] = None ):
46
+ """
47
+ :param constructor_name: Name of the function to create the equation.
48
+ :param constructor_args: Its arguments, exclusing the "Debug_String"
49
+ one, which we automatically add.
50
+ :param abstract_expr: Reference to the corresponding abstract
51
+ expression, if any.
52
+ """
53
+ args : List [Union [str , ResolvedExpression ]] = list (constructor_args )
54
+ if abstract_expr :
55
+ args .append (
56
+ f"Debug_String => { sloc_info_arg (abstract_expr .location )} "
57
+ )
58
+ super ().__init__ (
59
+ "Bind_Result" ,
60
+ constructor_name ,
61
+ T .Equation ,
62
+ args ,
63
+ abstract_expr = abstract_expr ,
64
+ )
65
+
66
+ @staticmethod
67
+ def functor_expr (type_name : str , prop : PropertyDef ) -> LiteralExpr :
68
+ """
69
+ Return an expression to create a functor for ``Prop``.
70
+
71
+ :param type_name: Name of the functor derived type.
72
+ :param prop: Property called by the functor.
73
+ """
74
+ assocs : List [Tuple [str , LiteralExpr ]] = [
75
+ ("Ref_Count" , IntegerLiteralExpr (1 )),
76
+ ("Cache_Set" , LiteralExpr ("False" , None )),
77
+ ("Cache_Key" , LiteralExpr ("<>" , None )),
78
+ ("Cache_Value" , LiteralExpr ("<>" , None )),
79
+ ] + [
80
+ (dynvar .argument_name , construct (dynvar ))
81
+ for dynvar in prop .dynamic_vars
82
+ ]
83
+ return aggregate_expr (type_name , assocs )
84
+
85
+
86
+ class AssignExpr (BindExpr ):
87
+ """
88
+ Resolved expression that creates Unify equations.
89
+ """
90
+
91
+ def __init__ (self ,
92
+ logic_var : ResolvedExpression ,
93
+ value : ResolvedExpression ,
94
+ conv_prop : Optional [PropertyDef ],
95
+ abstract_expr : Optional [AbstractExpression ] = None ):
96
+ self .logic_var = logic_var
97
+ self .value = value
98
+ self .conv_prop = conv_prop
99
+
100
+ constructor_args : List [Union [str , ResolvedExpression ]] = [
101
+ logic_var ,
102
+ value ,
103
+ self .functor_expr (f"Logic_Converter_{ conv_prop .uid } " , conv_prop )
104
+ if conv_prop else
105
+ "Solver_Ifc.No_Converter" ,
106
+ ]
107
+
108
+ super ().__init__ (
109
+ "Solver.Create_Assign" ,
110
+ constructor_args ,
111
+ abstract_expr = abstract_expr
112
+ )
113
+
114
+ @property
115
+ def subexprs (self ):
116
+ return {
117
+ 'logic_var' : self .logic_var ,
118
+ 'value' : self .value ,
119
+ 'conv_prop' : self .conv_prop ,
120
+ }
121
+
122
+ def __repr__ (self ):
123
+ return '<AssignExpr>'
124
+
125
+
126
+ class PropagateExpr (BindExpr ):
127
+ """
128
+ Resolved expression that creates Propagate equations.
129
+ """
130
+
131
+ def __init__ (self ,
132
+ dest_var : ResolvedExpression ,
133
+ arg_var : ResolvedExpression ,
134
+ conv_prop : Optional [PropertyDef ],
135
+ abstract_expr : Optional [AbstractExpression ] = None ):
136
+ self .dest_var = dest_var
137
+ self .arg_var = arg_var
138
+ self .conv_prop = conv_prop
139
+
140
+ constructor_args : List [Union [str , ResolvedExpression ]] = [
141
+ dest_var ,
142
+ arg_var ,
143
+ self .functor_expr (f"Logic_Converter_{ conv_prop .uid } " , conv_prop )
144
+ if conv_prop else
145
+ "Solver_Ifc.No_Converter" ,
146
+ ]
147
+
148
+ super ().__init__ (
149
+ "Solver.Create_Propagate" ,
150
+ constructor_args ,
151
+ abstract_expr = abstract_expr
152
+ )
153
+
154
+ @property
155
+ def subexprs (self ):
156
+ return {
157
+ 'dest_var' : self .dest_var ,
158
+ 'arg_var' : self .arg_var ,
159
+ 'conv_prop' : self .conv_prop ,
160
+ }
161
+
162
+ def __repr__ (self ):
163
+ return '<PropagateExpr>'
164
+
165
+
166
+ class UnifyExpr (BindExpr ):
167
+ """
168
+ Resolved expression that creates Unify equations.
169
+ """
170
+
171
+ def __init__ (self ,
172
+ left_var : ResolvedExpression ,
173
+ right_var : ResolvedExpression ,
174
+ abstract_expr : Optional [AbstractExpression ] = None ):
175
+ self .left_var = left_var
176
+ self .right_var = right_var
177
+
178
+ super ().__init__ (
179
+ "Solver.Create_Unify" ,
180
+ [self .left_var , self .right_var ],
181
+ abstract_expr = abstract_expr
182
+ )
183
+
184
+ @property
185
+ def subexprs (self ):
186
+ return {
187
+ 'left_var' : self .left_var ,
188
+ 'right_var' : self .right_var ,
189
+ }
190
+
191
+ def __repr__ (self ):
192
+ return '<UnifyExpr>'
193
+
194
+
36
195
@dsl_document
37
196
class Bind (AbstractExpression ):
38
197
"""
@@ -52,76 +211,6 @@ class Bind(AbstractExpression):
52
211
Bind(A, B, conv_prop=T.TypeOfA.some_property)
53
212
"""
54
213
55
- class Expr (CallExpr ):
56
- def __init__ (self ,
57
- conv_prop : PropertyDef ,
58
- lhs : ResolvedExpression ,
59
- rhs : ResolvedExpression ,
60
- abstract_expr : Optional [AbstractExpression ] = None ):
61
- self .conv_prop = conv_prop
62
- self .lhs = lhs
63
- self .rhs = rhs
64
-
65
- constructor_args : List [Union [str , ResolvedExpression ]] = [lhs , rhs ]
66
-
67
- if conv_prop :
68
- constructor_args .append (self .functor_expr (
69
- conv_prop ,
70
- f"Conv => Logic_Converter_{ self .conv_prop .uid } " ,
71
- ("Cache_Set" , LiteralExpr ("False" , None )),
72
- ("Cache_Key" , LiteralExpr ("<>" , None )),
73
- ("Cache_Value" , LiteralExpr ("<>" , None )),
74
- ))
75
-
76
- if abstract_expr :
77
- constructor_args .append (
78
- f"Debug_String => { sloc_info_arg (abstract_expr .location )} "
79
- )
80
-
81
- if rhs .type .matches (T .root_node .entity ):
82
- fn_name = 'Solver.Create_Assign'
83
- elif conv_prop :
84
- fn_name = 'Solver.Create_Propagate'
85
- else :
86
- fn_name = 'Solver.Create_Unify'
87
-
88
- super ().__init__ (
89
- 'Bind_Result' , fn_name ,
90
- T .Equation , constructor_args ,
91
- abstract_expr = abstract_expr
92
- )
93
-
94
- @staticmethod
95
- def functor_expr (prop : PropertyDef ,
96
- type_name : str ,
97
- * components : Tuple [str , LiteralExpr ]) -> LiteralExpr :
98
- """
99
- Return an expression to create a functor for ``Prop``.
100
-
101
- :param prop: Property called by the functor.
102
- :param type_name: Name of the functor derived type.
103
- :param components: Additional components (component name and
104
- initialization expression) for the functor.
105
- """
106
- assocs : List [Tuple [str , LiteralExpr ]] = []
107
- assocs .append (("Ref_Count" , IntegerLiteralExpr (1 )))
108
- assocs .extend (
109
- (dynvar .argument_name , construct (dynvar ))
110
- for dynvar in prop .dynamic_vars
111
- )
112
- assocs .extend (components )
113
-
114
- return aggregate_expr (type_name , assocs )
115
-
116
- @property
117
- def subexprs (self ):
118
- return {'conv_prop' : self .conv_prop ,
119
- 'lhs' : self .lhs ,
120
- 'rhs' : self .rhs }
121
-
122
- def __repr__ (self ):
123
- return '<Bind.Expr>'
124
-
125
214
def __init__ (self , from_expr , to_expr , conv_prop = None ):
126
215
"""
127
216
:param AbstractExpression from_expr: An expression resolving to a
@@ -201,30 +290,41 @@ def construct(self):
201
290
rhs = construct (self .to_expr )
202
291
203
292
if rhs .type .matches (T .LogicVar ):
293
+ # The second operand is a logic variable: this is a Propagate or a
294
+ # Unify equation depending on whether we have a conversion
295
+ # property.
296
+
204
297
# For this operand too, make sure it will work on a clean logic
205
298
# variable.
206
299
rhs = ResetLogicVar (rhs )
207
- elif rhs .type .matches (T .root_node ):
208
- from langkit .expressions import make_as_entity
209
- rhs = make_as_entity (rhs )
210
- else :
211
- check_source_language (
212
- rhs .type .matches (T .root_node .entity )
213
- or rhs .type .matches (T .LogicVar ),
214
- 'Right operand must be either a logic variable or an entity,'
215
- ' got {}' .format (rhs .type .dsl_name )
300
+
301
+ return (
302
+ PropagateExpr (lhs , rhs , self .conv_prop , abstract_expr = self )
303
+ if self .conv_prop else
304
+ UnifyExpr (lhs , rhs , abstract_expr = self )
216
305
)
217
306
218
- # Because of Ada OOP typing rules, for code generation to work
219
- # properly, make sure the type of `rhs` is the root node entity.
220
- if (
221
- rhs .type .matches (T .root_node .entity )
222
- and rhs .type is not T .root_node .entity
223
- ):
224
- from langkit .expressions import Cast
225
- rhs = Cast .Expr (rhs , T .root_node .entity )
307
+ else :
308
+ # The second operand is a value: this is an Assign equation
309
+
310
+ if rhs .type .matches (T .root_node ):
311
+ from langkit .expressions import make_as_entity
312
+ rhs = make_as_entity (rhs )
313
+ else :
314
+ check_source_language (
315
+ rhs .type .matches (T .root_node .entity )
316
+ or rhs .type .matches (T .LogicVar ),
317
+ "Right operand must be either a logic variable or an"
318
+ " entity, got {rhs.type.dsl_name}"
319
+ )
320
+
321
+ # Because of Ada OOP typing rules, for code generation to work
322
+ # properly, make sure the type of `rhs` is the root node entity.
323
+ if rhs .type is not T .root_node .entity :
324
+ from langkit .expressions import Cast
325
+ rhs = Cast .Expr (rhs , T .root_node .entity )
226
326
227
- return Bind . Expr ( self . conv_prop , lhs , rhs , abstract_expr = self )
327
+ return AssignExpr ( lhs , rhs , self . conv_prop , abstract_expr = self )
228
328
229
329
230
330
class DomainExpr (ComputingExpr ):
0 commit comments