]> gitweb.ps.run Git - toc/commitdiff
structs and functions in ctx
authorPatrick Schönberger <patrick.schoenberger@posteo.de>
Wed, 11 Aug 2021 16:02:56 +0000 (18:02 +0200)
committerPatrick Schönberger <patrick.schoenberger@posteo.de>
Wed, 11 Aug 2021 16:02:56 +0000 (18:02 +0200)
src/find.h
src/repr.h
src/repr_get.h
src/toc.h
src/typeInfo.h
src/visit.h
test/test2.toc

index fec540f1eee81853886fb7bf6009cd6403bf8495..ea3ae2227b89169d99e5b74fa039b1ab53a6889a 100644 (file)
@@ -27,202 +27,127 @@ opt<T *> findPtr(const std::vector<T> & ts, std::function<bool(T)> f)
   return nullopt;\r
 }\r
 \r
-opt<Function> findFunction(\r
-  const Program & p,\r
-  const std::string & name,\r
-  const std::vector<std::string> & namespacePrefixes)\r
+bool checkNamespace(std::shared_ptr<Context> ctx, const std::vector<std::string> & namespacePrefix)\r
 {\r
-  if (namespacePrefixes.empty())\r
-  {\r
-    return find<Function>(p.functions, [&](Function f) { return f.name == name; });\r
-  }\r
   \r
-  auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });\r
-\r
-  if (!n.has_value())\r
-    return nullopt;\r
-\r
-  std::vector<Namespace> namespaces = { n.value() };\r
+    bool prefixMatches = true;\r
+\r
+    auto nIt = ctx;\r
+    for (int i = namespacePrefix.size() - 1; i >= 0; i--)\r
+    {\r
+      const std::string & prefix = namespacePrefix[i];\r
+      if (nIt == nullptr || ! nIt->name.has_value() || nIt->name.value() != prefix)\r
+      {\r
+        prefixMatches = false;\r
+        break;\r
+      }\r
+      nIt = nIt->parent;\r
+    }\r
+\r
+    return prefixMatches;\r
+}\r
 \r
-  for (int i = 1; i < namespacePrefixes.size(); i++)\r
-  {\r
-    n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });\r
-    \r
-    if (!n.has_value())\r
-      return nullopt;\r
 \r
-    namespaces.push_back(n.value());\r
-  }\r
 \r
-  for (int i = namespaces.size()-1; i >= 0; i--)\r
+opt<Function> findFunction(\r
+  const std::string & name,\r
+  const std::vector<std::string> & namespacePrefix,\r
+  std::shared_ptr<Context> ctx)\r
+{\r
+  for (auto it = ctx; it != nullptr; it = it->parent)\r
   {\r
-    auto f = find<Function>(namespaces[i].functions, [&](Function f) { return f.name == name; });\r
-    if (f.has_value())\r
-      return f.value();\r
+    auto f = find<Function>(it->functions, [&](Function f) { return f.name == name; });\r
+    if (f.has_value() && checkNamespace(it, namespacePrefix))\r
+      return f;\r
   }\r
-\r
-  return find<Function>(p.functions, [&](Function f) { return f.name == name; });\r
+  return nullopt;\r
 }\r
 \r
 opt<Function *> findFunctionPtr(\r
-  const Program & p,\r
   const std::string & name,\r
-  const std::vector<std::string> & namespacePrefixes)\r
+  const std::vector<std::string> & namespacePrefix,\r
+  std::shared_ptr<Context> ctx)\r
 {\r
-  if (namespacePrefixes.empty())\r
+  for (auto it = ctx; it != nullptr; it = it->parent)\r
   {\r
-    return findPtr<Function>(p.functions, [&](Function f) { return f.name == name; });\r
-  }\r
-  \r
-  auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });\r
-\r
-  if (!n.has_value())\r
-    return nullopt;\r
-\r
-  std::vector<Namespace> namespaces = { n.value() };\r
-\r
-  for (int i = 1; i < namespacePrefixes.size(); i++)\r
-  {\r
-    n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });\r
-    \r
-    if (!n.has_value())\r
-      return nullopt;\r
-\r
-    namespaces.push_back(n.value());\r
+    auto f = findPtr<Function>(it->functions, [&](Function f) { return f.name == name; });\r
+    if (f.has_value() && checkNamespace(it, namespacePrefix))\r
+      return f;\r
   }\r
