From bea7aee068e1d9b3e0ff0c36474d03c37b2752b3 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner <inform@tiker.net> Date: Tue, 25 Jul 2017 13:25:01 -0500 Subject: [PATCH] Fortran: Support for else if --- loopy/frontend/fortran/translator.py | 42 ++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/loopy/frontend/fortran/translator.py b/loopy/frontend/fortran/translator.py index 7a08984f8..e801d09dc 100644 --- a/loopy/frontend/fortran/translator.py +++ b/loopy/frontend/fortran/translator.py @@ -212,6 +212,7 @@ class F2LoopyTranslator(FTreeWalkerBase): self.instruction_tags = [] self.conditions = [] + self.conditions_data = [] self.filename = filename @@ -451,7 +452,7 @@ class F2LoopyTranslator(FTreeWalkerBase): # node.expr # node.content[0] - def map_IfThen(self, node): + def realize_conditional(self, node, context_cond=None): scope = self.scope_stack[-1] cond_name = intern("loopy_cond%d" % self.condition_id_counter) @@ -466,22 +467,53 @@ class F2LoopyTranslator(FTreeWalkerBase): self.add_expression_instruction( cond_var, self.parse_expr(node, node.expr)) - self.conditions.append(cond_name) + cond_expr = cond_var + if context_cond is not None: + from pymbolic.primitives import LogicalAnd + cond_expr = LogicalAnd((cond_var, context_cond)) + + self.conditions_data.append((context_cond, cond_var)) + else: + self.conditions_data.append((None, cond_var)) + + self.conditions.append(cond_expr) + def map_IfThen(self, node): self.block_nest.append("if") + self.realize_conditional(node, None) + for c in node.content: self.rec(c) + def construct_else_condition(self): + context_cond, prev_cond = self.conditions_data.pop() + if prev_cond is None: + raise RuntimeError("else if may not follow else") + + self.conditions.pop() + + from pymbolic.primitives import LogicalNot, LogicalAnd + else_expr = LogicalNot(prev_cond) + if context_cond is not None: + else_expr = LogicalAnd((else_expr, context_cond)) + + return else_expr + def map_Else(self, node): - cond_name = self.conditions.pop() - self.conditions.append("!" + cond_name) + else_cond = self.construct_else_condition() + self.conditions.append(else_cond) + self.conditions_data.append((else_cond, None)) + + def map_ElseIf(self, node): + self.realize_conditional(node, self.construct_else_condition()) def map_EndIfThen(self, node): if not self.block_nest: - raise TranslationError("no if block started at end do") + raise TranslationError("no if block started at end if") if self.block_nest.pop() != "if": raise TranslationError("mismatched end if") + self.conditions_data.pop() self.conditions.pop() def map_Do(self, node): -- GitLab