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))
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))
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))
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))
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))
def _wrapped_emit(self, context): if context.builder is None: raise exc.InternalCompilerError('AST node requires builder.') return emit(self, context)