1 // =================================
   2 // Copyright (c) 2021 Seppo Laakko
   3 // Distributed under the MIT license
   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& definedconst boost::uuids::uuid& moduleId)
  25 {
  26     throw Exception("cannot evaluate statically"definedmoduleId);
  27 }
  28 
  29 void ThrowCannotEvaluateStatically(const Span& definedconst boost::uuids::uuid& moduleIdconst Span& referencedconst boost::uuids::uuid& referencedModuleId)
  30 {
  31     throw Exception("cannot evaluate statically"definedmoduleIdreferencedreferencedModuleId);
  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* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool 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* targetTypebool castconst Span& spanconst 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* targetTypebool castconst Span& spanconst 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* targetTypebool castconst Span& spanconst 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* targetTypebool castconst Span& spanconst 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::variableValueSymbolspan_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>>&valuesSymbolTable*symbolTablebool&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>>&argumentsbool&errorboolskipFirstBoundCompileUnit&boundCompileUnit);
 184 
 185 std::std::vector<std::std::unique_ptr<Value>>ArgumentsToValues(conststd::std::vector<std::std::unique_ptr<BoundExpression>>&argumentsbool&errorBoundCompileUnit&boundCompileUnit)
 186 {
 187     return ArgumentsToValues(argumentserrorfalseboundCompileUnit);
 188 }
 189 
 190 std::std::vector<std::std::unique_ptr<Value>>ArgumentsToValues(conststd::std::vector<std::std::unique_ptr<BoundExpression>>&argumentsbool&errorboolskipFirstBoundCompileUnit&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* leftValue* rightOp opconst Span& spanconst boost::uuids::uuid& moduleId)
 220 {
 221     ValueT* leftCasted = static_cast<ValueT*>(left);
 222     ValueT* rightCasted = static_cast<ValueT*>(right);
 223     return new ValueT(spanmoduleIdop(leftCasted->GetValue()rightCasted->GetValue()));
 224 }
 225 
 226 template< typename ValueT  typename Op>
 227 Value* BinaryPredEvaluate(Value* leftValue* rightOp opconst Span& spanconst boost::uuids::uuid& moduleId)
 228 {
 229     ValueT* leftCasted = static_cast<ValueT*>(left);
 230     ValueT* rightCasted = static_cast<ValueT*>(right);
 231     return new BoolValue(spanmoduleIdop(leftCasted->GetValue()rightCasted->GetValue()));
 232 }
 233 
 234 template<typename ValueT  typename Op>
 235 Value* UnaryEvaluate(Value* subjectOp opconst Span& spanconst boost::uuids::uuid& moduleId)
 236 {
 237     ValueT* subjectCasted = static_cast<ValueT*>(subject);
 238     return new ValueT(spanmoduleIdop(subjectCasted->GetValue()));
 239 }
 240 
 241 Value* NotSupported(Value* subjectconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 242 {
 243     if (dontThrow)
 244     {
 245         return nullptr;
 246     }
 247     throw Exception("operation not supported for type " + ValueTypeStr(subject->GetValueType())spanmoduleId);
 248 }
 249 
 250 Value* NotSupported(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool 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())spanmoduleId);
 257 }
 258 
 259 template<typename ValueT>
 260 Value* Disjunction(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 261 {
 262     return BinaryEvaluate::BinaryEvaluate<ValueT>(leftrightstd::logical_or<typename ValueT::OperandType>()spanmoduleId);
 263 }
 264 
 265 BinaryOperatorFun disjunction[uint8_t(ValueType::maxValue)] =
 266 {
 267     NotSupportedDisjunction<BoolValue>NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 268     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 269     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 270 };
 271 
 272 template<typename ValueT>
 273 Value* Conjunction(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 274 {
 275     return BinaryEvaluate::BinaryEvaluate<ValueT>(leftrightstd::logical_and<typename ValueT::OperandType>()spanmoduleId);
 276 }
 277 
 278 BinaryOperatorFun conjunction[uint8_t(ValueType::maxValue)] =
 279 {
 280     NotSupportedConjunction<BoolValue>NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 281     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 282     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 283 };
 284 
 285 template<typename ValueT>
 286 Value* BitOr(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 287 {
 288     return BinaryEvaluate::BinaryEvaluate<ValueT>(leftrightstd::bit_or<typename ValueT::OperandType>()spanmoduleId);
 289 }
 290 
 291 BinaryOperatorFun bitOr[uint8_t(ValueType::maxValue)] =
 292 {
 293     NotSupportedNotSupportedBitOr<SByteValue>BitOr<ByteValue>BitOr<ShortValue>BitOr<UShortValue>BitOr<IntValue>BitOr<UIntValue>
 294     BitOr<LongValue>BitOr<ULongValue>NotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 295     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 296 };
 297 
 298 template<typename ValueT>
 299 Value* BitXor(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 300 {
 301     return BinaryEvaluate::BinaryEvaluate<ValueT>(leftrightstd::bit_xor<typename ValueT::OperandType>()spanmoduleId);
 302 }
 303 
 304 BinaryOperatorFun bitXor[uint8_t(ValueType::maxValue)] =
 305 {
 306     NotSupportedNotSupportedBitXor<SByteValue>BitXor<ByteValue>BitXor<ShortValue>BitXor<UShortValue>BitXor<IntValue>BitXor<UIntValue>
 307     BitXor<LongValue>BitXor<ULongValue>NotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 308     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 309 };
 310 
 311 template<typename ValueT>
 312 Value* BitAnd(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 313 {
 314     return BinaryEvaluate::BinaryEvaluate<ValueT>(leftrightstd::bit_and<typename ValueT::OperandType>()spanmoduleId);
 315 }
 316 
 317 BinaryOperatorFun bitAnd[uint8_t(ValueType::maxValue)] =
 318 {
 319     NotSupportedNotSupportedBitAnd<SByteValue>BitAnd<ByteValue>BitAnd<ShortValue>BitAnd<UShortValue>BitAnd<IntValue>BitAnd<UIntValue>
 320     BitAnd<LongValue>BitAnd<ULongValue>NotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 321     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 322 };
 323 
 324 template<typename ValueT>
 325 Value* Equal(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 326 {
 327     return BinaryPredEvaluate::BinaryPredEvaluate<ValueT>(leftrightstd::equal_to<typename ValueT::OperandType>()spanmoduleId);
 328 }
 329 
 330 BinaryOperatorFun equal[uint8_t(ValueType::maxValue)] =
 331 {
 332     NotSupportedEqual<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     NotSupportedNotSupportedNotSupportedNotSupportedEqual<PointerValue>NotSupportedNotSupported
 335 };
 336 
 337 template<typename ValueT>
 338 Value* NotEqual(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 339 {
 340     return BinaryPredEvaluate::BinaryPredEvaluate<ValueT>(leftrightstd::not_equal_to<typename ValueT::OperandType>()spanmoduleId);
 341 }
 342 
 343 BinaryOperatorFun notEqual[uint8_t(ValueType::maxValue)] =
 344 {
 345     NotSupportedNotEqual<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     NotSupportedNotSupportedNotSupportedNotSupportedNotEqual<PointerValue>NotSupportedNotSupported
 348 };
 349 
 350 template<typename ValueT>
 351 Value* Less(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 352 {
 353     return BinaryPredEvaluate::BinaryPredEvaluate<ValueT>(leftrightstd::less<typename ValueT::OperandType>()spanmoduleId);
 354 }
 355 
 356 BinaryOperatorFun less[uint8_t(ValueType::maxValue)] =
 357 {
 358     NotSupportedNotSupportedLess<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     NotSupportedNotSupportedNotSupportedNotSupportedLess<PointerValue>NotSupportedNotSupported
 361 };
 362 
 363 template<typename ValueT>
 364 Value* Greater(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 365 {
 366     return BinaryPredEvaluate::BinaryPredEvaluate<ValueT>(leftrightstd::greater<typename ValueT::OperandType>()spanmoduleId);
 367 }
 368 
 369 BinaryOperatorFun greater[uint8_t(ValueType::maxValue)] =
 370 {
 371     NotSupportedNotSupportedGreater<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     NotSupportedNotSupportedNotSupportedNotSupportedGreater<PointerValue>NotSupportedNotSupported
 374 };
 375 
 376 template<typename ValueT>
 377 Value* LessEqual(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 378 {
 379     return BinaryPredEvaluate::BinaryPredEvaluate<ValueT>(leftrightstd::less_equal<typename ValueT::OperandType>()spanmoduleId);
 380 }
 381 
 382 BinaryOperatorFun lessEqual[uint8_t(ValueType::maxValue)] =
 383 {
 384     NotSupportedNotSupportedLessEqual<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     NotSupportedNotSupportedNotSupportedNotSupportedLessEqual<PointerValue>NotSupportedNotSupported
 387 };
 388 
 389 template<typename ValueT>
 390 Value* GreaterEqual(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 391 {
 392     return BinaryPredEvaluate::BinaryPredEvaluate<ValueT>(leftrightstd::greater_equal<typename ValueT::OperandType>()spanmoduleId);
 393 }
 394 
 395 BinaryOperatorFun greaterEqual[uint8_t(ValueType::maxValue)] =
 396 {
 397     NotSupportedNotSupportedGreaterEqual<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     NotSupportedNotSupportedNotSupportedNotSupportedGreaterEqual<PointerValue>NotSupportedNotSupported
 400 };
 401 
 402 template<typename T>
 403 struct shiftLeftFun  std::std::binary_function<TTT>
 404 {
 405     T operator()(const T& leftconst T& right) const
 406     {
 407         return left << right;
 408     }
 409 };
 410 
 411 template<typename ValueT>
 412 Value* ShiftLeft(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 413 {
 414     return BinaryEvaluate::BinaryEvaluate<ValueT>(leftrightshiftLeftFun<typename ValueT::OperandType>()spanmoduleId);
 415 }
 416 
 417 BinaryOperatorFun shiftLeft[uint8_t(ValueType::maxValue)] =
 418 {
 419     NotSupportedNotSupportedShiftLeft<SByteValue>ShiftLeft<ByteValue>ShiftLeft<ShortValue>ShiftLeft<UShortValue>ShiftLeft<IntValue>ShiftLeft<UIntValue>
 420     ShiftLeft<LongValue>ShiftLeft<ULongValue>NotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 421     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 422 };
 423 
 424 template<typename T>
 425 struct shiftRightFun  std::std::binary_function<TTT>
 426 {
 427     T operator()(const T& leftconst T& right) const
 428     {
 429         return left >> right;
 430     }
 431 };
 432 
 433 template<typename ValueT>
 434 Value* ShiftRight(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 435 {
 436     return BinaryEvaluate::BinaryEvaluate<ValueT>(leftrightshiftRightFun<typename ValueT::OperandType>()spanmoduleId);
 437 }
 438 
 439 BinaryOperatorFun shiftRight[uint8_t(ValueType::maxValue)] =
 440 {
 441     NotSupportedNotSupportedShiftRight<SByteValue>ShiftRight<ByteValue>ShiftRight<ShortValue>ShiftRight<UShortValue>ShiftRight<IntValue>ShiftRight<UIntValue>
 442     ShiftRight<LongValue>ShiftRight<ULongValue>NotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 443     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 444 };
 445 
 446 template<typename ValueT>
 447 Value* Add(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 448 {
 449     return BinaryEvaluate::BinaryEvaluate<ValueT>(leftrightstd::plus<typename ValueT::OperandType>()spanmoduleId);
 450 }
 451 
 452 BinaryOperatorFun add[uint8_t(ValueType::maxValue)] =
 453 {
 454     NotSupportedNotSupportedAdd<SByteValue>Add<ByteValue>Add<ShortValue>Add<UShortValue>Add<IntValue>Add<UIntValue>
 455     Add<LongValue>Add<ULongValue>Add<FloatValue>Add<DoubleValue>NotSupportedNotSupportedNotSupported
 456     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 457 };
 458 
 459 template<typename ValueT>
 460 Value* Sub(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 461 {
 462     return BinaryEvaluate::BinaryEvaluate<ValueT>(leftrightstd::minus<typename ValueT::OperandType>()spanmoduleId);
 463 }
 464 
 465 BinaryOperatorFun sub[uint8_t(ValueType::maxValue)] =
 466 {
 467     NotSupportedNotSupportedSub<SByteValue>Sub<ByteValue>Sub<ShortValue>Sub<UShortValue>Sub<IntValue>Sub<UIntValue>
 468     Sub<LongValue>Sub<ULongValue>Sub<FloatValue>Sub<DoubleValue>NotSupportedNotSupportedNotSupported
 469     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 470 };
 471 
 472 template<typename ValueT>
 473 Value* Mul(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 474 {
 475     return BinaryEvaluate::BinaryEvaluate<ValueT>(leftrightstd::multiplies<typename ValueT::OperandType>()spanmoduleId);
 476 }
 477 
 478 BinaryOperatorFun mul[uint8_t(ValueType::maxValue)] =
 479 {
 480     NotSupportedNotSupportedMul<SByteValue>Mul<ByteValue>Mul<ShortValue>Mul<UShortValue>Mul<IntValue>Mul<UIntValue>
 481     Mul<LongValue>Mul<ULongValue>Mul<FloatValue>Mul<DoubleValue>NotSupportedNotSupportedNotSupported
 482     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 483 };
 484 
 485 template<typename ValueT>
 486 Value* Div(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 487 {
 488     return BinaryEvaluate::BinaryEvaluate<ValueT>(leftrightstd::divides<typename ValueT::OperandType>()spanmoduleId);
 489 }
 490 
 491 BinaryOperatorFun div[uint8_t(ValueType::maxValue)] =
 492 {
 493     NotSupportedNotSupportedDiv<SByteValue>Div<ByteValue>Div<ShortValue>Div<UShortValue>Div<IntValue>Div<UIntValue>
 494     Div<LongValue>Div<ULongValue>Div<FloatValue>Div<DoubleValue>NotSupportedNotSupportedNotSupported
 495     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 496 };
 497 
 498 template<typename ValueT>
 499 Value* Rem(Value* leftValue* rightconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 500 {
 501     return BinaryEvaluate::BinaryEvaluate<ValueT>(leftrightstd::modulus<typename ValueT::OperandType>()spanmoduleId);
 502 }
 503 
 504 BinaryOperatorFun rem[uint8_t(ValueType::maxValue)] =
 505 {
 506     NotSupportedNotSupportedRem<SByteValue>Rem<ByteValue>Rem<ShortValue>Rem<UShortValue>Rem<IntValue>Rem<UIntValue>
 507     Rem<LongValue>Rem<ULongValue>NotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 508     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 509 };
 510 
 511 template<typename ValueT>
 512 Value* Not(Value* subjectconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 513 {
 514     return UnaryEvaluate::UnaryEvaluate<ValueT>(subjectstd::logical_not<typename ValueT::OperandType>()spanmoduleId);
 515 }
 516 
 517 UnaryOperatorFun logicalNot[uint8_t(ValueType::maxValue)] =
 518 {
 519     NotSupportedNot<BoolValue>NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 520     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 521     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 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* subjectconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 535 {
 536     return UnaryEvaluate::UnaryEvaluate<ValueT>(subjectIdentity<typename ValueT::OperandType>()spanmoduleId);
 537 }
 538 
 539 UnaryOperatorFun unaryPlus[uint8_t(ValueType::maxValue)] =
 540 {
 541     NotSupportedNotSupportedUnaryPlus<SByteValue>UnaryPlus<ByteValue>UnaryPlus<ShortValue>UnaryPlus<UShortValue>UnaryPlus<IntValue>UnaryPlus<UIntValue>
 542     UnaryPlus<LongValue>UnaryPlus<ULongValue>UnaryPlus<FloatValue>UnaryPlus<DoubleValue>NotSupportedNotSupportedNotSupported
 543     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 544 };
 545 
 546 template<typename ValueT>
 547 Value* UnaryMinus(Value* subjectconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 548 {
 549     return UnaryEvaluate::UnaryEvaluate<ValueT>(subjectstd::negate<typename ValueT::OperandType>()spanmoduleId);
 550 }
 551 
 552 UnaryOperatorFun unaryMinus[uint8_t(ValueType::maxValue)] =
 553 {
 554     NotSupportedNotSupportedUnaryMinus<SByteValue>UnaryMinus<ByteValue>UnaryMinus<ShortValue>UnaryMinus<UShortValue>UnaryMinus<IntValue>UnaryMinus<UIntValue>
 555     UnaryMinus<LongValue>UnaryMinus<ULongValue>UnaryMinus<FloatValue>UnaryMinus<DoubleValue>NotSupportedNotSupportedNotSupported
 556     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 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* subjectconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow)
 570 {
 571     return UnaryEvaluate::UnaryEvaluate<ValueT>(subjectBitNot<typename ValueT::OperandType>()spanmoduleId);
 572 }
 573 
 574 UnaryOperatorFun complement[uint8_t(ValueType::maxValue)] =
 575 {
 576     NotSupportedNotSupportedComplement<SByteValue>Complement<ByteValue>Complement<ShortValue>Complement<UShortValue>Complement<IntValue>Complement<UIntValue>
 577     Complement<LongValue>Complement<ULongValue>NotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 578     NotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupportedNotSupported
 579 };
 580 
 581 enum class Operator
 582 {
 583     addsubcomparisonother
 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& nodeBinaryOperatorFun* fun);
 752     void EvaluateBinOp(BinaryNode& nodeBinaryOperatorFun* funOperator op);
 753     void EvaluateAdditivePointerOp(const Span& spanOperator opconst std::std::unique_ptr<Value>&leftconststd::std::unique_ptr<Value>&right);
 754     void EvaluateUnaryOp(UnaryNode& nodeUnaryOperatorFun* fun);
 755     void EvaluateSymbol(Symbol* symbolconst Span& span);
 756     void EvaluateConstantSymbol(ConstantSymbol* constantSymbolconst Span& span);
 757     void EvaluateEnumConstantSymbol(EnumConstantSymbol* enumConstantSymbolconst 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& nodeBinaryOperatorFun* fun)
 770 {
 771     EvaluateBinOp(nodefunOperator::other);
 772 }
 773 
 774 void Evaluator::EvaluateBinOp(BinaryNode& nodeBinaryOperatorFun* funOperator 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(spanmoduleIdnode.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(spanmoduleIdnode.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()opleftright);
 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(leftTyperightType);
 837     ValueType operationType = commonType;
 838     if (targetValueType > operationType)
 839     {
 840         operationType = targetValueType;
 841     }
 842     TypeSymbol* type = GetTypeFor(operationTypesymbolTable);
 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"spanmoduleId);
 853         }
 854     }
 855     std::unique_ptr<Value> leftConverted(left->As(typecastnode.GetSpan()node.ModuleId()dontThrow));
 856     std::unique_ptr<Value> rightConverted(right->As(typecastnode.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& spanOperator opconst std::std::unique_ptr<Value>&leftconststd::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")castspanmoduleIddontThrow));
 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"spanmoduleId);
 897                 }
 898             }
 899         }
 900         else if (right->GetValueType() == ValueType::pointerValue)
 901         {
 902             std::unique_ptr<Value> leftConverted(right->As(symbolTable->GetTypeByName(U"long")castspanmoduleIddontThrow));
 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"spanmoduleId);
 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"spanmoduleId);
 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")castspanmoduleIddontThrow));
 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"spanmoduleId);
 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"spanmoduleId);
 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"spanmoduleId);
 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"spanmoduleId);
1009             }
1010         }
1011     }
1012 }
1013 
1014 void Evaluator::EvaluateUnaryOp(UnaryNode& nodeUnaryOperatorFun* 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(spanmoduleIdnode.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(operationTypesymbolTable);
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"spanmoduleId);
1051         }
1052     }
1053     std::unique_ptr<Value> subjectConverted(subject->As(typecastnode.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(spanmoduleIdU"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"spanmoduleId);
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(spanmoduleIdtemplateParameterNode->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"spanmoduleId);
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(spanmoduleIdU"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"spanmoduleId);
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::u32stringMemberInitializerNode*> 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(spanmoduleIdconstructorNode.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_parentcontainerScope));
1308         lookups.push_back(FunctionScopeLookup(ScopeLookup::this_memberVariableSymbol->GetType()->BaseType()->GetContainerScope()));
1309         lookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopesnullptr));
1310         std::vector<std::std::unique_ptr<BoundExpression>>initializerArguments=ValuesToLiterals(initializerArgumentValuessymbolTableerror);
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(spanmoduleIdconstructorNode.GetSpan()constructorNode.ModuleId());
1324             }
1325         }
1326         initializerArguments.insert(initializerArguments.begin()std::unique_ptr<BoundExpression>(new BoundTypeExpression(spanmoduleIdmemberVariableSymbol->GetType()->AddPointer(spanmoduleId))));
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"containerScopelookupsinitializerArgumentsboundCompileUnitcurrentFunction
1335             constructorNode.GetSpan()constructorNode.ModuleId()flagstemplateArgumentTypesexception);
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(spanmoduleIdconstructorNode.GetSpan()constructorNode.ModuleId());
1350             }
1351         }
1352         argumentValues = ArgumentsToValues(constructorCall->Arguments()errortrueboundCompileUnit);
1353         if (error)
1354         {
1355             if (dontThrow)
1356             {
1357                 return;
1358             }
1359             else
1360             {
1361                 ThrowCannotEvaluateStatically(spanmoduleIdconstructorNode.GetSpan()constructorNode.ModuleId());
1362             }
1363         }
1364         FunctionSymbol* constructorSymbol = constructorCall->GetFunctionSymbol();
1365         if (constructorSymbol->IsCompileTimePrimitiveFunction())
1366         {
1367             value = constructorSymbol->ConstructValue(argumentValuesspanmoduleIdnullptr);
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(spanmoduleIdconstructorNode.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(spanmoduleIdctorNode->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(spanmoduleIdconstructorNode.GetSpan()constructorNode.ModuleId());
1420             }
1421         }
1422         memberValues.push_back(std::move(value));
1423     }
1424     constructorNode.Body()->Accept(*this);
1425     value.reset(new StructuredValue(spanmoduleIdclassTypestd::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(spanmoduleIdU"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(spanmoduleIdmemberVariableSymbol->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(spanmoduleIdconversionFunctionNode.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(spanmoduleIdclassNode.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(spanmoduleIdstaticConstructorNode.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(spanmoduleIddestructorNode.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(spanmoduleIdinterfaceNode.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(spanmoduleIddelegateNode.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(spanmoduleIdclassDelegateNode.GetSpan()classDelegateNode.ModuleId());
1671     }
1672 }
1673 
1674 void Evaluator::Visit(CompoundStatementNode& compoundStatementNode)
1675 {
1676     DeclarationBlock* prevDeclarationBlock = currentDeclarationBlock;
1677     DeclarationBlock declarationBlock(spanmoduleIdU"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(spanmoduleIdU"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(spanmoduleIdgotoStatementNode.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()boundCompileUnitcontainerScope);
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(spanmoduleIdconstructionStatementNode.GetSpan()constructionStatementNode.ModuleId());
2032             }
2033         }
2034         values.push_back(std::move(value));
2035     }
2036     std::vector<std::std::unique_ptr<BoundExpression>>arguments=ValuesToLiterals(valuessymbolTableerror);
2037     if (error)
2038     {
2039         if (dontThrow)
2040         {
2041             return;
2042         }
2043         else
2044         {
2045             ThrowCannotEvaluateStatically(spanmoduleIdconstructionStatementNode.GetSpan()constructionStatementNode.ModuleId());
2046         }
2047     }
2048     arguments.insert(arguments.begin()std::unique_ptr<BoundExpression>(new BoundTypeExpression(spanmoduleIdtype->AddPointer(spanmoduleId))));
2049     std::vector<FunctionScopeLookup> scopeLookups;
2050     scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parentcontainerScope));
2051     scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopesnullptr));
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"containerScopescopeLookupsargumentsboundCompileUnitcurrentFunctionspanmoduleId
2060         flagstemplateArgumentTypesexception);
2061     if (!constructorCall)
2062     {
2063         if (dontThrow)
2064         {
2065             error = true;
2066             return;
2067         }
2068         else
2069         {
2070             ThrowCannotEvaluateStatically(spanmoduleIdconstructionStatementNode.GetSpan()constructionStatementNode.ModuleId());
2071         }
2072     }
2073     argumentValues = ArgumentsToValues(constructorCall->Arguments()errortrueboundCompileUnit);
2074     if (error)
2075     {
2076         if (dontThrow)
2077         {
2078             return;
2079         }
2080         else
2081         {
2082             ThrowCannotEvaluateStatically(spanmoduleIdconstructionStatementNode.GetSpan()constructionStatementNode.ModuleId());
2083         }
2084     }
2085     FunctionSymbol* constructorSymbol = constructorCall->GetFunctionSymbol();
2086     if (constructorSymbol->IsCompileTimePrimitiveFunction())
2087     {
2088         value = constructorSymbol->ConstructValue(argumentValuesspanmoduleIdnullptr);
2089         if (!value)
2090         {
2091             if (dontThrow)
2092             {
2093                 error = true;
2094                 return;
2095             }
2096             else
2097             {
2098                 ThrowCannotEvaluateStatically(spanmoduleIdconstructionStatementNode.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(spanmoduleIdctorNode->GetSpan()ctorNode->ModuleId());
2116             }
2117         }
2118     }
2119     else
2120     {
2121         if (dontThrow)
2122         {
2123             error = true;
2124             return;
2125         }
2126         else
2127         {
2128             ThrowCannotEvaluateStatically(spanmoduleIdconstructionStatementNode.GetSpan()constructionStatementNode.ModuleId());
2129         }
2130     }
2131     VariableValueSymbol* variableValue = new VariableValueSymbol(spanmoduleIdconstructionStatementNode.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(spanmoduleIddeleteStatementNode.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(spanmoduleIddestroyStatementNode.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(valuessymbolTableerror);
2175     if (error)
2176     {
2177         if (dontThrow)
2178         {
2179             return;
2180         }
2181         else
2182         {
2183             ThrowCannotEvaluateStatically(spanmoduleIdassignmentStatementNode.GetSpan()assignmentStatementNode.ModuleId());
2184         }
2185     }
2186     arguments.insert(arguments.begin()std::unique_ptr<BoundExpression>(new BoundTypeExpression(spanmoduleIdtarget->GetType()->AddPointer(spanmoduleId))));
2187     std::vector<FunctionScopeLookup> scopeLookups;
2188     scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parentcontainerScope));
2189     scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopesnullptr));
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="containerScopescopeLookupsargumentsboundCompileUnitcurrentFunctionspanmoduleId
2198         flagstemplateArgumentTypesexception);
2199     if (!assignmentCall)
2200     {
2201         if (dontThrow)
2202         {
2203             error = true;
2204             return;
2205         }
2206         else
2207         {
2208             ThrowCannotEvaluateStatically(spanmoduleIdassignmentStatementNode.GetSpan()assignmentStatementNode.ModuleId());
2209         }
2210     }
2211     argumentValues = ArgumentsToValues(assignmentCall->Arguments()errortrueboundCompileUnit);
2212     if (error)
2213     {
2214         if (dontThrow)
2215         {
2216             return;
2217         }
2218         else
2219         {
2220             ThrowCannotEvaluateStatically(spanmoduleIdassignmentStatementNode.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     // todo
2238     if (dontThrow)
2239     {
2240         error = true;
2241         return;
2242     }
2243     else
2244     {
2245         ThrowCannotEvaluateStatically(spanmoduleIdrangeForStatementNode.GetSpan()rangeForStatementNode.ModuleId());
2246     }
2247 }
2248 
2249 void Evaluator::Visit(SwitchStatementNode& switchStatementNode)
2250 {
2251     // todo
2252     if (dontThrow)
2253     {
2254         error = true;
2255         return;
2256     }
2257     else
2258     {
2259         ThrowCannotEvaluateStatically(spanmoduleIdswitchStatementNode.GetSpan()switchStatementNode.ModuleId());
2260     }
2261 }
2262 
2263 void Evaluator::Visit(CaseStatementNode& caseStatementNode)
2264 {
2265     // todo
2266     if (dontThrow)
2267     {
2268         error = true;
2269         return;
2270     }
2271     else
2272     {
2273         ThrowCannotEvaluateStatically(spanmoduleIdcaseStatementNode.GetSpan()caseStatementNode.ModuleId());
2274     }
2275 }
2276 
2277 void Evaluator::Visit(DefaultStatementNode& defaultStatementNode)
2278 {
2279     // todo
2280     if (dontThrow)
2281     {
2282         error = true;
2283         return;
2284     }
2285     else
2286     {
2287         ThrowCannotEvaluateStatically(spanmoduleIddefaultStatementNode.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(spanmoduleIdgotoCaseStatementNode.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(spanmoduleIdgotoDefaultStatementNode.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(spanmoduleIdthrowStatementNode.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(spanmoduleIdtryStatementNode.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(spanmoduleIdcatchNode.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(spanmoduleIdassertStatementNode.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"spanmoduleIdassertStatementNode.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"spanmoduleIdassertStatementNode.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(spanmoduleIdconditionalCompilationPartNode.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(spanmoduleIdconditionalCompilationDisjunctionNode.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(spanmoduleIdconditionalCompilationConjunctionNode.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(spanmoduleIdconditionalCompilationNotNode.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(spanmoduleIdconditionalCompilationPrimaryNode.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(spanmoduleIdconditionalCompilationStatementNode.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(spanmoduleIdboolNode.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(spanmoduleIdsbyteNode.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(spanmoduleIdbyteNode.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(spanmoduleIdshortNode.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(spanmoduleIdushortNode.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(spanmoduleIdintNode.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(spanmoduleIduintNode.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(spanmoduleIdlongNode.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(spanmoduleIdulongNode.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(spanmoduleIdfloatNode.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(spanmoduleIddoubleNode.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(spanmoduleIdcharNode.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(spanmoduleIdwcharNode.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(spanmoduleIducharNode.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(spanmoduleIdvoidNode.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"spanmoduleId);
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]elementTypecontainerScopeboundCompileUnitdontThrowcurrentFunctionarrayLiteralNode.GetSpan()arrayLiteralNode.ModuleId());
2783         if (error)
2784         {
2785             if (dontThrow)
2786             {
2787                 return;
2788             }
2789             else
2790             {
2791                 ThrowCannotEvaluateStatically(spanmoduleIdarrayLiteralNode.GetSpan()arrayLiteralNode.ModuleId());
2792             }
2793         }
2794         if (!value)
2795         {
2796             if (dontThrow)
2797             {
2798                 error = true;
2799                 return;
2800             }
2801             else
2802             {
2803                 ThrowCannotEvaluateStatically(spanmoduleIdarrayLiteralNode.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()narrayLiteralNode.GetSpan()arrayLiteralNode.ModuleId());
2811     }
2812     value.reset(new ArrayValue(arrayLiteralNode.GetSpan()arrayLiteralNode.ModuleId()arrayTypestd::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"spanmoduleId);
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]memberTypecontainerScopeboundCompileUnitdontThrowcurrentFunctionstructuredLiteralNode.GetSpan()structuredLiteralNode.ModuleId());
2863             if (error)
2864             {
2865                 if (dontThrow)
2866                 {
2867                     return;
2868                 }
2869                 else
2870                 {
2871                     ThrowCannotEvaluateStatically(spanmoduleIdstructuredLiteralNode.GetSpan()structuredLiteralNode.ModuleId());
2872                 }
2873             }
2874             if (!value)
2875             {
2876                 if (dontThrow)
2877                 {
2878                     error = true;
2879                     return;
2880                 }
2881                 else
2882                 {
2883                     ThrowCannotEvaluateStatically(spanmoduleIdstructuredLiteralNode.GetSpan()structuredLiteralNode.ModuleId());
2884                 }
2885             }
2886             memberValues.push_back(std::move(value));
2887         }
2888         std::vector<std::std::unique_ptr<BoundExpression>>arguments=ValuesToLiterals(memberValuessymbolTableerror);
2889         if (error)
2890         {
2891             if (dontThrow)
2892             {
2893                 return;
2894             }
2895             else
2896             {
2897                 ThrowCannotEvaluateStatically(spanmoduleIdstructuredLiteralNode.GetSpan()structuredLiteralNode.ModuleId());
2898             }
2899         }
2900         arguments.insert(arguments.begin()std::unique_ptr<BoundExpression>(new BoundTypeExpression(spanmoduleIdclassType->AddPointer(spanmoduleId))));
2901         std::vector<FunctionScopeLookup> scopeLookups;
2902         scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parentclassType->ClassOrNsScope()));
2903         scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parentcontainerScope));
2904         scopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopesnullptr));
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"containerScopescopeLookupsargumentsboundCompileUnitcurrentFunctionspanmoduleId
2913             flagstemplateArgumentTypesexception);
2914         if (!constructorCall)
2915         {
2916             if (dontThrow)
2917             {
2918                 error = true;
2919                 return;
2920             }
2921             else
2922             {
2923                 ThrowCannotEvaluateStatically(spanmoduleIdstructuredLiteralNode.GetSpan()structuredLiteralNode.ModuleId());
2924             }
2925         }
2926         argumentValues = ArgumentsToValues(constructorCall->Arguments()errortrueboundCompileUnit);
2927         if (error)
2928         {
2929             if (dontThrow)
2930             {
2931                 return;
2932             }
2933             else
2934             {
2935                 ThrowCannotEvaluateStatically(spanmoduleIdstructuredLiteralNode.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(spanmoduleIdstructuredLiteralNode.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(nameScopeLookup::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(symbolidentifierNode.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(templateArgumentNodeboundCompileUnitcontainerScope);
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(spanmoduleIdtemplateIdNode.GetSpan()templateIdNode.ModuleId());
3037         }
3038     }
3039 }
3040 
3041 void Evaluator::EvaluateSymbol(Symbol* symbolconst Span& span)
3042 {
3043     if (symbol->GetSymbolType() == SymbolType::constantSymbol)
3044     {
3045         ConstantSymbol* constantSymbol = static_cast<ConstantSymbol*>(symbol);
3046         EvaluateConstantSymbol(constantSymbolspan);
3047     }
3048     else if (symbol->GetSymbolType() == SymbolType::enumConstantSymbol)
3049     {
3050         EnumConstantSymbol* enumConstantSymbol = static_cast<EnumConstantSymbol*>(symbol);
3051         EvaluateEnumConstantSymbol(enumConstantSymbolspan);
3052     }
3053     else if (symbol->IsContainerSymbol())
3054     {
3055         ContainerSymbol* containerSymbol = static_cast<ContainerSymbol*>(symbol);
3056         value.reset(new ScopedValue(spanmoduleIdcontainerSymbol));
3057     }
3058     else if (symbol->GetSymbolType() == SymbolType::functionGroupSymbol)
3059     {
3060         FunctionGroupSymbol* functionGroup = static_cast<FunctionGroupSymbol*>(symbol);
3061         value.reset(new FunctionGroupValue(functionGroupqualifiedScope));
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(spanmoduleId);
3084         }
3085     }
3086 }
3087 
3088 void Evaluator::EvaluateConstantSymbol(ConstantSymbol* constantSymbolconst Span& span)
3089 {
3090     if (constantSymbol->Evaluating())
3091     {
3092         if (dontThrow)
3093         {
3094             error = true;
3095             return;
3096         }
3097         throw Exception("cyclic depenency detected"spanmoduleId);
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" spanmoduleId);
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* enumConstantSymbolconst Span& span)
3152 {
3153     if (enumConstantSymbol->Evaluating())
3154     {
3155         if (dontThrow)
3156         {
3157             error = true;
3158             return;
3159         }
3160         throw Exception("cyclic depenency detected"spanmoduleId);
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(spanmoduleIdtype);
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(spanmoduleIdtype);
3205             scopedValue->SetType(type->AddPointer(spanmoduleId));
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(spanmoduleIdtype);
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(spanmoduleIdtype);
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(symboldotNode.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(spanmoduleIdarrowNode.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(spanmoduleIdequivalenceNode.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(spanmoduleIdimplicationNode.GetSpan()implicationNode.ModuleId());
3314     }
3315 }
3316 
3317 void Evaluator::Visit(DisjunctionNode& disjunctionNode)
3318 {
3319     EvaluateBinOp(disjunctionNodedisjunction);
3320 }
3321 
3322 void Evaluator::Visit(ConjunctionNode& conjunctionNode)
3323 {
3324     EvaluateBinOp(conjunctionNodeconjunction);
3325 }
3326 
3327 void Evaluator::Visit(BitOrNode& bitOrNode)
3328 {
3329     EvaluateBinOp(bitOrNodebitOr);
3330 }
3331 
3332 void Evaluator::Visit(BitXorNode& bitXorNode)
3333 {
3334     EvaluateBinOp(bitXorNodebitXor);
3335 }
3336 
3337 void Evaluator::Visit(BitAndNode& bitAndNode)
3338 {
3339     EvaluateBinOp(bitAndNodebitAnd);
3340 }
3341 
3342 void Evaluator::Visit(EqualNode& equalNode)
3343 {
3344     EvaluateBinOp(equalNodeequalOperator::comparison);
3345 }
3346 
3347 void Evaluator::Visit(NotEqualNode& notEqualNode)
3348 {
3349     EvaluateBinOp(notEqualNodenotEqualOperator::comparison);
3350 }
3351 
3352 void Evaluator::Visit(LessNode& lessNode)
3353 {
3354     EvaluateBinOp(lessNodelessOperator::comparison);
3355 }
3356 
3357 void Evaluator::Visit(GreaterNode& greaterNode)
3358 {
3359     EvaluateBinOp(greaterNodegreaterOperator::comparison);
3360 }
3361 
3362 void Evaluator::Visit(LessOrEqualNode& lessOrEqualNode)
3363 {
3364     EvaluateBinOp(lessOrEqualNodelessEqualOperator::comparison);
3365 }
3366 
3367 void Evaluator::Visit(GreaterOrEqualNode& greaterOrEqualNode)
3368 {
3369     EvaluateBinOp(greaterOrEqualNodegreaterEqualOperator::comparison);
3370 }
3371 
3372 void Evaluator::Visit(ShiftLeftNode& shiftLeftNode)
3373 {
3374     EvaluateBinOp(shiftLeftNodeshiftLeft);
3375 }
3376 
3377 void Evaluator::Visit(ShiftRightNode& shiftRightNode)
3378 {
3379     EvaluateBinOp(shiftRightNodeshiftRight);
3380 }
3381 
3382 void Evaluator::Visit(AddNode& addNode)
3383 {
3384     EvaluateBinOp(addNodeaddOperator::add);
3385 }
3386 
3387 void Evaluator::Visit(SubNode& subNode)
3388 {
3389     EvaluateBinOp(subNodesubOperator::sub);
3390 }
3391 
3392 void Evaluator::Visit(MulNode& mulNode)
3393 {
3394     EvaluateBinOp(mulNodemul);
3395 }
3396 
3397 void Evaluator::Visit(DivNode& divNode)
3398 {
3399     EvaluateBinOp(divNodediv);
3400 }
3401 
3402 void Evaluator::Visit(RemNode& remNode)
3403 {
3404     EvaluateBinOp(remNoderem);
3405 }
3406 
3407 void Evaluator::Visit(NotNode& notNode)
3408 {
3409     EvaluateUnaryOp(notNodelogicalNot);
3410 }
3411 
3412 void Evaluator::Visit(UnaryPlusNode& unaryPlusNode)
3413 {
3414     EvaluateUnaryOp(unaryPlusNodeunaryPlus);
3415 }
3416 
3417 void Evaluator::Visit(UnaryMinusNode& unaryMinusNode)
3418 {
3419     EvaluateUnaryOp(unaryMinusNodeunaryMinus);
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(spanmoduleIdprefixIncrementNode.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(spanmoduleIdprefixIncrementNode.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(spanmoduleIdprefixDecrementNode.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(spanmoduleIdprefixDecrementNode.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(spanmoduleIdaddrOfNode.GetSpan()addrOfNode.ModuleId());
3567     }
3568 }
3569 
3570 void Evaluator::Visit(ComplementNode& complementNode)
3571 {
3572     EvaluateUnaryOp(complementNodecomplement);
3573 }
3574 
3575 void Evaluator::Visit(IsNode& isNode)
3576 {
3577     if (dontThrow)
3578     {
3579         error = true;
3580     }
3581     else
3582     {
3583         ThrowCannotEvaluateStatically(spanmoduleIdisNode.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(spanmoduleIdasNode.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")containerScopeboundCompileUnitdontThrowcurrentFunctionindexingNode.GetSpan()indexingNode.ModuleId());
3606         if (!value)
3607         {
3608             if (dontThrow)
3609             {
3610                 error = true;
3611                 return;
3612             }
3613             else
3614             {
3615                 ThrowCannotEvaluateStatically(spanmoduleIdindexingNode.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(spanmoduleIdindexingNode.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(spanmoduleIdinvokeNode.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_basefunctionGroupValue->QualifiedScope());
3699             functionScopeLookups.push_back(qualifiedScopeLookup);
3700         }
3701         else
3702         {
3703             functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parentcontainerScope));
3704             functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::fileScopesnullptr));
3705         }
3706         std::vector<std::std::unique_ptr<BoundExpression>>arguments=ValuesToLiterals(valuessymbolTableerror);
3707         if (error)
3708         {
3709             if (dontThrow)
3710             {
3711                 return;
3712             }
3713             else
3714             {
3715                 ThrowCannotEvaluateStatically(spanmoduleIdinvokeNode.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(spanmoduleIdtype)));
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()containerScopefunctionScopeLookupsargumentsboundCompileUnitcurrentFunctionspanmoduleId
3731             flagstemplateTypeArgumentsexception);
3732         bool memberFunctionCall = false;
3733         if (!functionCall)
3734         {
3735             if (currentClassType)
3736             {
3737                 arguments.insert(arguments.begin()std::unique_ptr<BoundExpression>(new BoundTypeExpression(spanmoduleIdcurrentClassType->AddPointer(spanmoduleId))));
3738                 functionScopeLookups.push_back(FunctionScopeLookup(ScopeLookup::this_and_base_and_parentcurrentClassType->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()containerScopefunctionScopeLookupsargumentsboundCompileUnitcurrentFunctionspanmoduleId
3746                     flagstemplateTypeArgumentsexception);
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(spanmoduleIdinvokeNode.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()errorskipFirstboundCompileUnit);
3771             if (error)
3772             {
3773                 if (dontThrow)
3774                 {
3775                     return;
3776                 }
3777                 else
3778                 {
3779                     ThrowCannotEvaluateStatically(spanmoduleIdinvokeNode.GetSpan()invokeNode.ModuleId());
3780                 }
3781             }
3782             value = functionSymbol->ConstructValue(argumentValuesinvokeNode.GetSpan()invokeNode.ModuleId()receiver);
3783             if (!value)
3784             {
3785                 if (dontThrow)
3786                 {
3787                     error = true;
3788                     return;
3789                 }
3790                 else
3791                 {
3792                     ThrowCannotEvaluateStatically(spanmoduleIdinvokeNode.GetSpan()invokeNode.ModuleId());
3793                 }
3794             }
3795         }
3796         else if (functionSymbol->IsConstExpr())
3797         {
3798             FunctionNode* functionNode = boundCompileUnit.GetFunctionNodeFor(functionSymbol);
3799             CheckFunctionReturnPaths(functionSymbol*functionNodecontainerScopeboundCompileUnit);
3800             bool skipFirst = memberFunctionCall || functionGroupValue->Receiver();
3801             argumentValues = ArgumentsToValues(functionCall->Arguments()errorskipFirstboundCompileUnit);
3802             if (error)
3803             {
3804                 if (dontThrow)
3805                 {
3806                     return;
3807                 }
3808                 else
3809                 {
3810                     ThrowCannotEvaluateStatically(spanmoduleIdinvokeNode.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()errorboundCompileUnit);
3832                 if (error)
3833                 {
3834                     if (dontThrow)
3835                     {
3836                         return;
3837                     }
3838                     else
3839                     {
3840                         ThrowCannotEvaluateStatically(spanmoduleIdinvokeNode.GetSpan()invokeNode.ModuleId());
3841                     }
3842                 }
3843                 value = intrinsic->Evaluate(argumentValuestemplateTypeArgumentsinvokeNode.GetSpan()invokeNode.ModuleId());
3844                 if (!value)
3845                 {
3846                     if (dontThrow)
3847                     {
3848                         error = true;
3849                         return;
3850                     }
3851                     else
3852                     {
3853                         ThrowCannotEvaluateStatically(spanmoduleIdinvokeNode.GetSpan()invokeNode.ModuleId());
3854                     }
3855                 }
3856             }
3857             else
3858             {
3859                 if (dontThrow)
3860                 {
3861                     error = true;
3862                     return;
3863                 }
3864                 else
3865                 {
3866                     ThrowCannotEvaluateStatically(spanmoduleIdinvokeNode.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(spanmoduleIdpostfixIncrementNode.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(spanmoduleIdpostfixDecrementNode.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(spanmoduleIdsizeOfNode.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(spanmoduleIdtypeNameNode.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(spanmoduleIdtypeIdNode.GetSpan()typeIdNode.ModuleId());
3987     }
3988 }
3989 
3990 void Evaluator::Visit(CastNode& castNode)
3991 {
3992     TypeSymbol* type = ResolveType(castNode.TargetTypeExpr()boundCompileUnitcontainerScope);
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(spanmoduleIdcastNode.GetSpan()castNode.ModuleId());
4007         }
4008     }
4009     value.reset(value->As(typetruecastNode.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(spanmoduleIdconstructNode.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(spanmoduleIdnewNode.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(spanmoduleIdthisNode.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(spanmoduleIdbaseNode.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*nodeTypeSymbol*targetTypeContainerScope*containerScopeBoundCompileUnit&boundCompileUnitbool dontThrowBoundFunction* currentFunctionconst Span& span
4067     const boost::uuids::uuid& moduleId)
4068 {
4069     ValueType targetValueType = targetType->GetValueType();
4070     Evaluator evaluator(boundCompileUnitcontainerScopetargetTypetargetValueTypefalsedontThrowcurrentFunctionspanmoduleId);
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(spanmoduleId)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(spanmoduleId)falsenode->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 } } // namespace cmajor::binder