예제 #1
0
    def emit(self, context):
        if self.op == '&':
            return self.rhs.reference().emit(context)
        elif self.op == '*':
            return self.rhs.dereference().emit(context)
        elif self.op == '-':
            rhs = self.rhs.emit(context)
            return context.builder.neg(rhs)
        elif self.op == '~':
            rhs = self.rhs.emit(context)
            return context.builder.not_(rhs)
        elif self.op == '!':
            # Logical not
            rhs = self.rhs.emit(context)
            zero = ir.Constant(context.word_type, 0)
            is_zero = context.builder.icmp_unsigned('==', rhs, zero)
            return context.builder.zext(is_zero, context.word_type)
        elif self.op in ['++', '--']:
            # pre-{inc,dec}rement
            rhs = self.rhs.emit(context)
            rhs_addr_val = self.rhs.reference().emit(context)
            rhs_ptr = address_to_llvm_ptr(context, rhs_addr_val,
                                          context.word_type.as_pointer())
            one = ir.Constant(context.word_type, 1)
            if self.op == '++':
                val = context.builder.add(rhs, one)
            else:
                val = context.builder.sub(rhs, one)
            context.builder.store(val, rhs_ptr)
            return val

        raise exc.InternalCompilerError('Unknown unary op: {}'.format(self.op))
예제 #2
0
def _emit_binary_op(context, lhs, op, rhs):
    # No short-cutting in B(!)
    lhs_val, rhs_val = lhs.emit(context), rhs.emit(context)

    if op in _SIMPLE_OPS:
        instr_name = _SIMPLE_OPS[op]
        return getattr(context.builder, instr_name)(lhs_val, rhs_val)

    if op in _REL_OPS:
        cmp_val = context.builder.icmp_signed(op, lhs_val, rhs_val)
        return context.builder.zext(cmp_val, context.word_type)

    raise exc.InternalCompilerError('Unknown binary op: {}'.format(op))
예제 #3
0
    def emit(self, context):
        if self.op in ['++', '--']:
            # post-{inc,dec}rement
            lhs = self.lhs.emit(context)
            lhs_addr_val = self.lhs.reference().emit(context)
            lhs_ptr = address_to_llvm_ptr(context, lhs_addr_val,
                                          context.word_type.as_pointer())
            one = ir.Constant(context.word_type, 1)
            if self.op == '++':
                val = context.builder.add(lhs, one)
            else:
                val = context.builder.sub(lhs, one)
            context.builder.store(val, lhs_ptr)
            return lhs

        raise exc.InternalCompilerError('Unknown unary op: {}'.format(self.op))
예제 #4
0
파일: __init__.py 프로젝트: rjw57/rbc
def make_node(type_name, **kwargs):
    """Construct an AST node given the type name and a set of keyword arguments.

    Returns:
        An :py:class:`.astnode.ASTNode` object.

    Raises:
        InternalCompilerError if type_name does not correspond to a known node.

    """

    try:
        return astnode.make_node(type_name, **kwargs)
    except KeyError:
        raise exc.InternalCompilerError(
            'Unknown AST node: {}'.format(type_name))
예제 #5
0
    def emit(self, context):
        if self.name == '__bytes_per_word':
            return ir.Constant(context.word_type, context.bytes_per_word)

        raise exc.InternalCompilerError('Unknown builtin value: {}'.format(
            self.name))
예제 #6
0
 def _wrapped_emit(self, context):
     if context.builder is None:
         raise exc.InternalCompilerError('AST node requires builder.')
     return emit(self, context)