#include <sstream>\r
\r
#include "repr.h"\r
+#include "generic.h"\r
#include "typeInfo.h"\r
\r
template<typename T>\r
return sstr.str();\r
}\r
\r
+static std::map<std::string, Type> currentInstantiation;\r
+\r
static Program globalPrg;\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
- out << vectorStr(t.namespacePrefixes, "_", true) << t.name;\r
+ for (auto kv : currentInstantiation)\r
+ {\r
+ if (t.name == kv.first)\r
+ {\r
+ out << kv.second;\r
+ return out;\r
+ }\r
+ }\r
+ TypeInfo ti = typeType(globalCtx, t);\r
+ if (ti.isStruct)\r
+ out << "struct ";\r
+ auto s = findStruct(t.name, t.namespacePrefixes, globalCtx);\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
+ if (!t.genericInstantiation.empty())\r
+ out << genericAppendix(t.genericInstantiation);\r
\r
return out;\r
}\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
{\r
}\r
std::ostream & operator<< (std::ostream & out, const Body & b)\r
{\r
+ b.ctx->parent = globalCtx;\r
+ globalCtx = b.ctx;\r
+\r
indent(out);\r
out << "{\n";\r
indentation += 2;\r
indent(out, -2);\r
out << "}\n";\r
\r
+ globalCtx = b.ctx->parent;\r
+\r
return out;\r
}\r
std::ostream & operator<< (std::ostream & out, const Expr & e)\r
switch (e.type)\r
{\r
case ExprType::Func:\r
- out << vectorStr(e._func.namespacePrefixes, "_", true) << e._func.functionName << "(" << vectorStr(e._func.arguments, ", ") << ")"; break;\r
+ {\r
+ auto f = findFunction(e._func.functionName, e._func.namespacePrefixes, globalCtx);\r
+\r
+ if (std::get<0>(*f).defined)\r
+ out << vectorStr(std::get<1>(*f), "_", true);\r
+\r
+ out << e._func.functionName;\r
+ if (!e._func.genericInstantiation.empty())\r
+ out << genericAppendix(e._func.genericInstantiation);\r
+ out <<"(" << vectorStr(e._func.arguments, ", ") << ")"; break;\r
+ }\r
case ExprType::Method:\r
{\r
- TypeInfo ti = typeExpr(globalPrg, namespaces, *e._method.expr);\r
+ TypeInfo ti = typeExpr(globalCtx, *e._method.expr);\r
out <<\r
vectorStr(ti.type.namespacePrefixes, "_", true) <<\r
- ti.type.name << "_" << e._method.methodName << "(" << *e._method.expr << vectorStr(e._method.arguments, ", ") << ")"; break;\r
+ ti.type.name << genericAppendix(ti.type.genericInstantiation) << "_" << e._method.methodName;\r
+ if (!e._method.genericInstantiation.empty())\r
+ out << genericAppendix(e._method.genericInstantiation);\r
+ out << "(";\r
+ if (e._method.expr->type == ExprType::Identifier)\r
+ out << "&";\r
+ out << *e._method.expr << (e._method.arguments.empty() ? "" : ", ") <<\r
+ vectorStr(e._method.arguments, ", ") << ")"; break;\r
}\r
case ExprType::Lit:\r
/**/ if (e._lit.type == LitType::Int) out << e._lit._int;\r
else if (e._lit.type == LitType::Bool) out << e._lit._bool;\r
break;\r
case ExprType::Paren:\r
- out << "(" << e._paren.expr << ")"; break;\r
+ out << "(" << *e._paren.expr << ")"; break;\r
case ExprType::Dot:\r
- out << *e._dot.expr << "." << e._dot.identifier; break;\r
+ out << *e._dot.expr << (e._dot.isPointer ? "->" : ".") << e._dot.identifier; break;\r
case ExprType::PrefixOp:\r
out << PrefixOperatorTypeStrings[(int)e._prefixOp.type] << *e._prefixOp.expr; break;\r
case ExprType::PostfixOp:\r
case ExprType::Bracket:\r
out << *e._brackets.lexpr << "[" << *e._brackets.rexpr << "]"; break;\r
case ExprType::Identifier:\r
- out << vectorStr(e._identifier.namespacePrefixes, "_", true) << e._identifier.identifier; break;\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
+ else\r
+ out << vectorStr(e._identifier.namespacePrefixes, "_", true);\r
+\r
+ out << e._identifier.identifier; break;\r
}\r
\r
return out;\r
\r
void tocFunction (std::ostream & out, const Function & f, bool stub)\r
{\r
- out << f.returnType << " " << namespacePrefix() << f.name << " (" << vectorStr(f.parameters, ", ") << ")";\r
+ if (!stub && !f.defined) return;\r
\r
- if (stub)\r
+ if (f.genericTypeNames.empty())\r
{\r
- out << ";\n";\r
+ out << f.returnType << " " << namespacePrefix() << f.name << " (" << vectorStr(f.parameters, ", ") << ")";\r
+\r
+ if (stub)\r
+ {\r
+ out << ";\n";\r
+ }\r
+ else\r
+ {\r
+ out << "\n" << f.body;\r
+ }\r
}\r
else\r
{\r
- out << "\n" << f.body;\r
+ for (auto instantiation : f.genericInstantiations)\r
+ {\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
+\r
+ if (stub)\r
+ {\r
+ out << ";\n";\r
+ }\r
+ else\r
+ {\r
+ out << "\n" << f.body;\r
+ }\r
+\r
+ currentInstantiation.clear();\r
+ }\r
}\r
}\r
void tocStruct (std::ostream & out, const Struct & s, bool stub)\r
{\r
- out << "struct " << namespacePrefix() << s.name;\r
- if (stub)\r
+ if (s.genericTypeNames.empty())\r
{\r
- out << ";\n";\r
+ out << "struct " << namespacePrefix() << s.name;\r
+ if (stub)\r
+ {\r
+ out << ";\n";\r
+ for (auto m : s.methods)\r
+ {\r
+ Function f = m;\r
+\r
+ f.parameters.insert(f.parameters.begin(),\r
+ {"this",\r
+ {\r
+ namespaces,\r
+ s.name,\r
+ {\r
+ {TypeModifierType::Pointer, false, -1}\r
+ }\r
+ }\r
+ });\r
+ out << f.returnType << " " <<\r
+ namespacePrefix() << s.name << "_" << f.name <<\r
+ " (" << vectorStr(f.parameters, ", ") << ");\n";\r
+ }\r
+ return;\r
+ }\r
+ out << "\n{\n";\r
+ indentation += 2;\r
+\r
+ for (auto m : s.members)\r
+ {\r
+ indent(out);\r
+ out << m << ";\n";\r
+ }\r
+\r
+ indent(out, -2);\r
+ out << "};\n";\r
+ \r
for (auto m : s.methods)\r
{\r
Function f = m;\r
-\r
f.parameters.insert(f.parameters.begin(),\r
- {"this",\r
- {\r
- namespaces,\r
- s.name,\r
+ {"this",\r
{\r
- {TypeModifierType::Pointer, false, -1}\r
+ namespaces,\r
+ s.name,\r
+ {\r
+ {TypeModifierType::Pointer, false, -1}\r
+ }\r
}\r
- }\r
- });\r
+ });\r
out << f.returnType << " " <<\r
- namespacePrefix() << s.name << "_" << f.name <<\r
- " (" << vectorStr(f.parameters, ", ") << ");\n";\r
+ namespacePrefix() << s.name << "_" << f.name <<\r
+ " (" << vectorStr(f.parameters, ", ") << ")\n" << f.body;\r
}\r
- return;\r
}\r
- out << "\n{\n";\r
- indentation += 2;\r
-\r
- for (auto m : s.members)\r
+ else\r
{\r
- indent(out);\r
- out << m << ";\n";\r
- }\r
+ for (auto instantiation : s.genericInstantiations)\r
+ {\r
+ for (int i = 0; i < s.genericTypeNames.size(); i++)\r
+ {\r
+ currentInstantiation[s.genericTypeNames[i]] = instantiation[i];\r
+ }\r
\r
- indent(out, -2);\r
- out << "};\n";\r
- \r
- for (auto m : s.methods)\r
- {\r
- Function f = m;\r
- f.parameters.insert(f.parameters.begin(),\r
- {"this",\r
+ out << "struct " << namespacePrefix() << s.name << genericAppendix(instantiation);\r
+ if (stub)\r
+ {\r
+ out << ";\n";\r
+ for (auto m : s.methods)\r
{\r
- namespaces,\r
- s.name,\r
- {\r
- {TypeModifierType::Pointer, false, -1}\r
- }\r
+ Function f = m;\r
+\r
+ f.parameters.insert(f.parameters.begin(),\r
+ {"this",\r
+ {\r
+ namespaces,\r
+ s.name + genericAppendix(instantiation),\r
+ {\r
+ {TypeModifierType::Pointer, false, -1}\r
+ }\r
+ }\r
+ });\r
+ out << f.returnType << " " <<\r
+ namespacePrefix() << s.name << genericAppendix(instantiation) << "_" << f.name <<\r
+ " (" << vectorStr(f.parameters, ", ") << ");\n";\r
}\r
- });\r
- out << f.returnType << " " <<\r
- namespacePrefix() << s.name << "_" << f.name <<\r
- " (" << vectorStr(f.parameters, ", ") << ")\n" << f.body;\r
+ return;\r
+ }\r
+ out << "\n{\n";\r
+ indentation += 2;\r
+\r
+ for (auto m : s.members)\r
+ {\r
+ indent(out);\r
+ out << m << ";\n";\r
+ }\r
+\r
+ indent(out, -2);\r
+ out << "};\n";\r
+ \r
+ for (auto m : s.methods)\r
+ {\r
+ Function f = m;\r
+ f.parameters.insert(f.parameters.begin(),\r
+ {"this",\r
+ {\r
+ namespaces,\r
+ s.name + genericAppendix(instantiation),\r
+ {\r
+ {TypeModifierType::Pointer, false, -1}\r
+ }\r
+ }\r
+ });\r
+ out << f.returnType << " " <<\r
+ namespacePrefix() << s.name << genericAppendix(instantiation) << "_" << f.name <<\r
+ " (" << vectorStr(f.parameters, ", ") << ")\n" << f.body;\r
+ }\r
+\r
+ currentInstantiation.clear();\r
+ }\r
}\r
}\r
void tocProgram (std::ostream & out, const Program & p)\r
{\r
+ globalCtx = p.ctx;\r
+\r
globalPrg = p;\r
- for (auto n : p.namespaces)\r
+ for (auto n : p.ctx->namespaces)\r
{\r
tocNamespace(out, n, true);\r
}\r
- for (auto s : p.structs)\r
+ out << "\n\n";\r
+ for (auto s : p.ctx->structs)\r
{\r
tocStruct(out, s, true);\r
}\r
- for (auto f : p.functions)\r
+ out << "\n\n";\r
+ for (auto f : p.ctx->functions)\r
{\r
tocFunction(out, f, true);\r
}\r
+ out << "\n\n";\r
\r
for (auto v : p.ctx->variables)\r
{\r
out << v << ";\n";\r
}\r
- for (auto n : p.namespaces)\r
+ out << "\n\n";\r
+ for (auto n : p.ctx->namespaces)\r
{\r
tocNamespace(out, n, false);\r
}\r
- for (auto s : p.structs)\r
+ out << "\n\n";\r
+ for (auto s : p.ctx->structs)\r
{\r
tocStruct(out, s, false);\r
}\r
- for (auto f : p.functions)\r
+ out << "\n\n";\r
+ for (auto f : p.ctx->functions)\r
{\r
tocFunction(out, f, false);\r
}\r
+ out << "\n\n";\r
}\r
\r
\r
void tocNamespace (std::ostream & out, const Namespace & n, bool stub)\r
{\r
+ n.ctx->parent = globalCtx;\r
+ globalCtx = n.ctx;\r
+\r
namespaces.push_back(n.name);\r
if (!stub)\r
{\r
{\r
out << v << ";\n";\r
}\r
+ out << "\n\n";\r
}\r
- for (auto n : n.namespaces)\r
+ for (auto n : n.ctx->namespaces)\r
{\r
tocNamespace(out, n, stub);\r
+ out << "\n\n";\r
}\r
- for (auto s : n.structs)\r
+ for (auto s : n.ctx->structs)\r
{\r
tocStruct(out, s, stub);\r
+ out << "\n\n";\r
}\r
- for (auto f : n.functions)\r
+ for (auto f : n.ctx->functions)\r
{\r
tocFunction(out, f, stub);\r
+ out << "\n\n";\r
}\r
namespaces.pop_back();\r
+\r
+ globalCtx = n.ctx->parent;\r
}
\ No newline at end of file