]> gitweb.ps.run Git - toc/blobdiff - src/toc.h
fixed NAME grammar rule
[toc] / src / toc.h
index 43ab1bad3831c508f50cf83868003b342d8860e8..e95ab3eca27872b427846614e33c7ba0fd2d93e5 100644 (file)
--- a/src/toc.h
+++ b/src/toc.h
@@ -4,6 +4,7 @@
 #include <sstream>\r
 \r
 #include "repr.h"\r
+#include "generic.h"\r
 #include "typeInfo.h"\r
 \r
 template<typename T>\r
@@ -53,11 +54,46 @@ static std::string namespacePrefix() {
   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
@@ -67,6 +103,10 @@ std::ostream & operator<< (std::ostream & out, const Variable & v)
 \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
@@ -92,6 +132,9 @@ std::ostream & operator<< (std::ostream & out, const Variable & v)
 }\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
@@ -113,6 +156,8 @@ std::ostream & operator<< (std::ostream & out, const Body & b)
   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
@@ -120,13 +165,30 @@ std::ostream & operator<< (std::ostream & out, const Expr & e)
   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
@@ -135,9 +197,9 @@ std::ostream & operator<< (std::ostream & out, const Expr & e)
     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
@@ -153,7 +215,13 @@ std::ostream & operator<< (std::ostream & out, const Expr & e)
   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
@@ -196,110 +264,219 @@ std::ostream & operator<< (std::ostream & out, const Stmt & s)
 \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
@@ -307,18 +484,24 @@ void tocNamespace  (std::ostream & out, const Namespace & n, bool stub)
     {\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