+  return nullopt;\r
+}\r
 \r
-  for (int i = namespaces.size()-1; i >= 0; i--)\r
-  {\r
-    auto f = findPtr<Function>(namespaces[i].functions, [&](Function f) { return f.name == name; });\r
-    if (f.has_value())\r
-      return f.value();\r
-  }\r
 \r
-  return findPtr<Function>(p.functions, [&](Function f) { return f.name == name; });\r
-}\r
 \r
 opt<Struct> findStruct(\r
-  const Program & p,\r
   const std::string & name,\r
-  const std::vector<std::string> & namespacePrefixes)\r
+  const std::vector<std::string> & namespacePrefix,\r
+  std::shared_ptr<Context> ctx)\r
 {\r
-  if (namespacePrefixes.empty())\r
+  for (auto it = ctx; it != nullptr; it = it->parent)\r
   {\r
-    return find<Struct>(p.structs, [&](Struct s) { return s.name == name; });\r
+    auto s = find<Struct>(it->structs, [&](Struct s) { return s.name == name; });\r
+    if (s.has_value() && checkNamespace(it, namespacePrefix))\r
+      return s;\r
   }\r
-  \r
-  auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });\r
-  \r
-  if (!n.has_value())\r
-    return nullopt;\r
-\r
-  std::vector<Namespace> namespaces = { n.value() };\r
-    \r
-  for (int i = 1; i < namespacePrefixes.size(); i++)\r
-  {\r
-    n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });\r
-\r
-    if (!n.has_value())\r
-      return nullopt;\r
-\r
-    namespaces.push_back(n.value());\r
-  }\r
-\r
-  for (int i = namespaces.size()-1; i >= 0; i--)\r
-  {\r
-    auto f = find<Struct>(namespaces[i].structs, [&](Struct f) { return f.name == name; });\r
-    if (f.has_value())\r
-      return f.value();\r
-  }\r
-\r
-  return find<Struct>(n.value().structs, [&](Struct s) { return s.name == name; });\r
+  return nullopt;\r
 }\r
 \r
 opt<Struct *> findStructPtr(\r
-  const Program & p,\r
   const std::string & name,\r
-  const std::vector<std::string> & namespacePrefixes)\r
+  const std::vector<std::string> & namespacePrefix,\r
+  std::shared_ptr<Context> ctx)\r
 {\r
-  if (namespacePrefixes.empty())\r
-  {\r
-    return findPtr<Struct>(p.structs, [&](Struct s) { return s.name == name; });\r
-  }\r
-  \r
-  auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });\r
-  \r
-  if (!n.has_value())\r
-    return nullopt;\r
-\r
-  std::vector<Namespace> namespaces = { n.value() };\r
-    \r
-  for (int i = 1; i < namespacePrefixes.size(); i++)\r
+  for (auto it = ctx; it != nullptr; it = it->parent)\r
   {\r
-    n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });\r
-\r
-    if (!n.has_value())\r
-      return nullopt;\r
-\r
-    namespaces.push_back(n.value());\r
+    auto s = findPtr<Struct>(it->structs, [&](Struct s) { return s.name == name; });\r
+    if (s.has_value() && checkNamespace(it, namespacePrefix))\r
+      return s;\r
   }\r
+  return nullopt;\r
+}\r
 \r
-  for (int i = namespaces.size()-1; i >= 0; i--)\r
-  {\r
-    auto f = findPtr<Struct>(namespaces[i].structs, [&](Struct f) { return f.name == name; });\r
-    if (f.has_value())\r
-      return f.value();\r
-  }\r
 \r
-  return findPtr<Struct>(n.value().structs, [&](Struct s) { return s.name == name; });\r
-}\r
 \r
 opt<Variable> findVariable(\r
-  const Program & p,\r
   const std::string & name,\r
+  const std::vector<std::string> & namespacePrefix,\r
   std::shared_ptr<Context> ctx)\r
 {\r
-  auto it = ctx;\r
-  while (it != nullptr)\r
+  for (auto it = ctx; it != nullptr; it = it->parent)\r
   {\r
     auto v = find<Variable>(it->variables, [&](Variable v) { return v.name == name; });\r
-    if (v.has_value())\r
+    if (v.has_value() && checkNamespace(it, namespacePrefix))\r
       return v;\r
-    it = it->parent;\r
   }\r
   return nullopt;\r
 }\r
 \r
