diff options
| author | Patrick Schönberger | 2021-08-12 09:26:17 +0200 |
|---|---|---|
| committer | Patrick Schönberger | 2021-08-12 09:26:17 +0200 |
| commit | c4231c6faf4e1b4650b075c641b0bb8c053739e4 (patch) | |
| tree | f6072f412383d29d2aac32fea8cb578ec9247063 /src | |
| parent | e8e6aebbb892a72b287f1378901f855246da15a2 (diff) | |
| download | toc-c4231c6faf4e1b4650b075c641b0bb8c053739e4.tar.gz toc-c4231c6faf4e1b4650b075c641b0bb8c053739e4.zip | |
add generic.h (how did i miss that...)
Diffstat (limited to 'src')
| -rw-r--r-- | src/generic.h | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/generic.h b/src/generic.h new file mode 100644 index 0000000..df203b3 --- /dev/null +++ b/src/generic.h @@ -0,0 +1,101 @@ +#pragma once
+
+#include "repr.h"
+#include "typeInfo.h"
+#include "visit.h"
+
+void addGenericInstantiation(
+ std::vector<std::vector<Type>> & insts,
+ const std::vector<Type> & newInst)
+{
+ if (insts.empty())
+ {
+ insts.push_back(newInst);
+ return;
+ }
+ for (auto inst : insts)
+ {
+ for (int i = 0; i < inst.size(); i++)
+ {
+ if (inst[i] != newInst[i])
+ {
+ insts.push_back(newInst);
+ return;
+ }
+ }
+ }
+}
+
+Program instantiateGenerics(const Program & p)
+{
+ Program result = p;
+
+ // Find generic instantiations
+
+ Visitor findGenericInstantiations;
+ findGenericInstantiations.onExpr =
+ [&](const Expr & e, const std::shared_ptr<Context> ctx)
+ {
+ if (e.type == ExprType::Func && !e._func.genericInstantiation.empty())
+ {
+ auto f = findFunctionPtr(e._func.functionName, e._func.namespacePrefixes, ctx);
+ if (f.has_value())
+ {
+ if (std::get<0>(*f)->genericTypeNames.empty())
+ throw "Trying to instantiate non-generic function";
+ if (e._func.genericInstantiation.size() != std::get<0>(*f)->genericTypeNames.size())
+ throw "Trying to instantiate function with wrong number of types";
+ addGenericInstantiation(std::get<0>(*f)->genericInstantiations, e._func.genericInstantiation);
+ }
+ }
+ // TODO: generic methods
+ };
+ findGenericInstantiations.onType =
+ [&](const Type & t, const std::shared_ptr<Context> ctx)
+ {
+ if (!t.genericInstantiation.empty())
+ {
+ auto s = findStructPtr(t.name, t.namespacePrefixes, ctx);
+ if (s.has_value())
+ {
+ if (std::get<0>(*s)->genericTypeNames.empty())
+ throw "Trying to instantiate non-generic struct";
+ if (t.genericInstantiation.size() != std::get<0>(*s)->genericTypeNames.size())
+ throw "Trying to instantiate struct with wrong number of types";
+ addGenericInstantiation(std::get<0>(*s)->genericInstantiations, t.genericInstantiation);
+ }
+ }
+ };
+ Visit v(findGenericInstantiations);
+ v.visit(result);
+
+ return result;
+}
+
+std::string genericAppendix(const std::vector<Type> & ts)
+{
+ std::stringstream sstr;
+ for (auto t : ts)
+ {
+ sstr << "_";
+ sstr << t.name;
+ for (auto m : t.modifiers)
+ {
+ if (m.type == TypeModifierType::Array)
+ {
+ sstr << "_arr";
+ if (m._staticArray)
+ sstr << m._arraySize;
+ }
+ else if (m.type == TypeModifierType::Pointer)
+ {
+ sstr << "_ptr";
+ }
+ }
+ if (!t.genericInstantiation.empty())
+ {
+ sstr << genericAppendix(t.genericInstantiation);
+ }
+ }
+ return sstr.str();
+}
\ No newline at end of file |
