]> gitweb.ps.run Git - toc/blob - src/typeInfo.h
function resolution, pre generics
[toc] / src / typeInfo.h
1 #pragma once\r
2 \r
3 #include "repr.h"\r
4 \r
5 struct TypeInfo\r
6 {\r
7   Type type;\r
8   bool isStruct;\r
9 };\r
10 \r
11 #include "find.h"\r
12 \r
13 TypeInfo typeType(const Program & p, Type t)\r
14 {\r
15   TypeInfo result;\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
19   {\r
20     result.isStruct = false;\r
21   }\r
22   result.type = t;\r
23   return result;\r
24 }\r
25 \r
26 TypeInfo typeExpr(const Program & p, const std::vector<std::string> & globalNamespace, std::shared_ptr<Context> globalCtx, Expr e)\r
27 {\r
28   TypeInfo result;\r
29 \r
30   switch (e.type)\r
31   {\r
32   case ExprType::Func:\r
33   {\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
39     if (!f.has_value())\r
40       throw "Unknown function";\r
41     result = typeType(p, f.value().returnType);\r
42     break;\r
43   }\r
44   case ExprType::Method:\r
45   {\r
46     TypeInfo tiCaller = typeExpr(p, globalNamespace, globalCtx, *e._method.expr);\r
47     auto m = findStructMethod(p, e._method.methodName, tiCaller);\r
48     if (!m.has_value())\r
49       throw "Unknown method";\r
50     result = typeType(p, m.value().returnType);\r
51     break;\r
52   }\r
53   case ExprType::Lit:\r
54     result.isStruct = false;\r
55     switch (e._lit.type)\r
56     {\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
61     }\r
62     break;\r
63   case ExprType::Paren:\r
64     result = typeExpr(p, globalNamespace, globalCtx, *e._paren.expr);\r
65     break;\r
66   case ExprType::Dot:\r
67   {\r
68     auto sm = findStructMember(p,\r
69         typeExpr(p, globalNamespace, globalCtx, *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
73     break;\r
74   }\r
75   case ExprType::PrefixOp:\r
76     result = typeExpr(p, globalNamespace, globalCtx, *e._prefixOp.expr);\r
77     break;\r
78   case ExprType::PostfixOp:\r
79     result = typeExpr(p, globalNamespace, globalCtx, *e._postfixOp.expr);\r
80     break;\r
81   case ExprType::BinaryOp:\r
82     result = typeExpr(p, globalNamespace, globalCtx, *e._binaryOp.lexpr);\r
83     break;\r
84   case ExprType::TernaryOp:\r
85     result = typeExpr(p, globalNamespace, globalCtx, *e._ternaryOp.rexprTrue);\r
86     break;\r
87   case ExprType::Bracket:\r
88   {\r
89     TypeInfo ti = typeExpr(p, globalNamespace, globalCtx, *e._brackets.lexpr);\r
90     if (!ti.type.modifiers.empty())\r
91     {\r
92       result = ti;\r
93       result.type.modifiers.pop_back();\r
94     }\r
95     else\r
96     {\r
97       throw "Indexing non-array";\r
98     }\r
99   }\r
100   case ExprType::Identifier:\r
101   {\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, globalCtx);\r
107     if (!v.has_value())\r
108       throw "Unknown variable";\r
109     result = typeType(p, v.value().type);\r
110     break;\r
111   }\r
112   }\r
113 \r
114   return result;\r
115 }