+\r
+\r
 opt<StructMember<Function>> findStructMethod(\r
-  const Program & p,\r
   const std::string & name,\r
-  TypeInfo ti)\r
+  const Struct & s)\r
 {\r
-  if (!ti.isStruct)\r
-    return nullopt;\r
-  auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);\r
-  if (!s.has_value())\r
-    return nullopt;\r
-  return find<StructMember<Function>>(s.value().methods, [&](Function f) { return f.name == name; });\r
+  return find<StructMember<Function>>(s.methods, [&](Function f) { return f.name == name; });\r
 }\r
 opt<StructMember<Function> *> findStructMethodPtr(\r
-  const Program & p,\r
   const std::string & name,\r
-  TypeInfo ti)\r
+  const Struct & s)\r
 {\r
-  if (!ti.isStruct)\r
-    return nullopt;\r
-  auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);\r
-  if (!s.has_value())\r
-    return nullopt;\r
-  return findPtr<StructMember<Function>>(s.value().methods, [&](Function f) { return f.name == name; });\r
+  return findPtr<StructMember<Function>>(s.methods, [&](Function f) { return f.name == name; });\r
 }\r
 \r
 opt<StructMember<Variable>> findStructMember(\r
-  const Program & p,\r
-  TypeInfo ti,\r
-  const std::string & name)\r
+  const std::string & name,\r
+  const Struct & s)\r
+{\r
+  return find<StructMember<Variable>>(s.members, [&](Variable v) { return v.name == name; });\r
+}\r
+\r
+opt<StructMember<Variable> *> findStructMemberPtr(\r
+  const std::string & name,\r
+  const Struct & s)\r
 {\r
-  auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);\r
-  if (!s.has_value())\r
-    return nullopt;\r
-  return find<StructMember<Variable>>(s.value().members, [&](Variable v) { return v.name == name; });\r
+  return findPtr<StructMember<Variable>>(s.members, [&](Variable v) { return v.name == name; });\r
 }
\ No newline at end of file
index ff54f971c731da26a9f2da64a683c5c86cc01d79..709528d3c8b55986ea65e73c164ff69f27d95855 100644 (file)
@@ -39,8 +39,11 @@ struct Stmt;
 \r
 struct Context\r
 {\r
+  std::optional<std::string> name;\r
   std::shared_ptr<Context> parent;\r
   std::vector<Variable> variables;\r
+  std::vector<Function> functions;\r
+  std::vector<Struct> structs;\r
 };\r
 \r
 enum class TypeModifierType\r
@@ -110,16 +113,12 @@ struct Namespace
 {\r
   std::string name;\r
   std::shared_ptr<Context> ctx;\r
-  std::vector<Struct> structs;\r
-  std::vector<Function> functions;\r
   std::vector<Namespace> namespaces;\r
 };\r
 \r
 struct Program\r
 {\r
   std::shared_ptr<Context> ctx;\r
-  std::vector<Struct> structs;\r
-  std::vector<Function> functions;\r
   std::vector<Namespace> namespaces;\r
 };\r
 \r
