diff options
| author | kintel <kintel@b57f626f-c46c-0410-a088-ec61d464b74c> | 2010-02-12 13:20:15 (GMT) | 
|---|---|---|
| committer | kintel <kintel@b57f626f-c46c-0410-a088-ec61d464b74c> | 2010-02-12 13:20:15 (GMT) | 
| commit | 572631746157766359a878c7b52d0c26ae731496 (patch) | |
| tree | 4bdcfc0176a0cf4e455a78c6e35cf2ff706ce7c9 /src | |
| parent | 501fc8d3a3503c88b54d37ede5388ac81814a330 (diff) | |
Support for if-else statements
git-svn-id: http://svn.clifford.at/openscad/trunk@436 b57f626f-c46c-0410-a088-ec61d464b74c
Diffstat (limited to 'src')
| -rw-r--r-- | src/control.cc | 15 | ||||
| -rw-r--r-- | src/lexer.l | 2 | ||||
| -rw-r--r-- | src/module.cc | 6 | ||||
| -rw-r--r-- | src/module.h | 9 | ||||
| -rw-r--r-- | src/parser.y | 63 | 
5 files changed, 83 insertions, 12 deletions
| diff --git a/src/control.cc b/src/control.cc index d0b96a1..5b7e1b1 100644 --- a/src/control.cc +++ b/src/control.cc @@ -149,12 +149,21 @@ AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstantiation  	if (type == IF)  	{ -		if (inst->argvalues.size() > 0 && inst->argvalues[0].type == Value::BOOL && inst->argvalues[0].b) -			foreach (ModuleInstantiation *v, inst->children) { -				AbstractNode *n = v->evaluate(inst->ctx); +		const IfElseModuleInstantiation *ifelse = dynamic_cast<const IfElseModuleInstantiation*>(inst); +		if (ifelse->argvalues.size() > 0 && ifelse->argvalues[0].type == Value::BOOL && ifelse->argvalues[0].b) { +			foreach (ModuleInstantiation *v, ifelse->children) { +				AbstractNode *n = v->evaluate(ifelse->ctx);  				if (n != NULL)  					node->children.append(n);  			} +		} +		else { +			foreach (ModuleInstantiation *v, ifelse->else_children) { +				AbstractNode *n = v->evaluate(ifelse->ctx); +				if (n != NULL) +					node->children.append(n); +			} +		}  	}  	return node; diff --git a/src/lexer.l b/src/lexer.l index b051a5d..5a5c0e9 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -96,6 +96,8 @@ extern const char *parser_source_path;  "module"	return TOK_MODULE;  "function"	return TOK_FUNCTION; +"if"		return TOK_IF; +"else"		return TOK_ELSE;  "true"		return TOK_TRUE;  "false"		return TOK_FALSE; diff --git a/src/module.cc b/src/module.cc index 51d191e..c165131 100644 --- a/src/module.cc +++ b/src/module.cc @@ -61,6 +61,12 @@ ModuleInstantiation::~ModuleInstantiation()  		delete v;  } +IfElseModuleInstantiation::~IfElseModuleInstantiation() +{ +	foreach (ModuleInstantiation *v, else_children) +		delete v; +} +  QString ModuleInstantiation::dump(QString indent) const  {  	QString text = indent; diff --git a/src/module.h b/src/module.h index 35cc872..20ea1af 100644 --- a/src/module.h +++ b/src/module.h @@ -22,12 +22,19 @@ public:  	const class Context *ctx;  	ModuleInstantiation() : tag_root(false), tag_highlight(false), tag_background(false), ctx(NULL) { } -	~ModuleInstantiation(); +	virtual ~ModuleInstantiation();  	QString dump(QString indent) const;  	class AbstractNode *evaluate(const Context *ctx) const;  }; +class IfElseModuleInstantiation : public ModuleInstantiation { +public: +	virtual ~IfElseModuleInstantiation(); + +	QVector<ModuleInstantiation*> else_children; +}; +  class AbstractModule  {  public: diff --git a/src/parser.y b/src/parser.y index 7bee0c1..a0e4ac9 100644 --- a/src/parser.y +++ b/src/parser.y @@ -62,12 +62,15 @@ public:  	class Value *value;  	class Expression *expr;  	class ModuleInstantiation *inst; +	class IfElseModuleInstantiation *ifelse;  	class ArgContainer *arg;  	class ArgsContainer *args;  }  %token TOK_MODULE  %token TOK_FUNCTION +%token TOK_IF +%token TOK_ELSE  %token <text> TOK_ID  %token <text> TOK_STRING @@ -96,6 +99,9 @@ public:  %type <expr> vector_expr  %type <inst> module_instantiation +%type <ifelse> if_statement +%type <ifelse> ifelse_statement +%type <inst> children_instantiation  %type <inst> module_instantiation_list  %type <inst> single_module_instantiation @@ -161,29 +167,70 @@ statement:  		delete $4;  	} ';' ; -module_instantiation: -	single_module_instantiation ';' { +/* Will return a dummy parent node with zero or more children */ +children_instantiation: +	module_instantiation { +		$$ = new ModuleInstantiation(); +		if ($1) { +			$$->children.append($1); +		} else { +			delete $1; +		} +	} | +	'{' module_instantiation_list '}' { +		$$ = $2; +	} ; + +if_statement: +	TOK_IF '(' expr ')' children_instantiation { +		$$ = new IfElseModuleInstantiation(); +		$$->modname = "if"; +		$$->argnames.append(QString()); +		$$->argexpr.append($3); + +		if ($$) { +			$$->children = $5->children; +		} else { +			for (int i = 0; i < $5->children.count(); i++) +				delete $5->children[i]; +		} +		$5->children.clear(); +		delete $5; +	} ; + +ifelse_statement: +	if_statement {  		$$ = $1;  	} | -	single_module_instantiation '{' module_instantiation_list '}' { +	if_statement TOK_ELSE children_instantiation {  		$$ = $1;  		if ($$) { -			$$->children = $3->children; +			$$->else_children = $3->children;  		} else {  			for (int i = 0; i < $3->children.count(); i++)  				delete $3->children[i];  		}  		$3->children.clear();  		delete $3; +	} ; + +module_instantiation: +	single_module_instantiation ';' { +		$$ = $1;  	} | -	single_module_instantiation module_instantiation { +	single_module_instantiation children_instantiation {  		$$ = $1;  		if ($$) { -			if ($2) -				$$->children.append($2); +			$$->children = $2->children;  		} else { -			delete $2; +			for (int i = 0; i < $2->children.count(); i++) +				delete $2->children[i];  		} +		$2->children.clear(); +		delete $2; +	} | +	ifelse_statement { +		$$ = $1;  	} ;  module_instantiation_list: | 
