abouttreesummaryrefslogcommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/find.h213
-rw-r--r--src/repr.h7
-rw-r--r--src/repr_get.h8
-rw-r--r--src/toc.h12
-rw-r--r--src/typeInfo.h20
-rw-r--r--src/visit.h68
6 files changed, 135 insertions, 193 deletions
diff --git a/src/find.h b/src/find.h
index fec540f..ea3ae22 100644
--- a/src/find.h
+++ b/src/find.h
@@ -27,202 +27,127 @@ opt<T *> findPtr(const std::vector<T> & ts, std::function<bool(T)> f)
return nullopt;
}
-opt<Function> findFunction(
- const Program & p,
- const std::string & name,
- const std::vector<std::string> & namespacePrefixes)
+bool checkNamespace(std::shared_ptr<Context> ctx, const std::vector<std::string> & namespacePrefix)
{
- if (namespacePrefixes.empty())
- {
- return find<Function>(p.functions, [&](Function f) { return f.name == name; });
- }
- auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });
-
- if (!n.has_value())
- return nullopt;
-
- std::vector<Namespace> namespaces = { n.value() };
+ bool prefixMatches = true;
+
+ auto nIt = ctx;
+ for (int i = namespacePrefix.size() - 1; i >= 0; i--)
+ {
+ const std::string & prefix = namespacePrefix[i];
+ if (nIt == nullptr || ! nIt->name.has_value() || nIt->name.value() != prefix)
+ {
+ prefixMatches = false;
+ break;
+ }
+ nIt = nIt->parent;
+ }
+
+ return prefixMatches;
+}
- for (int i = 1; i < namespacePrefixes.size(); i++)
- {
- n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });
-
- if (!n.has_value())
- return nullopt;
- namespaces.push_back(n.value());
- }
- for (int i = namespaces.size()-1; i >= 0; i--)
+opt<Function> findFunction(
+ const std::string & name,
+ const std::vector<std::string> & namespacePrefix,
+ std::shared_ptr<Context> ctx)
+{
+ for (auto it = ctx; it != nullptr; it = it->parent)
{
- auto f = find<Function>(namespaces[i].functions, [&](Function f) { return f.name == name; });
- if (f.has_value())
- return f.value();
+ auto f = find<Function>(it->functions, [&](Function f) { return f.name == name; });
+ if (f.has_value() && checkNamespace(it, namespacePrefix))
+ return f;
}
-
- return find<Function>(p.functions, [&](Function f) { return f.name == name; });
+ return nullopt;
}
opt<Function *> findFunctionPtr(
- const Program & p,
const std::string & name,
- const std::vector<std::string> & namespacePrefixes)
+ const std::vector<std::string> & namespacePrefix,
+ std::shared_ptr<Context> ctx)
{
- if (namespacePrefixes.empty())
+ for (auto it = ctx; it != nullptr; it = it->parent)
{
- return findPtr<Function>(p.functions, [&](Function f) { return f.name == name; });
- }
-
- auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });
-
- if (!n.has_value())
- return nullopt;
-
- std::vector<Namespace> namespaces = { n.value() };
-
- for (int i = 1; i < namespacePrefixes.size(); i++)
- {
- n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });
-
- if (!n.has_value())
- return nullopt;
-
- namespaces.push_back(n.value());
+ auto f = findPtr<Function>(it->functions, [&](Function f) { return f.name == name; });
+ if (f.has_value() && checkNamespace(it, namespacePrefix))
+ return f;
}
+ return nullopt;
+}
- for (int i = namespaces.size()-1; i >= 0; i--)
- {
- auto f = findPtr<Function>(namespaces[i].functions, [&](Function f) { return f.name == name; });
- if (f.has_value())
- return f.value();
- }
- return findPtr<Function>(p.functions, [&](Function f) { return f.name == name; });
-}
opt<Struct> findStruct(
- const Program & p,
const std::string & name,
- const std::vector<std::string> & namespacePrefixes)
+ const std::vector<std::string> & namespacePrefix,
+ std::shared_ptr<Context> ctx)
{
- if (namespacePrefixes.empty())
+ for (auto it = ctx; it != nullptr; it = it->parent)
{
- return find<Struct>(p.structs, [&](Struct s) { return s.name == name; });
+ auto s = find<Struct>(it->structs, [&](Struct s) { return s.name == name; });
+ if (s.has_value() && checkNamespace(it, namespacePrefix))
+ return s;
}
-
- auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });
-
- if (!n.has_value())
- return nullopt;
-
- std::vector<Namespace> namespaces = { n.value() };
-
- for (int i = 1; i < namespacePrefixes.size(); i++)
- {
- n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });
-
- if (!n.has_value())
- return nullopt;
-
- namespaces.push_back(n.value());
- }
-
- for (int i = namespaces.size()-1; i >= 0; i--)
- {
- auto f = find<Struct>(namespaces[i].structs, [&](Struct f) { return f.name == name; });
- if (f.has_value())
- return f.value();
- }
-
- return find<Struct>(n.value().structs, [&](Struct s) { return s.name == name; });
+ return nullopt;
}
opt<Struct *> findStructPtr(
- const Program & p,
const std::string & name,
- const std::vector<std::string> & namespacePrefixes)
+ const std::vector<std::string> & namespacePrefix,
+ std::shared_ptr<Context> ctx)
{
- if (namespacePrefixes.empty())
- {
- return findPtr<Struct>(p.structs, [&](Struct s) { return s.name == name; });
- }
-
- auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });
-
- if (!n.has_value())
- return nullopt;
-
- std::vector<Namespace> namespaces = { n.value() };
-
- for (int i = 1; i < namespacePrefixes.size(); i++)
+ for (auto it = ctx; it != nullptr; it = it->parent)
{
- n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });
-
- if (!n.has_value())
- return nullopt;
-
- namespaces.push_back(n.value());
+ auto s = findPtr<Struct>(it->structs, [&](Struct s) { return s.name == name; });
+ if (s.has_value() && checkNamespace(it, namespacePrefix))
+ return s;
}
+ return nullopt;
+}
- for (int i = namespaces.size()-1; i >= 0; i--)
- {
- auto f = findPtr<Struct>(namespaces[i].structs, [&](Struct f) { return f.name == name; });
- if (f.has_value())
- return f.value();
- }
- return findPtr<Struct>(n.value().structs, [&](Struct s) { return s.name == name; });
-}
opt<Variable> findVariable(
- const Program & p,
const std::string & name,
+ const std::vector<std::string> & namespacePrefix,
std::shared_ptr<Context> ctx)
{
- auto it = ctx;
- while (it != nullptr)
+ for (auto it = ctx; it != nullptr; it = it->parent)
{
auto v = find<Variable>(it->variables, [&](Variable v) { return v.name == name; });
- if (v.has_value())
+ if (v.has_value() && checkNamespace(it, namespacePrefix))
return v;
- it = it->parent;
}
return nullopt;
}
+
+
opt<StructMember<Function>> findStructMethod(
- const Program & p,
const std::string & name,
- TypeInfo ti)
+ const Struct & s)
{
- if (!ti.isStruct)
- return nullopt;
- auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);
- if (!s.has_value())
- return nullopt;
- return find<StructMember<Function>>(s.value().methods, [&](Function f) { return f.name == name; });
+ return find<StructMember<Function>>(s.methods, [&](Function f) { return f.name == name; });
}
opt<StructMember<Function> *> findStructMethodPtr(
- const Program & p,
const std::string & name,
- TypeInfo ti)
+ const Struct & s)
{
- if (!ti.isStruct)
- return nullopt;
- auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);
- if (!s.has_value())
- return nullopt;
- return findPtr<StructMember<Function>>(s.value().methods, [&](Function f) { return f.name == name; });
+ return findPtr<StructMember<Function>>(s.methods, [&](Function f) { return f.name == name; });
}
opt<StructMember<Variable>> findStructMember(
- const Program & p,
- TypeInfo ti,
- const std::string & name)
+ const std::string & name,
+ const Struct & s)
+{
+ return find<StructMember<Variable>>(s.members, [&](Variable v) { return v.name == name; });
+}
+
+opt<StructMember<Variable> *> findStructMemberPtr(
+ const std::string & name,
+ const Struct & s)
{
- auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);
- if (!s.has_value())
- return nullopt;
- return find<StructMember<Variable>>(s.value().members, [&](Variable v) { return v.name == name; });
+ return findPtr<StructMember<Variable>>(s.members, [&](Variable v) { return v.name == name; });
} \ No newline at end of file
diff --git a/src/repr.h b/src/repr.h
index ff54f97..709528d 100644
--- a/src/repr.h
+++ b/src/repr.h
@@ -39,8 +39,11 @@ struct Stmt;
struct Context
{
+ std::optional<std::string> name;
std::shared_ptr<Context> parent;
std::vector<Variable> variables;
+ std::vector<Function> functions;
+ std::vector<Struct> structs;
};
enum class TypeModifierType
@@ -110,16 +113,12 @@ struct Namespace
{
std::string name;
std::shared_ptr<Context> ctx;
- std::vector<Struct> structs;
- std::vector<Function> functions;
std::vector<Namespace> namespaces;
};
struct Program
{
std::shared_ptr<Context> ctx;
- std::vector<Struct> structs;
- std::vector<Function> functions;
std::vector<Namespace> namespaces;
};
diff --git a/src/repr_get.h b/src/repr_get.h
index 2d321b0..7436dde 100644
--- a/src/repr_get.h
+++ b/src/repr_get.h
@@ -153,11 +153,11 @@ Namespace getNamespace(TocParser::NamespaceDeclContext * ctx, std::shared_ptr<Co
}
if (d->funcDecl() != nullptr)
{
- result.functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));
+ result.ctx->functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));
}
if (d->structDecl() != nullptr)
{
- result.structs.push_back(getStruct(d->structDecl(), result.ctx));
+ result.ctx->structs.push_back(getStruct(d->structDecl(), result.ctx));
}
if (d->namespaceDecl() != nullptr)
{
@@ -178,11 +178,11 @@ Program getProgram(TocParser::ProgContext * ctx, std::shared_ptr<Context> parent
}
if (d->funcDecl() != nullptr)
{
- result.functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));
+ result.ctx->functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));
}
if (d->structDecl() != nullptr)
{
- result.structs.push_back(getStruct(d->structDecl(), result.ctx));
+ result.ctx->structs.push_back(getStruct(d->structDecl(), result.ctx));
}
if (d->namespaceDecl() != nullptr)
{
diff --git a/src/toc.h b/src/toc.h
index 659c9f3..8bf0e68 100644
--- a/src/toc.h
+++ b/src/toc.h
@@ -408,12 +408,12 @@ void tocProgram (std::ostream & out, const Program & _p)
tocNamespace(out, n, true);
}
out << "\n\n";
- for (auto s : p.structs)
+ for (auto s : p.ctx->structs)
{
tocStruct(out, s, true);
}
out << "\n\n";
- for (auto f : p.functions)
+ for (auto f : p.ctx->functions)
{
tocFunction(out, f, true);
}
@@ -429,12 +429,12 @@ void tocProgram (std::ostream & out, const Program & _p)
tocNamespace(out, n, false);
}
out << "\n\n";
- for (auto s : p.structs)
+ for (auto s : p.ctx->structs)
{
tocStruct(out, s, false);
}
out << "\n\n";
- for (auto f : p.functions)
+ for (auto f : p.ctx->functions)
{
tocFunction(out, f, false);
}
@@ -461,12 +461,12 @@ void tocNamespace (std::ostream & out, const Namespace & n, bool stub)
tocNamespace(out, n, stub);
out << "\n\n";
}
- for (auto s : n.structs)
+ for (auto s : n.ctx->structs)
{
tocStruct(out, s, stub);
out << "\n\n";
}
- for (auto f : n.functions)
+ for (auto f : n.ctx->functions)
{
tocFunction(out, f, stub);
out << "\n\n";
diff --git a/src/typeInfo.h b/src/typeInfo.h
index cbe421c..89fff2a 100644
--- a/src/typeInfo.h
+++ b/src/typeInfo.h
@@ -36,7 +36,7 @@ TypeInfo typeExpr(const Program & p, const std::vector<std::string> & globalName
namespacePrefixes.insert(namespacePrefixes.end(),
e._func.namespacePrefixes.begin(),
e._func.namespacePrefixes.end());
- auto f = findFunction(p, e._func.functionName, namespacePrefixes);
+ auto f = findFunction(e._func.functionName, e._func.namespacePrefixes, globalCtx);
if (!f.has_value())
throw "Unknown function";
result = typeType(p, f.value().returnType);
@@ -45,7 +45,12 @@ TypeInfo typeExpr(const Program & p, const std::vector<std::string> & globalName
case ExprType::Method:
{
TypeInfo tiCaller = typeExpr(p, globalNamespace, globalCtx, *e._method.expr);
- auto m = findStructMethod(p, e._method.methodName, tiCaller);
+ 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());
if (!m.has_value())
throw "Unknown method";
result = typeType(p, m.value().t.returnType);
@@ -66,8 +71,13 @@ TypeInfo typeExpr(const Program & p, const std::vector<std::string> & globalName
break;
case ExprType::Dot:
{
- auto sm = findStructMember(p,
- typeExpr(p, globalNamespace, globalCtx, *e._dot.expr), e._dot.identifier);
+ auto tiCaller = typeExpr(p, globalNamespace, 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());
if (!sm.has_value())
throw "Unknown struct member";
result = typeType(p, sm.value().t.type);
@@ -104,7 +114,7 @@ TypeInfo typeExpr(const Program & p, const std::vector<std::string> & globalName
namespacePrefixes.insert(namespacePrefixes.end(),
e._identifier.namespacePrefixes.begin(),
e._identifier.namespacePrefixes.end());
- auto v = findVariable(p, e._identifier.identifier, globalCtx);
+ auto v = findVariable(e._identifier.identifier, namespacePrefixes, globalCtx);
if (!v.has_value())
throw "Unknown variable";
result = typeType(p, v.value().type);
diff --git a/src/visit.h b/src/visit.h
index 0cfb9e6..3fe2cb2 100644
--- a/src/visit.h
+++ b/src/visit.h
@@ -5,17 +5,17 @@
#include <functional>
struct Visitor {
- std::function<void(const Type &, const std::vector<std::string> & namespaces)> onType = [](auto, auto){};
- std::function<void(const Expr &, const std::vector<std::string> & namespaces)> onExpr = [](auto, auto){};
- std::function<void(const Stmt &, const std::vector<std::string> & namespaces)> onStmt = [](auto, auto){};
- std::function<void(const Body &, const std::vector<std::string> & namespaces)> onBody = [](auto, auto){};
- std::function<void(const Function &, const std::vector<std::string> & namespaces)> onFunction = [](auto, auto){};
- std::function<void(const Variable &, const std::vector<std::string> & namespaces)> onVariable = [](auto, auto){};
- std::function<void(const StructMember<Function> &, const std::vector<std::string> & namespaces)> onStructMethod = [](auto, auto){};
- std::function<void(const StructMember<Variable> &, const std::vector<std::string> & namespaces)> onStructMember = [](auto, auto){};
- std::function<void(const Struct &, const std::vector<std::string> & namespaces)> onStruct = [](auto, auto){};
- std::function<void(const Namespace &, const std::vector<std::string> & namespaces)> onNamespace = [](auto, auto){};
- std::function<void(const Program &, const std::vector<std::string> & namespaces)> onProgram = [](auto, auto){};
+ std::function<void(const Type &, const std::shared_ptr<Context> ctx)> onType = [](auto, auto){};
+ std::function<void(const Expr &, const std::shared_ptr<Context> ctx)> onExpr = [](auto, auto){};
+ std::function<void(const Stmt &, const std::shared_ptr<Context> ctx)> onStmt = [](auto, auto){};
+ std::function<void(const Body &, const std::shared_ptr<Context> ctx)> onBody = [](auto, auto){};
+ std::function<void(const Function &, const std::shared_ptr<Context> ctx)> onFunction = [](auto, auto){};
+ std::function<void(const Variable &, const std::shared_ptr<Context> ctx)> onVariable = [](auto, auto){};
+ std::function<void(const StructMember<Function> &, const std::shared_ptr<Context> ctx)> onStructMethod = [](auto, auto){};
+ std::function<void(const StructMember<Variable> &, const std::shared_ptr<Context> ctx)> onStructMember = [](auto, auto){};
+ std::function<void(const Struct &, const std::shared_ptr<Context> ctx)> onStruct = [](auto, auto){};
+ std::function<void(const Namespace &, const std::shared_ptr<Context> ctx)> onNamespace = [](auto, auto){};
+ std::function<void(const Program &, const std::shared_ptr<Context> ctx)> onProgram = [](auto, auto){};
};
#define VISIT(XS) for (auto x : XS) visit(x);
@@ -23,7 +23,7 @@ struct Visitor {
struct Visit {
private:
Visitor v;
- std::vector<std::string> namespaces;
+ std::shared_ptr<Context> ctx;
public:
Visit(Visitor v)
{
@@ -31,11 +31,11 @@ public:
}
void visit(const Type & x)
{
- v.onType(x, namespaces);
+ v.onType(x, ctx);
}
void visit(const Expr & x)
{
- v.onExpr(x, namespaces);
+ v.onExpr(x, ctx);
switch (x.type)
{
@@ -79,7 +79,7 @@ public:
}
void visit(const Stmt & x)
{
- v.onStmt(x, namespaces);
+ v.onStmt(x, ctx);
switch (x.type)
{
@@ -126,32 +126,36 @@ public:
}
void visit(const Body & x)
{
- v.onBody(x, namespaces);
+ v.onBody(x, ctx);
+
+ ctx = x.ctx;
VISIT(x.ctx->variables)
VISIT(x.statements)
+
+ ctx = ctx->parent;
}
void visit(const Namespace & x)
{
- v.onNamespace(x, namespaces);
-
- namespaces.push_back(x.name);
+ v.onNamespace(x, ctx);
+
+ ctx = x.ctx;
VISIT(x.namespaces)
VISIT(x.ctx->variables)
- VISIT(x.structs)
- VISIT(x.functions)
+ VISIT(x.ctx->structs)
+ VISIT(x.ctx->functions)
- namespaces.pop_back();
+ ctx = ctx->parent;
}
void visit(const Variable & x)
{
- v.onVariable(x, namespaces);
+ v.onVariable(x, ctx);
visit(x.type);
}
void visit(const Function & x)
{
- v.onFunction(x, namespaces);
+ v.onFunction(x, ctx);
if (x.defined) {
visit(x.body);
@@ -161,31 +165,35 @@ public:
}
void visit(const StructMember<Function> & x)
{
- v.onStructMethod(x, namespaces);
+ v.onStructMethod(x, ctx);
visit(x.t);
}
void visit(const StructMember<Variable> & x)
{
- v.onStructMember(x, namespaces);
+ v.onStructMember(x, ctx);
visit(x.t);
}
void visit(const Struct & x)
{
- v.onStruct(x, namespaces);
+ v.onStruct(x, ctx);
VISIT(x.members)
VISIT(x.methods)
}
void visit(const Program & x)
{
- v.onProgram(x, namespaces);
+ v.onProgram(x, ctx);
+
+ ctx = x.ctx;
VISIT(x.namespaces)
VISIT(x.ctx->variables)
- VISIT(x.structs)
- VISIT(x.functions)
+ VISIT(x.ctx->structs)
+ VISIT(x.ctx->functions)
+
+ ctx = nullptr;
}
};