From 9610ce88f0b753db81014a053bd3c6d79471c90c Mon Sep 17 00:00:00 2001 From: Patrick Schönberger Date: Wed, 11 Aug 2021 23:34:11 +0200 Subject: add comments, fix struct/function lookup --- src/find.h | 104 +++++++++++++++++++++++++++++++++++++++------------------ src/main.cpp | 2 ++ src/repr.h | 18 ++++++++-- src/repr_get.h | 5 +-- src/toc.h | 57 ++++++++++++++++++++++--------- src/typeInfo.h | 40 +++++++++------------- src/visit.h | 4 +-- 7 files changed, 152 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/find.h b/src/find.h index ea3ae22..3342536 100644 --- a/src/find.h +++ b/src/find.h @@ -27,98 +27,136 @@ opt findPtr(const std::vector & ts, std::function f) return nullopt; } -bool checkNamespace(std::shared_ptr ctx, const std::vector & namespacePrefix) +std::optional< + std::tuple< + std::shared_ptr, + std::vector>> +getContext(std::shared_ptr ctx, const std::vector & namespacePrefix) { - - bool prefixMatches = true; + auto result = ctx; - auto nIt = ctx; - for (int i = namespacePrefix.size() - 1; i >= 0; i--) + for (auto name : namespacePrefix) + { + auto newResult = find(result->namespaces, [&](Namespace n) { return n.name == name; }); + if (newResult.has_value()) + { + result = newResult->ctx; + } + else { - const std::string & prefix = namespacePrefix[i]; - if (nIt == nullptr || ! nIt->name.has_value() || nIt->name.value() != prefix) - { - prefixMatches = false; - break; - } - nIt = nIt->parent; + return nullopt; } + } + + std::vector namespaces; + for (auto it = result; it != nullptr; it = it->parent) + { + if (it->name.has_value()) + { + namespaces.insert(namespaces.begin(), it->name.value()); + } + else if (it->parent != nullptr) + { + namespaces.clear(); + break; + } + } - return prefixMatches; + return std::make_tuple(result, namespaces); } -opt findFunction( +opt>> findFunction( const std::string & name, const std::vector & namespacePrefix, std::shared_ptr ctx) { for (auto it = ctx; it != nullptr; it = it->parent) { - auto f = find(it->functions, [&](Function f) { return f.name == name; }); - if (f.has_value() && checkNamespace(it, namespacePrefix)) - return f; + auto n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = find(std::get<0>(*n)->functions, [&](Function _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } return nullopt; } -opt findFunctionPtr( +opt>> findFunctionPtr( const std::string & name, const std::vector & namespacePrefix, std::shared_ptr ctx) { for (auto it = ctx; it != nullptr; it = it->parent) { - auto f = findPtr(it->functions, [&](Function f) { return f.name == name; }); - if (f.has_value() && checkNamespace(it, namespacePrefix)) - return f; + auto n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = findPtr(std::get<0>(*n)->functions, [&](Function _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } return nullopt; } -opt findStruct( +opt>> findStruct( const std::string & name, const std::vector & namespacePrefix, std::shared_ptr ctx) { for (auto it = ctx; it != nullptr; it = it->parent) { - auto s = find(it->structs, [&](Struct s) { return s.name == name; }); - if (s.has_value() && checkNamespace(it, namespacePrefix)) - return s; + auto n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = find(std::get<0>(*n)->structs, [&](Struct _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } return nullopt; } -opt findStructPtr( +opt>> findStructPtr( const std::string & name, const std::vector & namespacePrefix, std::shared_ptr ctx) { for (auto it = ctx; it != nullptr; it = it->parent) { - auto s = findPtr(it->structs, [&](Struct s) { return s.name == name; }); - if (s.has_value() && checkNamespace(it, namespacePrefix)) - return s; + auto n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = findPtr(std::get<0>(*n)->structs, [&](Struct _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } return nullopt; } -opt findVariable( +opt>> findVariable( const std::string & name, const std::vector & namespacePrefix, std::shared_ptr ctx) { for (auto it = ctx; it != nullptr; it = it->parent) { - auto v = find(it->variables, [&](Variable v) { return v.name == name; }); - if (v.has_value() && checkNamespace(it, namespacePrefix)) - return v; + auto n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = find(std::get<0>(*n)->variables, [&](Variable _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } return nullopt; } diff --git a/src/main.cpp b/src/main.cpp index 3523cdf..6792e83 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ #include "toc.h" #include "repr.h" #include "repr_get.h" +#include "generic.h" //#include "check.h" using namespace antlr4; @@ -35,6 +36,7 @@ int main(int argc, const char * argv[]) //std::cout << "Parse Tree: " << s << std::endl; Program prg = getProgram(prog, nullptr); + instantiateGenerics(prg); try { diff --git a/src/repr.h b/src/repr.h index 709528d..959e74d 100644 --- a/src/repr.h +++ b/src/repr.h @@ -44,6 +44,7 @@ struct Context std::vector variables; std::vector functions; std::vector structs; + std::vector namespaces; }; enum class TypeModifierType @@ -65,6 +66,21 @@ struct Type std::string name; std::vector modifiers; std::vector genericInstantiation; + + bool operator!=(const Type & that) + { + if (this->name != that.name) + return true; + + for (int i = 0; i < this->modifiers.size(); i++) + if (this->modifiers[i].type != that.modifiers[i].type) + return true; + + for (int i = 0; i < this->namespacePrefixes.size(); i++) + if (this->namespacePrefixes[i] != that.namespacePrefixes[i]) + return true; + return false; + } }; struct Variable @@ -113,13 +129,11 @@ struct Namespace { std::string name; std::shared_ptr ctx; - std::vector namespaces; }; struct Program { std::shared_ptr ctx; - std::vector namespaces; }; enum class ExprType diff --git a/src/repr_get.h b/src/repr_get.h index 7436dde..a1f496a 100644 --- a/src/repr_get.h +++ b/src/repr_get.h @@ -145,6 +145,7 @@ Namespace getNamespace(TocParser::NamespaceDeclContext * ctx, std::shared_ptr(); result.name = ctx->typeName()->getText(); + result.ctx->name = result.name; for (auto d : ctx->decl()) { if (d->varDecl() != nullptr) @@ -161,7 +162,7 @@ Namespace getNamespace(TocParser::NamespaceDeclContext * ctx, std::shared_ptrnamespaceDecl() != nullptr) { - result.namespaces.push_back(getNamespace(d->namespaceDecl(), result.ctx)); + result.ctx->namespaces.push_back(getNamespace(d->namespaceDecl(), result.ctx)); } } return result; @@ -186,7 +187,7 @@ Program getProgram(TocParser::ProgContext * ctx, std::shared_ptr parent } if (d->namespaceDecl() != nullptr) { - result.namespaces.push_back(getNamespace(d->namespaceDecl(), result.ctx)); + result.ctx->namespaces.push_back(getNamespace(d->namespaceDecl(), result.ctx)); } } return result; diff --git a/src/toc.h b/src/toc.h index 8bf0e68..c58e2fc 100644 --- a/src/toc.h +++ b/src/toc.h @@ -59,6 +59,21 @@ static std::map currentInstantiation; static Program globalPrg; static std::shared_ptr globalCtx; + + +// std::string getPrefix(std::shared_ptr ctx) +// { +// std::string result; +// for (auto it = ctx; it != nullptr; it = it->parent) +// { +// if (it->name.has_value()) +// { +// result = it->name.value() + "_" + result; +// } +// } +// return result; +// } + std::ostream & operator<< (std::ostream & out, const Type & t) { for (auto kv : currentInstantiation) @@ -72,7 +87,11 @@ std::ostream & operator<< (std::ostream & out, const Type & t) TypeInfo ti = typeType(globalPrg, t); if (ti.isStruct) out << "struct "; - out << vectorStr(t.namespacePrefixes, "_", true) << t.name; + auto s = findStruct(t.name, t.namespacePrefixes, globalCtx); + if (s.has_value()) + out << vectorStr(std::get<1>(*s), "_", true) << t.name; + else + out << vectorStr(t.namespacePrefixes, "_", true) << t.name; if (!t.genericInstantiation.empty()) out << genericAppendix(t.genericInstantiation); @@ -84,6 +103,10 @@ std::ostream & operator<< (std::ostream & out, const Variable & v) std::stringstream sstr; std::string s = v.name; + + auto var = findVariable(v.name, namespaces, globalCtx); + if (var.has_value()) + s = vectorStr(std::get<1>(*var), "_", true) + s; for (auto m = v.type.modifiers.rbegin(); m != v.type.modifiers.rend(); m++) { @@ -143,19 +166,19 @@ std::ostream & operator<< (std::ostream & out, const Expr & e) { case ExprType::Func: { - if (e._func.namespacePrefixes.empty()) - { - TypeInfo ti = typeExpr(globalPrg, namespaces, globalCtx, e); - - } - out << vectorStr(e._func.namespacePrefixes, "_", true) << e._func.functionName; + auto f = findFunction(e._func.functionName, e._func.namespacePrefixes, globalCtx); + + if (std::get<0>(*f).defined) + out << vectorStr(std::get<1>(*f), "_", true); + + out << e._func.functionName; if (!e._func.genericInstantiation.empty()) out << genericAppendix(e._func.genericInstantiation); out <<"(" << vectorStr(e._func.arguments, ", ") << ")"; break; } case ExprType::Method: { - TypeInfo ti = typeExpr(globalPrg, namespaces, globalCtx, *e._method.expr); + TypeInfo ti = typeExpr(globalPrg, globalCtx, *e._method.expr); out << vectorStr(ti.type.namespacePrefixes, "_", true) << ti.type.name << genericAppendix(ti.type.genericInstantiation) << "_" << e._method.methodName; @@ -189,7 +212,13 @@ std::ostream & operator<< (std::ostream & out, const Expr & e) case ExprType::Bracket: out << *e._brackets.lexpr << "[" << *e._brackets.rexpr << "]"; break; case ExprType::Identifier: - out << vectorStr(e._identifier.namespacePrefixes, "_", true) << e._identifier.identifier; break; + auto v = findVariable(e._identifier.identifier, e._identifier.namespacePrefixes, globalCtx); + if (v.has_value()) + out << vectorStr(std::get<1>(*v), "_", true); + else + out << vectorStr(e._identifier.namespacePrefixes, "_", true); + + out << e._identifier.identifier; break; } return out; @@ -396,14 +425,12 @@ void tocStruct (std::ostream & out, const Struct & s, bool stub) } } } -void tocProgram (std::ostream & out, const Program & _p) +void tocProgram (std::ostream & out, const Program & p) { - Program p = instantiateGenerics(_p); - globalCtx = p.ctx; globalPrg = p; - for (auto n : p.namespaces) + for (auto n : p.ctx->namespaces) { tocNamespace(out, n, true); } @@ -424,7 +451,7 @@ void tocProgram (std::ostream & out, const Program & _p) out << v << ";\n"; } out << "\n\n"; - for (auto n : p.namespaces) + for (auto n : p.ctx->namespaces) { tocNamespace(out, n, false); } @@ -456,7 +483,7 @@ void tocNamespace (std::ostream & out, const Namespace & n, bool stub) } out << "\n\n"; } - for (auto n : n.namespaces) + for (auto n : n.ctx->namespaces) { tocNamespace(out, n, stub); out << "\n\n"; diff --git a/src/typeInfo.h b/src/typeInfo.h index 89fff2a..10b4097 100644 --- a/src/typeInfo.h +++ b/src/typeInfo.h @@ -24,7 +24,7 @@ TypeInfo typeType(const Program & p, Type t) return result; } -TypeInfo typeExpr(const Program & p, const std::vector & globalNamespace, std::shared_ptr globalCtx, Expr e) +TypeInfo typeExpr(const Program & p, std::shared_ptr globalCtx, Expr e) { TypeInfo result; @@ -32,28 +32,24 @@ TypeInfo typeExpr(const Program & p, const std::vector & globalName { case ExprType::Func: { - auto namespacePrefixes = globalNamespace; - namespacePrefixes.insert(namespacePrefixes.end(), - e._func.namespacePrefixes.begin(), - e._func.namespacePrefixes.end()); auto f = findFunction(e._func.functionName, e._func.namespacePrefixes, globalCtx); if (!f.has_value()) throw "Unknown function"; - result = typeType(p, f.value().returnType); + result = typeType(p, std::get<0>(*f).returnType); break; } case ExprType::Method: { - TypeInfo tiCaller = typeExpr(p, globalNamespace, globalCtx, *e._method.expr); + TypeInfo tiCaller = typeExpr(p, globalCtx, *e._method.expr); if (!tiCaller.isStruct) throw "Calling method on non-struct"; auto s = findStruct(tiCaller.type.name, tiCaller.type.namespacePrefixes, globalCtx); if (!s.has_value()) throw "Calling method on unknown struct"; - auto m = findStructMethod(e._method.methodName, s.value()); + auto m = findStructMethod(e._method.methodName, std::get<0>(*s)); if (!m.has_value()) throw "Unknown method"; - result = typeType(p, m.value().t.returnType); + result = typeType(p, m->t.returnType); break; } case ExprType::Lit: @@ -67,37 +63,37 @@ TypeInfo typeExpr(const Program & p, const std::vector & globalName } break; case ExprType::Paren: - result = typeExpr(p, globalNamespace, globalCtx, *e._paren.expr); + result = typeExpr(p, globalCtx, *e._paren.expr); break; case ExprType::Dot: { - auto tiCaller = typeExpr(p, globalNamespace, globalCtx, *e._dot.expr); + auto tiCaller = typeExpr(p, globalCtx, *e._dot.expr); if (!tiCaller.isStruct) throw "Accessing member of non-struct"; auto s = findStruct(tiCaller.type.name, tiCaller.type.namespacePrefixes, globalCtx); if (!s.has_value()) throw "Calling method on unknown struct"; - auto sm = findStructMember(e._dot.identifier, s.value()); + auto sm = findStructMember(e._dot.identifier, std::get<0>(*s)); if (!sm.has_value()) throw "Unknown struct member"; - result = typeType(p, sm.value().t.type); + result = typeType(p, sm->t.type); break; } case ExprType::PrefixOp: - result = typeExpr(p, globalNamespace, globalCtx, *e._prefixOp.expr); + result = typeExpr(p, globalCtx, *e._prefixOp.expr); break; case ExprType::PostfixOp: - result = typeExpr(p, globalNamespace, globalCtx, *e._postfixOp.expr); + result = typeExpr(p, globalCtx, *e._postfixOp.expr); break; case ExprType::BinaryOp: - result = typeExpr(p, globalNamespace, globalCtx, *e._binaryOp.lexpr); + result = typeExpr(p, globalCtx, *e._binaryOp.lexpr); break; case ExprType::TernaryOp: - result = typeExpr(p, globalNamespace, globalCtx, *e._ternaryOp.rexprTrue); + result = typeExpr(p, globalCtx, *e._ternaryOp.rexprTrue); break; case ExprType::Bracket: { - TypeInfo ti = typeExpr(p, globalNamespace, globalCtx, *e._brackets.lexpr); + TypeInfo ti = typeExpr(p, globalCtx, *e._brackets.lexpr); if (!ti.type.modifiers.empty()) { result = ti; @@ -110,14 +106,10 @@ TypeInfo typeExpr(const Program & p, const std::vector & globalName } case ExprType::Identifier: { - auto namespacePrefixes = globalNamespace; - namespacePrefixes.insert(namespacePrefixes.end(), - e._identifier.namespacePrefixes.begin(), - e._identifier.namespacePrefixes.end()); - auto v = findVariable(e._identifier.identifier, namespacePrefixes, globalCtx); + auto v = findVariable(e._identifier.identifier, e._identifier.namespacePrefixes, globalCtx); if (!v.has_value()) throw "Unknown variable"; - result = typeType(p, v.value().type); + result = typeType(p, std::get<0>(*v).type); break; } } diff --git a/src/visit.h b/src/visit.h index 3fe2cb2..1175a86 100644 --- a/src/visit.h +++ b/src/visit.h @@ -141,7 +141,7 @@ public: ctx = x.ctx; - VISIT(x.namespaces) + VISIT(x.ctx->namespaces) VISIT(x.ctx->variables) VISIT(x.ctx->structs) VISIT(x.ctx->functions) @@ -188,7 +188,7 @@ public: ctx = x.ctx; - VISIT(x.namespaces) + VISIT(x.ctx->namespaces) VISIT(x.ctx->variables) VISIT(x.ctx->structs) VISIT(x.ctx->functions) -- cgit v1.2.3