summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorŁukasz Stelmach <stlman@poczta.fm>2013-08-18 15:18:43 (GMT)
committerŁukasz Stelmach <stlman@poczta.fm>2013-08-18 15:19:49 (GMT)
commit400d28d753aa8af8de60a7f82851ffdc3cdae672 (patch)
tree3e76d4c4449556c26d48073200956045bc092111
parentd67e0129161a98f852ed2685f43e7eb7c7538bf0 (diff)
Enable module stack introspection from within an SCAD script
The _current_module and _parent_module variables have been replaced by a built-in function parent_module(n). It takes one numeric parameter n, and returns n-th element from the module stack. If no argument provided, n defaults to 1 and the function returns the name of the direct parent module. If n is equal 0 current module name is returned.
-rw-r--r--src/func.cc24
-rw-r--r--src/module.cc10
-rw-r--r--src/module.h7
3 files changed, 33 insertions, 8 deletions
diff --git a/src/func.cc b/src/func.cc
index 20f487a..865a2b4 100644
--- a/src/func.cc
+++ b/src/func.cc
@@ -528,6 +528,29 @@ Value builtin_version_num(const Context *ctx, const EvalContext *evalctx)
return Value(y * 10000 + m * 100 + d);
}
+Value builtin_parent_module(const Context *, const EvalContext *evalctx)
+{
+ int n;
+ double d;
+ int s = Module::stack_size();
+ if (evalctx->numArgs() == 0)
+ d=1; // parent module
+ else if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER)
+ evalctx->getArgValue(0).getDouble(d);
+ else
+ return Value();
+ n=trunc(d);
+ if (n < 0) {
+ PRINTB("WARNING: Negative parent module index (%d) not allowed", n);
+ return Value();
+ }
+ if (n >= s) {
+ PRINTB("WARNING: Parent module index (%d) greater than the number of modules on the stack", n);
+ return Value();
+ }
+ return Value(Module::stack_element(s - 1 - n));
+}
+
void register_builtin_functions()
{
Builtins::init("abs", new BuiltinFunction(&builtin_abs));
@@ -556,4 +579,5 @@ void register_builtin_functions()
Builtins::init("search", new BuiltinFunction(&builtin_search));
Builtins::init("version", new BuiltinFunction(&builtin_version));
Builtins::init("version_num", new BuiltinFunction(&builtin_version_num));
+ Builtins::init("parent_module", new BuiltinFunction(&builtin_parent_module));
}
diff --git a/src/module.cc b/src/module.cc
index 970dd56..9c3541f 100644
--- a/src/module.cc
+++ b/src/module.cc
@@ -153,7 +153,7 @@ std::vector<AbstractNode*> IfElseModuleInstantiation::instantiateElseChildren(co
return this->else_scope.instantiateChildren(evalctx);
}
-std::stack<std::string> Module::stack;
+std::deque<std::string> Module::module_stack;
Module::~Module()
{
@@ -183,20 +183,18 @@ AbstractNode *Module::instantiate(const Context *ctx, const ModuleInstantiation
ModuleContext c(ctx, evalctx);
c.initializeModule(*this);
- c.set_variable("_current_module", inst->name());
- if (!stack.empty())
- c.set_variable("_parent_module", stack.top());
+ module_stack.push_back(inst->name());
+ c.set_variable("$parent_modules", Value(double(module_stack.size())));
c.set_variable("$children", Value(double(inst->scope.children.size())));
// FIXME: Set document path to the path of the module
#if 0 && DEBUG
c.dump(this, inst);
#endif
- stack.push(inst->name());
AbstractNode *node = new AbstractNode(inst);
std::vector<AbstractNode *> instantiatednodes = this->scope.instantiateChildren(&c);
node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end());
- stack.pop();
+ module_stack.pop_back();
return node;
}
diff --git a/src/module.h b/src/module.h
index fca88e3..8414706 100644
--- a/src/module.h
+++ b/src/module.h
@@ -4,7 +4,7 @@
#include <string>
#include <vector>
#include <list>
-#include <stack>
+#include <deque>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include <time.h>
@@ -74,12 +74,15 @@ public:
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx = NULL) const;
virtual std::string dump(const std::string &indent, const std::string &name) const;
+ static const std::string& stack_element(int n) { return module_stack[n]; };
+ static int stack_size() { return module_stack.size(); };
AssignmentList definition_arguments;
LocalScope scope;
+
private:
- static std::stack<std::string> stack;
+ static std::deque<std::string> module_stack;
};
// FIXME: A FileModule doesn't have definition arguments, so we shouldn't really
contact: Jan Huwald // Impressum