#include "generic.h"\r
#include "typeInfo.h"\r
\r
+// print a generic vector with specified separator, optionally printing the separator at the end aswell\r
template<typename T>\r
std::string vectorStr (const std::vector<T> & v, const std::string & separator, bool end = false)\r
{\r
return sstr.str();\r
}\r
\r
+// mapping from generic typenames (which are just names)\r
+// to actual instantiated types\r
static std::map<std::string, Type> currentInstantiation;\r
\r
-static Program globalPrg;\r
+// set current context so that lookups can be made correctly\r
static std::shared_ptr<Context> globalCtx;\r
\r
\r
-\r
-// std::string getPrefix(std::shared_ptr<Context> ctx)\r
-// {\r
-// std::string result;\r
-// for (auto it = ctx; it != nullptr; it = it->parent)\r
-// {\r
-// if (it->name.has_value())\r
-// {\r
-// result = it->name.value() + "_" + result;\r
-// }\r
-// }\r
-// return result;\r
-// }\r
-\r
std::ostream & operator<< (std::ostream & out, const Type & t)\r
{\r
+ // if the typename equals one of the current generic instantiations\r
+ // print instantiated type instead\r
for (auto kv : currentInstantiation)\r
{\r
if (t.name == kv.first)\r
TypeInfo ti = typeType(globalCtx, t);\r
if (ti.isStruct)\r
out << "struct ";\r
+ // try finding type in current context\r
auto s = findStruct(t.name, t.namespacePrefixes, globalCtx);\r
+ // print prefix for either found type or the specified \r
+ // prefix if type is not found (shouldn't happen)\r
if (s.has_value())\r
out << vectorStr(std::get<1>(*s), "_", true) << t.name; \r
else\r
out << vectorStr(t.namespacePrefixes, "_", true) << t.name;\r
+\r
+ // print generic appendix\r
if (!t.genericInstantiation.empty())\r
out << genericAppendix(t.genericInstantiation);\r
\r
return out;\r
}\r
-std::ostream & operator<< (std::ostream & out, const Variable & v)\r
-{\r
- out << v.type << " ";\r
\r
+std::string generateModifiers (std::string s, std::vector<TypeModifier> modifiers)\r
+{\r
std::stringstream sstr;\r
- std::string s = v.name;\r
- \r
- auto var = findVariable(v.name, namespaces, globalCtx);\r
- if (var.has_value())\r
- s = vectorStr(std::get<1>(*var), "_", true) + s;\r
\r
- for (auto m = v.type.modifiers.rbegin(); m != v.type.modifiers.rend(); m++)\r
+ // apply modifiers, inverted because C defines them\r
+ // the opposite direction\r
+ for (auto m = modifiers.rbegin(); m != modifiers.rend(); m++)\r
{\r
if (m->type == TypeModifierType::Pointer)\r
{\r
s = sstr.str();\r
}\r
}\r
- out << s;\r
+\r
+ return s;\r
+}\r
+\r
+std::ostream & operator<< (std::ostream & out, const Variable & v)\r
+{\r
+ out << v.type << " ";\r
+\r
+ std::string s = v.name;\r
+ \r
+ // lookup variable and change name to reflect containing namespace\r
+ auto var = findVariable(v.name, namespaces, globalCtx);\r
+ if (var.has_value())\r
+ s = vectorStr(std::get<1>(*var), "_", true) + s;\r
+\r
+ // apply modifiers in C fashion\r
+ out << generateModifiers(s, v.type.modifiers);\r
\r
return out;\r
}\r
{\r
case ExprType::Func:\r
{\r
+ // print function call\r
auto f = findFunction(e._func.functionName, e._func.namespacePrefixes, globalCtx);\r
\r
if (std::get<0>(*f).defined)\r
}\r
case ExprType::Method:\r
{\r
+ // get TypeInfo on the Expression that the method is called on\r
+ // then print method call\r
TypeInfo ti = typeExpr(globalCtx, *e._method.expr);\r
out <<\r
vectorStr(ti.type.namespacePrefixes, "_", true) <<\r
case ExprType::Bracket:\r
out << *e._brackets.lexpr << "[" << *e._brackets.rexpr << "]"; break;\r
case ExprType::Identifier:\r
+ // try variable lookup\r
auto v = findVariable(e._identifier.identifier, e._identifier.namespacePrefixes, globalCtx);\r
if (v.has_value())\r
out << vectorStr(std::get<1>(*v), "_", true);\r
\r
void tocFunction (std::ostream & out, const Function & f, bool stub)\r
{\r
- if (!stub && !f.defined) return;\r
+ // for a function that is not defined, only the stub can be printed\r
+ if (!f.defined && !stub) return;\r
\r
+ // regular function\r
if (f.genericTypeNames.empty())\r
{\r
- out << f.returnType << " " << namespacePrefix() << f.name << " (" << vectorStr(f.parameters, ", ") << ")";\r
+ out << f.returnType << " " << generateModifiers(namespacePrefix() + f.name, f.returnType.modifiers) << " (" << vectorStr(f.parameters, ", ") << ")";\r
\r
if (stub)\r
{\r
out << "\n" << f.body;\r
}\r
}\r
+ // generic function\r
else\r
{\r
+ // print one instance per instantiation\r
for (auto instantiation : f.genericInstantiations)\r
{\r
+ // set global type mapping\r
for (int i = 0; i < f.genericTypeNames.size(); i++)\r
{\r
currentInstantiation[f.genericTypeNames[i]] = instantiation[i];\r
}\r
\r
- out << f.returnType << " " << namespacePrefix() << f.name << genericAppendix(instantiation) << " (" << vectorStr(f.parameters, ", ") << ")";\r
+ out << f.returnType << " " <<\r
+ generateModifiers(namespacePrefix() + f.name + genericAppendix(instantiation), f.returnType.modifiers) <<\r
+ " (" << vectorStr(f.parameters, ", ") << ")";\r
\r
if (stub)\r
{\r
}\r
void tocStruct (std::ostream & out, const Struct & s, bool stub)\r
{\r
+ // regular struct\r
if (s.genericTypeNames.empty())\r
{\r
out << "struct " << namespacePrefix() << s.name;\r
{\r
Function f = m;\r
\r
+ // add implicit this parameter\r
f.parameters.insert(f.parameters.begin(),\r
{"this",\r
{\r
}\r
});\r
out << f.returnType << " " <<\r
- namespacePrefix() << s.name << "_" << f.name <<\r
+ generateModifiers(namespacePrefix() + s.name + "_" + f.name, f.returnType.modifiers) <<\r
" (" << vectorStr(f.parameters, ", ") << ");\n";\r
}\r
return;\r
for (auto m : s.methods)\r
{\r
Function f = m;\r
+ \r
+ // add implicit this parameter\r
f.parameters.insert(f.parameters.begin(),\r
{"this",\r
{\r
}\r
});\r
out << f.returnType << " " <<\r
- namespacePrefix() << s.name << "_" << f.name <<\r
- " (" << vectorStr(f.parameters, ", ") << ")\n" << f.body;\r
+ generateModifiers(namespacePrefix() + s.name + "_" + f.name, f.returnType.modifiers) <<\r
+ " (" << vectorStr(f.parameters, ", ") << ")\n" << f.body;\r
}\r
}\r
+ // generic struct\r
else\r
{\r
for (auto instantiation : s.genericInstantiations)\r
{\r
Function f = m;\r
\r
+ // add implicit this parameter\r
f.parameters.insert(f.parameters.begin(),\r
{"this",\r
{\r
}\r
});\r
out << f.returnType << " " <<\r
- namespacePrefix() << s.name << genericAppendix(instantiation) << "_" << f.name <<\r
+ generateModifiers(namespacePrefix() + s.name + genericAppendix(instantiation) + "_" + f.name, f.returnType.modifiers) <<\r
" (" << vectorStr(f.parameters, ", ") << ");\n";\r
}\r
return;\r
for (auto m : s.methods)\r
{\r
Function f = m;\r
+ \r
+ // add implicit this parameter\r
f.parameters.insert(f.parameters.begin(),\r
{"this",\r
{\r
}\r
});\r
out << f.returnType << " " <<\r
- namespacePrefix() << s.name << genericAppendix(instantiation) << "_" << f.name <<\r
- " (" << vectorStr(f.parameters, ", ") << ")\n" << f.body;\r
+ generateModifiers(namespacePrefix() + s.name + genericAppendix(instantiation) + "_" + f.name, f.returnType.modifiers) <<\r
+ " (" << vectorStr(f.parameters, ", ") << ")\n" << f.body;\r
}\r
\r
currentInstantiation.clear();\r
{\r
globalCtx = p.ctx;\r
\r
- globalPrg = p;\r
for (auto n : p.ctx->namespaces)\r
{\r
tocNamespace(out, n, true);\r