1
2
3
4
5
6 #include <cmajor/binder/Evaluator.hpp>
7 #include <cmajor/binder/BoundCompileUnit.hpp>
8 #include <cmajor/binder/TypeBinder.hpp>
9 #include <cmajor/binder/TypeResolver.hpp>
10 #include <cmajor/binder/OverloadResolution.hpp>
11 #include <cmajor/binder/StatementBinder.hpp>
12 #include <cmajor/symbols/Exception.hpp>
13 #include <sngcm/ast/Visitor.hpp>
14 #include <sngcm/ast/BasicType.hpp>
15 #include <sngcm/ast/Literal.hpp>
16 #include <sngcm/ast/Expression.hpp>
17 #include <sngcm/ast/Identifier.hpp>
18 #include <soulng/util/Unicode.hpp>
19
20 namespace cmajor { namespace binder {
21
22 using namespace soulng::unicode;
23
24 void ThrowCannotEvaluateStatically(const Span& defined, const boost::uuids::uuid& moduleId)
25 {
26 throw Exception("cannot evaluate statically", defined, moduleId);
27 }
28
29 void ThrowCannotEvaluateStatically(const Span& defined, const boost::uuids::uuid& moduleId, const Span& referenced, const boost::uuids::uuid& referencedModuleId)
30 {
31 throw Exception("cannot evaluate statically", defined, moduleId, referenced, referencedModuleId);
32 }
33
34 typedef Value* (*BinaryOperatorFun)(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow);
35 typedef Value* (*UnaryOperatorFun)(Value* operand, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow);
36
37 class ScopedValue : public Value
38 {
39 public:
40 ScopedValue(const Span& span_, const boost::uuids::uuid& moduleId_, ContainerSymbol* containerSymbol_);
41 bool IsComplete() const override { return false; }
42 bool IsScopedValue() const override { return true; }
43 const ContainerSymbol* GetContainerSymbol() const { return containerSymbol; }
44 ContainerSymbol* GetContainerSymbol() { return containerSymbol; }
45 Value* Clone() const override { Assert(false, "scoped value cannot be cloned"); return nullptr; }
46 void Write(BinaryWriter& writer) override {}
47 void Read(BinaryReader& reader) override {}
48 Value* As(TypeSymbol* targetType, bool cast, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow) const override { Assert(false, "scoped value cannot be converted"); return nullptr; }
49 void* IrValue(Emitter& emitter) override { Assert(false, "scoped value does not have ir value"); return nullptr; }
50 TypeSymbol* GetType(SymbolTable* symbolTable) override { return type; }
51 void SetType(TypeSymbol* type_) override { type = type_; }
52 Value* GetSubject() override { return subject.get(); }
53 void SetSubject(Value* subject_) { subject.reset(subject_); }
54 private:
55 ContainerSymbol* containerSymbol;
56 TypeSymbol* type;
57 std::unique_ptr<Value> subject;
58 };
59
60 ScopedValue::ScopedValue(const Span& span_, const boost::uuids::uuid& moduleId_, ContainerSymbol* containerSymbol_) :
61 Value(span_, moduleId_, ValueType::none), containerSymbol(containerSymbol_), type(nullptr)
62 {
63 }
64
65 class FunctionGroupValue : public Value
66 {
67 public:
68 FunctionGroupValue(FunctionGroupSymbol* functionGroup_, ContainerScope* qualifiedScope_);
69 bool IsComplete() const override { return false; }
70 bool IsFunctionGroupValue() const override { return true; }
71 Value* Clone() const override { Assert(false, "function group value cannot be cloned"); return nullptr; }
72 void Write(BinaryWriter& writer) override {}
73 void Read(BinaryReader& reader) override {}
74 Value* As(TypeSymbol* targetType, bool cast, const Span& span, const boost::uuids::uuid& moduleId_, bool dontThrow) const override { Assert(false, "function group value cannot be converted"); return nullptr; }
75 void* IrValue(Emitter& emitter) override { Assert(false, "function group value does not have ir value"); return nullptr; }
76 FunctionGroupSymbol* FunctionGroup() { return functionGroup; }
77 ContainerScope* QualifiedScope() { return qualifiedScope; }
78 TypeSymbol* GetType(SymbolTable* symbolTable) override { return nullptr; }
79 void SetTemplateTypeArguments(std::std::vector<TypeSymbol*>&&templateTypeArguments_){templateTypeArguments = std::move(templateTypeArguments_);}
80 std::std::vector<TypeSymbol*>TemplateTypeArguments(){returnstd::move(templateTypeArguments);}
81 void SetReceiver(std::std::unique_ptr<Value>&&receiver_){receiver = std::move(receiver_);}
82 Value* Receiver() { return receiver.get(); }
83 private:
84 FunctionGroupSymbol* functionGroup;
85 ContainerScope* qualifiedScope;
86 std::vector<TypeSymbol*> templateTypeArguments;
87 std::unique_ptr<Value> receiver;
88 };
89
90 FunctionGroupValue::FunctionGroupValue(FunctionGroupSymbol* functionGroup_, ContainerScope* qualifiedScope_) : Value(Span(), boost::uuids::nil_uuid(), ValueType::none), functionGroup(functionGroup_), qualifiedScope(qualifiedScope_)
91 {
92 }
93
94 class ArrayReferenceValue : public Value
95 {
96 public:
97 ArrayReferenceValue(ArrayValue* arrayValue_);
98 bool IsArrayReferenceValue() const override { return true; }
99 Value* Clone() const override { return new ArrayReferenceValue(arrayValue); }
100 void Write(BinaryWriter& writer) override {}
101 void Read(BinaryReader& reader) override {}
102 Value* As(TypeSymbol* targetType, bool cast, const Span& span, const boost::uuids::uuid& moduleId_, bool dontThrow) const override { Assert(false, "array reference value cannot be converted"); return nullptr; }
103 void* IrValue(Emitter& emitter) override { Assert(false, "array reference does not have ir value"); return nullptr; }
104 TypeSymbol* GetType(SymbolTable* symbolTable) override { return arrayValue->GetType(symbolTable); }
105 ArrayValue* GetArrayValue() const { return arrayValue; }
106 private:
107 ArrayValue* arrayValue;
108 };
109
110 ArrayReferenceValue::ArrayReferenceValue(ArrayValue* arrayValue_) : Value(arrayValue_->GetSpan(), arrayValue_->ModuleId(), ValueType::none), arrayValue(arrayValue_)
111 {
112 }
113
114 class StructuredReferenceValue : public Value
115 {
116 public:
117 StructuredReferenceValue(StructuredValue* structuredValue_);
118 bool IsStructuredReferenceValue() const override { return true; }
119 Value* Clone() const override { return new StructuredReferenceValue(structuredValue); }
120 void Write(BinaryWriter& writer) override {}
121 void Read(BinaryReader& reader) override {}
122 Value* As(TypeSymbol* targetType, bool cast, const Span& span, const boost::uuids::uuid& moduleId_, bool dontThrow) const override { Assert(false, "structured reference value cannot be converted"); return nullptr; }
123 void* IrValue(Emitter& emitter) override { Assert(false, "structured reference does not have ir value"); return nullptr; }
124 TypeSymbol* GetType(SymbolTable* symbolTable) override { return structuredValue->GetType(symbolTable); }
125 StructuredValue* GetStructuredValue() const { return structuredValue; }
126 private:
127 StructuredValue* structuredValue;
128 };
129
130 StructuredReferenceValue::StructuredReferenceValue(StructuredValue* structuredValue_) : Value(structuredValue_->GetSpan(), structuredValue_->ModuleId(), ValueType::none), structuredValue(structuredValue_)
131 {
132 }
133
134 class StringReferenceValue : public Value
135 {
136 public:
137 StringReferenceValue(Value* stringValue_);
138 bool IsStringReferenceValue() const override { return true; }
139 Value* Clone() const override { return new StringReferenceValue(stringValue); }
140 void Write(BinaryWriter& writer) override {}
141 void Read(BinaryReader& reader) override {}
142 Value* As(TypeSymbol* targetType, bool cast, const Span& span, const boost::uuids::uuid& moduleId_, bool dontThrow) const override { Assert(false, "string reference value cannot be converted"); return nullptr; }
143 void* IrValue(Emitter& emitter) override { return stringValue->IrValue(emitter); }
144 TypeSymbol* GetType(SymbolTable* symbolTable) override { return stringValue->GetType(symbolTable); }
145 Value* GetSubject() override { return stringValue; }
146 private:
147 Value* stringValue;
148 };
149
150 StringReferenceValue::StringReferenceValue(Value* stringValue_) : Value(stringValue_->GetSpan(), stringValue_->ModuleId(), ValueType::none), stringValue(stringValue_)
151 {
152 }
153
154 class VariableValueSymbol : public VariableSymbol
155 {
156 public:
157 VariableValueSymbol(const Span& span_, const boost::uuids::uuid& moduleId_, const std::u32string& name_, std::std::unique_ptr<Value>&&value_);
158 Value* GetValue() { return value.get(); }
159 void SetValue(Value* value_) { value.reset(value_); }
160 const char* ClassName() const override { return "VariableValueSymbol"; }
161 private:
162 std::unique_ptr<Value> value;
163 };
164
165 VariableValueSymbol::VariableValueSymbol(const Span& span_, const boost::uuids::uuid& moduleId_, const std::u32string& name_, std::std::unique_ptr<Value>&&value_):
166 VariableSymbol(SymbolType::variableValueSymbol, span_, moduleId_, name_), value(std::move(value_))
167 {
168 }
169
170 std::std::vector<std::std::unique_ptr<BoundExpression>>ValuesToLiterals(std::std::vector<std::std::unique_ptr<Value>>&values, SymbolTable*symbolTable, bool&error)
171 {
172 std::vector<std::std::unique_ptr<BoundExpression>>arguments;
173 for (std::std::unique_ptr<Value>&value : values)
174 {
175 ValueType valueType = value->GetValueType();
176 TypeSymbol* type = value->GetType(symbolTable);
177 BoundLiteral* literal = new BoundLiteral(std::move(value), type);
178 arguments.push_back(std::unique_ptr<BoundExpression>(literal));
179 }
180 return arguments;
181 }
182
183 std::vector<std::std::unique_ptr<Value>>ArgumentsToValues(conststd::std::vector<std::std::unique_ptr<BoundExpression>>&arguments, bool&error, boolskipFirst, BoundCompileUnit&boundCompileUnit);
184
185 std::std::vector<std::std::unique_ptr<Value>>ArgumentsToValues(conststd::std::vector<std::std::unique_ptr<BoundExpression>>&arguments, bool&error, BoundCompileUnit&boundCompileUnit)
186 {
187 return ArgumentsToValues(arguments, error, false, boundCompileUnit);
188 }
189
190 std::std::vector<std::std::unique_ptr<Value>>ArgumentsToValues(conststd::std::vector<std::std::unique_ptr<BoundExpression>>&arguments, bool&error, boolskipFirst, BoundCompileUnit&boundCompileUnit)
191 {
192 std::vector<std::std::unique_ptr<Value>>values;
193 bool first = true;
194 for (const std::std::unique_ptr<BoundExpression>&argument : arguments)
195 {
196 if (first)
197 {
198 first = false;
199 if (skipFirst)
200 {
201 continue;
202 }
203 }
204 std::unique_ptr<Value> value = argument->ToValue(boundCompileUnit);
205 if (value)
206 {
207 values.push_back(std::move(value));
208 }
209 else
210 {
211 error = true;
212 return values;
213 }
214 }
215 return values;
216 }
217
218 template< typename ValueT typename Op>
219 Value* BinaryEvaluate(Value* left, Value* right, Op op, const Span& span, const boost::uuids::uuid& moduleId)
220 {
221 ValueT* leftCasted = static_cast<ValueT*>(left);
222 ValueT* rightCasted = static_cast<ValueT*>(right);
223 return new ValueT(span, moduleId, op(leftCasted->GetValue(), rightCasted->GetValue()));
224 }
225
226 template< typename ValueT typename Op>
227 Value* BinaryPredEvaluate(Value* left, Value* right, Op op, const Span& span, const boost::uuids::uuid& moduleId)
228 {
229 ValueT* leftCasted = static_cast<ValueT*>(left);
230 ValueT* rightCasted = static_cast<ValueT*>(right);
231 return new BoolValue(span, moduleId, op(leftCasted->GetValue(), rightCasted->GetValue()));
232 }
233
234 template<typename ValueT typename Op>
235 Value* UnaryEvaluate(Value* subject, Op op, const Span& span, const boost::uuids::uuid& moduleId)
236 {
237 ValueT* subjectCasted = static_cast<ValueT*>(subject);
238 return new ValueT(span, moduleId, op(subjectCasted->GetValue()));
239 }
240
241 Value* NotSupported(Value* subject, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
242 {
243 if (dontThrow)
244 {
245 return nullptr;
246 }
247 throw Exception("operation not supported for type " + ValueTypeStr(subject->GetValueType()), span, moduleId);
248 }
249
250 Value* NotSupported(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
251 {
252 if (dontThrow)
253 {
254 return nullptr;
255 }
256 throw Exception("operation not supported for types " + ValueTypeStr(left->GetValueType()) + " and " + ValueTypeStr(right->GetValueType()), span, moduleId);
257 }
258
259 template<typename ValueT>
260 Value* Disjunction(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
261 {
262 return BinaryEvaluate::BinaryEvaluate<ValueT>(left, right, std::logical_or<typename ValueT::OperandType>(), span, moduleId);
263 }
264
265 BinaryOperatorFun disjunction[uint8_t(ValueType::maxValue)] =
266 {
267 NotSupported, Disjunction<BoolValue>, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported,
268 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported,
269 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
270 };
271
272 template<typename ValueT>
273 Value* Conjunction(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
274 {
275 return BinaryEvaluate::BinaryEvaluate<ValueT>(left, right, std::logical_and<typename ValueT::OperandType>(), span, moduleId);
276 }
277
278 BinaryOperatorFun conjunction[uint8_t(ValueType::maxValue)] =
279 {
280 NotSupported, Conjunction<BoolValue>, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported,
281 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported,
282 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
283 };
284
285 template<typename ValueT>
286 Value* BitOr(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
287 {
288 return BinaryEvaluate::BinaryEvaluate<ValueT>(left, right, std::bit_or<typename ValueT::OperandType>(), span, moduleId);
289 }
290
291 BinaryOperatorFun bitOr[uint8_t(ValueType::maxValue)] =
292 {
293 NotSupported, NotSupported, BitOr<SByteValue>, BitOr<ByteValue>, BitOr<ShortValue>, BitOr<UShortValue>, BitOr<IntValue>, BitOr<UIntValue>,
294 BitOr<LongValue>, BitOr<ULongValue>, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported,
295 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
296 };
297
298 template<typename ValueT>
299 Value* BitXor(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
300 {
301 return BinaryEvaluate::BinaryEvaluate<ValueT>(left, right, std::bit_xor<typename ValueT::OperandType>(), span, moduleId);
302 }
303
304 BinaryOperatorFun bitXor[uint8_t(ValueType::maxValue)] =
305 {
306 NotSupported, NotSupported, BitXor<SByteValue>, BitXor<ByteValue>, BitXor<ShortValue>, BitXor<UShortValue>, BitXor<IntValue>, BitXor<UIntValue>,
307 BitXor<LongValue>, BitXor<ULongValue>, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported,
308 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
309 };
310
311 template<typename ValueT>
312 Value* BitAnd(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
313 {
314 return BinaryEvaluate::BinaryEvaluate<ValueT>(left, right, std::bit_and<typename ValueT::OperandType>(), span, moduleId);
315 }
316
317 BinaryOperatorFun bitAnd[uint8_t(ValueType::maxValue)] =
318 {
319 NotSupported, NotSupported, BitAnd<SByteValue>, BitAnd<ByteValue>, BitAnd<ShortValue>, BitAnd<UShortValue>, BitAnd<IntValue>, BitAnd<UIntValue>,
320 BitAnd<LongValue>, BitAnd<ULongValue>, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported,
321 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
322 };
323
324 template<typename ValueT>
325 Value* Equal(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
326 {
327 return BinaryPredEvaluate::BinaryPredEvaluate<ValueT>(left, right, std::equal_to<typename ValueT::OperandType>(), span, moduleId);
328 }
329
330 BinaryOperatorFun equal[uint8_t(ValueType::maxValue)] =
331 {
332 NotSupported, Equal<BoolValue>, Equal<SByteValue>, Equal<ByteValue>, Equal<ShortValue>, Equal<UShortValue>, Equal<IntValue>, Equal<UIntValue>,
333 Equal<LongValue>, Equal<ULongValue>, Equal<FloatValue>, Equal<DoubleValue>, Equal<CharValue>, Equal<WCharValue>, Equal<UCharValue>,
334 NotSupported, NotSupported, NotSupported, NotSupported, Equal<PointerValue>, NotSupported, NotSupported
335 };
336
337 template<typename ValueT>
338 Value* NotEqual(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
339 {
340 return BinaryPredEvaluate::BinaryPredEvaluate<ValueT>(left, right, std::not_equal_to<typename ValueT::OperandType>(), span, moduleId);
341 }
342
343 BinaryOperatorFun notEqual[uint8_t(ValueType::maxValue)] =
344 {
345 NotSupported, NotEqual<BoolValue>, NotEqual<SByteValue>, NotEqual<ByteValue>, NotEqual<ShortValue>, NotEqual<UShortValue>, NotEqual<IntValue>, NotEqual<UIntValue>,
346 NotEqual<LongValue>, NotEqual<ULongValue>, NotEqual<FloatValue>, NotEqual<DoubleValue>, NotEqual<CharValue>, NotEqual<WCharValue>, NotEqual<UCharValue>,
347 NotSupported, NotSupported, NotSupported, NotSupported, NotEqual<PointerValue>, NotSupported, NotSupported
348 };
349
350 template<typename ValueT>
351 Value* Less(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
352 {
353 return BinaryPredEvaluate::BinaryPredEvaluate<ValueT>(left, right, std::less<typename ValueT::OperandType>(), span, moduleId);
354 }
355
356 BinaryOperatorFun less[uint8_t(ValueType::maxValue)] =
357 {
358 NotSupported, NotSupported, Less<SByteValue>, Less<ByteValue>, Less<ShortValue>, Less<UShortValue>, Less<IntValue>, Less<UIntValue>,
359 Less<LongValue>, Less<ULongValue>, Less<FloatValue>, Less<DoubleValue>, Less<CharValue>, Less<WCharValue>, Less<UCharValue>,
360 NotSupported, NotSupported, NotSupported, NotSupported, Less<PointerValue>, NotSupported, NotSupported
361 };
362
363 template<typename ValueT>
364 Value* Greater(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
365 {
366 return BinaryPredEvaluate::BinaryPredEvaluate<ValueT>(left, right, std::greater<typename ValueT::OperandType>(), span, moduleId);
367 }
368
369 BinaryOperatorFun greater[uint8_t(ValueType::maxValue)] =
370 {
371 NotSupported, NotSupported, Greater<SByteValue>, Greater<ByteValue>, Greater<ShortValue>, Greater<UShortValue>, Greater<IntValue>, Greater<UIntValue>,
372 Greater<LongValue>, Greater<ULongValue>, Greater<FloatValue>, Greater<DoubleValue>, Greater<CharValue>, Greater<WCharValue>, Greater<UCharValue>,
373 NotSupported, NotSupported, NotSupported, NotSupported, Greater<PointerValue>, NotSupported, NotSupported
374 };
375
376 template<typename ValueT>
377 Value* LessEqual(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
378 {
379 return BinaryPredEvaluate::BinaryPredEvaluate<ValueT>(left, right, std::less_equal<typename ValueT::OperandType>(), span, moduleId);
380 }
381
382 BinaryOperatorFun lessEqual[uint8_t(ValueType::maxValue)] =
383 {
384 NotSupported, NotSupported, LessEqual<SByteValue>, LessEqual<ByteValue>, LessEqual<ShortValue>, LessEqual<UShortValue>, LessEqual<IntValue>, LessEqual<UIntValue>,
385 LessEqual<LongValue>, LessEqual<ULongValue>, LessEqual<FloatValue>, LessEqual<DoubleValue>, LessEqual<CharValue>, LessEqual<WCharValue>, LessEqual<UCharValue>,
386 NotSupported, NotSupported, NotSupported, NotSupported, LessEqual<PointerValue>, NotSupported, NotSupported
387 };
388
389 template<typename ValueT>
390 Value* GreaterEqual(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
391 {
392 return BinaryPredEvaluate::BinaryPredEvaluate<ValueT>(left, right, std::greater_equal<typename ValueT::OperandType>(), span, moduleId);
393 }
394
395 BinaryOperatorFun greaterEqual[uint8_t(ValueType::maxValue)] =
396 {
397 NotSupported, NotSupported, GreaterEqual<SByteValue>, GreaterEqual<ByteValue>, GreaterEqual<ShortValue>, GreaterEqual<UShortValue>, GreaterEqual<IntValue>, GreaterEqual<UIntValue>,
398 GreaterEqual<LongValue>, GreaterEqual<ULongValue>, GreaterEqual<FloatValue>, GreaterEqual<DoubleValue>, GreaterEqual<CharValue>, GreaterEqual<WCharValue>, GreaterEqual<UCharValue>,
399 NotSupported, NotSupported, NotSupported, NotSupported, GreaterEqual<PointerValue>, NotSupported, NotSupported
400 };
401
402 template<typename T>
403 struct shiftLeftFun : std::std::binary_function<T, T, T>
404 {
405 T operator()(const T& left, const T& right) const
406 {
407 return left << right;
408 }
409 };
410
411 template<typename ValueT>
412 Value* ShiftLeft(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
413 {
414 return BinaryEvaluate::BinaryEvaluate<ValueT>(left, right, shiftLeftFun<typename ValueT::OperandType>(), span, moduleId);
415 }
416
417 BinaryOperatorFun shiftLeft[uint8_t(ValueType::maxValue)] =
418 {
419 NotSupported, NotSupported, ShiftLeft<SByteValue>, ShiftLeft<ByteValue>, ShiftLeft<ShortValue>, ShiftLeft<UShortValue>, ShiftLeft<IntValue>, ShiftLeft<UIntValue>,
420 ShiftLeft<LongValue>, ShiftLeft<ULongValue>, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported,
421 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
422 };
423
424 template<typename T>
425 struct shiftRightFun : std::std::binary_function<T, T, T>
426 {
427 T operator()(const T& left, const T& right) const
428 {
429 return left >> right;
430 }
431 };
432
433 template<typename ValueT>
434 Value* ShiftRight(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
435 {
436 return BinaryEvaluate::BinaryEvaluate<ValueT>(left, right, shiftRightFun<typename ValueT::OperandType>(), span, moduleId);
437 }
438
439 BinaryOperatorFun shiftRight[uint8_t(ValueType::maxValue)] =
440 {
441 NotSupported, NotSupported, ShiftRight<SByteValue>, ShiftRight<ByteValue>, ShiftRight<ShortValue>, ShiftRight<UShortValue>, ShiftRight<IntValue>, ShiftRight<UIntValue>,
442 ShiftRight<LongValue>, ShiftRight<ULongValue>, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported,
443 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
444 };
445
446 template<typename ValueT>
447 Value* Add(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
448 {
449 return BinaryEvaluate::BinaryEvaluate<ValueT>(left, right, std::plus<typename ValueT::OperandType>(), span, moduleId);
450 }
451
452 BinaryOperatorFun add[uint8_t(ValueType::maxValue)] =
453 {
454 NotSupported, NotSupported, Add<SByteValue>, Add<ByteValue>, Add<ShortValue>, Add<UShortValue>, Add<IntValue>, Add<UIntValue>,
455 Add<LongValue>, Add<ULongValue>, Add<FloatValue>, Add<DoubleValue>, NotSupported, NotSupported, NotSupported,
456 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
457 };
458
459 template<typename ValueT>
460 Value* Sub(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
461 {
462 return BinaryEvaluate::BinaryEvaluate<ValueT>(left, right, std::minus<typename ValueT::OperandType>(), span, moduleId);
463 }
464
465 BinaryOperatorFun sub[uint8_t(ValueType::maxValue)] =
466 {
467 NotSupported, NotSupported, Sub<SByteValue>, Sub<ByteValue>, Sub<ShortValue>, Sub<UShortValue>, Sub<IntValue>, Sub<UIntValue>,
468 Sub<LongValue>, Sub<ULongValue>, Sub<FloatValue>, Sub<DoubleValue>, NotSupported, NotSupported, NotSupported,
469 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
470 };
471
472 template<typename ValueT>
473 Value* Mul(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
474 {
475 return BinaryEvaluate::BinaryEvaluate<ValueT>(left, right, std::multiplies<typename ValueT::OperandType>(), span, moduleId);
476 }
477
478 BinaryOperatorFun mul[uint8_t(ValueType::maxValue)] =
479 {
480 NotSupported, NotSupported, Mul<SByteValue>, Mul<ByteValue>, Mul<ShortValue>, Mul<UShortValue>, Mul<IntValue>, Mul<UIntValue>,
481 Mul<LongValue>, Mul<ULongValue>, Mul<FloatValue>, Mul<DoubleValue>, NotSupported, NotSupported, NotSupported,
482 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
483 };
484
485 template<typename ValueT>
486 Value* Div(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
487 {
488 return BinaryEvaluate::BinaryEvaluate<ValueT>(left, right, std::divides<typename ValueT::OperandType>(), span, moduleId);
489 }
490
491 BinaryOperatorFun div[uint8_t(ValueType::maxValue)] =
492 {
493 NotSupported, NotSupported, Div<SByteValue>, Div<ByteValue>, Div<ShortValue>, Div<UShortValue>, Div<IntValue>, Div<UIntValue>,
494 Div<LongValue>, Div<ULongValue>, Div<FloatValue>, Div<DoubleValue>, NotSupported, NotSupported, NotSupported,
495 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
496 };
497
498 template<typename ValueT>
499 Value* Rem(Value* left, Value* right, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
500 {
501 return BinaryEvaluate::BinaryEvaluate<ValueT>(left, right, std::modulus<typename ValueT::OperandType>(), span, moduleId);
502 }
503
504 BinaryOperatorFun rem[uint8_t(ValueType::maxValue)] =
505 {
506 NotSupported, NotSupported, Rem<SByteValue>, Rem<ByteValue>, Rem<ShortValue>, Rem<UShortValue>, Rem<IntValue>, Rem<UIntValue>,
507 Rem<LongValue>, Rem<ULongValue>, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported,
508 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
509 };
510
511 template<typename ValueT>
512 Value* Not(Value* subject, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
513 {
514 return UnaryEvaluate::UnaryEvaluate<ValueT>(subject, std::logical_not<typename ValueT::OperandType>(), span, moduleId);
515 }
516
517 UnaryOperatorFun logicalNot[uint8_t(ValueType::maxValue)] =
518 {
519 NotSupported, Not<BoolValue>, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported,
520 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported,
521 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
522 };
523
524 template<typename T>
525 struct Identity
526 {
527 const T& operator()(const T& value) const
528 {
529 return value;
530 }
531 };
532
533 template<typename ValueT>
534 Value* UnaryPlus(Value* subject, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
535 {
536 return UnaryEvaluate::UnaryEvaluate<ValueT>(subject, Identity<typename ValueT::OperandType>(), span, moduleId);
537 }
538
539 UnaryOperatorFun unaryPlus[uint8_t(ValueType::maxValue)] =
540 {
541 NotSupported, NotSupported, UnaryPlus<SByteValue>, UnaryPlus<ByteValue>, UnaryPlus<ShortValue>, UnaryPlus<UShortValue>, UnaryPlus<IntValue>, UnaryPlus<UIntValue>,
542 UnaryPlus<LongValue>, UnaryPlus<ULongValue>, UnaryPlus<FloatValue>, UnaryPlus<DoubleValue>, NotSupported, NotSupported, NotSupported,
543 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
544 };
545
546 template<typename ValueT>
547 Value* UnaryMinus(Value* subject, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
548 {
549 return UnaryEvaluate::UnaryEvaluate<ValueT>(subject, std::negate<typename ValueT::OperandType>(), span, moduleId);
550 }
551
552 UnaryOperatorFun unaryMinus[uint8_t(ValueType::maxValue)] =
553 {
554 NotSupported, NotSupported, UnaryMinus<SByteValue>, UnaryMinus<ByteValue>, UnaryMinus<ShortValue>, UnaryMinus<UShortValue>, UnaryMinus<IntValue>, UnaryMinus<UIntValue>,
555 UnaryMinus<LongValue>, UnaryMinus<ULongValue>, UnaryMinus<FloatValue>, UnaryMinus<DoubleValue>, NotSupported, NotSupported, NotSupported,
556 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
557 };
558
559 template< typename T>
560 struct BitNot
561 {
562 T operator()(const T& x) const
563 {
564 return ~x;
565 }
566 };
567
568 template<typename ValueT>
569 Value* Complement(Value* subject, const Span& span, const boost::uuids::uuid& moduleId, bool dontThrow)
570 {
571 return UnaryEvaluate::UnaryEvaluate<ValueT>(subject, BitNot<typename ValueT::OperandType>(), span, moduleId);
572 }
573
574 UnaryOperatorFun complement[uint8_t(ValueType::maxValue)] =
575 {
576 NotSupported, NotSupported, Complement<SByteValue>, Complement<ByteValue>, Complement<ShortValue>, Complement<UShortValue>, Complement<IntValue>, Complement<UIntValue>,
577 Complement<LongValue>, Complement<ULongValue>, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported,
578 NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported, NotSupported
579 };
580
581 enum class Operator
582 {
583 add, sub, comparison, other
584 };
585
586 class Evaluator : public Visitor
587 {
588 public:
589 Evaluator(BoundCompileUnit& boundCompileUnit_, ContainerScope* containerScope_, TypeSymbol* targetType_, ValueType targetValueType_, bool cast_, bool dontThrow_, BoundFunction* currentFunction_, const Span& span_,
590 const boost::uuids::uuid& moduleId_);
591 bool Error() const { return error; }
592 std::unique_ptr<Value> GetValue();
593
594 void Visit(NamespaceImportNode& namespaceImportNode) override;
595 void Visit(AliasNode& aliasNode) override;
596 void Visit(FunctionNode& functionNode) override;
597 void Visit(ClassNode& classNode) override;
598 void Visit(StaticConstructorNode& staticConstructorNode) override;
599 void Visit(ConstructorNode& constructorNode) override;
600 void Visit(DestructorNode& destructorNode) override;
601 void Visit(MemberFunctionNode& memberFunctionNode) override;
602 void Visit(ConversionFunctionNode& conversionFunctionNode) override;
603 void Visit(MemberVariableNode& memberVariableNode) override;
604 void Visit(InterfaceNode& interfaceNode) override;
605 void Visit(DelegateNode& delegateNode) override;
606 void Visit(ClassDelegateNode& classDelegateNode) override;
607
608 void Visit(CompoundStatementNode& compoundStatementNode) override;
609 void Visit(ReturnStatementNode& returnStatementNode) override;
610 void Visit(IfStatementNode& ifStatementNode) override;
611 void Visit(WhileStatementNode& whileStatementNode) override;
612 void Visit(DoStatementNode& doStatementNode) override;
613 void Visit(ForStatementNode& forStatementNode) override;
614 void Visit(BreakStatementNode& breakStatementNode) override;
615 void Visit(ContinueStatementNode& continueStatementNode) override;
616 void Visit(GotoStatementNode& gotoStatementNode) override;
617 void Visit(ConstructionStatementNode& constructionStatementNode) override;
618 void Visit(DeleteStatementNode& deleteStatementNode) override;
619 void Visit(DestroyStatementNode& destroyStatementNode) override;
620 void Visit(AssignmentStatementNode& assignmentStatementNode) override;
621 void Visit(ExpressionStatementNode& expressionStatementNode) override;
622 void Visit(EmptyStatementNode& emptyStatementNode) override;
623 void Visit(RangeForStatementNode& rangeForStatementNode) override;
624 void Visit(SwitchStatementNode& switchStatementNode) override;
625 void Visit(CaseStatementNode& caseStatementNode) override;
626 void Visit(DefaultStatementNode& defaultStatementNode) override;
627 void Visit(GotoCaseStatementNode& gotoCaseStatementNode) override;
628 void Visit(GotoDefaultStatementNode& gotoDefaultStatementNode) override;
629 void Visit(ThrowStatementNode& throwStatementNode) override;
630 void Visit(TryStatementNode& tryStatementNode) override;
631 void Visit(CatchNode& catchNode) override;
632 void Visit(AssertStatementNode& assertStatementNode) override;
633 void Visit(ConditionalCompilationPartNode& conditionalCompilationPartNode) override;
634 void Visit(ConditionalCompilationDisjunctionNode& conditionalCompilationDisjunctionNode) override;
635 void Visit(ConditionalCompilationConjunctionNode& conditionalCompilationConjunctionNode) override;
636 void Visit(ConditionalCompilationNotNode& conditionalCompilationNotNode) override;
637 void Visit(ConditionalCompilationPrimaryNode& conditionalCompilationPrimaryNode) override;
638 void Visit(ConditionalCompilationStatementNode& conditionalCompilationStatementNode) override;
639
640 void Visit(BoolNode& boolNode) override;
641 void Visit(SByteNode& sbyteNode) override;
642 void Visit(ByteNode& byteNode) override;
643 void Visit(ShortNode& shortNode) override;
644 void Visit(UShortNode& ushortNode) override;
645 void Visit(IntNode& intNode) override;
646 void Visit(UIntNode& uintNode) override;
647 void Visit(LongNode& longNode) override;
648 void Visit(ULongNode& ulongNode) override;
649 void Visit(FloatNode& floatNode) override;
650 void Visit(DoubleNode& doubleNode) override;
651 void Visit(CharNode& charNode) override;
652 void Visit(WCharNode& wcharNode) override;
653 void Visit(UCharNode& ucharNode) override;
654 void Visit(VoidNode& voidNode) override;
655
656 void Visit(BooleanLiteralNode& booleanLiteralNode) override;
657 void Visit(SByteLiteralNode& sbyteLiteralNode) override;
658 void Visit(ByteLiteralNode& byteLiteralNode) override;
659 void Visit(ShortLiteralNode& shortLiteralNode) override;
660 void Visit(UShortLiteralNode& ushortLiteralNode) override;
661 void Visit(IntLiteralNode& intLiteralNode) override;
662 void Visit(UIntLiteralNode& uintLiteralNode) override;
663 void Visit(LongLiteralNode& longLiteralNode) override;
664 void Visit(ULongLiteralNode& ulongLiteralNode) override;
665 void Visit(FloatLiteralNode& floatLiteralNode) override;
666 void Visit(DoubleLiteralNode& doubleLiteralNode) override;
667 void Visit(CharLiteralNode& charLiteralNode) override;
668 void Visit(WCharLiteralNode& wcharLiteralNode) override;
669 void Visit(UCharLiteralNode& ucharLiteralNode) override;
670 void Visit(StringLiteralNode& stringLiteralNode) override;
671 void Visit(WStringLiteralNode& wstringLiteralNode) override;
672 void Visit(UStringLiteralNode& ustringLiteralNode) override;
673 void Visit(NullLiteralNode& nullLiteralNode) override;
674 void Visit(ArrayLiteralNode& arrayLiteralNode) override;
675 void Visit(StructuredLiteralNode& structuredLiteralNode) override;
676
677 void Visit(IdentifierNode& identifierNode) override;
678 void Visit(TemplateIdNode& templateIdNode) override;
679
680 void Visit(DotNode& dotNode) override;
681 void Visit(ArrowNode& arrowNode) override;
682 void Visit(EquivalenceNode& equivalenceNode) override;
683 void Visit(ImplicationNode& implicationNode) override;
684 void Visit(DisjunctionNode& disjunctionNode) override;
685 void Visit(ConjunctionNode& conjunctionNode) override;
686 void Visit(BitOrNode& bitOrNode) override;
687 void Visit(BitXorNode& bitXorNode) override;
688 void Visit(BitAndNode& bitAndNode) override;
689 void Visit(EqualNode& equalNode) override;
690 void Visit(NotEqualNode& notEqualNode) override;
691 void Visit(LessNode& lessNode) override;
692 void Visit(GreaterNode& greaterNode) override;
693 void Visit(LessOrEqualNode& lessOrEqualNode) override;
694 void Visit(GreaterOrEqualNode& greaterOrEqualNode) override;
695 void Visit(ShiftLeftNode& shiftLeftNode) override;
696 void Visit(ShiftRightNode& shiftRightNode) override;
697 void Visit(AddNode& addNode) override;
698 void Visit(SubNode& subNode) override;
699 void Visit(MulNode& mulNode) override;
700 void Visit(DivNode& divNode) override;
701 void Visit(RemNode& remNode) override;
702 void Visit(NotNode& notNode) override;
703 void Visit(UnaryPlusNode& unaryPlusNode) override;
704 void Visit(UnaryMinusNode& unaryMinusNode) override;
705 void Visit(PrefixIncrementNode& prefixIncrementNode) override;
706 void Visit(PrefixDecrementNode& prefixDecrementNode) override;
707 void Visit(DerefNode& derefNode) override;
708 void Visit(AddrOfNode& addrOfNode) override;
709 void Visit(ComplementNode& complementNode) override;
710 void Visit(IsNode& isNode) override;
711 void Visit(AsNode& asNode) override;
712 void Visit(IndexingNode& indexingNode) override;
713 void Visit(InvokeNode& invokeNode) override;
714 void Visit(PostfixIncrementNode& postfixIncrementNode) override;
715 void Visit(PostfixDecrementNode& postfixDecrementNode) override;
716 void Visit(SizeOfNode& sizeOfNode) override;
717 void Visit(TypeNameNode& typeNameNode) override;
718 void Visit(TypeIdNode& typeIdNode) override;
719 void Visit(CastNode& castNode) override;
720 void Visit(ConstructNode& constructNode) override;
721 void Visit(NewNode& newNode) override;
722 void Visit(ThisNode& thisNode) override;
723 void Visit(BaseNode& baseNode) override;
724 void Visit(ParenthesizedExpressionNode& parenthesizedExpressionNode) override;
725 private:
726 BoundCompileUnit& boundCompileUnit;
727 SymbolTable* symbolTable;
728 Module* module;
729 ContainerScope* containerScope;
730 ContainerScope* qualifiedScope;
731 BoundFunction* currentFunction;
732 DeclarationBlock* currentDeclarationBlock;
733 FileScope* currentFileScope;
734 ClassTypeSymbol* currentClassType;
735 bool cast;
736 bool dontThrow;
737 bool error;
738 bool returned;
739 bool broke;
740 bool continued;
741 bool lvalue;
742 Span span;
743 boost::uuids::uuid moduleId;
744 std::unique_ptr<Value> value;
745 TypeSymbol* targetType;
746 ValueType targetValueType;
747 VariableValueSymbol* targetValueSymbol;
748 std::vector<std::std::unique_ptr<Value>>argumentValues;
749 std::unique_ptr<Value> structureReferenceValue;
750 std::vector<TypeSymbol*> templateTypeArguments;
751 void EvaluateBinOp(BinaryNode& node, BinaryOperatorFun* fun);
752 void EvaluateBinOp(BinaryNode& node, BinaryOperatorFun* fun, Operator op);
753 void EvaluateAdditivePointerOp(const Span& span, Operator op, const std::std::unique_ptr<Value>&left, conststd::std::unique_ptr<Value>&right);
754 void EvaluateUnaryOp(UnaryNode& node, UnaryOperatorFun* fun);
755 void EvaluateSymbol(Symbol* symbol, const Span& span);
756 void EvaluateConstantSymbol(ConstantSymbol* constantSymbol, const Span& span);
757 void EvaluateEnumConstantSymbol(EnumConstantSymbol* enumConstantSymbol, const Span& span);
758 };
759
760 Evaluator::Evaluator(BoundCompileUnit& boundCompileUnit_, ContainerScope* containerScope_, TypeSymbol* targetType_, ValueType targetValueType_, bool cast_, bool dontThrow_, BoundFunction* currentFunction_,
761 const Span& span_, const boost::uuids::uuid& moduleId_) :
762 boundCompileUnit(boundCompileUnit_), symbolTable(&boundCompileUnit.GetSymbolTable()), module(&boundCompileUnit.GetModule()),
763 containerScope(containerScope_), qualifiedScope(nullptr), cast(cast_), dontThrow(dontThrow_), error(false),
764 returned(false), broke(false), continued(false), lvalue(false), currentFunction(currentFunction_), currentDeclarationBlock(nullptr), currentFileScope(nullptr), currentClassType(nullptr),
765 span(span_), moduleId(moduleId_), value(), targetType(targetType_), targetValueType(targetValueType_), targetValueSymbol(nullptr)
766 {
767 }
768
769 void Evaluator::EvaluateBinOp(BinaryNode& node, BinaryOperatorFun* fun)
770 {
771 EvaluateBinOp(node, fun, Operator::other);
772 }
773
774 void Evaluator::EvaluateBinOp(BinaryNode& node, BinaryOperatorFun* fun, Operator op)
775 {
776 node.Left()->Accept(*this);
777 if (error)
778 {
779 return;
780 }
781 if (!value)
782 {
783 if (dontThrow)
784 {
785 error = true;
786 return;
787 }
788 else
789 {
790 ThrowCannotEvaluateStatically(span, moduleId, node.GetSpan(), node.ModuleId());
791 }
792 }
793 std::unique_ptr<Value> left(value.release());
794 node.Right()->Accept(*this);
795 if (error)
796 {
797 return;
798 }
799 if (!value)
800 {
801 if (dontThrow)
802 {
803 error = true;
804 return;
805 }
806 else
807 {
808 ThrowCannotEvaluateStatically(span, moduleId, node.GetSpan(), node.ModuleId());
809 }
810 }
811 std::unique_ptr<Value> right(value.release());
812 if ((op == Operator::add || op == Operator::sub) && (left->GetValueType() == ValueType::pointerValue || right->GetValueType() == ValueType::pointerValue))
813 {
814 EvaluateAdditivePointerOp(node.GetSpan(), op, left, right);
815 return;
816 }
817 if (op == Operator::comparison && left->GetValueType() == ValueType::pointerValue && right->GetValueType() == ValueType::pointerValue)
818 {
819 PointerValue* leftPtr = static_cast<PointerValue*>(left.get());
820 PointerValue* rightPtr = static_cast<PointerValue*>(right.get());
821 if (leftPtr->GetValue() != nullptr && rightPtr->GetValue() != nullptr && leftPtr->PointeeType() != rightPtr->PointeeType())
822 {
823 if (dontThrow)
824 {
825 error = true;
826 return;
827 }
828 else
829 {
830 throw Exception("incompatible pointer types for comparison", node.GetSpan(), node.ModuleId());
831 }
832 }
833 }
834 ValueType leftType = left->GetValueType();
835 ValueType rightType = right->GetValueType();
836 ValueType commonType = CommonType(leftType, rightType);
837 ValueType operationType = commonType;
838 if (targetValueType > operationType)
839 {
840 operationType = targetValueType;
841 }
842 TypeSymbol* type = GetTypeFor(operationType, symbolTable);
843 if (!type)
844 {
845 if (dontThrow)
846 {
847 error = true;
848 return;
849 }
850 else
851 {
852 throw Exception("conversion from " + ValueTypeStr(leftType) + " to " + ValueTypeStr(operationType) + " is not valid", span, moduleId);
853 }
854 }
855 std::unique_ptr<Value> leftConverted(left->As(type, cast, node.GetSpan(), node.ModuleId(), dontThrow));
856 std::unique_ptr<Value> rightConverted(right->As(type, cast, node.GetSpan(), node.ModuleId(), dontThrow));
857 if (dontThrow)
858 {
859 if (!leftConverted || !rightConverted)
860 {
861 error = true;
862 return;
863 }
864 }
865 BinaryOperatorFun operation = fun[uint8_t(operationType)];
866 value.reset(operation(leftConverted.get(), rightConverted.get(), node.GetSpan(), node.ModuleId(), dontThrow));
867 }
868
869 void Evaluator::EvaluateAdditivePointerOp(const Span& span, Operator op, const std::std::unique_ptr<Value>&left, conststd::std::unique_ptr<Value>&right)
870 {
871 if (op == Operator::add)
872 {
873 if (left->GetValueType() == ValueType::pointerValue)
874 {
875 std::unique_ptr<Value> rightConverted(right->As(symbolTable->GetTypeByName(U"long"), cast, span, moduleId, dontThrow));
876 if (dontThrow)
877 {
878 if (!rightConverted)
879 {
880 error = true;
881 return;
882 }
883 }
884 int64_t offset = static_cast<LongValue*>(rightConverted.get())->GetValue();
885 PointerValue* leftPointerValue = static_cast<PointerValue*>(left.get());
886 value.reset(leftPointerValue->Add(offset));
887 if (!value)
888 {
889 if (dontThrow)
890 {
891 error = true;
892 return;
893 }
894 else
895 {
896 throw Exception("invalid pointer operands", span, moduleId);
897 }
898 }
899 }
900 else if (right->GetValueType() == ValueType::pointerValue)
901 {
902 std::unique_ptr<Value> leftConverted(right->As(symbolTable->GetTypeByName(U"long"), cast, span, moduleId, dontThrow));
903 if (dontThrow)
904 {
905 if (!leftConverted)
906 {
907 error = true;
908 return;
909 }
910 }
911 int64_t offset = static_cast<LongValue*>(leftConverted.get())->GetValue();
912 PointerValue* rightPointerValue = static_cast<PointerValue*>(right.get());
913 value.reset(rightPointerValue->Add(offset));
914 if (!value)
915 {
916 if (dontThrow)
917 {
918 error = true;
919 return;
920 }
921 else
922 {
923 throw Exception("invalid pointer operands", span, moduleId);
924 }
925 }
926 }
927 else
928 {
929 if (dontThrow)
930 {
931 error = true;
932 return;
933 }
934 else
935 {
936 throw Exception("invalid pointer operands", span, moduleId);
937 }
938 }
939 }
940 else if (op == Operator::sub)
941 {
942 if (left->GetValueType() == ValueType::pointerValue && right->GetValueType() != ValueType::pointerValue)
943 {
944 std::unique_ptr<Value> rightConverted(right->As(symbolTable->GetTypeByName(U"long"), cast, span, moduleId, dontThrow));
945 if (dontThrow)
946 {
947 if (!rightConverted)
948 {
949 error = true;
950 return;
951 }
952 }
953 int64_t offset = static_cast<LongValue*>(rightConverted.get())->GetValue();
954 PointerValue* leftPointerValue = static_cast<PointerValue*>(left.get());
955 value.reset(leftPointerValue->Sub(offset));
956 if (!value)
957 {
958 if (dontThrow)
959 {
960 error = true;
961 return;
962 }
963 else
964 {
965 throw Exception("invalid pointer operands", span, moduleId);
966 }
967 }
968 }
969 else if (left->GetValueType() == ValueType::pointerValue && right->GetValueType() == ValueType::pointerValue)
970 {
971 PointerValue* leftPointerValue = static_cast<PointerValue*>(left.get());
972 PointerValue* rightPointerValue = static_cast<PointerValue*>(right.get());
973 if (leftPointerValue->PointeeType() != rightPointerValue->PointeeType())
974 {
975 if (dontThrow)
976 {
977 error = true;
978 return;
979 }
980 else
981 {
982 throw Exception("incompatible pointer operands", span, moduleId);
983 }
984 }
985 value.reset(leftPointerValue->Sub(rightPointerValue->GetValue()));
986 if (!value)
987 {
988 if (dontThrow)
989 {
990 error = true;
991 return;
992 }
993 else
994 {
995 throw Exception("invalid pointer operands", span, moduleId);
996 }
997 }
998 }
999 else
1000 {
1001 if (dontThrow)
1002 {
1003 error = true;
1004 return;
1005 }
1006 else
1007 {
1008 throw Exception("invalid pointer operands", span, moduleId);
1009 }
1010 }
1011 }
1012 }
1013
1014 void Evaluator::EvaluateUnaryOp(UnaryNode& node, UnaryOperatorFun* fun)
1015 {
1016 node.Subject()->Accept(*this);
1017 if (error)
1018 {
1019 return;
1020 }
1021 if (!value)
1022 {
1023 if (dontThrow)
1024 {
1025 error = true;
1026 return;
1027 }
1028 else
1029 {
1030 ThrowCannotEvaluateStatically(span, moduleId, node.GetSpan(), node.ModuleId());
1031 }
1032 }
1033 std::unique_ptr<Value> subject(value.release());
1034 ValueType subjectType = subject->GetValueType();
1035 ValueType operationType = subjectType;
1036 if (targetValueType > operationType)
1037 {
1038 operationType = targetValueType;
1039 }
1040 TypeSymbol* type = GetTypeFor(operationType, symbolTable);
1041 if (!type)
1042 {
1043 if (dontThrow)
1044 {
1045 error = true;
1046 return;
1047 }
1048 else
1049 {
1050 throw Exception("conversion from " + ValueTypeStr(subjectType) + " to " + ValueTypeStr(operationType) + " is not valid", span, moduleId);
1051 }
1052 }
1053 std::unique_ptr<Value> subjectConverted(subject->As(type, cast, node.GetSpan(), node.ModuleId(), dontThrow));
1054 if (dontThrow)
1055 {
1056 if (!subjectConverted)
1057 {
1058 error = true;
1059 return;
1060 }
1061 }
1062 UnaryOperatorFun operation = fun[uint8_t(operationType)];
1063 value.reset(operation(subjectConverted.get(), node.GetSpan(), node.ModuleId(), dontThrow));
1064 }
1065
1066 std::std::unique_ptr<Value>Evaluator::GetValue()
1067 {
1068 if (error)
1069 {
1070 return std::unique_ptr<Value>();
1071 }
1072 return std::move(value);
1073 }
1074
1075 void Evaluator::Visit(FunctionNode& functionNode)
1076 {
1077 bool fileScopeAdded = false;
1078 Symbol* symbol = symbolTable->GetSymbol(&functionNode);
1079 if (symbol->IsFunctionSymbol())
1080 {
1081 FunctionSymbol* functionSymbol = static_cast<FunctionSymbol*>(symbol);
1082 int n = functionSymbol->UsingNodes().Count();
1083 if (n > 0)
1084 {
1085 FileScope* fileScope = new FileScope();
1086 FileScope* prevFileScope = currentFileScope;
1087 currentFileScope = fileScope;
1088 boundCompileUnit.AddFileScope(fileScope);
1089 fileScopeAdded = true;
1090 for (int i = 0; i < n; ++i)
1091 {
1092 Node* usingNode = functionSymbol->UsingNodes()[i];
1093 usingNode->Accept(*this);
1094 }
1095 currentFileScope = prevFileScope;
1096 }
1097 }
1098 bool prevReturned = returned;
1099 DeclarationBlock* prevDeclarationBlock = currentDeclarationBlock;
1100 DeclarationBlock declarationBlock(span, moduleId, U"functionBlock");
1101 currentDeclarationBlock = &declarationBlock;
1102 ContainerScope* prevContainerScope = containerScope;
1103 containerScope = symbol->GetContainerScope();
1104 declarationBlock.GetContainerScope()->SetParentScope(containerScope);
1105 containerScope = declarationBlock.GetContainerScope();
1106 int nt = functionNode.TemplateParameters().Count();
1107 if (nt != templateTypeArguments.size())
1108 {
1109 if (dontThrow)
1110 {
1111 containerScope = prevContainerScope;
1112 currentDeclarationBlock = prevDeclarationBlock;
1113 returned = prevReturned;
1114 error = true;
1115 return;
1116 }
1117 else
1118 {
1119 throw Exception("wrong number of function template type arguments", span, moduleId);
1120 }
1121 }
1122 for (int i = 0; i < nt; ++i)
1123 {
1124 TemplateParameterNode* templateParameterNode = functionNode.TemplateParameters()[i];
1125 TypeSymbol* templateTypeArgument = templateTypeArguments[i];
1126 BoundTemplateParameterSymbol* boundTemplateParameter = new BoundTemplateParameterSymbol(span, moduleId, templateParameterNode->Id()->Str());
1127 boundTemplateParameter->SetType(templateTypeArgument);
1128 declarationBlock.AddMember(boundTemplateParameter);
1129 }
1130 int n = functionNode.Parameters().Count();
1131 if (n != argumentValues.size())
1132 {
1133 if (dontThrow)
1134 {
1135 containerScope = prevContainerScope;
1136 currentDeclarationBlock = prevDeclarationBlock;
1137 returned = prevReturned;
1138 error = true;
1139 return;
1140 }
1141 else
1142 {
1143 throw Exception("wrong number of function arguments", span, moduleId);
1144 }
1145 }
1146 for (int i = 0; i < n; ++i)
1147 {
1148 std::unique_ptr<Value> argumentValue = std::move(argumentValues[i]);
1149 TypeSymbol* argumentType = argumentValue->GetType(symbolTable);
1150 ParameterNode* parameterNode = functionNode.Parameters()[i];
1151 VariableValueSymbol* variableValueSymbol = new VariableValueSymbol(parameterNode->GetSpan(), parameterNode->ModuleId(), parameterNode->Id()->Str(), std::move(argumentValue));
1152 variableValueSymbol->SetType(argumentType);
1153 declarationBlock.AddMember(variableValueSymbol);
1154 }
1155 functionNode.Body()->Accept(*this);
1156 containerScope = prevContainerScope;
1157 currentDeclarationBlock = prevDeclarationBlock;
1158 returned = prevReturned;
1159 if (fileScopeAdded)
1160 {
1161 boundCompileUnit.RemoveLastFileScope();
1162 }
1163 }
1164
1165 void Evaluator::Visit(ConstructorNode& constructorNode)
1166 {
1167 bool fileScopeAdded = false;
1168 Symbol* symbol = symbolTable->GetSymbol(&constructorNode);
1169 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(symbol->Parent());
1170 ClassTypeSymbol* prevClassType = currentClassType;
1171 currentClassType = classType;
1172 if (symbol->IsFunctionSymbol())
1173 {
1174 FunctionSymbol* functionSymbol = static_cast<FunctionSymbol*>(symbol);
1175 int n = functionSymbol->UsingNodes().Count();
1176 if (n > 0)
1177 {
1178 FileScope* fileScope = new FileScope();
1179 FileScope* prevFileScope = currentFileScope;
1180 currentFileScope = fileScope;
1181 boundCompileUnit.AddFileScope(fileScope);
1182 fileScopeAdded = true;
1183 for (int i = 0; i < n; ++i)
1184 {
1185 Node* usingNode = functionSymbol->UsingNodes()[i];
1186 usingNode->Accept(*this);
1187 }
1188 currentFileScope = prevFileScope;
1189 }
1190 }
1191 bool prevReturned = returned;
1192 DeclarationBlock* prevDeclarationBlock = currentDeclarationBlock;
1193 DeclarationBlock declarationBlock(span, moduleId, U"constructorBlock");
1194 currentDeclarationBlock = &declarationBlock;
1195 ContainerScope* prevContainerScope = containerScope;
1196 containerScope = symbol->GetContainerScope();
1197 declarationBlock.GetContainerScope()->SetParentScope(containerScope);
1198 containerScope = declarationBlock.GetContainerScope();
1199 int n = constructorNode.Parameters().Count();
1200 if (n != argumentValues.size())
1201 {
1202 if (dontThrow)
1203 {
1204 containerScope = prevContainerScope;
1205 currentDeclarationBlock = prevDeclarationBlock;
1206 returned = prevReturned;
1207 currentClassType = prevClassType;
1208 error = true;
1209 return;
1210 }
1211 else
1212 {
1213 throw Exception("wrong number of constructor arguments", span, moduleId);
1214 }
1215 }
1216 for (int i = 0; i < n; ++i)
1217 {
1218 std::unique_ptr<Value> argumentValue = std::move(argumentValues[i]);
1219 TypeSymbol* argumentType = argumentValue->GetType(symbolTable);
1220 ParameterNode* parameterNode = constructorNode.Parameters()[i];
1221 VariableValueSymbol* variableValueSymbol = new VariableValueSymbol(parameterNode->GetSpan(), parameterNode->ModuleId(), parameterNode->Id()->Str(), std::move(argumentValue));
1222 variableValueSymbol->SetType(argumentType);
1223 declarationBlock.AddMember(variableValueSymbol);
1224 }
1225 std::unordered_map<std::u32string, MemberInitializerNode*> memberInitializerMap;
1226 int ni = constructorNode.Initializers().Count();
1227 for (int i = 0; i < ni; ++i)
1228 {
1229 InitializerNode* initializer = constructorNode.Initializers()[i];
1230 if (initializer->GetNodeType() == NodeType::thisInitializerNode || initializer->GetNodeType() == NodeType::baseInitializerNode)
1231 {
1232 if (dontThrow)
1233 {
1234 containerScope = prevContainerScope;
1235 currentDeclarationBlock = prevDeclarationBlock;
1236 returned = prevReturned;
1237 currentClassType = prevClassType;
1238 error = true;
1239 return;
1240 }
1241 else
1242 {
1243 throw Exception("this and base initializers not supported for a constexpr constructor", constructorNode.GetSpan(), constructorNode.ModuleId());
1244 }
1245 }
1246 else
1247 {
1248 MemberInitializerNode* memberInitializer = static_cast<MemberInitializerNode*>(initializer);
1249 std::u32string memberName = memberInitializer->MemberId()->Str();
1250 auto it = memberInitializerMap.find(memberName);
1251 if (it != memberInitializerMap.cend())
1252 {
1253 if (dontThrow)
1254 {
1255 containerScope = prevContainerScope;
1256 currentDeclarationBlock = prevDeclarationBlock;
1257 returned = prevReturned;
1258 currentClassType = prevClassType;
1259 error = true;
1260 return;
1261 }
1262 else
1263 {
1264 throw Exception("already has initializer for member variable '" + ToUtf8(memberName) + "'", initializer->GetSpan(), initializer->ModuleId());
1265 }
1266 }
1267 memberInitializerMap[memberName] = memberInitializer;
1268 }
1269 }
1270 std::vector<std::std::unique_ptr<Value>>memberValues;
1271 int nm = classType->MemberVariables().size();
1272 for (int i = 0; i < nm; ++i)
1273 {
1274 value.reset();
1275 MemberVariableSymbol* memberVariableSymbol = classType->MemberVariables()[i];
1276 std::vector<std::std::unique_ptr<Value>>initializerArgumentValues;
1277 auto it = memberInitializerMap.find(memberVariableSymbol->Name());
1278 if (it != memberInitializerMap.cend())
1279 {
1280 MemberInitializerNode* memberInitializer = it->second;
1281 int na = memberInitializer->Arguments().Count();
1282 for (int i = 0; i < na; ++i)
1283 {
1284 Node* argumentNode = memberInitializer->Arguments()[i];
1285 argumentNode->Accept(*this);
1286 if (error) return;
1287 if (!value)
1288 {
1289 if (dontThrow)
1290 {
1291 containerScope = prevContainerScope;
1292 currentDeclarationBlock = prevDeclarationBlock;
1293 returned = prevReturned;
1294 currentClassType = prevClassType;
1295 error = true;
1296 return;
1297 }
1298 else
1299 {
1300 ThrowCannotEvaluateStatically(span, moduleId, constructorNode.GetSpan(), constructorNode.ModuleId());
1301 }
1302 }
1303 initializerArgumentValues.push_back(std::move(value));
1304 }
1305 }
1306 std::vector<FunctionScopeLookup> lookups;
1307 lookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, containerScope));
1308 lookups.push_back(FunctionScopeLookup(ScopeLookup::this_, memberVariableSymbol->GetType()->BaseType()->GetContainerScope()));
1309 lookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopes, nullptr));
1310 std::vector<std::std::unique_ptr<BoundExpression>>initializerArguments=ValuesToLiterals(initializerArgumentValues, symbolTable, error);
1311 if (error)
1312 {
1313 if (dontThrow)
1314 {
1315 containerScope = prevContainerScope;
1316 currentDeclarationBlock = prevDeclarationBlock;
1317 returned = prevReturned;
1318 currentClassType = prevClassType;
1319 return;
1320 }
1321 else
1322 {
1323 ThrowCannotEvaluateStatically(span, moduleId, constructorNode.GetSpan(), constructorNode.ModuleId());
1324 }
1325 }
1326 initializerArguments.insert(initializerArguments.begin(), std::unique_ptr<BoundExpression>(new BoundTypeExpression(span, moduleId, memberVariableSymbol->GetType()->AddPointer(span, moduleId))));
1327 OverloadResolutionFlags flags = OverloadResolutionFlags::dontInstantiate;
1328 if (dontThrow)
1329 {
1330 flags = flags | OverloadResolutionFlags::dontThrow;
1331 }
1332 std::vector<TypeSymbol*> templateArgumentTypes;
1333 std::unique_ptr<Exception> exception;
1334 std::unique_ptr<BoundFunctionCall> constructorCall = ResolveOverload(U"@constructor", containerScope, lookups, initializerArguments, boundCompileUnit, currentFunction,
1335 constructorNode.GetSpan(), constructorNode.ModuleId(), flags, templateArgumentTypes, exception);
1336 if (!constructorCall)
1337 {
1338 if (dontThrow)
1339 {
1340 containerScope = prevContainerScope;
1341 currentDeclarationBlock = prevDeclarationBlock;
1342 returned = prevReturned;
1343 currentClassType = prevClassType;
1344 error = true;
1345 return;
1346 }
1347 else
1348 {
1349 ThrowCannotEvaluateStatically(span, moduleId, constructorNode.GetSpan(), constructorNode.ModuleId());
1350 }
1351 }
1352 argumentValues = ArgumentsToValues(constructorCall->Arguments(), error, true, boundCompileUnit);
1353 if (error)
1354 {
1355 if (dontThrow)
1356 {
1357 return;
1358 }
1359 else
1360 {
1361 ThrowCannotEvaluateStatically(span, moduleId, constructorNode.GetSpan(), constructorNode.ModuleId());
1362 }
1363 }
1364 FunctionSymbol* constructorSymbol = constructorCall->GetFunctionSymbol();
1365 if (constructorSymbol->IsCompileTimePrimitiveFunction())
1366 {
1367 value = constructorSymbol->ConstructValue(argumentValues, span, moduleId, nullptr);
1368 if (!value)
1369 {
1370 if (dontThrow)
1371 {
1372 containerScope = prevContainerScope;
1373 currentDeclarationBlock = prevDeclarationBlock;
1374 returned = prevReturned;
1375 currentClassType = prevClassType;
1376 error = true;
1377 return;
1378 }
1379 else
1380 {
1381 ThrowCannotEvaluateStatically(span, moduleId, constructorNode.GetSpan(), constructorNode.ModuleId());
1382 }
1383 }
1384 }
1385 else if (constructorSymbol->IsConstExpr())
1386 {
1387 FunctionNode* ctorNode = boundCompileUnit.GetFunctionNodeFor(constructorSymbol);
1388 ctorNode->Accept(*this);
1389 if (!value)
1390 {
1391 if (dontThrow)
1392 {
1393 containerScope = prevContainerScope;
1394 currentDeclarationBlock = prevDeclarationBlock;
1395 returned = prevReturned;
1396 currentClassType = prevClassType;
1397 error = true;
1398 return;
1399 }
1400 else
1401 {
1402 ThrowCannotEvaluateStatically(span, moduleId, ctorNode->GetSpan(), ctorNode->ModuleId());
1403 }
1404 }
1405 }
1406 else
1407 {
1408 if (dontThrow)
1409 {
1410 containerScope = prevContainerScope;
1411 currentDeclarationBlock = prevDeclarationBlock;
1412 returned = prevReturned;
1413 currentClassType = prevClassType;
1414 error = true;
1415 return;
1416 }
1417 else
1418 {
1419 ThrowCannotEvaluateStatically(span, moduleId, constructorNode.GetSpan(), constructorNode.ModuleId());
1420 }
1421 }
1422 memberValues.push_back(std::move(value));
1423 }
1424 constructorNode.Body()->Accept(*this);
1425 value.reset(new StructuredValue(span, moduleId, classType, std::move(memberValues)));
1426 containerScope = prevContainerScope;
1427 currentDeclarationBlock = prevDeclarationBlock;
1428 returned = prevReturned;
1429 currentClassType = prevClassType;
1430 if (fileScopeAdded)
1431 {
1432 boundCompileUnit.RemoveLastFileScope();
1433 }
1434 }
1435
1436 void Evaluator::Visit(MemberFunctionNode& memberFunctionNode)
1437 {
1438 bool fileScopeAdded = false;
1439 Symbol* symbol = symbolTable->GetSymbol(&memberFunctionNode);
1440 if (symbol->IsFunctionSymbol())
1441 {
1442 FunctionSymbol* functionSymbol = static_cast<FunctionSymbol*>(symbol);
1443 int n = functionSymbol->UsingNodes().Count();
1444 if (n > 0)
1445 {
1446 FileScope* fileScope = new FileScope();
1447 FileScope* prevFileScope = currentFileScope;
1448 currentFileScope = fileScope;
1449 boundCompileUnit.AddFileScope(fileScope);
1450 fileScopeAdded = true;
1451 for (int i = 0; i < n; ++i)
1452 {
1453 Node* usingNode = functionSymbol->UsingNodes()[i];
1454 usingNode->Accept(*this);
1455 }
1456 currentFileScope = prevFileScope;
1457 }
1458 }
1459 bool prevReturned = returned;
1460 DeclarationBlock* prevDeclarationBlock = currentDeclarationBlock;
1461 DeclarationBlock declarationBlock(span, moduleId, U"functionBlock");
1462 currentDeclarationBlock = &declarationBlock;
1463 ContainerScope* prevContainerScope = containerScope;
1464 containerScope = symbol->GetContainerScope();
1465 declarationBlock.GetContainerScope()->SetParentScope(containerScope);
1466 containerScope = declarationBlock.GetContainerScope();
1467 int n = memberFunctionNode.Parameters().Count();
1468 if (n != argumentValues.size())
1469 {
1470 if (dontThrow)
1471 {
1472 containerScope = prevContainerScope;
1473 currentDeclarationBlock = prevDeclarationBlock;
1474 returned = prevReturned;
1475 error = true;
1476 return;
1477 }
1478 else
1479 {
1480 throw Exception("wrong number of function arguments", memberFunctionNode.GetSpan(), memberFunctionNode.ModuleId());
1481 }
1482 }
1483 for (int i = 0; i < n; ++i)
1484 {
1485 std::unique_ptr<Value> argumentValue = std::move(argumentValues[i]);
1486 TypeSymbol* argumentType = argumentValue->GetType(symbolTable);
1487 ParameterNode* parameterNode = memberFunctionNode.Parameters()[i];
1488 VariableValueSymbol* variableValueSymbol = new VariableValueSymbol(parameterNode->GetSpan(), parameterNode->ModuleId(), parameterNode->Id()->Str(), std::move(argumentValue));
1489 variableValueSymbol->SetType(argumentType);
1490 declarationBlock.AddMember(variableValueSymbol);
1491 }
1492 if (currentClassType && structureReferenceValue)
1493 {
1494 StructuredValue* structuredValue = nullptr;
1495 if (structureReferenceValue->IsStructuredReferenceValue())
1496 {
1497 structuredValue = static_cast<StructuredReferenceValue*>(structureReferenceValue.get())->GetStructuredValue();
1498 }
1499 else
1500 {
1501 if (dontThrow)
1502 {
1503 containerScope = prevContainerScope;
1504 currentDeclarationBlock = prevDeclarationBlock;
1505 returned = prevReturned;
1506 error = true;
1507 return;
1508 }
1509 else
1510 {
1511 throw Exception("structured reference value expected", memberFunctionNode.GetSpan(), memberFunctionNode.ModuleId());
1512 }
1513 }
1514 int n = currentClassType->MemberVariables().size();
1515 if (n != structuredValue->Members().size())
1516 {
1517 if (dontThrow)
1518 {
1519 containerScope = prevContainerScope;
1520 currentDeclarationBlock = prevDeclarationBlock;
1521 returned = prevReturned;
1522 error = true;
1523 return;
1524 }
1525 else
1526 {
1527 throw Exception("wrong number of structured value members", memberFunctionNode.GetSpan(), memberFunctionNode.ModuleId());
1528 }
1529 }
1530 for (int i = 0; i < n; ++i)
1531 {
1532 MemberVariableSymbol* memberVariableSymbol = currentClassType->MemberVariables()[i];
1533 Value* memberValue = structuredValue->Members()[i].get();
1534 ConstantSymbol* constantSymbol = new ConstantSymbol(span, moduleId, memberVariableSymbol->Name());
1535 constantSymbol->SetModule(module);
1536 constantSymbol->SetType(memberVariableSymbol->GetType());
1537 if (memberValue->GetValueType() == ValueType::arrayValue)
1538 {
1539 constantSymbol->SetValue(new ArrayReferenceValue(static_cast<ArrayValue*>(memberValue)));
1540 }
1541 else if (memberValue->GetValueType() == ValueType::structuredValue)
1542 {
1543 constantSymbol->SetValue(new StructuredReferenceValue(static_cast<StructuredValue*>(memberValue)));
1544 }
1545 else
1546 {
1547 constantSymbol->SetValue(memberValue->Clone());
1548 }
1549 declarationBlock.AddMember(constantSymbol);
1550 }
1551 }
1552 memberFunctionNode.Body()->Accept(*this);
1553 containerScope = prevContainerScope;
1554 currentDeclarationBlock = prevDeclarationBlock;
1555 returned = prevReturned;
1556 if (fileScopeAdded)
1557 {
1558 boundCompileUnit.RemoveLastFileScope();
1559 }
1560 }
1561
1562 void Evaluator::Visit(ConversionFunctionNode& conversionFunctionNode)
1563 {
1564 if (dontThrow)
1565 {
1566 error = true;
1567 return;
1568 }
1569 else
1570 {
1571 ThrowCannotEvaluateStatically(span, moduleId, conversionFunctionNode.GetSpan(), conversionFunctionNode.ModuleId());
1572 }
1573 }
1574
1575 void Evaluator::Visit(NamespaceImportNode& namespaceImportNode)
1576 {
1577 if (currentFileScope)
1578 {
1579 currentFileScope->InstallNamespaceImport(containerScope, &namespaceImportNode);
1580 }
1581 }
1582
1583 void Evaluator::Visit(AliasNode& aliasNode)
1584 {
1585 if (currentFileScope)
1586 {
1587 currentFileScope->InstallAlias(containerScope, &aliasNode);
1588 }
1589 }
1590
1591 void Evaluator::Visit(ClassNode& classNode)
1592 {
1593 if (dontThrow)
1594 {
1595 error = true;
1596 return;
1597 }
1598 else
1599 {
1600 ThrowCannotEvaluateStatically(span, moduleId, classNode.GetSpan(), classNode.ModuleId());
1601 }
1602 }
1603
1604 void Evaluator::Visit(StaticConstructorNode& staticConstructorNode)
1605 {
1606 if (dontThrow)
1607 {
1608 error = true;
1609 return;
1610 }
1611 else
1612 {
1613 ThrowCannotEvaluateStatically(span, moduleId, staticConstructorNode.GetSpan(), staticConstructorNode.ModuleId());
1614 }
1615 }
1616
1617 void Evaluator::Visit(DestructorNode& destructorNode)
1618 {
1619 if (dontThrow)
1620 {
1621 error = true;
1622 return;
1623 }
1624 else
1625 {
1626 ThrowCannotEvaluateStatically(span, moduleId, destructorNode.GetSpan(), destructorNode.ModuleId());
1627 }
1628 }
1629
1630 void Evaluator::Visit(MemberVariableNode& memberVariableNode)
1631 {
1632 memberVariableNode.Id()->Accept(*this);
1633 }
1634
1635 void Evaluator::Visit(InterfaceNode& interfaceNode)
1636 {
1637 if (dontThrow)
1638 {
1639 error = true;
1640 return;
1641 }
1642 else
1643 {
1644 ThrowCannotEvaluateStatically(span, moduleId, interfaceNode.GetSpan(), interfaceNode.ModuleId());
1645 }
1646 }
1647
1648 void Evaluator::Visit(DelegateNode& delegateNode)
1649 {
1650 if (dontThrow)
1651 {
1652 error = true;
1653 return;
1654 }
1655 else
1656 {
1657 ThrowCannotEvaluateStatically(span, moduleId, delegateNode.GetSpan(), delegateNode.ModuleId());
1658 }
1659 }
1660
1661 void Evaluator::Visit(ClassDelegateNode& classDelegateNode)
1662 {
1663 if (dontThrow)
1664 {
1665 error = true;
1666 return;
1667 }
1668 else
1669 {
1670 ThrowCannotEvaluateStatically(span, moduleId, classDelegateNode.GetSpan(), classDelegateNode.ModuleId());
1671 }
1672 }
1673
1674 void Evaluator::Visit(CompoundStatementNode& compoundStatementNode)
1675 {
1676 DeclarationBlock* prevDeclarationBlock = currentDeclarationBlock;
1677 DeclarationBlock declarationBlock(span, moduleId, U"block");
1678 currentDeclarationBlock = &declarationBlock;
1679 ContainerScope* prevContainerScope = containerScope;
1680 declarationBlock.GetContainerScope()->SetParentScope(containerScope);
1681 containerScope = declarationBlock.GetContainerScope();
1682 int n = compoundStatementNode.Statements().Count();
1683 for (int i = 0; i < n; ++i)
1684 {
1685 StatementNode* statementNode = compoundStatementNode.Statements()[i];
1686 statementNode->Accept(*this);
1687 if (error || returned || broke || continued)
1688 {
1689 currentDeclarationBlock = prevDeclarationBlock;
1690 containerScope = prevContainerScope;
1691 return;
1692 }
1693 }
1694 containerScope = prevContainerScope;
1695 currentDeclarationBlock = prevDeclarationBlock;
1696 }
1697
1698 void Evaluator::Visit(ReturnStatementNode& returnStatementNode)
1699 {
1700 if (returnStatementNode.Expression())
1701 {
1702 returnStatementNode.Expression()->Accept(*this);
1703 if (error) return;
1704 }
1705 returned = true;
1706 }
1707
1708 void Evaluator::Visit(IfStatementNode& ifStatementNode)
1709 {
1710 ifStatementNode.Condition()->Accept(*this);
1711 if (error) return;
1712 if (value && value->GetValueType() == ValueType::boolValue)
1713 {
1714 BoolValue* condition = static_cast<BoolValue*>(value.get());
1715 if (condition->GetValue())
1716 {
1717 ifStatementNode.ThenS()->Accept(*this);
1718 }
1719 else if (ifStatementNode.ElseS())
1720 {
1721 ifStatementNode.ElseS()->Accept(*this);
1722 }
1723 }
1724 else
1725 {
1726 if (dontThrow)
1727 {
1728 error = true;
1729 }
1730 else
1731 {
1732 throw Exception("Boolean expression expected", ifStatementNode.GetSpan(), ifStatementNode.ModuleId());
1733 }
1734 }
1735 }
1736
1737 void Evaluator::Visit(WhileStatementNode& whileStatementNode)
1738 {
1739 bool prevBroke = broke;
1740 bool prevContinued = continued;
1741 whileStatementNode.Condition()->Accept(*this);
1742 if (error)
1743 {
1744 broke = prevBroke;
1745 continued = prevContinued;
1746 return;
1747 }
1748 if (value && value->GetValueType() == ValueType::boolValue)
1749 {
1750 BoolValue* condition = static_cast<BoolValue*>(value.get());
1751 while (condition->GetValue())
1752 {
1753 whileStatementNode.Statement()->Accept(*this);
1754 if (error || returned)
1755 {
1756 broke = prevBroke;
1757 continued = prevContinued;
1758 return;
1759 }
1760 if (broke)
1761 {
1762 break;
1763 }
1764 if (continued)
1765 {
1766 continued = false;
1767 }
1768 whileStatementNode.Condition()->Accept(*this);
1769 if (error)
1770 {
1771 broke = prevBroke;
1772 continued = prevContinued;
1773 return;
1774 }
1775 if (value && value->GetValueType() == ValueType::boolValue)
1776 {
1777 condition = static_cast<BoolValue*>(value.get());
1778 }
1779 else
1780 {
1781 if (dontThrow)
1782 {
1783 broke = prevBroke;
1784 continued = prevContinued;
1785 error = true;
1786 return;
1787 }
1788 else
1789 {
1790 throw Exception("Boolean expression expected", whileStatementNode.GetSpan(), whileStatementNode.ModuleId());
1791 }
1792 }
1793 }
1794 }
1795 else
1796 {
1797 if (dontThrow)
1798 {
1799 error = true;
1800 }
1801 else
1802 {
1803 throw Exception("Boolean expression expected", whileStatementNode.GetSpan(), whileStatementNode.ModuleId());
1804 }
1805 }
1806 broke = prevBroke;
1807 continued = prevContinued;
1808 }
1809
1810 void Evaluator::Visit(DoStatementNode& doStatementNode)
1811 {
1812 bool prevBroke = broke;
1813 bool prevContinued = continued;
1814 bool loop = true;
1815 while (loop)
1816 {
1817 doStatementNode.Statement()->Accept(*this);
1818 if (error || returned)
1819 {
1820 broke = prevBroke;
1821 continued = prevContinued;
1822 return;
1823 }
1824 if (broke)
1825 {
1826 break;
1827 }
1828 if (continued)
1829 {
1830 continued = false;
1831 }
1832 doStatementNode.Condition()->Accept(*this);
1833 if (error)
1834 {
1835 broke = prevBroke;
1836 continued = prevContinued;
1837 return;
1838 }
1839 if (value && value->GetValueType() == ValueType::boolValue)
1840 {
1841 BoolValue* condition = static_cast<BoolValue*>(value.get());
1842 loop = condition->GetValue();
1843 }
1844 else
1845 {
1846 if (dontThrow)
1847 {
1848 broke = prevBroke;
1849 continued = prevContinued;
1850 error = true;
1851 return;
1852 }
1853 else
1854 {
1855 throw Exception("Boolean expression expected", doStatementNode.GetSpan(), doStatementNode.ModuleId());
1856 }
1857 }
1858 }
1859 broke = prevBroke;
1860 continued = prevContinued;
1861 }
1862
1863 void Evaluator::Visit(ForStatementNode& forStatementNode)
1864 {
1865 bool prevBroke = broke;
1866 bool prevContinued = continued;
1867 DeclarationBlock* prevDeclarationBlock = currentDeclarationBlock;
1868 DeclarationBlock declarationBlock(span, moduleId, U"forBlock");
1869 currentDeclarationBlock = &declarationBlock;
1870 ContainerScope* prevContainerScope = containerScope;
1871 declarationBlock.GetContainerScope()->SetParentScope(containerScope);
1872 containerScope = declarationBlock.GetContainerScope();
1873 forStatementNode.InitS()->Accept(*this);
1874 if (error || returned)
1875 {
1876 containerScope = prevContainerScope;
1877 currentDeclarationBlock = prevDeclarationBlock;
1878 broke = prevBroke;
1879 continued = prevContinued;
1880 return;
1881 }
1882 forStatementNode.Condition()->Accept(*this);
1883 if (error)
1884 {
1885 containerScope = prevContainerScope;
1886 currentDeclarationBlock = prevDeclarationBlock;
1887 broke = prevBroke;
1888 continued = prevContinued;
1889 return;
1890 }
1891 if (value && value->GetValueType() == ValueType::boolValue)
1892 {
1893 BoolValue* condition = static_cast<BoolValue*>(value.get());
1894 bool loop = condition->GetValue();
1895 while (loop)
1896 {
1897 forStatementNode.ActionS()->Accept(*this);
1898 if (error || returned)
1899 {
1900 containerScope = prevContainerScope;
1901 currentDeclarationBlock = prevDeclarationBlock;
1902 broke = prevBroke;
1903 continued = prevContinued;
1904 return;
1905 }
1906 if (broke)
1907 {
1908 break;
1909 }
1910 if (continued)
1911 {
1912 continued = false;
1913 }
1914 forStatementNode.LoopS()->Accept(*this);
1915 if (error)
1916 {
1917 containerScope = prevContainerScope;
1918 currentDeclarationBlock = prevDeclarationBlock;
1919 broke = prevBroke;
1920 continued = prevContinued;
1921 return;
1922 }
1923 forStatementNode.Condition()->Accept(*this);
1924 if (error)
1925 {
1926 containerScope = prevContainerScope;
1927 currentDeclarationBlock = prevDeclarationBlock;
1928 broke = prevBroke;
1929 continued = prevContinued;
1930 return;
1931 }
1932 if (value && value->GetValueType() == ValueType::boolValue)
1933 {
1934 BoolValue* condition = static_cast<BoolValue*>(value.get());
1935 loop = condition->GetValue();
1936 }
1937 else
1938 {
1939 if (dontThrow)
1940 {
1941 containerScope = prevContainerScope;
1942 currentDeclarationBlock = prevDeclarationBlock;
1943 broke = prevBroke;
1944 continued = prevContinued;
1945 error = true;
1946 return;
1947 }
1948 else
1949 {
1950 throw Exception("Boolean expression expected", forStatementNode.GetSpan(), forStatementNode.ModuleId());
1951 }
1952 }
1953 }
1954 }
1955 else
1956 {
1957 if (dontThrow)
1958 {
1959 containerScope = prevContainerScope;
1960 currentDeclarationBlock = prevDeclarationBlock;
1961 broke = prevBroke;
1962 continued = prevContinued;
1963 error = true;
1964 return;
1965 }
1966 else
1967 {
1968 throw Exception("Boolean expression expected", forStatementNode.GetSpan(), forStatementNode.ModuleId());
1969 }
1970 }
1971 containerScope = prevContainerScope;
1972 currentDeclarationBlock = prevDeclarationBlock;
1973 broke = prevBroke;
1974 continued = prevContinued;
1975 }
1976
1977 void Evaluator::Visit(BreakStatementNode& breakStatementNode)
1978 {
1979 broke = true;
1980 }
1981
1982 void Evaluator::Visit(ContinueStatementNode& continueStatementNode)
1983 {
1984 continued = true;
1985 }
1986
1987 void Evaluator::Visit(GotoStatementNode& gotoStatementNode)
1988 {
1989 if (dontThrow)
1990 {
1991 error = true;
1992 return;
1993 }
1994 else
1995 {
1996 ThrowCannotEvaluateStatically(span, moduleId, gotoStatementNode.GetSpan(), gotoStatementNode.ModuleId());
1997 }
1998 }
1999
2000 void Evaluator::Visit(ConstructionStatementNode& constructionStatementNode)
2001 {
2002 if (!currentDeclarationBlock)
2003 {
2004 if (dontThrow)
2005 {
2006 error = true;
2007 return;
2008 }
2009 else
2010 {
2011 throw Exception("internal error: current declaration block not set", constructionStatementNode.GetSpan(), constructionStatementNode.ModuleId());
2012 }
2013 }
2014 TypeSymbol* type = ResolveType(constructionStatementNode.TypeExpr(), boundCompileUnit, containerScope);
2015 std::vector<std::std::unique_ptr<Value>>values;
2016 int n = constructionStatementNode.Arguments().Count();
2017 for (int i = 0; i < n; ++i)
2018 {
2019 Node* argumentNode = constructionStatementNode.Arguments()[i];
2020 argumentNode->Accept(*this);
2021 if (error) return;
2022 if (!value)
2023 {
2024 if (dontThrow)
2025 {
2026 error = true;
2027 return;
2028 }
2029 else
2030 {
2031 ThrowCannotEvaluateStatically(span, moduleId, constructionStatementNode.GetSpan(), constructionStatementNode.ModuleId());
2032 }
2033 }
2034 values.push_back(std::move(value));
2035 }
2036 std::vector<std::std::unique_ptr<BoundExpression>>arguments=ValuesToLiterals(values, symbolTable, error);
2037 if (error)
2038 {
2039 if (dontThrow)
2040 {
2041 return;
2042 }
2043 else
2044 {
2045 ThrowCannotEvaluateStatically(span, moduleId, constructionStatementNode.GetSpan(), constructionStatementNode.ModuleId());
2046 }
2047 }
2048 arguments.insert(arguments.begin(), std::unique_ptr<BoundExpression>(new BoundTypeExpression(span, moduleId, type->AddPointer(span, moduleId))));
2049 std::vector<FunctionScopeLookup> scopeLookups;
2050 scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, containerScope));
2051 scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopes, nullptr));
2052 std::unique_ptr<Exception> exception;
2053 OverloadResolutionFlags flags = OverloadResolutionFlags::dontInstantiate;
2054 if (dontThrow)
2055 {
2056 flags = flags | OverloadResolutionFlags::dontThrow;
2057 }
2058 std::vector<TypeSymbol*> templateArgumentTypes;
2059 std::unique_ptr<BoundFunctionCall> constructorCall = ResolveOverload(U"@constructor", containerScope, scopeLookups, arguments, boundCompileUnit, currentFunction, span, moduleId,
2060 flags, templateArgumentTypes, exception);
2061 if (!constructorCall)
2062 {
2063 if (dontThrow)
2064 {
2065 error = true;
2066 return;
2067 }
2068 else
2069 {
2070 ThrowCannotEvaluateStatically(span, moduleId, constructionStatementNode.GetSpan(), constructionStatementNode.ModuleId());
2071 }
2072 }
2073 argumentValues = ArgumentsToValues(constructorCall->Arguments(), error, true, boundCompileUnit);
2074 if (error)
2075 {
2076 if (dontThrow)
2077 {
2078 return;
2079 }
2080 else
2081 {
2082 ThrowCannotEvaluateStatically(span, moduleId, constructionStatementNode.GetSpan(), constructionStatementNode.ModuleId());
2083 }
2084 }
2085 FunctionSymbol* constructorSymbol = constructorCall->GetFunctionSymbol();
2086 if (constructorSymbol->IsCompileTimePrimitiveFunction())
2087 {
2088 value = constructorSymbol->ConstructValue(argumentValues, span, moduleId, nullptr);
2089 if (!value)
2090 {
2091 if (dontThrow)
2092 {
2093 error = true;
2094 return;
2095 }
2096 else
2097 {
2098 ThrowCannotEvaluateStatically(span, moduleId, constructionStatementNode.GetSpan(), constructionStatementNode.ModuleId());
2099 }
2100 }
2101 }
2102 else if (constructorSymbol->IsConstExpr())
2103 {
2104 FunctionNode* ctorNode = boundCompileUnit.GetFunctionNodeFor(constructorSymbol);
2105 ctorNode->Accept(*this);
2106 if (!value)
2107 {
2108 if (dontThrow)
2109 {
2110 error = true;
2111 return;
2112 }
2113 else
2114 {
2115 ThrowCannotEvaluateStatically(span, moduleId, ctorNode->GetSpan(), ctorNode->ModuleId());
2116 }
2117 }
2118 }
2119 else
2120 {
2121 if (dontThrow)
2122 {
2123 error = true;
2124 return;
2125 }
2126 else
2127 {
2128 ThrowCannotEvaluateStatically(span, moduleId, constructionStatementNode.GetSpan(), constructionStatementNode.ModuleId());
2129 }
2130 }
2131 VariableValueSymbol* variableValue = new VariableValueSymbol(span, moduleId, constructionStatementNode.Id()->Str(), std::move(value));
2132 variableValue->SetType(type);
2133 currentDeclarationBlock->AddMember(variableValue);
2134 }
2135
2136 void Evaluator::Visit(DeleteStatementNode& deleteStatementNode)
2137 {
2138 if (dontThrow)
2139 {
2140 error = true;
2141 return;
2142 }
2143 else
2144 {
2145 ThrowCannotEvaluateStatically(span, moduleId, deleteStatementNode.GetSpan(), deleteStatementNode.ModuleId());
2146 }
2147 }
2148
2149 void Evaluator::Visit(DestroyStatementNode& destroyStatementNode)
2150 {
2151 if (dontThrow)
2152 {
2153 error = true;
2154 return;
2155 }
2156 else
2157 {
2158 ThrowCannotEvaluateStatically(span, moduleId, destroyStatementNode.GetSpan(), destroyStatementNode.ModuleId());
2159 }
2160 }
2161
2162 void Evaluator::Visit(AssignmentStatementNode& assignmentStatementNode)
2163 {
2164 bool prevLvalue = lvalue;
2165 lvalue = true;
2166 VariableValueSymbol* prevTargetValueSymbol = targetValueSymbol;
2167 assignmentStatementNode.TargetExpr()->Accept(*this);
2168 VariableValueSymbol* target = targetValueSymbol;
2169 targetValueSymbol = prevTargetValueSymbol;
2170 lvalue = prevLvalue;
2171 assignmentStatementNode.SourceExpr()->Accept(*this);
2172 std::vector<std::std::unique_ptr<Value>>values;
2173 values.push_back(std::move(value));
2174 std::vector<std::std::unique_ptr<BoundExpression>>arguments=ValuesToLiterals(values, symbolTable, error);
2175 if (error)
2176 {
2177 if (dontThrow)
2178 {
2179 return;
2180 }
2181 else
2182 {
2183 ThrowCannotEvaluateStatically(span, moduleId, assignmentStatementNode.GetSpan(), assignmentStatementNode.ModuleId());
2184 }
2185 }
2186 arguments.insert(arguments.begin(), std::unique_ptr<BoundExpression>(new BoundTypeExpression(span, moduleId, target->GetType()->AddPointer(span, moduleId))));
2187 std::vector<FunctionScopeLookup> scopeLookups;
2188 scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, containerScope));
2189 scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopes, nullptr));
2190 std::unique_ptr<Exception> exception;
2191 OverloadResolutionFlags flags = OverloadResolutionFlags::dontInstantiate;
2192 if (dontThrow)
2193 {
2194 flags = flags | OverloadResolutionFlags::dontThrow;
2195 }
2196 std::vector<TypeSymbol*> templateArgumentTypes;
2197 std::unique_ptr<BoundFunctionCall> assignmentCall = ResolveOverload(U"operator=", containerScope, scopeLookups, arguments, boundCompileUnit, currentFunction, span, moduleId,
2198 flags, templateArgumentTypes, exception);
2199 if (!assignmentCall)
2200 {
2201 if (dontThrow)
2202 {
2203 error = true;
2204 return;
2205 }
2206 else
2207 {
2208 ThrowCannotEvaluateStatically(span, moduleId, assignmentStatementNode.GetSpan(), assignmentStatementNode.ModuleId());
2209 }
2210 }
2211 argumentValues = ArgumentsToValues(assignmentCall->Arguments(), error, true, boundCompileUnit);
2212 if (error)
2213 {
2214 if (dontThrow)
2215 {
2216 return;
2217 }
2218 else
2219 {
2220 ThrowCannotEvaluateStatically(span, moduleId, assignmentStatementNode.GetSpan(), assignmentStatementNode.ModuleId());
2221 }
2222 }
2223 target->SetValue(argumentValues.front().release());
2224 }
2225
2226 void Evaluator::Visit(ExpressionStatementNode& expressionStatementNode)
2227 {
2228 expressionStatementNode.Expression()->Accept(*this);
2229 }
2230
2231 void Evaluator::Visit(EmptyStatementNode& emptyStatementNode)
2232 {
2233 }
2234
2235 void Evaluator::Visit(RangeForStatementNode& rangeForStatementNode)
2236 {
2237
2238 if (dontThrow)
2239 {
2240 error = true;
2241 return;
2242 }
2243 else
2244 {
2245 ThrowCannotEvaluateStatically(span, moduleId, rangeForStatementNode.GetSpan(), rangeForStatementNode.ModuleId());
2246 }
2247 }
2248
2249 void Evaluator::Visit(SwitchStatementNode& switchStatementNode)
2250 {
2251
2252 if (dontThrow)
2253 {
2254 error = true;
2255 return;
2256 }
2257 else
2258 {
2259 ThrowCannotEvaluateStatically(span, moduleId, switchStatementNode.GetSpan(), switchStatementNode.ModuleId());
2260 }
2261 }
2262
2263 void Evaluator::Visit(CaseStatementNode& caseStatementNode)
2264 {
2265
2266 if (dontThrow)
2267 {
2268 error = true;
2269 return;
2270 }
2271 else
2272 {
2273 ThrowCannotEvaluateStatically(span, moduleId, caseStatementNode.GetSpan(), caseStatementNode.ModuleId());
2274 }
2275 }
2276
2277 void Evaluator::Visit(DefaultStatementNode& defaultStatementNode)
2278 {
2279
2280 if (dontThrow)
2281 {
2282 error = true;
2283 return;
2284 }
2285 else
2286 {
2287 ThrowCannotEvaluateStatically(span, moduleId, defaultStatementNode.GetSpan(), defaultStatementNode.ModuleId());
2288 }
2289 }
2290
2291 void Evaluator::Visit(GotoCaseStatementNode& gotoCaseStatementNode)
2292 {
2293 if (dontThrow)
2294 {
2295 error = true;
2296 return;
2297 }
2298 else
2299 {
2300 ThrowCannotEvaluateStatically(span, moduleId, gotoCaseStatementNode.GetSpan(), gotoCaseStatementNode.ModuleId());
2301 }
2302 }
2303
2304 void Evaluator::Visit(GotoDefaultStatementNode& gotoDefaultStatementNode)
2305 {
2306 if (dontThrow)
2307 {
2308 error = true;
2309 return;
2310 }
2311 else
2312 {
2313 ThrowCannotEvaluateStatically(span, moduleId, gotoDefaultStatementNode.GetSpan(), gotoDefaultStatementNode.ModuleId());
2314 }
2315 }
2316
2317 void Evaluator::Visit(ThrowStatementNode& throwStatementNode)
2318 {
2319 if (dontThrow)
2320 {
2321 error = true;
2322 return;
2323 }
2324 else
2325 {
2326 ThrowCannotEvaluateStatically(span, moduleId, throwStatementNode.GetSpan(), throwStatementNode.ModuleId());
2327 }
2328 }
2329
2330 void Evaluator::Visit(TryStatementNode& tryStatementNode)
2331 {
2332 if (dontThrow)
2333 {
2334 error = true;
2335 return;
2336 }
2337 else
2338 {
2339 ThrowCannotEvaluateStatically(span, moduleId, tryStatementNode.GetSpan(), tryStatementNode.ModuleId());
2340 }
2341 }
2342
2343 void Evaluator::Visit(CatchNode& catchNode)
2344 {
2345 if (dontThrow)
2346 {
2347 error = true;
2348 return;
2349 }
2350 else
2351 {
2352 ThrowCannotEvaluateStatically(span, moduleId, catchNode.GetSpan(), catchNode.ModuleId());
2353 }
2354 }
2355
2356 void Evaluator::Visit(AssertStatementNode& assertStatementNode)
2357 {
2358 assertStatementNode.AssertExpr()->Accept(*this);
2359 if (error) return;
2360 if (!value)
2361 {
2362 if (dontThrow)
2363 {
2364 error = true;
2365 return;
2366 }
2367 else
2368 {
2369 ThrowCannotEvaluateStatically(span, moduleId, assertStatementNode.GetSpan(), assertStatementNode.ModuleId());
2370 }
2371 }
2372 if (value->GetValueType() == ValueType::boolValue)
2373 {
2374 BoolValue* boolValue = static_cast<BoolValue*>(value.get());
2375 if (!boolValue->GetValue())
2376 {
2377 if (dontThrow)
2378 {
2379 error = true;
2380 return;
2381 }
2382 else
2383 {
2384 throw Exception("assertion '" + assertStatementNode.AssertExpr()->ToString() + "' failed", span, moduleId, assertStatementNode.GetSpan(), assertStatementNode.ModuleId());
2385 }
2386 }
2387 }
2388 else
2389 {
2390 if (dontThrow)
2391 {
2392 error = true;
2393 return;
2394 }
2395 else
2396 {
2397 throw Exception("assertion expression is not a Boolean-valued expression", span, moduleId, assertStatementNode.GetSpan(), assertStatementNode.ModuleId());
2398 }
2399 }
2400 }
2401
2402 void Evaluator::Visit(ConditionalCompilationPartNode& conditionalCompilationPartNode)
2403 {
2404 if (dontThrow)
2405 {
2406 error = true;
2407 return;
2408 }
2409 else
2410 {
2411 ThrowCannotEvaluateStatically(span, moduleId, conditionalCompilationPartNode.GetSpan(), conditionalCompilationPartNode.ModuleId());
2412 }
2413 }
2414
2415 void Evaluator::Visit(ConditionalCompilationDisjunctionNode& conditionalCompilationDisjunctionNode)
2416 {
2417 if (dontThrow)
2418 {
2419 error = true;
2420 return;
2421 }
2422 else
2423 {
2424 ThrowCannotEvaluateStatically(span, moduleId, conditionalCompilationDisjunctionNode.GetSpan(), conditionalCompilationDisjunctionNode.ModuleId());
2425 }
2426 }
2427
2428 void Evaluator::Visit(ConditionalCompilationConjunctionNode& conditionalCompilationConjunctionNode)
2429 {
2430 if (dontThrow)
2431 {
2432 error = true;
2433 return;
2434 }
2435 else
2436 {
2437 ThrowCannotEvaluateStatically(span, moduleId, conditionalCompilationConjunctionNode.GetSpan(), conditionalCompilationConjunctionNode.ModuleId());
2438 }
2439 }
2440
2441 void Evaluator::Visit(ConditionalCompilationNotNode& conditionalCompilationNotNode)
2442 {
2443 if (dontThrow)
2444 {
2445 error = true;
2446 return;
2447 }
2448 else
2449 {
2450 ThrowCannotEvaluateStatically(span, moduleId, conditionalCompilationNotNode.GetSpan(), conditionalCompilationNotNode.ModuleId());
2451 }
2452 }
2453
2454 void Evaluator::Visit(ConditionalCompilationPrimaryNode& conditionalCompilationPrimaryNode)
2455 {
2456 if (dontThrow)
2457 {
2458 error = true;
2459 return;
2460 }
2461 else
2462 {
2463 ThrowCannotEvaluateStatically(span, moduleId, conditionalCompilationPrimaryNode.GetSpan(), conditionalCompilationPrimaryNode.ModuleId());
2464 }
2465 }
2466
2467 void Evaluator::Visit(ConditionalCompilationStatementNode& conditionalCompilationStatementNode)
2468 {
2469 if (dontThrow)
2470 {
2471 error = true;
2472 return;
2473 }
2474 else
2475 {
2476 ThrowCannotEvaluateStatically(span, moduleId, conditionalCompilationStatementNode.GetSpan(), conditionalCompilationStatementNode.ModuleId());
2477 }
2478 }
2479
2480 void Evaluator::Visit(BoolNode& boolNode)
2481 {
2482 if (dontThrow)
2483 {
2484 error = true;
2485 }
2486 else
2487 {
2488 ThrowCannotEvaluateStatically(span, moduleId, boolNode.GetSpan(), boolNode.ModuleId());
2489 }
2490 }
2491
2492 void Evaluator::Visit(SByteNode& sbyteNode)
2493 {
2494 if (dontThrow)
2495 {
2496 error = true;
2497 }
2498 else
2499 {
2500 ThrowCannotEvaluateStatically(span, moduleId, sbyteNode.GetSpan(), sbyteNode.ModuleId());
2501 }
2502 }
2503
2504 void Evaluator::Visit(ByteNode& byteNode)
2505 {
2506 if (dontThrow)
2507 {
2508 error = true;
2509 }
2510 else
2511 {
2512 ThrowCannotEvaluateStatically(span, moduleId, byteNode.GetSpan(), byteNode.ModuleId());
2513 }
2514 }
2515
2516 void Evaluator::Visit(ShortNode& shortNode)
2517 {
2518 if (dontThrow)
2519 {
2520 error = true;
2521 }
2522 else
2523 {
2524 ThrowCannotEvaluateStatically(span, moduleId, shortNode.GetSpan(), shortNode.ModuleId());
2525 }
2526 }
2527
2528 void Evaluator::Visit(UShortNode& ushortNode)
2529 {
2530 if (dontThrow)
2531 {
2532 error = true;
2533 }
2534 else
2535 {
2536 ThrowCannotEvaluateStatically(span, moduleId, ushortNode.GetSpan(), ushortNode.ModuleId());
2537 }
2538 }
2539
2540 void Evaluator::Visit(IntNode& intNode)
2541 {
2542 if (dontThrow)
2543 {
2544 error = true;
2545 }
2546 else
2547 {
2548 ThrowCannotEvaluateStatically(span, moduleId, intNode.GetSpan(), intNode.ModuleId());
2549 }
2550 }
2551
2552 void Evaluator::Visit(UIntNode& uintNode)
2553 {
2554 if (dontThrow)
2555 {
2556 error = true;
2557 }
2558 else
2559 {
2560 ThrowCannotEvaluateStatically(span, moduleId, uintNode.GetSpan(), uintNode.ModuleId());
2561 }
2562 }
2563
2564 void Evaluator::Visit(LongNode& longNode)
2565 {
2566 if (dontThrow)
2567 {
2568 error = true;
2569 }
2570 else
2571 {
2572 ThrowCannotEvaluateStatically(span, moduleId, longNode.GetSpan(), longNode.ModuleId());
2573 }
2574 }
2575
2576 void Evaluator::Visit(ULongNode& ulongNode)
2577 {
2578 if (dontThrow)
2579 {
2580 error = true;
2581 }
2582 else
2583 {
2584 ThrowCannotEvaluateStatically(span, moduleId, ulongNode.GetSpan(), ulongNode.ModuleId());
2585 }
2586 }
2587
2588 void Evaluator::Visit(FloatNode& floatNode)
2589 {
2590 if (dontThrow)
2591 {
2592 error = true;
2593 }
2594 else
2595 {
2596 ThrowCannotEvaluateStatically(span, moduleId, floatNode.GetSpan(), floatNode.ModuleId());
2597 }
2598 }
2599
2600 void Evaluator::Visit(DoubleNode& doubleNode)
2601 {
2602 if (dontThrow)
2603 {
2604 error = true;
2605 }
2606 else
2607 {
2608 ThrowCannotEvaluateStatically(span, moduleId, doubleNode.GetSpan(), doubleNode.ModuleId());
2609 }
2610 }
2611
2612 void Evaluator::Visit(CharNode& charNode)
2613 {
2614 if (dontThrow)
2615 {
2616 error = true;
2617 }
2618 else
2619 {
2620 ThrowCannotEvaluateStatically(span, moduleId, charNode.GetSpan(), charNode.ModuleId());
2621 }
2622 }
2623
2624 void Evaluator::Visit(WCharNode& wcharNode)
2625 {
2626 if (dontThrow)
2627 {
2628 error = true;
2629 }
2630 else
2631 {
2632 ThrowCannotEvaluateStatically(span, moduleId, wcharNode.GetSpan(), wcharNode.ModuleId());
2633 }
2634 }
2635
2636 void Evaluator::Visit(UCharNode& ucharNode)
2637 {
2638 if (dontThrow)
2639 {
2640 error = true;
2641 }
2642 else
2643 {
2644 ThrowCannotEvaluateStatically(span, moduleId, ucharNode.GetSpan(), ucharNode.ModuleId());
2645 }
2646 }
2647
2648 void Evaluator::Visit(VoidNode& voidNode)
2649 {
2650 if (dontThrow)
2651 {
2652 error = true;
2653 }
2654 else
2655 {
2656 ThrowCannotEvaluateStatically(span, moduleId, voidNode.GetSpan(), voidNode.ModuleId());
2657 }
2658 }
2659
2660 void Evaluator::Visit(BooleanLiteralNode& booleanLiteralNode)
2661 {
2662 value.reset(new BoolValue(booleanLiteralNode.GetSpan(), booleanLiteralNode.ModuleId(), booleanLiteralNode.Value()));
2663 }
2664
2665 void Evaluator::Visit(SByteLiteralNode& sbyteLiteralNode)
2666 {
2667 value.reset(new SByteValue(sbyteLiteralNode.GetSpan(), sbyteLiteralNode.ModuleId(), sbyteLiteralNode.Value()));
2668 }
2669
2670 void Evaluator::Visit(ByteLiteralNode& byteLiteralNode)
2671 {
2672 value.reset(new ByteValue(byteLiteralNode.GetSpan(), byteLiteralNode.ModuleId(), byteLiteralNode.Value()));
2673 }
2674
2675 void Evaluator::Visit(ShortLiteralNode& shortLiteralNode)
2676 {
2677 value.reset(new ShortValue(shortLiteralNode.GetSpan(), shortLiteralNode.ModuleId(), shortLiteralNode.Value()));
2678 }
2679
2680 void Evaluator::Visit(UShortLiteralNode& ushortLiteralNode)
2681 {
2682 value.reset(new UShortValue(ushortLiteralNode.GetSpan(), ushortLiteralNode.ModuleId(), ushortLiteralNode.Value()));
2683 }
2684
2685 void Evaluator::Visit(IntLiteralNode& intLiteralNode)
2686 {
2687 value.reset(new IntValue(intLiteralNode.GetSpan(), intLiteralNode.ModuleId(), intLiteralNode.Value()));
2688 }
2689
2690 void Evaluator::Visit(UIntLiteralNode& uintLiteralNode)
2691 {
2692 value.reset(new UIntValue(uintLiteralNode.GetSpan(), uintLiteralNode.ModuleId(), uintLiteralNode.Value()));
2693 }
2694
2695 void Evaluator::Visit(LongLiteralNode& longLiteralNode)
2696 {
2697 value.reset(new LongValue(longLiteralNode.GetSpan(), longLiteralNode.ModuleId(), longLiteralNode.Value()));
2698 }
2699
2700 void Evaluator::Visit(ULongLiteralNode& ulongLiteralNode)
2701 {
2702 value.reset(new ULongValue(ulongLiteralNode.GetSpan(), ulongLiteralNode.ModuleId(), ulongLiteralNode.Value()));
2703 }
2704
2705 void Evaluator::Visit(FloatLiteralNode& floatLiteralNode)
2706 {
2707 value.reset(new FloatValue(floatLiteralNode.GetSpan(), floatLiteralNode.ModuleId(), floatLiteralNode.Value()));
2708 }
2709
2710 void Evaluator::Visit(DoubleLiteralNode& doubleLiteralNode)
2711 {
2712 value.reset(new DoubleValue(doubleLiteralNode.GetSpan(), doubleLiteralNode.ModuleId(), doubleLiteralNode.Value()));
2713 }
2714
2715 void Evaluator::Visit(CharLiteralNode& charLiteralNode)
2716 {
2717 value.reset(new CharValue(charLiteralNode.GetSpan(), charLiteralNode.ModuleId(), charLiteralNode.Value()));
2718 }
2719
2720 void Evaluator::Visit(WCharLiteralNode& wcharLiteralNode)
2721 {
2722 value.reset(new WCharValue(wcharLiteralNode.GetSpan(), wcharLiteralNode.ModuleId(), wcharLiteralNode.Value()));
2723 }
2724
2725 void Evaluator::Visit(UCharLiteralNode& ucharLiteralNode)
2726 {
2727 value.reset(new UCharValue(ucharLiteralNode.GetSpan(), ucharLiteralNode.ModuleId(), ucharLiteralNode.Value()));
2728 }
2729
2730 void Evaluator::Visit(StringLiteralNode& stringLiteralNode)
2731 {
2732 value.reset(new StringValue(stringLiteralNode.GetSpan(), stringLiteralNode.ModuleId(), boundCompileUnit.Install(stringLiteralNode.Value()), stringLiteralNode.Value()));
2733 }
2734
2735 void Evaluator::Visit(WStringLiteralNode& wstringLiteralNode)
2736 {
2737 value.reset(new WStringValue(wstringLiteralNode.GetSpan(), wstringLiteralNode.ModuleId(), boundCompileUnit.Install(wstringLiteralNode.Value()), wstringLiteralNode.Value()));
2738 }
2739
2740 void Evaluator::Visit(UStringLiteralNode& ustringLiteralNode)
2741 {
2742 value.reset(new UStringValue(ustringLiteralNode.GetSpan(), ustringLiteralNode.ModuleId(), boundCompileUnit.Install(ustringLiteralNode.Value()), ustringLiteralNode.Value()));
2743 }
2744
2745 void Evaluator::Visit(NullLiteralNode& nullLiteralNode)
2746 {
2747 value.reset(new NullValue(nullLiteralNode.GetSpan(), nullLiteralNode.ModuleId(), symbolTable->GetTypeByName(U"@nullptr_type")));
2748 }
2749
2750 void Evaluator::Visit(ArrayLiteralNode& arrayLiteralNode)
2751 {
2752 if (targetValueType != ValueType::arrayValue)
2753 {
2754 if (dontThrow)
2755 {
2756 error = true;
2757 return;
2758 }
2759 else
2760 {
2761 throw Exception("array type expected", span, moduleId);
2762 }
2763 }
2764 ArrayTypeSymbol* arrayType = static_cast<ArrayTypeSymbol*>(targetType);
2765 TypeSymbol* elementType = arrayType->ElementType();
2766 std::vector<std::std::unique_ptr<Value>>elementValues;
2767 int n = arrayLiteralNode.Values().Count();
2768 if (arrayType->Size() != -1 && arrayType->Size() != n)
2769 {
2770 if (dontThrow)
2771 {
2772 error = true;
2773 return;
2774 }
2775 else
2776 {
2777 throw Exception("invalid length for array literal of type '" + ToUtf8(arrayType->FullName()) + "'", arrayLiteralNode.GetSpan(), arrayLiteralNode.ModuleId());
2778 }
2779 }
2780 for (int i = 0; i < n; ++i)
2781 {
2782 value = Evaluate(arrayLiteralNode.Values()[i], elementType, containerScope, boundCompileUnit, dontThrow, currentFunction, arrayLiteralNode.GetSpan(), arrayLiteralNode.ModuleId());
2783 if (error)
2784 {
2785 if (dontThrow)
2786 {
2787 return;
2788 }
2789 else
2790 {
2791 ThrowCannotEvaluateStatically(span, moduleId, arrayLiteralNode.GetSpan(), arrayLiteralNode.ModuleId());
2792 }
2793 }
2794 if (!value)
2795 {
2796 if (dontThrow)
2797 {
2798 error = true;
2799 return;
2800 }
2801 else
2802 {
2803 ThrowCannotEvaluateStatically(span, moduleId, arrayLiteralNode.GetSpan(), arrayLiteralNode.ModuleId());
2804 }
2805 }
2806 elementValues.push_back(std::move(value));
2807 }
2808 if (arrayType->Size() == -1)
2809 {
2810 arrayType = symbolTable->MakeArrayType(arrayType->ElementType(), n, arrayLiteralNode.GetSpan(), arrayLiteralNode.ModuleId());
2811 }
2812 value.reset(new ArrayValue(arrayLiteralNode.GetSpan(), arrayLiteralNode.ModuleId(), arrayType, std::move(elementValues)));
2813 }
2814
2815 void Evaluator::Visit(StructuredLiteralNode& structuredLiteralNode)
2816 {
2817 if (targetValueType != ValueType::structuredValue)
2818 {
2819 if (dontThrow)
2820 {
2821 error = true;
2822 return;
2823 }
2824 else
2825 {
2826 throw Exception("class type expected", span, moduleId);
2827 }
2828 }
2829 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(targetType);
2830 if (!currentFunction)
2831 {
2832 if (classType->IsProject() && !classType->IsBound())
2833 {
2834 Node* node = boundCompileUnit.GetSymbolTable().GetNodeNoThrow(classType);
2835 if (node)
2836 {
2837 TypeBinder typeBinder(boundCompileUnit);
2838 typeBinder.SetContainerScope(containerScope);
2839 node->Accept(typeBinder);
2840 }
2841 }
2842 }
2843 if (classType->IsLiteralClassType())
2844 {
2845 std::vector<std::std::unique_ptr<Value>>memberValues;
2846 int n = structuredLiteralNode.Members().Count();
2847 if (classType->MemberVariables().size() != n)
2848 {
2849 if (dontThrow)
2850 {
2851 error = true;
2852 return;
2853 }
2854 else
2855 {
2856 throw Exception("wrong number of members variables for class literal of type '" + ToUtf8(classType->FullName()) + "'", structuredLiteralNode.GetSpan(), structuredLiteralNode.ModuleId());
2857 }
2858 }
2859 for (int i = 0; i < n; ++i)
2860 {
2861 TypeSymbol* memberType = classType->MemberVariables()[i]->GetType();
2862 value = Evaluate(structuredLiteralNode.Members()[i], memberType, containerScope, boundCompileUnit, dontThrow, currentFunction, structuredLiteralNode.GetSpan(), structuredLiteralNode.ModuleId());
2863 if (error)
2864 {
2865 if (dontThrow)
2866 {
2867 return;
2868 }
2869 else
2870 {
2871 ThrowCannotEvaluateStatically(span, moduleId, structuredLiteralNode.GetSpan(), structuredLiteralNode.ModuleId());
2872 }
2873 }
2874 if (!value)
2875 {
2876 if (dontThrow)
2877 {
2878 error = true;
2879 return;
2880 }
2881 else
2882 {
2883 ThrowCannotEvaluateStatically(span, moduleId, structuredLiteralNode.GetSpan(), structuredLiteralNode.ModuleId());
2884 }
2885 }
2886 memberValues.push_back(std::move(value));
2887 }
2888 std::vector<std::std::unique_ptr<BoundExpression>>arguments=ValuesToLiterals(memberValues, symbolTable, error);
2889 if (error)
2890 {
2891 if (dontThrow)
2892 {
2893 return;
2894 }
2895 else
2896 {
2897 ThrowCannotEvaluateStatically(span, moduleId, structuredLiteralNode.GetSpan(), structuredLiteralNode.ModuleId());
2898 }
2899 }
2900 arguments.insert(arguments.begin(), std::unique_ptr<BoundExpression>(new BoundTypeExpression(span, moduleId, classType->AddPointer(span, moduleId))));
2901 std::vector<FunctionScopeLookup> scopeLookups;
2902 scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, classType->ClassOrNsScope()));
2903 scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, containerScope));
2904 scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopes, nullptr));
2905 std::unique_ptr<Exception> exception;
2906 OverloadResolutionFlags flags = OverloadResolutionFlags::dontInstantiate;
2907 if (dontThrow)
2908 {
2909 flags = flags | OverloadResolutionFlags::dontThrow;
2910 }
2911 std::vector<TypeSymbol*> templateArgumentTypes;
2912 std::unique_ptr<BoundFunctionCall> constructorCall = ResolveOverload(U"@constructor", containerScope, scopeLookups, arguments, boundCompileUnit, currentFunction, span, moduleId,
2913 flags, templateArgumentTypes, exception);
2914 if (!constructorCall)
2915 {
2916 if (dontThrow)
2917 {
2918 error = true;
2919 return;
2920 }
2921 else
2922 {
2923 ThrowCannotEvaluateStatically(span, moduleId, structuredLiteralNode.GetSpan(), structuredLiteralNode.ModuleId());
2924 }
2925 }
2926 argumentValues = ArgumentsToValues(constructorCall->Arguments(), error, true, boundCompileUnit);
2927 if (error)
2928 {
2929 if (dontThrow)
2930 {
2931 return;
2932 }
2933 else
2934 {
2935 ThrowCannotEvaluateStatically(span, moduleId, structuredLiteralNode.GetSpan(), structuredLiteralNode.ModuleId());
2936 }
2937 }
2938 FunctionSymbol* constructorSymbol = constructorCall->GetFunctionSymbol();
2939 if (constructorSymbol->IsConstExpr())
2940 {
2941 FunctionNode* constructorNode = boundCompileUnit.GetFunctionNodeFor(constructorSymbol);
2942 constructorNode->Accept(*this);
2943 }
2944 else
2945 {
2946 if (dontThrow)
2947 {
2948 error = true;
2949 return;
2950 }
2951 else
2952 {
2953 ThrowCannotEvaluateStatically(span, moduleId, structuredLiteralNode.GetSpan(), structuredLiteralNode.ModuleId());
2954 }
2955 }
2956 }
2957 else
2958 {
2959 if (dontThrow)
2960 {
2961 error = true;
2962 return;
2963 }
2964 else
2965 {
2966 throw Exception("class '" + ToUtf8(classType->FullName()) + "' is not a literal class ", structuredLiteralNode.GetSpan(), structuredLiteralNode.ModuleId());
2967 }
2968 }
2969 }
2970
2971 void Evaluator::Visit(IdentifierNode& identifierNode)
2972 {
2973 std::u32string name = identifierNode.Str();
2974 Symbol* symbol = containerScope->Lookup(name, ScopeLookup::this_and_base_and_parent);
2975 if (!symbol)
2976 {
2977 for (const std::std::unique_ptr<FileScope>&fileScope : boundCompileUnit.FileScopes())
2978 {
2979 symbol = fileScope->Lookup(name);
2980 if (symbol) break;
2981 }
2982 }
2983 if (symbol)
2984 {
2985 qualifiedScope = nullptr;
2986 if (name.find('.') != std::u32string::npos)
2987 {
2988 qualifiedScope = symbol->Parent()->GetContainerScope();
2989 }
2990 EvaluateSymbol(symbol, identifierNode.GetSpan());
2991 if (error)
2992 {
2993 return;
2994 }
2995 }
2996 else
2997 {
2998 if (dontThrow)
2999 {
3000 error = true;
3001 return;
3002 }
3003 else
3004 {
3005 throw Exception("symbol '" + ToUtf8(name) + "' not found", identifierNode.GetSpan(), identifierNode.ModuleId());
3006 }
3007 }
3008 }
3009
3010 void Evaluator::Visit(TemplateIdNode& templateIdNode)
3011 {
3012 templateIdNode.Primary()->Accept(*this);
3013 if (error) return;
3014 if (value && value->IsFunctionGroupValue())
3015 {
3016 FunctionGroupValue* functionGroupValue = static_cast<FunctionGroupValue*>(value.get());
3017 FunctionGroupSymbol* functionGroup = functionGroupValue->FunctionGroup();
3018 std::vector<TypeSymbol*> templateTypeArguments;
3019 int n = templateIdNode.TemplateArguments().Count();
3020 for (int i = 0; i < n; ++i)
3021 {
3022 Node* templateArgumentNode = templateIdNode.TemplateArguments()[i];
3023 TypeSymbol* templateTypeArgument = ResolveType(templateArgumentNode, boundCompileUnit, containerScope);
3024 templateTypeArguments.push_back(templateTypeArgument);
3025 }
3026 functionGroupValue->SetTemplateTypeArguments(std::move(templateTypeArguments));
3027 }
3028 else
3029 {
3030 if (dontThrow)
3031 {
3032 error = true;
3033 }
3034 else
3035 {
3036 ThrowCannotEvaluateStatically(span, moduleId, templateIdNode.GetSpan(), templateIdNode.ModuleId());
3037 }
3038 }
3039 }
3040
3041 void Evaluator::EvaluateSymbol(Symbol* symbol, const Span& span)
3042 {
3043 if (symbol->GetSymbolType() == SymbolType::constantSymbol)
3044 {
3045 ConstantSymbol* constantSymbol = static_cast<ConstantSymbol*>(symbol);
3046 EvaluateConstantSymbol(constantSymbol, span);
3047 }
3048 else if (symbol->GetSymbolType() == SymbolType::enumConstantSymbol)
3049 {
3050 EnumConstantSymbol* enumConstantSymbol = static_cast<EnumConstantSymbol*>(symbol);
3051 EvaluateEnumConstantSymbol(enumConstantSymbol, span);
3052 }
3053 else if (symbol->IsContainerSymbol())
3054 {
3055 ContainerSymbol* containerSymbol = static_cast<ContainerSymbol*>(symbol);
3056 value.reset(new ScopedValue(span, moduleId, containerSymbol));
3057 }
3058 else if (symbol->GetSymbolType() == SymbolType::functionGroupSymbol)
3059 {
3060 FunctionGroupSymbol* functionGroup = static_cast<FunctionGroupSymbol*>(symbol);
3061 value.reset(new FunctionGroupValue(functionGroup, qualifiedScope));
3062 }
3063 else if (symbol->GetSymbolType() == SymbolType::variableValueSymbol)
3064 {
3065 VariableValueSymbol* variableValueSymbol = static_cast<VariableValueSymbol*>(symbol);
3066 if (lvalue)
3067 {
3068 targetValueSymbol = variableValueSymbol;
3069 }
3070 else
3071 {
3072 value.reset(variableValueSymbol->GetValue()->Clone());
3073 }
3074 }
3075 else
3076 {
3077 if (dontThrow)
3078 {
3079 error = true;
3080 }
3081 else
3082 {
3083 ThrowCannotEvaluateStatically(span, moduleId);
3084 }
3085 }
3086 }
3087
3088 void Evaluator::EvaluateConstantSymbol(ConstantSymbol* constantSymbol, const Span& span)
3089 {
3090 if (constantSymbol->Evaluating())
3091 {
3092 if (dontThrow)
3093 {
3094 error = true;
3095 return;
3096 }
3097 throw Exception("cyclic depenency detected", span, moduleId);
3098 }
3099 Value* constantValue = constantSymbol->GetValue();
3100 if (constantValue)
3101 {
3102 switch (constantValue->GetValueType())
3103 {
3104 case ValueType::arrayValue:
3105 {
3106 value.reset(new ArrayReferenceValue(static_cast<ArrayValue*>(constantValue)));
3107 break;
3108 }
3109 case ValueType::structuredValue:
3110 {
3111 value.reset(new StructuredReferenceValue(static_cast<StructuredValue*>(constantValue)));
3112 break;
3113 }
3114 case ValueType::stringValue: case ValueType::wstringValue: case ValueType::ustringValue:
3115 {
3116 value.reset(new StringReferenceValue(constantValue));
3117 break;
3118 }
3119 default:
3120 {
3121 value.reset(constantValue->Clone());
3122 break;
3123 }
3124 }
3125 }
3126 else
3127 {
3128 Node* node = symbolTable->GetNodeNoThrow(constantSymbol);
3129 if (!node)
3130 {
3131 if (dontThrow)
3132 {
3133 error = true;
3134 return;
3135 }
3136 throw Exception("node for constant symbol '" + ToUtf8(constantSymbol->FullName()) + "' not found from symbol table", span, moduleId);
3137 }
3138 Assert(node->GetNodeType() == NodeType::constantNode, "constant node expected");
3139 ConstantNode* constantNode = static_cast<ConstantNode*>(node);
3140 constantSymbol->SetEvaluating();
3141 TypeBinder typeBinder(boundCompileUnit);
3142 typeBinder.SetContainerScope(containerScope);
3143 constantNode->Accept(typeBinder);
3144 constantSymbol->ResetEvaluating();
3145 Value* constantValue = constantSymbol->GetValue();
3146 Assert(constantValue, "constant value expected");
3147 value.reset(constantValue->Clone());
3148 }
3149 }
3150
3151 void Evaluator::EvaluateEnumConstantSymbol(EnumConstantSymbol* enumConstantSymbol, const Span& span)
3152 {
3153 if (enumConstantSymbol->Evaluating())
3154 {
3155 if (dontThrow)
3156 {
3157 error = true;
3158 return;
3159 }
3160 throw Exception("cyclic depenency detected", span, moduleId);
3161 }
3162 Value* enumConstantValue = enumConstantSymbol->GetValue();
3163 if (enumConstantValue)
3164 {
3165 value.reset(enumConstantValue->Clone());
3166 }
3167 else
3168 {
3169 Symbol* symbol = enumConstantSymbol->Parent();
3170 Assert(symbol->GetSymbolType() == SymbolType::enumTypeSymbol, "enum type symbol expected");
3171 EnumTypeSymbol* enumTypeSymbol = static_cast<EnumTypeSymbol*>(symbol);
3172 Node* node = boundCompileUnit.GetSymbolTable().GetNode(enumTypeSymbol);
3173 Assert(node->GetNodeType() == NodeType::enumTypeNode, "enum type node expected");
3174 EnumTypeNode* enumTypeNode = static_cast<EnumTypeNode*>(node);
3175 TypeBinder typeBinder(boundCompileUnit);
3176 typeBinder.SetContainerScope(containerScope);
3177 enumTypeNode->Accept(typeBinder);
3178 enumConstantSymbol->ResetEvaluating();
3179 Value* enumConstantValue = enumConstantSymbol->GetValue();
3180 Assert(enumConstantValue, "enum constant value expected");
3181 value.reset(enumConstantValue->Clone());
3182 }
3183 }
3184
3185 void Evaluator::Visit(DotNode& dotNode)
3186 {
3187 dotNode.Subject()->Accept(*this);
3188 if (error)
3189 {
3190 return;
3191 }
3192 if (value)
3193 {
3194 if (value->IsArrayReferenceValue())
3195 {
3196 TypeSymbol* type = static_cast<ArrayReferenceValue*>(value.get())->GetArrayValue()->GetType(symbolTable);
3197 ScopedValue* scopedValue = new ScopedValue(span, moduleId, type);
3198 scopedValue->SetType(type);
3199 value.reset(scopedValue);
3200 }
3201 else if (value->IsStructuredReferenceValue())
3202 {
3203 TypeSymbol* type = static_cast<StructuredReferenceValue*>(value.get())->GetStructuredValue()->GetType(symbolTable);
3204 ScopedValue* scopedValue = new ScopedValue(span, moduleId, type);
3205 scopedValue->SetType(type->AddPointer(span, moduleId));
3206 scopedValue->SetSubject(value.release());
3207 value.reset(scopedValue);
3208 }
3209 else if (value->IsStringReferenceValue())
3210 {
3211 TypeSymbol* type = symbolTable->GetTypeByName(U"@string_functions");
3212 ScopedValue* scopedValue = new ScopedValue(span, moduleId, type);
3213 scopedValue->SetType(type);
3214 scopedValue->SetSubject(value.release());
3215 value.reset(scopedValue);
3216 }
3217 else if (value->GetValueType() == ValueType::structuredValue)
3218 {
3219 TypeSymbol* type = static_cast<StructuredValue*>(value.get())->GetType(symbolTable);
3220 ScopedValue* scopedValue = new ScopedValue(span, moduleId, type);
3221 scopedValue->SetType(type);
3222 value.reset(scopedValue);
3223 }
3224 }
3225 if (value && value->IsScopedValue())
3226 {
3227 ScopedValue* scopedValue = static_cast<ScopedValue*>(value.get());
3228 ContainerSymbol* containerSymbol = scopedValue->GetContainerSymbol();
3229 if (containerSymbol->GetSymbolType() == SymbolType::classGroupTypeSymbol)
3230 {
3231 ClassGroupTypeSymbol* classGroupTypeSymbol = static_cast<ClassGroupTypeSymbol*>(containerSymbol);
3232 containerSymbol = classGroupTypeSymbol->GetClass(0);
3233 }
3234 ContainerScope* scope = containerSymbol->GetContainerScope();
3235 qualifiedScope = scope;
3236 std::u32string memberName = dotNode.MemberId()->Str();
3237 Symbol* symbol = scope->Lookup(memberName);
3238 if (symbol)
3239 {
3240 std::unique_ptr<Value> receiver;
3241 TypeSymbol* type = scopedValue->GetType(symbolTable);
3242 if (type&&( type->IsArrayType() || type->BaseType()->IsClassTypeSymbol() || type->IsStringFunctionContainer()))
3243 {
3244 receiver = std::move(value);
3245 }
3246 EvaluateSymbol(symbol, dotNode.GetSpan());
3247 if (error) return;
3248 if (receiver && value->IsFunctionGroupValue())
3249 {
3250 FunctionGroupValue* functionGroupValue = static_cast<FunctionGroupValue*>(value.get());
3251 functionGroupValue->SetReceiver(std::move(receiver));
3252 }
3253 }
3254 else
3255 {
3256 if (dontThrow)
3257 {
3258 error = true;
3259 return;
3260 }
3261 else
3262 {
3263 throw Exception("symbol '" + ToUtf8(containerSymbol->FullName()) + "' does not have member '" + ToUtf8(memberName) + "'", dotNode.GetSpan(), dotNode.ModuleId());
3264 }
3265 }
3266 }
3267 else
3268 {
3269 if (dontThrow)
3270 {
3271 error = true;
3272 return;
3273 }
3274 else
3275 {
3276 throw Exception("expression '" + dotNode.Subject()->ToString() + "' must denote a namespace, class type or enumerated type", dotNode.Subject()->GetSpan(), dotNode.Subject()->ModuleId());
3277 }
3278 }
3279 }
3280
3281 void Evaluator::Visit(ArrowNode& arrowNode)
3282 {
3283 if (dontThrow)
3284 {
3285 error = true;
3286 }
3287 else
3288 {
3289 ThrowCannotEvaluateStatically(span, moduleId, arrowNode.GetSpan(), arrowNode.ModuleId());
3290 }
3291 }
3292
3293 void Evaluator::Visit(EquivalenceNode& equivalenceNode)
3294 {
3295 if (dontThrow)
3296 {
3297 error = true;
3298 }
3299 else
3300 {
3301 ThrowCannotEvaluateStatically(span, moduleId, equivalenceNode.GetSpan(), equivalenceNode.ModuleId());
3302 }
3303 }
3304
3305 void Evaluator::Visit(ImplicationNode& implicationNode)
3306 {
3307 if (dontThrow)
3308 {
3309 error = true;
3310 }
3311 else
3312 {
3313 ThrowCannotEvaluateStatically(span, moduleId, implicationNode.GetSpan(), implicationNode.ModuleId());
3314 }
3315 }
3316
3317 void Evaluator::Visit(DisjunctionNode& disjunctionNode)
3318 {
3319 EvaluateBinOp(disjunctionNode, disjunction);
3320 }
3321
3322 void Evaluator::Visit(ConjunctionNode& conjunctionNode)
3323 {
3324 EvaluateBinOp(conjunctionNode, conjunction);
3325 }
3326
3327 void Evaluator::Visit(BitOrNode& bitOrNode)
3328 {
3329 EvaluateBinOp(bitOrNode, bitOr);
3330 }
3331
3332 void Evaluator::Visit(BitXorNode& bitXorNode)
3333 {
3334 EvaluateBinOp(bitXorNode, bitXor);
3335 }
3336
3337 void Evaluator::Visit(BitAndNode& bitAndNode)
3338 {
3339 EvaluateBinOp(bitAndNode, bitAnd);
3340 }
3341
3342 void Evaluator::Visit(EqualNode& equalNode)
3343 {
3344 EvaluateBinOp(equalNode, equal, Operator::comparison);
3345 }
3346
3347 void Evaluator::Visit(NotEqualNode& notEqualNode)
3348 {
3349 EvaluateBinOp(notEqualNode, notEqual, Operator::comparison);
3350 }
3351
3352 void Evaluator::Visit(LessNode& lessNode)
3353 {
3354 EvaluateBinOp(lessNode, less, Operator::comparison);
3355 }
3356
3357 void Evaluator::Visit(GreaterNode& greaterNode)
3358 {
3359 EvaluateBinOp(greaterNode, greater, Operator::comparison);
3360 }
3361
3362 void Evaluator::Visit(LessOrEqualNode& lessOrEqualNode)
3363 {
3364 EvaluateBinOp(lessOrEqualNode, lessEqual, Operator::comparison);
3365 }
3366
3367 void Evaluator::Visit(GreaterOrEqualNode& greaterOrEqualNode)
3368 {
3369 EvaluateBinOp(greaterOrEqualNode, greaterEqual, Operator::comparison);
3370 }
3371
3372 void Evaluator::Visit(ShiftLeftNode& shiftLeftNode)
3373 {
3374 EvaluateBinOp(shiftLeftNode, shiftLeft);
3375 }
3376
3377 void Evaluator::Visit(ShiftRightNode& shiftRightNode)
3378 {
3379 EvaluateBinOp(shiftRightNode, shiftRight);
3380 }
3381
3382 void Evaluator::Visit(AddNode& addNode)
3383 {
3384 EvaluateBinOp(addNode, add, Operator::add);
3385 }
3386
3387 void Evaluator::Visit(SubNode& subNode)
3388 {
3389 EvaluateBinOp(subNode, sub, Operator::sub);
3390 }
3391
3392 void Evaluator::Visit(MulNode& mulNode)
3393 {
3394 EvaluateBinOp(mulNode, mul);
3395 }
3396
3397 void Evaluator::Visit(DivNode& divNode)
3398 {
3399 EvaluateBinOp(divNode, div);
3400 }
3401
3402 void Evaluator::Visit(RemNode& remNode)
3403 {
3404 EvaluateBinOp(remNode, rem);
3405 }
3406
3407 void Evaluator::Visit(NotNode& notNode)
3408 {
3409 EvaluateUnaryOp(notNode, logicalNot);
3410 }
3411
3412 void Evaluator::Visit(UnaryPlusNode& unaryPlusNode)
3413 {
3414 EvaluateUnaryOp(unaryPlusNode, unaryPlus);
3415 }
3416
3417 void Evaluator::Visit(UnaryMinusNode& unaryMinusNode)
3418 {
3419 EvaluateUnaryOp(unaryMinusNode, unaryMinus);
3420 }
3421
3422 void Evaluator::Visit(PrefixIncrementNode& prefixIncrementNode)
3423 {
3424 prefixIncrementNode.Subject()->Accept(*this);
3425 if (error)
3426 {
3427 return;
3428 }
3429 if (!value)
3430 {
3431 if (dontThrow)
3432 {
3433 error = true;
3434 return;
3435 }
3436 else
3437 {
3438 ThrowCannotEvaluateStatically(span, moduleId, prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId());
3439 }
3440 }
3441 bool unsignedType = value->GetType(symbolTable)->IsUnsignedType();
3442 CloneContext cloneContext;
3443 if (unsignedType)
3444 {
3445 AssignmentStatementNode assignmentStatementNode(prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId(), prefixIncrementNode.Subject()->Clone(cloneContext),
3446 new AddNode(prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId(), prefixIncrementNode.Subject()->Clone(cloneContext),
3447 new ByteLiteralNode(prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId(), 1)));
3448 assignmentStatementNode.Accept(*this);
3449 }
3450 else
3451 {
3452 AssignmentStatementNode assignmentStatementNode(prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId(), prefixIncrementNode.Subject()->Clone(cloneContext),
3453 new AddNode(prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId(), prefixIncrementNode.Subject()->Clone(cloneContext),
3454 new SByteLiteralNode(prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId(), 1)));
3455 assignmentStatementNode.Accept(*this);
3456 }
3457 prefixIncrementNode.Subject()->Accept(*this);
3458 if (error)
3459 {
3460 return;
3461 }
3462 if (!value)
3463 {
3464 if (dontThrow)
3465 {
3466 error = true;
3467 return;
3468 }
3469 else
3470 {
3471 ThrowCannotEvaluateStatically(span, moduleId, prefixIncrementNode.GetSpan(), prefixIncrementNode.ModuleId());
3472 }
3473 }
3474 }
3475
3476 void Evaluator::Visit(PrefixDecrementNode& prefixDecrementNode)
3477 {
3478 prefixDecrementNode.Subject()->Accept(*this);
3479 if (error)
3480 {
3481 return;
3482 }
3483 if (!value)
3484 {
3485 if (dontThrow)
3486 {
3487 error = true;
3488 return;
3489 }
3490 else
3491 {
3492 ThrowCannotEvaluateStatically(span, moduleId, prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId());
3493 }
3494 }
3495 bool unsignedType = value->GetType(symbolTable)->IsUnsignedType();
3496 CloneContext cloneContext;
3497 if (unsignedType)
3498 {
3499 AssignmentStatementNode assignmentStatementNode(prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId(), prefixDecrementNode.Subject()->Clone(cloneContext),
3500 new SubNode(prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId(), prefixDecrementNode.Subject()->Clone(cloneContext),
3501 new ByteLiteralNode(prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId(), 1)));
3502 assignmentStatementNode.Accept(*this);
3503 }
3504 else
3505 {
3506 AssignmentStatementNode assignmentStatementNode(prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId(), prefixDecrementNode.Subject()->Clone(cloneContext),
3507 new SubNode(prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId(), prefixDecrementNode.Subject()->Clone(cloneContext),
3508 new SByteLiteralNode(prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId(), 1)));
3509 assignmentStatementNode.Accept(*this);
3510 }
3511 prefixDecrementNode.Subject()->Accept(*this);
3512 if (!value)
3513 {
3514 if (dontThrow)
3515 {
3516 error = true;
3517 return;
3518 }
3519 else
3520 {
3521 ThrowCannotEvaluateStatically(span, moduleId, prefixDecrementNode.GetSpan(), prefixDecrementNode.ModuleId());
3522 }
3523 }
3524 }
3525
3526 void Evaluator::Visit(DerefNode& derefNode)
3527 {
3528 derefNode.Subject()->Accept(*this);
3529 if (value && value->GetValueType() == ValueType::pointerValue)
3530 {
3531 PointerValue* pointerValue = static_cast<PointerValue*>(value.get());
3532 value.reset(pointerValue->Deref());
3533 if (!value)
3534 {
3535 if (dontThrow)
3536 {
3537 error = true;
3538 }
3539 else
3540 {
3541 throw Exception("unsupported pointer value", derefNode.GetSpan(), derefNode.ModuleId());
3542 }
3543 }
3544 }
3545 else
3546 {
3547 if (dontThrow)
3548 {
3549 error = true;
3550 }
3551 else
3552 {
3553 throw Exception("pointer value expected", derefNode.GetSpan(), derefNode.ModuleId());
3554 }
3555 }
3556 }
3557
3558 void Evaluator::Visit(AddrOfNode& addrOfNode)
3559 {
3560 if (dontThrow)
3561 {
3562 error = true;
3563 }
3564 else
3565 {
3566 ThrowCannotEvaluateStatically(span, moduleId, addrOfNode.GetSpan(), addrOfNode.ModuleId());
3567 }
3568 }
3569
3570 void Evaluator::Visit(ComplementNode& complementNode)
3571 {
3572 EvaluateUnaryOp(complementNode, complement);
3573 }
3574
3575 void Evaluator::Visit(IsNode& isNode)
3576 {
3577 if (dontThrow)
3578 {
3579 error = true;
3580 }
3581 else
3582 {
3583 ThrowCannotEvaluateStatically(span, moduleId, isNode.GetSpan(), isNode.ModuleId());
3584 }
3585 }
3586
3587 void Evaluator::Visit(AsNode& asNode)
3588 {
3589 if (dontThrow)
3590 {
3591 error = true;
3592 }
3593 else
3594 {
3595 ThrowCannotEvaluateStatically(span, moduleId, asNode.GetSpan(), asNode.ModuleId());
3596 }
3597 }
3598
3599 void Evaluator::Visit(IndexingNode& indexingNode)
3600 {
3601 indexingNode.Subject()->Accept(*this);
3602 if (value && value->IsArrayReferenceValue())
3603 {
3604 ArrayValue* arrayValue = static_cast<ArrayReferenceValue*>(value.get())->GetArrayValue();
3605 value = Evaluate(indexingNode.Index(), symbolTable->GetTypeByName(U"long"), containerScope, boundCompileUnit, dontThrow, currentFunction, indexingNode.GetSpan(), indexingNode.ModuleId());
3606 if (!value)
3607 {
3608 if (dontThrow)
3609 {
3610 error = true;
3611 return;
3612 }
3613 else
3614 {
3615 ThrowCannotEvaluateStatically(span, moduleId, indexingNode.GetSpan(), indexingNode.ModuleId());
3616 }
3617 }
3618 LongValue* indexValue = static_cast<LongValue*>(value.get());
3619 int64_t index = indexValue->GetValue();
3620 if (index < 0 || index >= int64_t(arrayValue->Elements().size()))
3621 {
3622 if (dontThrow)
3623 {
3624 error = true;
3625 return;
3626 }
3627 else
3628 {
3629 throw Exception("array index out of range", indexingNode.GetSpan(), indexingNode.ModuleId());
3630 }
3631 }
3632 Value* elementValue = arrayValue->Elements()[index].get();
3633 switch (elementValue->GetValueType())
3634 {
3635 case ValueType::arrayValue:
3636 {
3637 value.reset(new ArrayReferenceValue(static_cast<ArrayValue*>(elementValue)));
3638 break;
3639 }
3640 case ValueType::stringValue: case ValueType::wstringValue: case ValueType::ustringValue:
3641 {
3642 value.reset(new StringReferenceValue(elementValue));
3643 break;
3644 }
3645 default:
3646 {
3647 value = std::unique_ptr<Value>(elementValue->Clone());
3648 break;
3649 }
3650 }
3651 }
3652 else
3653 {
3654 if (dontThrow)
3655 {
3656 error = true;
3657 }
3658 else
3659 {
3660 ThrowCannotEvaluateStatically(span, moduleId, indexingNode.GetSpan(), indexingNode.ModuleId());
3661 }
3662 }
3663 }
3664
3665 void Evaluator::Visit(InvokeNode& invokeNode)
3666 {
3667 if (error) return;
3668 std::vector<std::std::unique_ptr<Value>>values;
3669 int n = invokeNode.Arguments().Count();
3670 for (int i = 0; i < n; ++i)
3671 {
3672 Node* arg = invokeNode.Arguments()[i];
3673 arg->Accept(*this);
3674 if (error) return;
3675 if (!value)
3676 {
3677 if (dontThrow)
3678 {
3679 error = true;
3680 return;
3681 }
3682 else
3683 {
3684 ThrowCannotEvaluateStatically(span, moduleId, invokeNode.GetSpan(), invokeNode.ModuleId());
3685 }
3686 }
3687 values.push_back(std::move(value));
3688 }
3689 invokeNode.Subject()->Accept(*this);
3690 if (error) return;
3691 if (value && value->IsFunctionGroupValue())
3692 {
3693 FunctionGroupValue* functionGroupValue = static_cast<FunctionGroupValue*>(value.get());
3694 FunctionGroupSymbol* functionGroup = functionGroupValue->FunctionGroup();
3695 std::vector<FunctionScopeLookup> functionScopeLookups;
3696 if (functionGroupValue->QualifiedScope())
3697 {
3698 FunctionScopeLookup qualifiedScopeLookup(ScopeLookup::this_and_base, functionGroupValue->QualifiedScope());
3699 functionScopeLookups.push_back(qualifiedScopeLookup);
3700 }
3701 else
3702 {
3703 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, containerScope));
3704 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopes, nullptr));
3705 }
3706 std::vector<std::std::unique_ptr<BoundExpression>>arguments=ValuesToLiterals(values, symbolTable, error);
3707 if (error)
3708 {
3709 if (dontThrow)
3710 {
3711 return;
3712 }
3713 else
3714 {
3715 ThrowCannotEvaluateStatically(span, moduleId, invokeNode.GetSpan(), invokeNode.ModuleId());
3716 }
3717 }
3718 if (functionGroupValue->Receiver() && functionGroupValue->Receiver()->IsScopedValue())
3719 {
3720 TypeSymbol* type = static_cast<ScopedValue*>(functionGroupValue->Receiver())->GetType(symbolTable);
3721 if (type)
3722 {
3723 arguments.insert(arguments.begin(), std::unique_ptr<BoundExpression>(new BoundTypeExpression(span, moduleId, type)));
3724 }
3725 }
3726 templateTypeArguments = std::move(functionGroupValue->TemplateTypeArguments());
3727 std::unique_ptr<Exception> exception;
3728 OverloadResolutionFlags flags = OverloadResolutionFlags::dontInstantiate;
3729 flags = flags | OverloadResolutionFlags::dontThrow;
3730 std::unique_ptr<BoundFunctionCall> functionCall = ResolveOverload(functionGroup->Name(), containerScope, functionScopeLookups, arguments, boundCompileUnit, currentFunction, span, moduleId,
3731 flags, templateTypeArguments, exception);
3732 bool memberFunctionCall = false;
3733 if (!functionCall)
3734 {
3735 if (currentClassType)
3736 {
3737 arguments.insert(arguments.begin(), std::unique_ptr<BoundExpression>(new BoundTypeExpression(span, moduleId, currentClassType->AddPointer(span, moduleId))));
3738 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parent, currentClassType->GetContainerScope()));
3739 OverloadResolutionFlags flags = OverloadResolutionFlags::dontInstantiate;
3740 if (dontThrow)
3741 {
3742 flags = flags | OverloadResolutionFlags::dontThrow;
3743 }
3744 std::unique_ptr<Exception> exception;
3745 functionCall = ResolveOverload(functionGroup->Name(), containerScope, functionScopeLookups, arguments, boundCompileUnit, currentFunction, span, moduleId,
3746 flags, templateTypeArguments, exception);
3747 if (functionCall)
3748 {
3749 memberFunctionCall = true;
3750 }
3751 }
3752 if (!functionCall)
3753 {
3754 if (dontThrow)
3755 {
3756 error = true;
3757 return;
3758 }
3759 else
3760 {
3761 ThrowCannotEvaluateStatically(span, moduleId, invokeNode.GetSpan(), invokeNode.ModuleId());
3762 }
3763 }
3764 }
3765 FunctionSymbol* functionSymbol = functionCall->GetFunctionSymbol();
3766 if (functionSymbol->IsCompileTimePrimitiveFunction())
3767 {
3768 Value* receiver = functionGroupValue->Receiver();
3769 bool skipFirst = receiver != nullptr;;
3770 argumentValues = ArgumentsToValues(functionCall->Arguments(), error, skipFirst, boundCompileUnit);
3771 if (error)
3772 {
3773 if (dontThrow)
3774 {
3775 return;
3776 }
3777 else
3778 {
3779 ThrowCannotEvaluateStatically(span, moduleId, invokeNode.GetSpan(), invokeNode.ModuleId());
3780 }
3781 }
3782 value = functionSymbol->ConstructValue(argumentValues, invokeNode.GetSpan(), invokeNode.ModuleId(), receiver);
3783 if (!value)
3784 {
3785 if (dontThrow)
3786 {
3787 error = true;
3788 return;
3789 }
3790 else
3791 {
3792 ThrowCannotEvaluateStatically(span, moduleId, invokeNode.GetSpan(), invokeNode.ModuleId());
3793 }
3794 }
3795 }
3796 else if (functionSymbol->IsConstExpr())
3797 {
3798 FunctionNode* functionNode = boundCompileUnit.GetFunctionNodeFor(functionSymbol);
3799 CheckFunctionReturnPaths(functionSymbol, *functionNode, containerScope, boundCompileUnit);
3800 bool skipFirst = memberFunctionCall || functionGroupValue->Receiver();
3801 argumentValues = ArgumentsToValues(functionCall->Arguments(), error, skipFirst, boundCompileUnit);
3802 if (error)
3803 {
3804 if (dontThrow)
3805 {
3806 return;
3807 }
3808 else
3809 {
3810 ThrowCannotEvaluateStatically(span, moduleId, invokeNode.GetSpan(), invokeNode.ModuleId());
3811 }
3812 }
3813 ClassTypeSymbol* prevClassType = currentClassType;
3814 if (functionGroupValue->Receiver() && functionGroupValue->Receiver()->IsScopedValue())
3815 {
3816 ScopedValue* receiver = static_cast<ScopedValue*>(functionGroupValue->Receiver());
3817 if (receiver->GetSubject() && receiver->GetSubject()->GetType(symbolTable)->IsClassTypeSymbol())
3818 {
3819 currentClassType = static_cast<ClassTypeSymbol*>(receiver->GetSubject()->GetType(symbolTable));
3820 structureReferenceValue = std::unique_ptr<Value>(receiver->GetSubject()->Clone());
3821 }
3822 }
3823 functionNode->Accept(*this);
3824 currentClassType = prevClassType;
3825 }
3826 else
3827 {
3828 IntrinsicFunction* intrinsic = functionSymbol->GetIntrinsic();
3829 if (intrinsic)
3830 {
3831 argumentValues = ArgumentsToValues(functionCall->Arguments(), error, boundCompileUnit);
3832 if (error)
3833 {
3834 if (dontThrow)
3835 {
3836 return;
3837 }
3838 else
3839 {
3840 ThrowCannotEvaluateStatically(span, moduleId, invokeNode.GetSpan(), invokeNode.ModuleId());
3841 }
3842 }
3843 value = intrinsic->Evaluate(argumentValues, templateTypeArguments, invokeNode.GetSpan(), invokeNode.ModuleId());
3844 if (!value)
3845 {
3846 if (dontThrow)
3847 {
3848 error = true;
3849 return;
3850 }
3851 else
3852 {
3853 ThrowCannotEvaluateStatically(span, moduleId, invokeNode.GetSpan(), invokeNode.ModuleId());
3854 }
3855 }
3856 }
3857 else
3858 {
3859 if (dontThrow)
3860 {
3861 error = true;
3862 return;
3863 }
3864 else
3865 {
3866 ThrowCannotEvaluateStatically(span, moduleId, invokeNode.GetSpan(), invokeNode.ModuleId());
3867 }
3868 }
3869 }
3870 }
3871 else
3872 {
3873 if (dontThrow)
3874 {
3875 error = true;
3876 }
3877 else
3878 {
3879 throw Exception("function group expected", invokeNode.GetSpan(), invokeNode.ModuleId());
3880 }
3881 }
3882 }
3883
3884 void Evaluator::Visit(PostfixIncrementNode& postfixIncrementNode)
3885 {
3886 postfixIncrementNode.Subject()->Accept(*this);
3887 if (error) return;
3888 if (!value)
3889 {
3890 if (dontThrow)
3891 {
3892 error = true;
3893 return;
3894 }
3895 else
3896 {
3897 ThrowCannotEvaluateStatically(span, moduleId, postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId());
3898 }
3899 }
3900 bool unsignedType = value->GetType(symbolTable)->IsUnsignedType();
3901 std::unique_ptr<Value> result = std::move(value);
3902 CloneContext cloneContext;
3903 if (unsignedType)
3904 {
3905 AssignmentStatementNode assignmentStatementNode(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId(), postfixIncrementNode.Subject()->Clone(cloneContext),
3906 new AddNode(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId(), postfixIncrementNode.Subject()->Clone(cloneContext), new ByteLiteralNode(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId(), 1)));
3907 assignmentStatementNode.Accept(*this);
3908 }
3909 else
3910 {
3911 AssignmentStatementNode assignmentStatementNode(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId(), postfixIncrementNode.Subject()->Clone(cloneContext),
3912 new AddNode(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId(), postfixIncrementNode.Subject()->Clone(cloneContext), new SByteLiteralNode(postfixIncrementNode.GetSpan(), postfixIncrementNode.ModuleId(), 1)));
3913 assignmentStatementNode.Accept(*this);
3914 }
3915 value = std::move(result);
3916 }
3917
3918 void Evaluator::Visit(PostfixDecrementNode& postfixDecrementNode)
3919 {
3920 postfixDecrementNode.Subject()->Accept(*this);
3921 if (error) return;
3922 if (!value)
3923 {
3924 if (dontThrow)
3925 {
3926 error = true;
3927 return;
3928 }
3929 else
3930 {
3931 ThrowCannotEvaluateStatically(span, moduleId, postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId());
3932 }
3933 }
3934 bool unsignedType = value->GetType(symbolTable)->IsUnsignedType();
3935 std::unique_ptr<Value> result = std::move(value);
3936 CloneContext cloneContext;
3937 if (unsignedType)
3938 {
3939 AssignmentStatementNode assignmentStatementNode(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId(), postfixDecrementNode.Subject()->Clone(cloneContext),
3940 new SubNode(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId(), postfixDecrementNode.Subject()->Clone(cloneContext),
3941 new ByteLiteralNode(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId(), 1)));
3942 assignmentStatementNode.Accept(*this);
3943 }
3944 else
3945 {
3946 AssignmentStatementNode assignmentStatementNode(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId(), postfixDecrementNode.Subject()->Clone(cloneContext),
3947 new SubNode(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId(), postfixDecrementNode.Subject()->Clone(cloneContext),
3948 new SByteLiteralNode(postfixDecrementNode.GetSpan(), postfixDecrementNode.ModuleId(), 1)));
3949 assignmentStatementNode.Accept(*this);
3950 }
3951 value = std::move(result);
3952 }
3953
3954 void Evaluator::Visit(SizeOfNode& sizeOfNode)
3955 {
3956 if (dontThrow)
3957 {
3958 error = true;
3959 }
3960 else
3961 {
3962 ThrowCannotEvaluateStatically(span, moduleId, sizeOfNode.GetSpan(), sizeOfNode.ModuleId());
3963 }
3964 }
3965
3966 void Evaluator::Visit(TypeNameNode& typeNameNode)
3967 {
3968 if (dontThrow)
3969 {
3970 error = true;
3971 }
3972 else
3973 {
3974 ThrowCannotEvaluateStatically(span, moduleId, typeNameNode.GetSpan(), typeNameNode.ModuleId());
3975 }
3976 }
3977
3978 void Evaluator::Visit(TypeIdNode& typeIdNode)
3979 {
3980 if (dontThrow)
3981 {
3982 error = true;
3983 }
3984 else
3985 {
3986 ThrowCannotEvaluateStatically(span, moduleId, typeIdNode.GetSpan(), typeIdNode.ModuleId());
3987 }
3988 }
3989
3990 void Evaluator::Visit(CastNode& castNode)
3991 {
3992 TypeSymbol* type = ResolveType(castNode.TargetTypeExpr(), boundCompileUnit, containerScope);
3993 bool prevCast = cast;
3994 cast = true;
3995 castNode.SourceExpr()->Accept(*this);
3996 if (error) return;
3997 if (!value)
3998 {
3999 if (dontThrow)
4000 {
4001 error = true;
4002 return;
4003 }
4004 else
4005 {
4006 ThrowCannotEvaluateStatically(span, moduleId, castNode.GetSpan(), castNode.ModuleId());
4007 }
4008 }
4009 value.reset(value->As(type, true, castNode.GetSpan(), castNode.ModuleId(), dontThrow));
4010 cast = prevCast;
4011 }
4012
4013 void Evaluator::Visit(ConstructNode& constructNode)
4014 {
4015 if (dontThrow)
4016 {
4017 error = true;
4018 }
4019 else
4020 {
4021 ThrowCannotEvaluateStatically(span, moduleId, constructNode.GetSpan(), constructNode.ModuleId());
4022 }
4023 }
4024
4025 void Evaluator::Visit(NewNode& newNode)
4026 {
4027 if (dontThrow)
4028 {
4029 error = true;
4030 }
4031 else
4032 {
4033 ThrowCannotEvaluateStatically(span, moduleId, newNode.GetSpan(), newNode.ModuleId());
4034 }
4035 }
4036
4037 void Evaluator::Visit(ThisNode& thisNode)
4038 {
4039 if (dontThrow)
4040 {
4041 error = true;
4042 }
4043 else
4044 {
4045 ThrowCannotEvaluateStatically(span, moduleId, thisNode.GetSpan(), thisNode.ModuleId());
4046 }
4047 }
4048
4049 void Evaluator::Visit(BaseNode& baseNode)
4050 {
4051 if (dontThrow)
4052 {
4053 error = true;
4054 }
4055 else
4056 {
4057 ThrowCannotEvaluateStatically(span, moduleId, baseNode.GetSpan(), baseNode.ModuleId());
4058 }
4059 }
4060
4061 void Evaluator::Visit(ParenthesizedExpressionNode& parenthesizedExpressionNode)
4062 {
4063 parenthesizedExpressionNode.Subject()->Accept(*this);
4064 }
4065
4066 std::std::unique_ptr<Value>Evaluate(Node*node, TypeSymbol*targetType, ContainerScope*containerScope, BoundCompileUnit&boundCompileUnit, bool dontThrow, BoundFunction* currentFunction, const Span& span,
4067 const boost::uuids::uuid& moduleId)
4068 {
4069 ValueType targetValueType = targetType->GetValueType();
4070 Evaluator evaluator(boundCompileUnit, containerScope, targetType, targetValueType, false, dontThrow, currentFunction, span, moduleId);
4071 node->Accept(evaluator);
4072 if (evaluator.Error())
4073 {
4074 return std::unique_ptr<Value>();
4075 }
4076 else
4077 {
4078 std::unique_ptr<Value> value = evaluator.GetValue();
4079 if (value && value->IsComplete())
4080 {
4081 if (!TypesEqual(targetType->PlainType(span, moduleId), value->GetType(&boundCompileUnit.GetSymbolTable())))
4082 {
4083 if (targetType->IsArrayType() && static_cast<ArrayTypeSymbol*>(targetType)->Size() == -1)
4084 {
4085 return std::move(value);
4086 }
4087 if (value->IsStringReferenceValue())
4088 {
4089 return std::move(value);
4090 }
4091 value.reset(value->As(targetType->PlainType(span, moduleId), false, node->GetSpan(), node->ModuleId(), dontThrow));
4092 }
4093 return std::move(value);
4094 }
4095 else
4096 {
4097 if (dontThrow)
4098 {
4099 return std::unique_ptr<Value>();
4100 }
4101 else
4102 {
4103 throw Exception("value not complete", node->GetSpan(), node->ModuleId());
4104 }
4105 }
4106 }
4107 }
4108
4109 } }