\r
#include "find.h"\r
\r
-TypeInfo typeType(const Program & p, Type t)\r
+TypeInfo typeType(std::shared_ptr<Context> globalCtx, Type t)\r
{\r
+ // used to differentiate basic types from user defined types\r
TypeInfo result;\r
result.isStruct = true;\r
if (t.name == "int" || t.name == "float" || t.name == "double" ||\r
- t.name == "char" || t.name == "long" || t.name == "short" || t.name == "bool")\r
+ t.name == "char" || t.name == "long" || t.name == "short" || t.name == "bool" ||\r
+ t.name == "void")\r
{\r
result.isStruct = false;\r
}\r
result.type = t;\r
+\r
return result;\r
}\r
\r
-TypeInfo typeExpr(const Program & p, const std::vector<std::string> & globalNamespace, std::shared_ptr<Context> globalCtx, Expr e)\r
+TypeInfo typeExpr(std::shared_ptr<Context> globalCtx, Expr e)\r
{\r
TypeInfo result;\r
\r
{\r
case ExprType::Func:\r
{\r
- auto namespacePrefixes = globalNamespace;\r
- namespacePrefixes.insert(namespacePrefixes.end(),\r
- e._func.namespacePrefixes.begin(),\r
- e._func.namespacePrefixes.end());\r
- auto f = findFunction(p, e._func.functionName, namespacePrefixes);\r
+ // get type info from return type\r
+ auto f = findFunction(e._func.functionName, e._func.namespacePrefixes, globalCtx);\r
if (!f.has_value())\r
throw "Unknown function";\r
- result = typeType(p, f.value().returnType);\r
+ result = typeType(globalCtx, std::get<0>(*f).returnType);\r
break;\r
}\r
case ExprType::Method:\r
{\r
- TypeInfo tiCaller = typeExpr(p, globalNamespace, globalCtx, *e._method.expr);\r
- auto m = findStructMethod(p, e._method.methodName, tiCaller);\r
+ // get type info from return type\r
+ TypeInfo tiCaller = typeExpr(globalCtx, *e._method.expr);\r
+ if (!tiCaller.isStruct)\r
+ throw "Calling method on non-struct";\r
+ auto s = findStruct(tiCaller.type.name, tiCaller.type.namespacePrefixes, globalCtx);\r
+ if (!s.has_value())\r
+ throw "Calling method on unknown struct";\r
+ auto m = findStructMethod(e._method.methodName, std::get<0>(*s));\r
if (!m.has_value())\r
throw "Unknown method";\r
- result = typeType(p, m.value().returnType);\r
+ result = typeType(globalCtx, m->t.returnType);\r
break;\r
}\r
case ExprType::Lit:\r
+ // literal types are defined\r
result.isStruct = false;\r
switch (e._lit.type)\r
{\r
}\r
break;\r
case ExprType::Paren:\r
- result = typeExpr(p, globalNamespace, globalCtx, *e._paren.expr);\r
+ result = typeExpr(globalCtx, *e._paren.expr);\r
break;\r
case ExprType::Dot:\r
{\r
- auto sm = findStructMember(p,\r
- typeExpr(p, globalNamespace, globalCtx, *e._dot.expr), e._dot.identifier);\r
+ // assume dot access is always member access\r
+ // and lookup struct variable\r
+ auto tiCaller = typeExpr(globalCtx, *e._dot.expr);\r
+ if (!tiCaller.isStruct)\r
+ throw "Accessing member of non-struct";\r
+ auto s = findStruct(tiCaller.type.name, tiCaller.type.namespacePrefixes, globalCtx);\r
+ if (!s.has_value())\r
+ throw "Calling method on unknown struct";\r
+ auto sm = findStructMember(e._dot.identifier, std::get<0>(*s));\r
if (!sm.has_value())\r
throw "Unknown struct member";\r
- result = typeType(p, sm.value().type);\r
+ result = typeType(globalCtx, sm->t.type);\r
break;\r
}\r
case ExprType::PrefixOp:\r
- result = typeExpr(p, globalNamespace, globalCtx, *e._prefixOp.expr);\r
+ result = typeExpr(globalCtx, *e._prefixOp.expr);\r
break;\r
case ExprType::PostfixOp:\r
- result = typeExpr(p, globalNamespace, globalCtx, *e._postfixOp.expr);\r
+ result = typeExpr(globalCtx, *e._postfixOp.expr);\r
break;\r
case ExprType::BinaryOp:\r
- result = typeExpr(p, globalNamespace, globalCtx, *e._binaryOp.lexpr);\r
+ result = typeExpr(globalCtx, *e._binaryOp.lexpr);\r
break;\r
case ExprType::TernaryOp:\r
- result = typeExpr(p, globalNamespace, globalCtx, *e._ternaryOp.rexprTrue);\r
+ result = typeExpr(globalCtx, *e._ternaryOp.rexprTrue);\r
break;\r
case ExprType::Bracket:\r
{\r
- TypeInfo ti = typeExpr(p, globalNamespace, globalCtx, *e._brackets.lexpr);\r
+ // get type of expr and remove array/ptr modifier to get\r
+ // type of [] access\r
+ TypeInfo ti = typeExpr(globalCtx, *e._brackets.lexpr);\r
if (!ti.type.modifiers.empty())\r
{\r
result = ti;\r
}\r
case ExprType::Identifier:\r
{\r
- auto namespacePrefixes = globalNamespace;\r
- namespacePrefixes.insert(namespacePrefixes.end(),\r
- e._identifier.namespacePrefixes.begin(),\r
- e._identifier.namespacePrefixes.end());\r
- auto v = findVariable(p, e._identifier.identifier, globalCtx);\r
+ // var lookup and return var type\r
+ auto v = findVariable(e._identifier.identifier, e._identifier.namespacePrefixes, globalCtx);\r
if (!v.has_value())\r
throw "Unknown variable";\r
- result = typeType(p, v.value().type);\r
+ result = typeType(globalCtx, std::get<0>(*v).type);\r
break;\r
}\r
}\r