1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <cmajor/symbols/StringFunctions.hpp>
  7 #include <cmajor/symbols/Value.hpp>
  8 #include <cmajor/symbols/Module.hpp>
  9 
 10 namespace cmajor { namespace symbols {
 11 
 12 StringFunctionContainerSymbol::StringFunctionContainerSymbol() : TypeSymbol(SymbolType::stringFunctionContainerSymbolSpan()boost::uuids::nil_uuid()U"@string_functions")
 13 {
 14     AddMember(new StringLengthFunction(this));
 15 }
 16 
 17 void* StringFunctionContainerSymbol::IrType(Emitter& emitter)
 18 {
 19     throw std::runtime_error("string function container symbol has no IR type");
 20 }
 21 
 22 void* StringFunctionContainerSymbol::CreateDefaultIrValue(Emitter& emitter)
 23 {
 24     throw std::runtime_error("string function container symbol has no IR value");
 25 }
 26 
 27 StringFunctionContainerSymbol::StringFunctionContainerSymbol(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_) :
 28     TypeSymbol(SymbolType::stringFunctionContainerSymbolspan_sourceModuleId_name_)
 29 {
 30 }
 31 
 32 void StringFunctionContainerSymbol::Write(SymbolWriter& writer)
 33 {
 34     TypeSymbol::Write(writer);
 35 }
 36 
 37 void StringFunctionContainerSymbol::Read(SymbolReader& reader)
 38 {
 39     TypeSymbol::Read(reader);
 40 }
 41 
 42 StringLengthFunction::StringLengthFunction(TypeSymbol* parentType) : FunctionSymbol(SymbolType::stringLengthFunctionSymbolSpan()boost::uuids::nil_uuid()U"Length")
 43 {
 44     SetGroupName(U"Length");
 45     SetAccess(SymbolAccess::public_);
 46     ParameterSymbol* stringValueParam = new ParameterSymbol(Span()boost::uuids::nil_uuid()U"stringValue");
 47     stringValueParam->SetType(parentType);
 48     AddMember(stringValueParam);
 49     TypeSymbol* longType = GetRootModuleForCurrentThread()->GetSymbolTable().GetTypeByName(U"long");
 50     SetReturnType(longType);
 51     ComputeName();
 52     GetRootModuleForCurrentThread()->GetSymbolTable().SetFunctionIdFor(this);
 53 }
 54 
 55 StringLengthFunction::StringLengthFunction(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_) : FunctionSymbol(span_sourceModuleId_name_)
 56 {
 57 }
 58 
 59 void StringLengthFunction::Write(SymbolWriter& writer)
 60 {
 61     FunctionSymbol::Write(writer);
 62 }
 63 
 64 void StringLengthFunction::Read(SymbolReader& reader)
 65 {
 66     FunctionSymbol::Read(reader);
 67 }
 68 
 69 void StringLengthFunction::GenerateCall(Emitter& emitterstd::std::vector<GenObject*>&genObjectsOperationFlagsflagsconstSpan&spanconstboost::uuids::uuid& moduleId)
 70 {
 71     Assert(false"string length is compile time function only");
 72 }
 73 
 74 std::std::unique_ptr<Value>StringLengthFunction::ConstructValue(conststd::std::vector<std::std::unique_ptr<Value>>&argumentValuesconstSpan&spanconstboost::uuids::uuid&moduleIdValue*receiver) const
 75 {
 76     if (argumentValues.size() == 0)
 77     {
 78         if (receiver && receiver->IsScopedValue())
 79         {
 80             Value* value = receiver->GetSubject();
 81             if (value->IsStringReferenceValue())
 82             {
 83                 value = value->GetSubject();
 84             }
 85             if (value)
 86             {
 87                 switch (value->GetValueType())
 88                 {
 89                     case ValueType::stringValue:
 90                     {
 91                         StringValue* stringValue = static_cast<StringValue*>(value);
 92                         return std::unique_ptr<Value>(new LongValue(spanmoduleIdstringValue->Str().length()));
 93                     }
 94                     case ValueType::wstringValue:
 95                     {
 96                         WStringValue* stringValue = static_cast<WStringValue*>(value);
 97                         return std::unique_ptr<Value>(new LongValue(spanmoduleIdstringValue->Str().length()));
 98                     }
 99                     case ValueType::ustringValue:
100                     {
101                         UStringValue* stringValue = static_cast<UStringValue*>(value);
102                         return std::unique_ptr<Value>(new LongValue(spanmoduleIdstringValue->Str().length()));
103                     }
104                 }
105             }
106         }
107     }
108     return std::unique_ptr<Value>();
109 }
110 
111 } } // namespace cmajor::symbols