diff options
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: |