13 TypeInfo typeType(const Program & p, Type t)
\r
16 result.isStruct = true;
\r
17 if (t.name == "int" || t.name == "float" || t.name == "double" ||
\r
18 t.name == "char" || t.name == "long" || t.name == "short" || t.name == "bool")
\r
20 result.isStruct = false;
\r
26 TypeInfo typeExpr(const Program & p, const std::vector<string> & globalNamespace, Expr e)
\r
32 case ExprType::Func:
\r
34 auto namespacePrefixes = globalNamespace;
\r
35 namespacePrefixes.insert(namespacePrefixes.end(),
\r
36 e._func.namespacePrefixes.begin(),
\r
37 e._func.namespacePrefixes.end());
\r
38 auto f = findFunction(p, e._func.functionName, namespacePrefixes);
\r
40 throw "Unknown function";
\r
41 result = typeType(p, f.value().returnType);
\r
44 case ExprType::Method:
\r
46 TypeInfo tiCaller = typeExpr(p, globalNamespace, *e._method.expr);
\r
47 auto m = findStructMethod(p, e._method.methodName, tiCaller);
\r
49 throw "Unknown method";
\r
50 result = typeType(p, m.value().returnType);
\r
54 result.isStruct = false;
\r
55 switch (e._lit.type)
\r
57 case LitType::Bool: result.type.name = "bool"; break;
\r
58 case LitType::Int: result.type.name = "int"; break;
\r
59 case LitType::Decimal: result.type.name = "double"; break;
\r
60 case LitType::String: result.type.name = "char"; result.type.modifiers.push_back({ TypeModifierType::Pointer, false, -1 }); break;
\r
63 case ExprType::Paren:
\r
64 result = typeExpr(p, globalNamespace, *e._paren.expr);
\r
68 auto sm = findStructMember(p,
\r
69 typeExpr(p, globalNamespace, *e._dot.expr), e._dot.identifier);
\r
70 if (!sm.has_value())
\r
71 throw "Unknown struct member";
\r
72 result = typeType(p, sm.value().type);
\r
75 case ExprType::PrefixOp:
\r
76 result = typeExpr(p, globalNamespace, *e._prefixOp.expr);
\r
78 case ExprType::PostfixOp:
\r
79 result = typeExpr(p, globalNamespace, *e._postfixOp.expr);
\r
81 case ExprType::BinaryOp:
\r
82 result = typeExpr(p, globalNamespace, *e._binaryOp.lexpr);
\r
84 case ExprType::TernaryOp:
\r
85 result = typeExpr(p, globalNamespace, *e._ternaryOp.rexprTrue);
\r
87 case ExprType::Bracket:
\r
89 TypeInfo ti = typeExpr(p, globalNamespace, *e._brackets.lexpr);
\r
90 if (!ti.type.modifiers.empty())
\r
93 result.type.modifiers.pop_back();
\r
97 throw "Indexing non-array";
\r
100 case ExprType::Identifier:
\r
102 auto namespacePrefixes = globalNamespace;
\r
103 namespacePrefixes.insert(namespacePrefixes.end(),
\r
104 e._identifier.namespacePrefixes.begin(),
\r
105 e._identifier.namespacePrefixes.end());
\r
106 auto v = findVariable(p, e._identifier.identifier, namespacePrefixes);
\r
107 if (!v.has_value())
\r
108 throw "Unknown variable";
\r
109 result = typeType(p, v.value().type);
\r