diff options
| 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) | 
| commit | 400d28d753aa8af8de60a7f82851ffdc3cdae672 (patch) | |
| tree | 3e76d4c4449556c26d48073200956045bc092111 /src | |
| parent | d67e0129161a98f852ed2685f43e7eb7c7538bf0 (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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/func.cc | 24 | ||||
| -rw-r--r-- | src/module.cc | 10 | ||||
| -rw-r--r-- | src/module.h | 7 | 
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  | 
