1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <cmajor/symbols/Meta.hpp>
  7 #include <cmajor/symbols/Exception.hpp>
  8 #include <cmajor/symbols/FunctionSymbol.hpp>
  9 #include <cmajor/symbols/TemplateSymbol.hpp>
 10 #include <cmajor/symbols/SymbolTable.hpp>
 11 #include <soulng/util/Unicode.hpp>
 12 
 13 namespace cmajor { namespace symbols {
 14 
 15 using namespace soulng::unicode;
 16 
 17 IntrinsicFunction::IntrinsicFunction()
 18 {
 19 }
 20 
 21 IntrinsicFunction::~IntrinsicFunction()
 22 {
 23 }
 24 
 25 std::std::unique_ptr<Value>IntrinsicFunction::Evaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId)
 26 {
 27     if (arguments.size() != Arity())
 28     {
 29         throw Exception("wrong number of parameters for intrinsic " + std::string(GroupName())spanmoduleId);
 30     }
 31     if (templateArguments.size() != NumberOfTypeParameters())
 32     {
 33         throw Exception("wrong number of template type arguments for intrinsic " + std::string(GroupName())spanmoduleId);
 34     }
 35     return DoEvaluate(argumentstemplateArgumentsspanmoduleId);
 36 }
 37 
 38 FunctionSymbol* CreateIntrinsic(IntrinsicFunction* intrinsicSymbolTable& symbolTableContainerSymbol* parent)
 39 {
 40     FunctionSymbol* fun = new FunctionSymbol(Span()boost::uuids::nil_uuid()ToUtf32(intrinsic->GroupName()));
 41     fun->SetModule(symbolTable.GetModule());
 42     fun->SetGroupName(ToUtf32(intrinsic->GroupName()));
 43     fun->SetIntrinsic(intrinsic);
 44     fun->SetAccess(SymbolAccess::public_);
 45     fun->SetReturnType(intrinsic->ReturnType(symbolTable));
 46     fun->SetParent(parent);
 47     int n = intrinsic->NumberOfTypeParameters();
 48     for (int i = 0; i < n; ++i)
 49     {
 50         std::u32string p = U"T";
 51         if (i > 0)
 52         {
 53             p.append(ToUtf32(std::to_string(i)));
 54         }
 55         TemplateParameterSymbol* s = new TemplateParameterSymbol(Span()boost::uuids::nil_uuid()p);
 56         symbolTable.SetTypeIdFor(s);
 57         s->SetModule(symbolTable.GetModule());
 58         fun->AddMember(s);
 59     }
 60     fun->ComputeName();
 61     return fun;
 62 }
 63 
 64 class TypePredicate public IntrinsicFunction
 65 {
 66 public:
 67     TypePredicate();
 68     int Arity() const override { return 0; }
 69     int NumberOfTypeParameters() const override { return 1; }
 70     TypeSymbol* ReturnType(SymbolTable& symbolTable) const override { return symbolTable.GetTypeByName(U"bool"); }
 71 };
 72 
 73 TypePredicate::TypePredicate() : IntrinsicFunction()
 74 {
 75 }
 76 
 77 class IsIntegralTypePredicate public TypePredicate
 78 {
 79 public:
 80     IsIntegralTypePredicate();
 81     const char* GroupName() const override { return "IsIntegralType"; }
 82     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
 83     {
 84         TypeSymbol* type = templateArguments.front();
 85         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsIntegralType()));
 86     }
 87 };
 88 
 89 IsIntegralTypePredicate::IsIntegralTypePredicate() : TypePredicate()
 90 {
 91 }
 92 
 93 class IsSignedTypePredicate public TypePredicate
 94 {
 95 public:
 96     IsSignedTypePredicate();
 97     const char* GroupName() const override { return "IsSignedType"; }
 98     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
 99     {
100         TypeSymbol* type = templateArguments.front();
101         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsIntegralType() && !type->IsUnsignedType()));
102     }
103 };
104 
105 IsSignedTypePredicate::IsSignedTypePredicate() : TypePredicate()
106 {
107 }
108 
109 class IsUnsignedTypePredicate public TypePredicate
110 {
111 public:
112     IsUnsignedTypePredicate();
113     const char* GroupName() const override { return "IsUnsignedType"; }
114     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
115     {
116         TypeSymbol* type = templateArguments.front();
117         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsUnsignedType()));
118     }
119 };
120 
121 IsUnsignedTypePredicate::IsUnsignedTypePredicate() : TypePredicate()
122 {
123 }
124 
125 class IsFloatingPointTypePredicate public TypePredicate
126 {
127 public:
128     IsFloatingPointTypePredicate();
129     const char* GroupName() const override { return "IsFloatingPointType"; }
130     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
131     {
132         TypeSymbol* type = templateArguments.front();
133         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsFloatingPointType()));
134     }
135 };
136 
137 IsFloatingPointTypePredicate::IsFloatingPointTypePredicate() : TypePredicate()
138 {
139 }
140 
141 class IsBasicTypePredicate public TypePredicate
142 {
143 public:
144     IsBasicTypePredicate();
145     const char* GroupName() const override { return "IsBasicType"; }
146     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
147     {
148         TypeSymbol* type = templateArguments.front();
149         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsBasicTypeSymbol()));
150     }
151 };
152 
153 IsBasicTypePredicate::IsBasicTypePredicate() : TypePredicate()
154 {
155 }
156 
157 class IsBoolTypePredicate public TypePredicate
158 {
159 public:
160     IsBoolTypePredicate();
161     const char* GroupName() const override { return "IsBoolType"; }
162     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
163     {
164         TypeSymbol* type = templateArguments.front();
165         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::boolTypeSymbol));
166     }
167 };
168 
169 IsBoolTypePredicate::IsBoolTypePredicate() : TypePredicate()
170 {
171 }
172 
173 class IsSByteTypePredicate public TypePredicate
174 {
175 public:
176     IsSByteTypePredicate();
177     const char* GroupName() const override { return "IsSByteType"; }
178     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
179     {
180         TypeSymbol* type = templateArguments.front();
181         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::sbyteTypeSymbol));
182     }
183 };
184 
185 IsSByteTypePredicate::IsSByteTypePredicate() : TypePredicate()
186 {
187 }
188 
189 class IsByteTypePredicate public TypePredicate
190 {
191 public:
192     IsByteTypePredicate();
193     const char* GroupName() const override { return "IsByteType"; }
194     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
195     {
196         TypeSymbol* type = templateArguments.front();
197         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::byteTypeSymbol));
198     }
199 };
200 
201 IsByteTypePredicate::IsByteTypePredicate() : TypePredicate()
202 {
203 }
204 
205 class IsShortTypePredicate public TypePredicate
206 {
207 public:
208     IsShortTypePredicate();
209     const char* GroupName() const override { return "IsShortType"; }
210     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
211     {
212         TypeSymbol* type = templateArguments.front();
213         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::shortTypeSymbol));
214     }
215 };
216 
217 IsShortTypePredicate::IsShortTypePredicate() : TypePredicate()
218 {
219 }
220 
221 class IsUShortTypePredicate public TypePredicate
222 {
223 public:
224     IsUShortTypePredicate();
225     const char* GroupName() const override { return "IsUShortType"; }
226     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
227     {
228         TypeSymbol* type = templateArguments.front();
229         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::ushortTypeSymbol));
230     }
231 };
232 
233 IsUShortTypePredicate::IsUShortTypePredicate() : TypePredicate()
234 {
235 }
236 
237 class IsIntTypePredicate public TypePredicate
238 {
239 public:
240     IsIntTypePredicate();
241     const char* GroupName() const override { return "IsIntType"; }
242     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
243     {
244         TypeSymbol* type = templateArguments.front();
245         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::intTypeSymbol));
246     }
247 };
248 
249 IsIntTypePredicate::IsIntTypePredicate() : TypePredicate()
250 {
251 }
252 
253 class IsUIntTypePredicate public TypePredicate
254 {
255 public:
256     IsUIntTypePredicate();
257     const char* GroupName() const override { return "IsUIntType"; }
258     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
259     {
260         TypeSymbol* type = templateArguments.front();
261         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::uintTypeSymbol));
262     }
263 };
264 
265 IsUIntTypePredicate::IsUIntTypePredicate() : TypePredicate()
266 {
267 }
268 
269 class IsLongTypePredicate public TypePredicate
270 {
271 public:
272     IsLongTypePredicate();
273     const char* GroupName() const override { return "IsLongType"; }
274     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
275     {
276         TypeSymbol* type = templateArguments.front();
277         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::longTypeSymbol));
278     }
279 };
280 
281 IsLongTypePredicate::IsLongTypePredicate() : TypePredicate()
282 {
283 }
284 
285 class IsULongTypePredicate public TypePredicate
286 {
287 public:
288     IsULongTypePredicate();
289     const char* GroupName() const override { return "IsULongType"; }
290     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
291     {
292         TypeSymbol* type = templateArguments.front();
293         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::ulongTypeSymbol));
294     }
295 };
296 
297 IsULongTypePredicate::IsULongTypePredicate() : TypePredicate()
298 {
299 }
300 
301 class IsFloatTypePredicate public TypePredicate
302 {
303 public:
304     IsFloatTypePredicate();
305     const char* GroupName() const override { return "IsFloatType"; }
306     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
307     {
308         TypeSymbol* type = templateArguments.front();
309         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::floatTypeSymbol));
310     }
311 };
312 
313 IsFloatTypePredicate::IsFloatTypePredicate() : TypePredicate()
314 {
315 }
316 
317 class IsDoubleTypePredicate public TypePredicate
318 {
319 public:
320     IsDoubleTypePredicate();
321     const char* GroupName() const override { return "IsDoubleType"; }
322     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
323     {
324         TypeSymbol* type = templateArguments.front();
325         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::doubleTypeSymbol));
326     }
327 };
328 
329 IsDoubleTypePredicate::IsDoubleTypePredicate() : TypePredicate()
330 {
331 }
332 
333 class IsCharTypePredicate public TypePredicate
334 {
335 public:
336     IsCharTypePredicate();
337     const char* GroupName() const override { return "IsCharType"; }
338     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
339     {
340         TypeSymbol* type = templateArguments.front();
341         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::charTypeSymbol));
342     }
343 };
344 
345 IsCharTypePredicate::IsCharTypePredicate() : TypePredicate()
346 {
347 }
348 
349 class IsWCharTypePredicate public TypePredicate
350 {
351 public:
352     IsWCharTypePredicate();
353     const char* GroupName() const override { return "IsWCharType"; }
354     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
355     {
356         TypeSymbol* type = templateArguments.front();
357         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::wcharTypeSymbol));
358     }
359 };
360 
361 IsWCharTypePredicate::IsWCharTypePredicate() : TypePredicate()
362 {
363 }
364 
365 class IsUCharTypePredicate public TypePredicate
366 {
367 public:
368     IsUCharTypePredicate();
369     const char* GroupName() const override { return "IsUCharType"; }
370     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
371     {
372         TypeSymbol* type = templateArguments.front();
373         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::ucharTypeSymbol));
374     }
375 };
376 
377 IsUCharTypePredicate::IsUCharTypePredicate() : TypePredicate()
378 {
379 }
380 
381 class IsVoidTypePredicate public TypePredicate
382 {
383 public:
384     IsVoidTypePredicate();
385     const char* GroupName() const override { return "IsVoidType"; }
386     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
387     {
388         TypeSymbol* type = templateArguments.front();
389         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::voidTypeSymbol));
390     }
391 };
392 
393 IsVoidTypePredicate::IsVoidTypePredicate() : TypePredicate()
394 {
395 }
396 
397 class IsClassTypePredicate public TypePredicate
398 {
399 public:
400     IsClassTypePredicate();
401     const char* GroupName() const override { return "IsClassType"; }
402     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
403     {
404         TypeSymbol* type = templateArguments.front();
405         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsClassTypeSymbol()));
406     }
407 };
408 
409 IsClassTypePredicate::IsClassTypePredicate() : TypePredicate()
410 {
411 }
412 
413 class IsPolymorphicTypePredicate public TypePredicate
414 {
415 public:
416     IsPolymorphicTypePredicate();
417     const char* GroupName() const override { return "IsPolymorphicType"; }
418     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
419     {
420         TypeSymbol* type = templateArguments.front();
421         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsPolymorphicType()));
422     }
423 };
424 
425 IsPolymorphicTypePredicate::IsPolymorphicTypePredicate() : TypePredicate()
426 {
427 }
428 
429 class IsInterfaceTypePredicate public TypePredicate
430 {
431 public:
432     IsInterfaceTypePredicate();
433     const char* GroupName() const override { return "IsInterfaceType"; }
434     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
435     {
436         TypeSymbol* type = templateArguments.front();
437         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->GetSymbolType() == SymbolType::interfaceTypeSymbol));
438     }
439 };
440 
441 IsInterfaceTypePredicate::IsInterfaceTypePredicate() : TypePredicate()
442 {
443 }
444 
445 class IsDelegateTypePredicate public TypePredicate
446 {
447 public:
448     IsDelegateTypePredicate();
449     const char* GroupName() const override { return "IsDelegateType"; }
450     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
451     {
452         TypeSymbol* type = templateArguments.front();
453         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsDelegateType()));
454     }
455 };
456 
457 IsDelegateTypePredicate::IsDelegateTypePredicate() : TypePredicate()
458 {
459 }
460 
461 class IsClassDelegateTypePredicate public TypePredicate
462 {
463 public:
464     IsClassDelegateTypePredicate();
465     const char* GroupName() const override { return "IsClassDelegateType"; }
466     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
467     {
468         TypeSymbol* type = templateArguments.front();
469         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsClassDelegateType()));
470     }
471 };
472 
473 IsClassDelegateTypePredicate::IsClassDelegateTypePredicate() : TypePredicate()
474 {
475 }
476 
477 class IsEnumeratedTypePredicate public TypePredicate
478 {
479 public:
480     IsEnumeratedTypePredicate();
481     const char* GroupName() const override { return "IsEnumeratedType"; }
482     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
483     {
484         TypeSymbol* type = templateArguments.front();
485         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsEnumeratedType()));
486     }
487 };
488 
489 IsEnumeratedTypePredicate::IsEnumeratedTypePredicate() : TypePredicate()
490 {
491 }
492 
493 class IsConstTypePredicate public TypePredicate
494 {
495 public:
496     IsConstTypePredicate();
497     const char* GroupName() const override { return "IsConstType"; }
498     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
499     {
500         TypeSymbol* type = templateArguments.front();
501         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsConstType()));
502     }
503 };
504 
505 IsConstTypePredicate::IsConstTypePredicate() : TypePredicate()
506 {
507 }
508 
509 class IsReferenceTypePredicate public TypePredicate
510 {
511 public:
512     IsReferenceTypePredicate();
513     const char* GroupName() const override { return "IsReferenceType"; }
514     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
515     {
516         TypeSymbol* type = templateArguments.front();
517         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsReferenceType()));
518     }
519 };
520 
521 IsReferenceTypePredicate::IsReferenceTypePredicate() : TypePredicate()
522 {
523 }
524 
525 class IsLvalueReferenceTypePredicate public TypePredicate
526 {
527 public:
528     IsLvalueReferenceTypePredicate();
529     const char* GroupName() const override { return "IsLvalueReferenceType"; }
530     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
531     {
532         TypeSymbol* type = templateArguments.front();
533         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsLvalueReferenceType()));
534     }
535 };
536 
537 IsLvalueReferenceTypePredicate::IsLvalueReferenceTypePredicate() : TypePredicate()
538 {
539 }
540 
541 class IsRvalueReferenceTypePredicate public TypePredicate
542 {
543 public:
544     IsRvalueReferenceTypePredicate();
545     const char* GroupName() const override { return "IsRvalueReferenceType"; }
546     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
547     {
548         TypeSymbol* type = templateArguments.front();
549         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsRvalueReferenceType()));
550     }
551 };
552 
553 IsRvalueReferenceTypePredicate::IsRvalueReferenceTypePredicate() : TypePredicate()
554 {
555 }
556 
557 class IsArrayTypePredicate public TypePredicate
558 {
559 public:
560     IsArrayTypePredicate();
561     const char* GroupName() const override { return "IsArrayType"; }
562     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
563     {
564         TypeSymbol* type = templateArguments.front();
565         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsArrayType()));
566     }
567 };
568 
569 IsArrayTypePredicate::IsArrayTypePredicate() : TypePredicate()
570 {
571 }
572 
573 class IsPointerTypePredicate public TypePredicate
574 {
575 public:
576     IsPointerTypePredicate();
577     const char* GroupName() const override { return "IsPointerType"; }
578     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
579     {
580         TypeSymbol* type = templateArguments.front();
581         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsPointerType()));
582     }
583 };
584 
585 IsPointerTypePredicate::IsPointerTypePredicate() : TypePredicate()
586 {
587 }
588 
589 class IsGenericPtrTypePredicate public TypePredicate
590 {
591 public:
592     IsGenericPtrTypePredicate();
593     const char* GroupName() const override { return "IsGenericPtrType"; }
594     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
595     {
596         TypeSymbol* type = templateArguments.front();
597         return std::unique_ptr<Value>(new BoolValue(spanmoduleIdtype->IsVoidPtrType()));
598     }
599 };
600 
601 IsGenericPtrTypePredicate::IsGenericPtrTypePredicate() : TypePredicate()
602 {
603 }
604 
605 class PointerCountIntrinsicFunction public IntrinsicFunction
606 {
607 public:
608     PointerCountIntrinsicFunction();
609     int Arity() const override { return 0; }
610     int NumberOfTypeParameters() const override { return 1; }
611     TypeSymbol* ReturnType(SymbolTable& symbolTable) const override { return symbolTable.GetTypeByName(U"int"); }
612     const char* GroupName() const override { return "PointerCount"; }
613     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
614     {
615         TypeSymbol* type = templateArguments.front();
616         return std::unique_ptr<Value>(new IntValue(spanmoduleIdtype->PointerCount()));
617     }
618 };
619 
620 PointerCountIntrinsicFunction::PointerCountIntrinsicFunction() : IntrinsicFunction()
621 {
622 }
623 
624 class ArrayLengthIntrinsicFunction public IntrinsicFunction
625 {
626 public:
627     ArrayLengthIntrinsicFunction();
628     int Arity() const override { return 0; }
629     int NumberOfTypeParameters() const override { return 1; }
630     TypeSymbol* ReturnType(SymbolTable& symbolTable) const override { return symbolTable.GetTypeByName(U"long"); }
631     const char* GroupName() const override { return "ArrayLength"; }
632     std::std::unique_ptr<Value>DoEvaluate(conststd::std::vector<std::std::unique_ptr<Value>>&argumentsconststd::std::vector<TypeSymbol*>&templateArgumentsconstSpan&spanconstboost::uuids::uuid&moduleId) override
633     {
634         TypeSymbol* type = templateArguments.front();
635         if (type->IsArrayType())
636         {
637             ArrayTypeSymbol* arrayType = static_cast<ArrayTypeSymbol*>(type);
638             return std::unique_ptr<Value>(new LongValue(spanmoduleIdarrayType->Size()));
639         }
640         return std::unique_ptr<Value>(new LongValue(spanmoduleId0));
641     }
642 };
643 
644 ArrayLengthIntrinsicFunction::ArrayLengthIntrinsicFunction() : IntrinsicFunction()
645 {
646 }
647 
648 void MetaInit(SymbolTable& symbolTable)
649 {
650     symbolTable.BeginNamespace(U"System.Meta"Span()boost::uuids::nil_uuid());
651     symbolTable.Container()->AddMember(CreateIntrinsic(new IsIntegralTypePredicate()symbolTablesymbolTable.Container()));
652     symbolTable.Container()->AddMember(CreateIntrinsic(new IsSignedTypePredicate()symbolTablesymbolTable.Container()));
653     symbolTable.Container()->AddMember(CreateIntrinsic(new IsUnsignedTypePredicate()symbolTablesymbolTable.Container()));
654     symbolTable.Container()->AddMember(CreateIntrinsic(new IsFloatingPointTypePredicate()symbolTablesymbolTable.Container()));
655     symbolTable.Container()->AddMember(CreateIntrinsic(new IsBasicTypePredicate()symbolTablesymbolTable.Container()));
656     symbolTable.Container()->AddMember(CreateIntrinsic(new IsBoolTypePredicate()symbolTablesymbolTable.Container()));
657     symbolTable.Container()->AddMember(CreateIntrinsic(new IsSByteTypePredicate()symbolTablesymbolTable.Container()));
658     symbolTable.Container()->AddMember(CreateIntrinsic(new IsByteTypePredicate()symbolTablesymbolTable.Container()));
659     symbolTable.Container()->AddMember(CreateIntrinsic(new IsShortTypePredicate()symbolTablesymbolTable.Container()));
660     symbolTable.Container()->AddMember(CreateIntrinsic(new IsUShortTypePredicate()symbolTablesymbolTable.Container()));
661     symbolTable.Container()->AddMember(CreateIntrinsic(new IsIntTypePredicate()symbolTablesymbolTable.Container()));
662     symbolTable.Container()->AddMember(CreateIntrinsic(new IsUIntTypePredicate()symbolTablesymbolTable.Container()));
663     symbolTable.Container()->AddMember(CreateIntrinsic(new IsLongTypePredicate()symbolTablesymbolTable.Container()));
664     symbolTable.Container()->AddMember(CreateIntrinsic(new IsULongTypePredicate()symbolTablesymbolTable.Container()));
665     symbolTable.Container()->AddMember(CreateIntrinsic(new IsFloatTypePredicate()symbolTablesymbolTable.Container()));
666     symbolTable.Container()->AddMember(CreateIntrinsic(new IsDoubleTypePredicate()symbolTablesymbolTable.Container()));
667     symbolTable.Container()->AddMember(CreateIntrinsic(new IsCharTypePredicate()symbolTablesymbolTable.Container()));
668     symbolTable.Container()->AddMember(CreateIntrinsic(new IsWCharTypePredicate()symbolTablesymbolTable.Container()));
669     symbolTable.Container()->AddMember(CreateIntrinsic(new IsUCharTypePredicate()symbolTablesymbolTable.Container()));
670     symbolTable.Container()->AddMember(CreateIntrinsic(new IsVoidTypePredicate()symbolTablesymbolTable.Container()));
671     symbolTable.Container()->AddMember(CreateIntrinsic(new IsClassTypePredicate()symbolTablesymbolTable.Container()));
672     symbolTable.Container()->AddMember(CreateIntrinsic(new IsPolymorphicTypePredicate()symbolTablesymbolTable.Container()));
673     symbolTable.Container()->AddMember(CreateIntrinsic(new IsInterfaceTypePredicate()symbolTablesymbolTable.Container()));
674     symbolTable.Container()->AddMember(CreateIntrinsic(new IsDelegateTypePredicate()symbolTablesymbolTable.Container()));
675     symbolTable.Container()->AddMember(CreateIntrinsic(new IsClassDelegateTypePredicate()symbolTablesymbolTable.Container()));
676     symbolTable.Container()->AddMember(CreateIntrinsic(new IsEnumeratedTypePredicate()symbolTablesymbolTable.Container()));
677     symbolTable.Container()->AddMember(CreateIntrinsic(new IsConstTypePredicate()symbolTablesymbolTable.Container()));
678     symbolTable.Container()->AddMember(CreateIntrinsic(new IsReferenceTypePredicate()symbolTablesymbolTable.Container()));
679     symbolTable.Container()->AddMember(CreateIntrinsic(new IsLvalueReferenceTypePredicate()symbolTablesymbolTable.Container()));
680     symbolTable.Container()->AddMember(CreateIntrinsic(new IsRvalueReferenceTypePredicate()symbolTablesymbolTable.Container()));
681     symbolTable.Container()->AddMember(CreateIntrinsic(new IsArrayTypePredicate()symbolTablesymbolTable.Container()));
682     symbolTable.Container()->AddMember(CreateIntrinsic(new IsPointerTypePredicate()symbolTablesymbolTable.Container()));
683     symbolTable.Container()->AddMember(CreateIntrinsic(new IsGenericPtrTypePredicate()symbolTablesymbolTable.Container()));
684     symbolTable.Container()->AddMember(CreateIntrinsic(new PointerCountIntrinsicFunction()symbolTablesymbolTable.Container()));
685     symbolTable.Container()->AddMember(CreateIntrinsic(new ArrayLengthIntrinsicFunction()symbolTablesymbolTable.Container()));
686     symbolTable.EndNamespace();
687 }
688 
689 } } // namespace cmajor::symbols