diff options
| author | Vicnet <vo.publique@gmail.com> | 2013-09-24 05:06:44 (GMT) | 
|---|---|---|
| committer | Vicnet <vo.publique@gmail.com> | 2013-10-07 14:04:42 (GMT) | 
| commit | 119bf37cb343ec9873698a76150bca77b4d8e0b4 (patch) | |
| tree | 9d5f4d257a6586b284e6b0755304cb838677d27a /src | |
| parent | 572ab5804b62d6995491cd21d6af3ae319abd245 (diff) | |
add children primitive, and refactor control.cc a little
Diffstat (limited to 'src')
| -rw-r--r-- | src/control.cc | 121 | ||||
| -rw-r--r-- | src/highlighter.cc | 2 | 
2 files changed, 82 insertions, 41 deletions
diff --git a/src/control.cc b/src/control.cc index 50e5eae..ec13650 100644 --- a/src/control.cc +++ b/src/control.cc @@ -33,24 +33,36 @@  #include <sstream>  #include "mathc99.h" -enum control_type_e { -	CHILD, -	ECHO, -	ASSIGN, -	FOR, -	INT_FOR, -	IF -}; -  class ControlModule : public AbstractModule  { -public: -	control_type_e type; -	ControlModule(control_type_e type) : type(type) { } +public: // types +	enum Type { +		CHILD, +		CHILDREN, +		ECHO, +		ASSIGN, +		FOR, +		INT_FOR, +		IF +    }; +public: // methods +	ControlModule(Type type) +		: type(type) +	{ } +  	virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const; -}; -void for_eval(AbstractNode &node, const ModuleInstantiation &inst, size_t l,  +	static void for_eval(AbstractNode &node, const ModuleInstantiation &inst, size_t l,  +						 const Context *ctx, const EvalContext *evalctx); + +	static const EvalContext* getLastModuleCtx(const EvalContext *evalctx); + +private: // data +	Type type; + +}; // class ControlModule + +void ControlModule::for_eval(AbstractNode &node, const ModuleInstantiation &inst, size_t l,   							const Context *ctx, const EvalContext *evalctx)  {  	if (evalctx->numArgs() > l) { @@ -87,6 +99,26 @@ void for_eval(AbstractNode &node, const ModuleInstantiation &inst, size_t l,  	}  } +const EvalContext* ControlModule::getLastModuleCtx(const EvalContext *evalctx) +{ +	// Find the last custom module invocation, which will contain +	// an eval context with the children of the module invokation +	const Context *tmpc = evalctx; +	while (tmpc->parent) { +		const ModuleContext *modulectx = dynamic_cast<const ModuleContext*>(tmpc->parent); +		if (modulectx) { +			// This will trigger if trying to invoke child from the root of any file +			// assert(filectx->evalctx); +			if (modulectx->evalctx) { +				return modulectx->evalctx; +			} +			return NULL; +		} +		tmpc = tmpc->parent; +	} +	return NULL; +} +  AbstractNode *ControlModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const  {  	AbstractNode *node = NULL; @@ -107,27 +139,35 @@ AbstractNode *ControlModule::instantiate(const Context *ctx, const ModuleInstant  		// Find the last custom module invocation, which will contain  		// an eval context with the children of the module invokation -		const Context *tmpc = evalctx; -		while (tmpc->parent) { -			const ModuleContext *filectx = dynamic_cast<const ModuleContext*>(tmpc->parent); -			if (filectx) { -        // This will trigger if trying to invoke child from the root of any file -        // assert(filectx->evalctx); - -				if (filectx->evalctx) { -					if (n < (int)filectx->evalctx->numChildren()) { -						node = filectx->evalctx->getChild(n)->evaluate(filectx->evalctx); -					} -					else { -						// How to deal with negative objects in this case? +		const EvalContext *modulectx = getLastModuleCtx(evalctx); +		if (modulectx==NULL) { +			return NULL; +		} +		// This will trigger if trying to invoke child from the root of any file +        if (n < (int)modulectx->numChildren()) { +			node = modulectx->getChild(n)->evaluate(modulectx); +		} +		else { +			// How to deal with negative objects in this case?              // (e.g. first child of difference is invalid) -						PRINTB("WARNING: Child index (%d) out of bounds (%d children)",  -									 n % filectx->evalctx->numChildren()); -					} -				} -				return node; -			} -			tmpc = tmpc->parent; +			PRINTB("WARNING: Child index (%d) out of bounds (%d children)",  +				   n % modulectx->numChildren()); +		} +		return node; +	} + +	if (type == CHILDREN) +	{ +		const EvalContext *modulectx = getLastModuleCtx(evalctx); +		if (modulectx==NULL) { +			return NULL; +		} +		AbstractNode* node = new AbstractNode(inst); +		// This will trigger if trying to invoke child from the root of any file +		// assert(filectx->evalctx); +		for (int n = 0; n < (int)modulectx->numChildren(); ++n) { +			AbstractNode* childnode = modulectx->getChild(n)->evaluate(modulectx); +			node->children.push_back(childnode);  		}  		return node;  	} @@ -183,10 +223,11 @@ AbstractNode *ControlModule::instantiate(const Context *ctx, const ModuleInstant  void register_builtin_control()  { -	Builtins::init("child", new ControlModule(CHILD)); -	Builtins::init("echo", new ControlModule(ECHO)); -	Builtins::init("assign", new ControlModule(ASSIGN)); -	Builtins::init("for", new ControlModule(FOR)); -	Builtins::init("intersection_for", new ControlModule(INT_FOR)); -	Builtins::init("if", new ControlModule(IF)); +	Builtins::init("child", new ControlModule(ControlModule::CHILD)); +	Builtins::init("children", new ControlModule(ControlModule::CHILDREN)); +	Builtins::init("echo", new ControlModule(ControlModule::ECHO)); +	Builtins::init("assign", new ControlModule(ControlModule::ASSIGN)); +	Builtins::init("for", new ControlModule(ControlModule::FOR)); +	Builtins::init("intersection_for", new ControlModule(ControlModule::INT_FOR)); +	Builtins::init("if", new ControlModule(ControlModule::IF));  } diff --git a/src/highlighter.cc b/src/highlighter.cc index 4b4aa30..1da0e88 100644 --- a/src/highlighter.cc +++ b/src/highlighter.cc @@ -154,7 +154,7 @@ Highlighter::Highlighter(QTextDocument *parent)  	tokentypes["import"] << "include" << "use" << "import_stl" << "import" << "import_dxf" << "dxf_dim" << "dxf_cross" << "surface";  	typeformats["import"].setForeground(Qt::darkYellow); -	tokentypes["special"] << "$children" << "child" << "$fn" << "$fa" << "$fs" << "$t" << "$vpt" << "$vpr"; +	tokentypes["special"] << "$children" << "child" << "children" << "$fn" << "$fa" << "$fs" << "$t" << "$vpt" << "$vpr";  	typeformats["special"].setForeground(Qt::darkGreen);  	tokentypes["extrude"] << "linear_extrude" << "rotate_extrude";  | 
