Beispiel #1
0
    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
Beispiel #2
0
 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)
Beispiel #3
0
    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))
Beispiel #4
0
 def __init__(self, *nodes):
     super().__init__(*(x for x in nodes if not check.is_null(x)))