index 2d321b0a9bd7ef4cd7aa8e9a7f56afd7631e8464..7436dde1e553874a206590e8a9d222e681b86379 100644 (file)
@@ -153,11 +153,11 @@ Namespace getNamespace(TocParser::NamespaceDeclContext * ctx, std::shared_ptr<Co
     }\r
     if (d->funcDecl() != nullptr)\r
     {\r
-      result.functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));\r
+      result.ctx->functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));\r
     }\r
     if (d->structDecl() != nullptr)\r
     {\r
-      result.structs.push_back(getStruct(d->structDecl(), result.ctx));\r
+      result.ctx->structs.push_back(getStruct(d->structDecl(), result.ctx));\r
     }\r
     if (d->namespaceDecl() != nullptr)\r
     {\r
@@ -178,11 +178,11 @@ Program getProgram(TocParser::ProgContext * ctx, std::shared_ptr<Context> parent
     }\r
     if (d->funcDecl() != nullptr)\r
     {\r
-      result.functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));\r
+      result.ctx->functions.push_back(getFunction(d->funcDecl()->func(), result.ctx));\r
     }\r
     if (d->structDecl() != nullptr)\r
     {\r
-      result.structs.push_back(getStruct(d->structDecl(), result.ctx));\r
+      result.ctx->structs.push_back(getStruct(d->structDecl(), result.ctx));\r
     }\r
     if (d->namespaceDecl() != nullptr)\r
     {\r
index 659c9f32f4157cf832128ec3d828105c1827db2c..8bf0e689e01cf8499bfdbce6290af3d41eda9524 100644 (file)
--- a/src/toc.h
+++ b/src/toc.h
@@ -408,12 +408,12 @@ void tocProgram (std::ostream & out, const Program & _p)
     tocNamespace(out, n, true);\r
   }\r
   out << "\n\n";\r
-  for (auto s : p.structs)\r
+  for (auto s : p.ctx->structs)\r
   {\r
     tocStruct(out, s, true);\r
   }\r
   out << "\n\n";\r
-  for (auto f : p.functions)\r
+  for (auto f : p.ctx->functions)\r
   {\r
     tocFunction(out, f, true);\r
   }\r
@@ -429,12 +429,12 @@ void tocProgram (std::ostream & out, const Program & _p)
     tocNamespace(out, n, false);\r
   }\r
   out << "\n\n";\r
-  for (auto s : p.structs)\r
+  for (auto s : p.ctx->structs)\r
   {\r
     tocStruct(out, s, false);\r
   }\r
   out << "\n\n";\r
-  for (auto f : p.functions)\r
+  for (auto f : p.ctx->functions)\r
   {\r
     tocFunction(out, f, false);\r
   }\r
@@ -461,12 +461,12 @@ void tocNamespace  (std::ostream & out, const Namespace & n, bool stub)
     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
