def visit_IF(self, node): expr_ = (yield ToVisit(node.children[0])) then_ = (yield ToVisit(node.children[1])) else_ = (yield ToVisit(node.children[2])) if len(node.children) == 3 else self.NOP if self.O_LEVEL >= 1: if chk.is_null(then_, else_): src.api.errmsg.warning_empty_if(node.lineno) yield self.NOP return block_accessed = chk.is_block_accessed(then_) or chk.is_block_accessed(else_) if not block_accessed and chk.is_number(expr_): # constant condition if expr_.value: # always true (then_) yield then_ else: # always false (else_) yield else_ return if chk.is_null(else_) and len(node.children) == 3: node.children.pop() # remove empty else yield node return for i in range(len(node.children)): node.children[i] = (expr_, then_, else_)[i] yield node
def append(self, *args): for arg in args: if check.is_null(arg): continue assert isinstance(arg, Symbol), f"Invalid argument '{arg}'" if arg.token == 'BLOCK': self.append(*arg.children) else: self.children.append(arg)
def visit_BLOCK(self, node): warning_emitted = False i = 0 while i < len(node): sentence = node[i] if chk.is_ender(sentence): j = i + 1 while j < len(node): if chk.is_LABEL(node[j]): break if node[j].token == 'FUNCDECL': j += 1 continue if node[j].token == 'SENTENCE' \ and node[j].is_sentinel: # "Sentinel" instructions can be freely removed node.pop(j) continue if node[j].token == 'ASM': break # User's ASM must always be left there if not warning_emitted and self.O_LEVEL > 0: warning_emitted = True errmsg.warning_unreachable_code(lineno=node[j].lineno, fname=node[j].filename) if self.O_LEVEL < 2: break node.pop(j) i += 1 if self.O_LEVEL >= 1 and chk.is_null(node): yield self.NOP return yield (yield self.generic_visit(node))
def __init__(self, *nodes): super().__init__(*(x for x in nodes if not check.is_null(x)))