\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
{\r
case ExprType::Func:\r
{\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
}\r
case ExprType::Method:\r
{\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
break;\r
}\r
case ExprType::Lit:\r
+ // literal types are defined\r
result.isStruct = false;\r
switch (e._lit.type)\r
{\r
break;\r
case ExprType::Dot:\r
{\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
break;\r
case ExprType::Bracket:\r
{\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
}\r
case ExprType::Identifier:\r
{\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