index cbe421ca33fe4108471adc571864ae8222991f1c..89fff2a1800d7ceebaed464a9c6c6cebc6314d0d 100644 (file)
@@ -36,7 +36,7 @@ TypeInfo typeExpr(const Program & p, const std::vector<std::string> & globalName
     namespacePrefixes.insert(namespacePrefixes.end(),\r
       e._func.namespacePrefixes.begin(),\r
       e._func.namespacePrefixes.end());\r
-    auto f = findFunction(p, e._func.functionName, namespacePrefixes);\r
+    auto f = findFunction(e._func.functionName, e._func.namespacePrefixes, globalCtx);\r
     if (!f.has_value())\r
       throw "Unknown function";\r
     result = typeType(p, f.value().returnType);\r
@@ -45,7 +45,12 @@ TypeInfo typeExpr(const Program & p, const std::vector<std::string> & globalName
   case ExprType::Method:\r
   {\r
     TypeInfo tiCaller = typeExpr(p, globalNamespace, globalCtx, *e._method.expr);\r
-    auto m = findStructMethod(p, e._method.methodName, tiCaller);\r
+    if (!tiCaller.isStruct)\r
+      throw "Calling method on non-struct";\r
+    auto s = findStruct(tiCaller.type.name, tiCaller.type.namespacePrefixes, globalCtx);\r
+    if (!s.has_value())\r
+      throw "Calling method on unknown struct";\r
+    auto m = findStructMethod(e._method.methodName, s.value());\r
     if (!m.has_value())\r
       throw "Unknown method";\r
     result = typeType(p, m.value().t.returnType);\r
@@ -66,8 +71,13 @@ TypeInfo typeExpr(const Program & p, const std::vector<std::string> & globalName
     break;\r
   case ExprType::Dot:\r
   {\r
-    auto sm = findStructMember(p,\r
-        typeExpr(p, globalNamespace, globalCtx, *e._dot.expr), e._dot.identifier);\r
+    auto tiCaller = typeExpr(p, globalNamespace, globalCtx, *e._dot.expr);\r
+    if (!tiCaller.isStruct)\r
+      throw "Accessing member of non-struct";\r
+    auto s = findStruct(tiCaller.type.name, tiCaller.type.namespacePrefixes, globalCtx);\r
+    if (!s.has_value())\r
+      throw "Calling method on unknown struct";\r
+    auto sm = findStructMember(e._dot.identifier, s.value());\r
     if (!sm.has_value())\r
       throw "Unknown struct member";\r
     result = typeType(p, sm.value().t.type);\r
@@ -104,7 +114,7 @@ TypeInfo typeExpr(const Program & p, const std::vector<std::string> & globalName
     namespacePrefixes.insert(namespacePrefixes.end(),\r
       e._identifier.namespacePrefixes.begin(),\r
       e._identifier.namespacePrefixes.end());\r
-    auto v = findVariable(p, e._identifier.identifier, globalCtx);\r
+    auto v = findVariable(e._identifier.identifier, namespacePrefixes, globalCtx);\r
     if (!v.has_value())\r
       throw "Unknown variable";\r
     result = typeType(p, v.value().type);\r
index 0cfb9e6036b7442cb7a0896ff9ea8a11c465117d..3fe2cb2b96f833aa16ae47e63b026bcb287b127d 100644 (file)
@@ -5,17 +5,17 @@
 #include <functional>\r
 \r
 struct Visitor {\r
-  std::function<void(const Type &, const std::vector<std::string> & namespaces)> onType = [](auto, auto){};\r
-  std::function<void(const Expr &, const std::vector<std::string> & namespaces)> onExpr = [](auto, auto){};\r
-  std::function<void(const Stmt &, const std::vector<std::string> & namespaces)> onStmt = [](auto, auto){};\r
-  std::function<void(const Body &, const std::vector<std::string> & namespaces)> onBody = [](auto, auto){};\r
-  std::function<void(const Function &, const std::vector<std::string> & namespaces)> onFunction = [](auto, auto){};\r
-  std::function<void(const Variable &, const std::vector<std::string> & namespaces)> onVariable = [](auto, auto){};\r
-  std::function<void(const StructMember<Function> &, const std::vector<std::string> & namespaces)> onStructMethod = [](auto, auto){};\r
-  std::function<void(const StructMember<Variable> &, const std::vector<std::string> & namespaces)> onStructMember = [](auto, auto){};\r
-  std::function<void(const Struct &, const std::vector<std::string> & namespaces)> onStruct = [](auto, auto){};\r
-  std::function<void(const Namespace &, const std::vector<std::string> & namespaces)> onNamespace = [](auto, auto){};\r
-  std::function<void(const Program &, const std::vector<std::string> & namespaces)> onProgram = [](auto, auto){};\r
+  std::function<void(const Type &, const std::shared_ptr<Context> ctx)> onType = [](auto, auto){};\r
+  std::function<void(const Expr &, const std::shared_ptr<Context> ctx)> onExpr = [](auto, auto){};\r
+  std::function<void(const Stmt &, const std::shared_ptr<Context> ctx)> onStmt = [](auto, auto){};\r
+  std::function<void(const Body &, const std::shared_ptr<Context> ctx)> onBody = [](auto, auto){};\r
+  std::function<void(const Function &, const std::shared_ptr<Context> ctx)> onFunction = [](auto, auto){};\r
+  std::function<void(const Variable &, const std::shared_ptr<Context> ctx)> onVariable = [](auto, auto){};\r
+  std::function<void(const StructMember<Function> &, const std::shared_ptr<Context> ctx)> onStructMethod = [](auto, auto){};\r
+  std::function<void(const StructMember<Variable> &, const std::shared_ptr<Context> ctx)> onStructMember = [](auto, auto){};\r
+  std::function<void(const Struct &, const std::shared_ptr<Context> ctx)> onStruct = [](auto, auto){};\r
+  std::function<void(const Namespace &, const std::shared_ptr<Context> ctx)> onNamespace = [](auto, auto){};\r
+  std::function<void(const Program &, const std::shared_ptr<Context> ctx)> onProgram = [](auto, auto){};\r
 };\r
 \r
 #define VISIT(XS) for (auto x : XS) visit(x);\r
@@ -23,7 +23,7 @@ struct Visitor {
 struct Visit {\r
 private:\r
   Visitor v;\r
-  std::vector<std::string> namespaces;\r
+  std::shared_ptr<Context> ctx;\r
 public:\r
   Visit(Visitor v)\r
   {\r
@@ -31,11 +31,11 @@ public:
   }\r
   void visit(const Type & x)\r
   {\r
-    v.onType(x, namespaces);\r
+    v.onType(x, ctx);\r
   }\r
   void visit(const Expr & x)\r
   {\r
-    v.onExpr(x, namespaces);\r
+    v.onExpr(x, ctx);\r
 \r
     switch (x.type)\r
     {\r
@@ -79,7 +79,7 @@ public:
   }\r
   void visit(const Stmt & x)\r
   {\r
-    v.onStmt(x, namespaces);\r
+    v.onStmt(x, ctx);\r
 \r
     switch (x.type)\r
     {\r
@@ -126,32 +126,36 @@ public:
   }\r
   void visit(const Body & x)\r
   {\r
-    v.onBody(x, namespaces);\r
+    v.onBody(x, ctx);\r
+\r
+    ctx = x.ctx;\r
 \r
     VISIT(x.ctx->variables)\r
     VISIT(x.statements)\r
+\r
+    ctx = ctx->parent;\r
   }\r
   void visit(const Namespace & x)\r
   {\r
-    v.onNamespace(x, namespaces);\r
-\r
-    namespaces.push_back(x.name);\r
+    v.onNamespace(x, ctx);\r
+    \r
+    ctx = x.ctx;\r
 \r
     VISIT(x.namespaces)\r
     VISIT(x.ctx->variables)\r
-    VISIT(x.structs)\r
-    VISIT(x.functions)\r
+    VISIT(x.ctx->structs)\r
+    VISIT(x.ctx->functions)\r
 \r
-    namespaces.pop_back();\r
+    ctx = ctx->parent;\r
   }\r
   void visit(const Variable & x)\r
   {\r
-    v.onVariable(x, namespaces);\r
+    v.onVariable(x, ctx);\r
     visit(x.type);\r
   }\r
   void visit(const Function & x)\r
   {\r
-    v.onFunction(x, namespaces);\r
+    v.onFunction(x, ctx);\r
 \r
     if (x.defined) {\r
       visit(x.body);\r
@@ -161,31 +165,35 @@ public:
   }\r
   void visit(const StructMember<Function> & x)\r
   {\r
-    v.onStructMethod(x, namespaces);\r
+    v.onStructMethod(x, ctx);\r
 \r
     visit(x.t);\r
   }\r
   void visit(const StructMember<Variable> & x)\r
   {\r
-    v.onStructMember(x, namespaces);\r
+    v.onStructMember(x, ctx);\r
 \r
     visit(x.t);\r
   }\r
   void visit(const Struct & x)\r
   {\r
-    v.onStruct(x, namespaces);\r
+    v.onStruct(x, ctx);\r
 \r
     VISIT(x.members)\r
     VISIT(x.methods)\r
   }\r
   void visit(const Program & x)\r
   {\r
-    v.onProgram(x, namespaces);\r
+    v.onProgram(x, ctx);\r
+\r
+    ctx = x.ctx;\r
 \r
     VISIT(x.namespaces)\r
     VISIT(x.ctx->variables)\r
-    VISIT(x.structs)\r
-    VISIT(x.functions)\r
+    VISIT(x.ctx->structs)\r
+    VISIT(x.ctx->functions)\r
+\r
+    ctx = nullptr;\r
   }\r
 };\r
 \r
index 1447c8f3ea5cc70e961fb74d4ce492f1e465086e..abd6bc77ea9874eef8ecd6fc27f32402c5d392f7 100644 (file)
@@ -13,6 +13,7 @@ namespace N1 {
       m1(i: int) : int {\r
         this->i3 = this->i1 * this->i2;\r
 \r
+        f1();\r
         N1::f1();\r
 \r
         return this->i1 + this->i2;\r
@@ -21,6 +22,7 @@ namespace N1 {
 \r
     func f1() : void {\r
       var s1 : N1::N2::S1;\r
+\r
       s1.m1(123);\r
     }\r
   }\r