def constant(self, x): if isinstance(x, bool): return TypedExpression(self, native_ast.const_bool_expr(x), bool, False) if isinstance(x, int): return TypedExpression(self, native_ast.const_int_expr(x), int, False) if isinstance(x, float): return TypedExpression(self, native_ast.const_float_expr(x), float, False) assert False
def isInitializedVarExpr(self, name): return TypedExpression(self, native_ast.Expression.StackSlot( name=name + ".isInitialized", type=native_ast.Bool), bool, isReference=True)
def convertBoolOp(depth=0): with self.subcontext() as sc: value = self.convert_expression_ast(ast.values[depth]) value = TypedExpression.asBool(value) if value is not None: if depth == len(ast.values) - 1: sc.expr = value.expr else: tail_expr = convertBoolOp(depth + 1) if ast.op.matches.And: sc.expr = native_ast.Expression.Branch( cond=value.expr, true=tail_expr, false=native_ast.falseExpr) elif ast.op.matches.Or: sc.expr = native_ast.Expression.Branch( cond=value.expr, true=native_ast.trueExpr, false=tail_expr) else: raise Exception( f"Unknown kind of Boolean operator: {ast.op.Name}" ) return sc.result
def pushLet(self, type, expression, isReference): """Push an arbitrary expression onto the stack.""" varname = self.functionContext.let_varname() self.intermediates.append( ExpressionIntermediate.Simple(name=varname, expr=expression) ) return TypedExpression(self, native_ast.Expression.Variable(varname), type, isReference)
def pushReference(self, type, expression): """Push a reference to an object that's guaranteed to be alive for the duration of the expression.""" type = typeWrapper(type) varname = self.functionContext.let_varname() self.intermediates.append( ExpressionIntermediate.Simple(name=varname, expr=expression) ) return TypedExpression(self, native_ast.Expression.Variable(varname), type, True)
def convert_default_initialize(self, context, target): if isinstance(None, self.typeRepresentation): target.convert_copy_initialize( TypedExpression(context, self, runtime_functions.get_pyobj_None.call(), False)) return context.pushException( TypeError, "Can't default-initialize %s" % self.typeRepresentation.__qualname__)
def construct_starargs_around(self, res, star_args_name): args_type = self._varname_to_type[star_args_name] stararg_slot = self.named_var_expr(star_args_name) return (args_type.convert_initialize(self, stararg_slot, [ TypedExpression( native_ast.Expression.Variable(".star_args.%s" % i), args_type.element_types[i][1]) for i in range(len(args_type.element_types)) ]).with_comment("initialize *args slot") + res)
def named_var_expr(self, name): if self.functionContext._varname_to_type[name] is None: raise ConversionException("variable %s is not in scope here" % name) slot_type = self.functionContext._varname_to_type[name] return TypedExpression(self, native_ast.Expression.StackSlot( name=name, type=slot_type.getNativeLayoutType()), slot_type, isReference=True)
def pushPod(self, type, expression): """stash an expression that generates POD passed as a value""" type = typeWrapper(type) assert type.is_pod assert not type.is_pass_by_ref varname = self.functionContext.let_varname() self.intermediates.append( ExpressionIntermediate.Simple(name=varname, expr=expression) ) return TypedExpression(self, native_ast.Expression.Variable(varname), type, False)
def push(self, type, callback, wantsTeardown=True): """Allocate a stackvariable of type 'type' and pass it to 'callback' which should return a native_ast.Expression or TypedExpression(None) initializing it. """ type = typeWrapper(type) if type.is_pod: wantsTeardown = False varname = self.functionContext.stack_varname() resExpr = TypedExpression( self, native_ast.Expression.StackSlot(name=varname, type=type.getNativeLayoutType()), type, True ) expr = callback(resExpr) if expr is None: expr = native_ast.nullExpr if isinstance(expr, TypedExpression): assert expr.expr_type.typeRepresentation is NoneType(), expr.expr_type expr = expr.expr else: assert isinstance(expr, native_ast.Expression) self.intermediates.append( ExpressionIntermediate.StackSlot( name=varname, expr=expr if not wantsTeardown else expr >> native_ast.Expression.ActivatesTeardown(varname) ) ) if wantsTeardown: with self.subcontext() as sc: type.convert_destroy(self, resExpr) self.teardowns.append( native_ast.Teardown.ByTag( tag=varname, expr=sc.result ) ) return resExpr
def allocateUninitializedSlot(self, type): type = typeWrapper(type) varname = self.functionContext.stack_varname() resExpr = TypedExpression( self, native_ast.Expression.StackSlot(name=varname, type=type.getNativeLayoutType()), type, True) if not type.is_pod: with self.subcontext() as sc: type.convert_destroy(self, resExpr) self.teardowns.append( native_ast.Teardown.ByTag(tag=varname, expr=sc.result)) return resExpr
def convert_statement_ast(self, ast): if ast.matches.Assign or ast.matches.AugAssign: if ast.matches.Assign: assert len(ast.targets) == 1 op = None target = ast.targets[0] else: target = ast.target op = ast.op if target.matches.Name and target.ctx.matches.Store: varname = target.id if varname not in self._varname_to_type: self._varname_to_type[varname] = None subcontext = ExpressionConversionContext(self) val_to_store = subcontext.convert_expression_ast(ast.value) if val_to_store is None: return subcontext.finalize(None), False if op is not None: if varname not in self._varname_to_type: raise NotImplementedError() else: slot_ref = subcontext.named_var_expr(varname) val_to_store = slot_ref.convert_bin_op( op, val_to_store) if val_to_store is None: return subcontext.finalize(None), False self.generateAssignmentExpr(varname, val_to_store) return subcontext.finalize(None).with_comment("Assign %s" % (varname)), True if target.matches.Subscript and target.ctx.matches.Store: assert target.slice.matches.Index subcontext = ExpressionConversionContext(self) slicing = subcontext.convert_expression_ast(target.value) if slicing is None: return subcontext.finalize(None), False index = subcontext.convert_expression_ast(target.slice.value) if slicing is None: return subcontext.finalize(None), False val_to_store = subcontext.convert_expression_ast(ast.value) if val_to_store is None: return subcontext.finalize(None), False if op is not None: val_to_store = slicing.convert_getitem( index).convert_bin_op(op, val_to_store) if val_to_store is None: return subcontext.finalize(None), False slicing.convert_setitem(index, val_to_store) return subcontext.finalize(None), True if target.matches.Attribute and target.ctx.matches.Store: subcontext = ExpressionConversionContext(self) slicing = subcontext.convert_expression_ast(target.value) attr = target.attr val_to_store = subcontext.convert_expression_ast(ast.value) if val_to_store is None: return subcontext.finalize(None), False if op is not None: input_val = slicing.convert_attribute(attr) if input_val is None: return subcontext.finalize(None), False val_to_store = input_val.convert_bin_op(op, val_to_store) if val_to_store is None: return subcontext.finalize(None), False slicing.convert_set_attribute(attr, val_to_store) return subcontext.finalize(None), True if ast.matches.Return: subcontext = ExpressionConversionContext(self) if ast.value is None: e = subcontext.convert_expression_ast( python_ast.Expr.Num(n=python_ast.NumericConstant.None_())) else: e = subcontext.convert_expression_ast(ast.value) if e is None: return subcontext.finalize(None), False if not self._functionOutputTypeKnown: if self._varname_to_type.get(FunctionOutput) is None: self.markTypesAreUnstable() self._varname_to_type[FunctionOutput] = e.expr_type else: self.upsizeVariableType(FunctionOutput, e.expr_type) if e.expr_type != self._varname_to_type[FunctionOutput]: e = e.convert_to_type(self._varname_to_type[FunctionOutput]) if e is None: return subcontext.finalize(None), False if e.expr_type.is_pass_by_ref: returnTarget = TypedExpression( subcontext, native_ast.Expression.Variable(name=".return"), self._varname_to_type[FunctionOutput], True) returnTarget.convert_copy_initialize(e) subcontext.pushTerminal(native_ast.Expression.Return(arg=None)) else: subcontext.pushTerminal( native_ast.Expression.Return(arg=e.nonref_expr)) return subcontext.finalize(None), False if ast.matches.Expr: subcontext = ExpressionConversionContext(self) result_expr = subcontext.convert_expression_ast(ast.value) return subcontext.finalize(result_expr), result_expr is not None if ast.matches.If: cond_context = ExpressionConversionContext(self) cond = cond_context.convert_expression_ast(ast.test) if cond is None: return cond_context.finalize(None), False cond = cond.toBool() if cond is None: return cond_context.finalize(None), False if cond.expr.matches.Constant: truth_val = cond.expr.val.truth_value() branch, flow_returns = self.convert_statement_list_ast( ast.body if truth_val else ast.orelse) return cond.expr + branch, flow_returns true, true_returns = self.convert_statement_list_ast(ast.body) false, false_returns = self.convert_statement_list_ast(ast.orelse) return (native_ast.Expression.Branch( cond=cond_context.finalize(cond.nonref_expr), true=true, false=false), true_returns or false_returns) if ast.matches.Pass: return native_ast.nullExpr, True if ast.matches.While: cond_context = ExpressionConversionContext(self) cond = cond_context.convert_expression_ast(ast.test) if cond is None: return cond_context.finalize(None), False cond = cond.toBool() if cond is None: return cond_context.finalize(None), False true, true_returns = self.convert_statement_list_ast(ast.body) false, false_returns = self.convert_statement_list_ast(ast.orelse) return (native_ast.Expression.While( cond=cond_context.finalize(cond.nonref_expr), while_true=true, orelse=false), true_returns or false_returns) if ast.matches.Try: raise NotImplementedError() if ast.matches.For: if not ast.target.matches.Name: raise NotImplementedError( "Can't handle multi-variable loop expressions") target_var_name = ast.target.id # create a variable to hold the iterator, and instantiate it there iter_varname = target_var_name + ".iter." + str(ast.line_number) iterator_setup_context = ExpressionConversionContext(self) to_iterate = iterator_setup_context.convert_expression_ast( ast.iter) if to_iterate is None: return iterator_setup_context.finalize(to_iterate), False iterator_object = to_iterate.convert_method_call( "__iter__", (), {}) if iterator_object is None: return iterator_setup_context.finalize(iterator_object), False self.generateAssignmentExpr(iter_varname, iterator_object) cond_context = ExpressionConversionContext(self) iter_obj = cond_context.named_var_expr(iter_varname) next_ptr, is_populated = iter_obj.convert_next( ) # this conversion is special - it returns two values with cond_context.ifelse(is_populated.nonref_expr) as (if_true, if_false): with if_true: self.generateAssignmentExpr(target_var_name, next_ptr) true, true_returns = self.convert_statement_list_ast(ast.body) false, false_returns = self.convert_statement_list_ast(ast.orelse) return (iterator_setup_context.finalize(None) >> native_ast.Expression.While( cond=cond_context.finalize(is_populated), while_true=true, orelse=false), true_returns or false_returns) if ast.matches.Raise: raise NotImplementedError() raise ConversionException("Can't handle python ast Statement.%s" % ast._which)
def convert_expression_ast(self, ast): if ast.matches.Attribute: attr = ast.attr val = self.convert_expression_ast(ast.value) return val.convert_attribute(attr) if ast.matches.Name: assert ast.ctx.matches.Load if ast.id in self.functionContext._varname_to_type: with self.ifelse(self.isInitializedVarExpr(ast.id)) as (true,false): with false: self.pushException(UnboundLocalError, "local variable '%s' referenced before assignment" % ast.id) return self.named_var_expr(ast.id) if ast.id in self.functionContext._free_variable_lookup: return pythonObjectRepresentation(self, self.functionContext._free_variable_lookup[ast.id]) elif ast.id in __builtins__: return pythonObjectRepresentation(self, __builtins__[ast.id]) if ast.id not in self.functionContext._varname_to_type: self.pushException(NameError, "name '%s' is not defined" % ast.id) return None if ast.matches.Num: if ast.n.matches.None_: return pythonObjectRepresentation(self, None) if ast.n.matches.Boolean: return pythonObjectRepresentation(self, bool(ast.n.value)) if ast.n.matches.Int: return pythonObjectRepresentation(self, int(ast.n.value)) if ast.n.matches.Float: return pythonObjectRepresentation(self, float(ast.n.value)) if ast.matches.Str: return pythonObjectRepresentation(self, ast.s) if ast.matches.BoolOp: values = [] for v in ast.values: v = self.convert_expression_ast(v) if v is not None: v = v.toBool() values.append(v) op = ast.op expr_so_far = [] for v in ast.values: v = self.convert_expression_ast(v) if v is None: expr_so_far.append(None) break v = v.toBool() if v is None: expr_so_far.append(None) break expr_so_far.append(v.expr) if expr_so_far[-1] is None: if len(expr_so_far) == 1: return None elif expr_so_far[-1].matches.Constant: if (expr_so_far[-1].val.val and op.matches.Or or (not expr_so_far[-1].val.val) and op.matches.And): #this is a short-circuit if len(expr_so_far) == 1: return expr_so_far[0] return TypedExpression( self, native_ast.Expression.Sequence(expr_so_far), typeWrapper(bool), False ) else: expr_so_far.pop() if not expr_so_far: if op.matches.Or: #must have had all False constants return TypedExpression(self, native_ast.falseExpr, typeWrapper(bool), False) else: #must have had all True constants return TypedExpression(self, native_ast.trueExpr, typeWrapper(bool), False) while len(expr_so_far) > 1: l,r = expr_so_far[-2], expr_so_far[-1] expr_so_far.pop() expr_so_far.pop() if op.matches.And: new_expr = native_ast.Expression.Branch(cond=l, true=r, false=native_ast.falseExpr) else: new_expr = native_ast.Expression.Branch(cond=l, true=native_ast.trueExpr, false=r) expr_so_far.append(new_expr) return TypedExpression(self, expr_so_far[0], typeWrapper(bool), False) if ast.matches.BinOp: l = self.convert_expression_ast(ast.left) if l is None: return None r = self.convert_expression_ast(ast.right) if r is None: return None return l.convert_bin_op(ast.op, r) if ast.matches.UnaryOp: operand = self.convert_expression_ast(ast.operand) return operand.convert_unary_op(ast.op) if ast.matches.Subscript: assert ast.slice.matches.Index val = self.convert_expression_ast(ast.value) if val is None: return None index = self.convert_expression_ast(ast.slice.value) if index is None: return None return val.convert_getitem(index) if ast.matches.Call: l = self.convert_expression_ast(ast.func) if l is None: return None ast_args = ast.args stararg = None for a in ast_args: assert not a.matches.Starred, "not implemented yet" args = [] for a in ast_args: args.append(self.convert_expression_ast(a)) if args[-1] is None: return None return l.convert_call(args) if ast.matches.Compare: assert len(ast.comparators) == 1, "multi-comparison not implemented yet" assert len(ast.ops) == 1 l = self.convert_expression_ast(ast.left) r = self.convert_expression_ast(ast.comparators[0]) return l.convert_bin_op(ast.ops[0], r) if ast.matches.Tuple: raise NotImplementedError("not implemented yet") if ast.matches.IfExp: test = self.convert_expression_ast(ast.test) if test is None: return None test = test.toBool() if test is None: return None with self.ifelse(test) as (true_block, false_block): with true_block: true_res = self.convert_expression_ast(ast.body) with false_block: false_res = self.conversion_exception(ast.orelse) if true_res.expr_type != false_res.expr_type: out_type = typeWrapper(OneOf(true_res.expr_type.typeRepresentation, false_res.expr_type.typeRepresentation)) else: out_type = true_res.expr_type out_slot = self.allocateUninitializedSlot(out_type) with true_block: true_res = true_res.convert_to_type(out_type) out_slot.convert_copy_initialize(true_res) self.markUninitializedSlotInitialized(out_slot) with false_block: false_res = false_res.convert_to_type(out_type) out_slot.convert_copy_initialize(false_res) self.markUninitializedSlotInitialized(out_slot) return out_slot raise ConversionException("can't handle python expression type %s" % ast._which)
def pythonObjectRepresentation(context, f): if f is len: return TypedExpression(context, native_ast.nullExpr, LenWrapper(), False) if f is range: return TypedExpression(context, native_ast.nullExpr, _RangeWrapper, False) if f is bytecount: return TypedExpression(context, native_ast.nullExpr, BytecountWrapper(), False) if f is None: return TypedExpression( context, native_ast.Expression.Constant( val=native_ast.Constant.Void() ), NoneWrapper(), False ) if isinstance(f, bool): return TypedExpression( context, native_ast.Expression.Constant( val=native_ast.Constant.Int(val=f, bits=1, signed=False) ), BoolWrapper(), False ) if isinstance(f, int): return TypedExpression( context, native_ast.Expression.Constant( val=native_ast.Constant.Int(val=f, bits=64, signed=True) ), Int64Wrapper(), False ) if isinstance(f, float): return TypedExpression( context, native_ast.Expression.Constant( val=native_ast.Constant.Float(val=f, bits=64) ), Float64Wrapper(), False ) if isinstance(f, str): return StringWrapper().constant(context, f) if isinstance(f, bytes): return BytesWrapper().constant(context, f) if isinstance(f, type(pythonObjectRepresentation)): return TypedExpression( context, native_ast.nullExpr, PythonFreeFunctionWrapper(f), False ) if hasattr(f, '__typed_python_category__'): if f.__typed_python_category__ == "Function": return TypedExpression( context, native_ast.nullExpr, PythonTypedFunctionWrapper(f), False ) if isinstance(f, type): return TypedExpression(context, native_ast.nullExpr, PythonTypeObjectWrapper(f), False) if isinstance(f, ModuleType): return TypedExpression(context, native_ast.nullExpr, ModuleWrapper(f), False) return TypedExpression(context, native_ast.nullExpr, PythonFreeObjectWrapper(f), False)
def convert_expression_ast(self, ast): if ast.matches.Attribute: attr = ast.attr val = self.convert_expression_ast(ast.value) if val is None: return None return val.convert_attribute(attr) if ast.matches.Name: assert ast.ctx.matches.Load if ast.id in self.functionContext._varname_to_type: with self.ifelse(self.isInitializedVarExpr(ast.id)) as (true, false): with false: self.pushException( UnboundLocalError, "local variable '%s' referenced before assignment" % ast.id) return self.named_var_expr(ast.id) if ast.id in self.functionContext._free_variable_lookup: return pythonObjectRepresentation( self, self.functionContext._free_variable_lookup[ast.id]) elif ast.id in __builtins__: return pythonObjectRepresentation(self, __builtins__[ast.id]) if ast.id not in self.functionContext._varname_to_type: self.pushException(NameError, "name '%s' is not defined" % ast.id) return None if ast.matches.Num: if ast.n.matches.None_: return pythonObjectRepresentation(self, None) if ast.n.matches.Boolean: return pythonObjectRepresentation(self, bool(ast.n.value)) if ast.n.matches.Int: return pythonObjectRepresentation(self, int(ast.n.value)) if ast.n.matches.Float: return pythonObjectRepresentation(self, float(ast.n.value)) if ast.matches.Str: return pythonObjectRepresentation(self, ast.s) if ast.matches.BoolOp: def convertBoolOp(depth=0): with self.subcontext() as sc: value = self.convert_expression_ast(ast.values[depth]) value = TypedExpression.asBool(value) if value is not None: if depth == len(ast.values) - 1: sc.expr = value.expr else: tail_expr = convertBoolOp(depth + 1) if ast.op.matches.And: sc.expr = native_ast.Expression.Branch( cond=value.expr, true=tail_expr, false=native_ast.falseExpr) elif ast.op.matches.Or: sc.expr = native_ast.Expression.Branch( cond=value.expr, true=native_ast.trueExpr, false=tail_expr) else: raise Exception( f"Unknown kind of Boolean operator: {ast.op.Name}" ) return sc.result return TypedExpression(self, convertBoolOp(), typeWrapper(bool), False) if ast.matches.BinOp: lhs = self.convert_expression_ast(ast.left) if lhs is None: return None rhs = self.convert_expression_ast(ast.right) if rhs is None: return None return lhs.convert_bin_op(ast.op, rhs) if ast.matches.UnaryOp: operand = self.convert_expression_ast(ast.operand) return operand.convert_unary_op(ast.op) if ast.matches.Subscript: assert ast.slice.matches.Index val = self.convert_expression_ast(ast.value) if val is None: return None index = self.convert_expression_ast(ast.slice.value) if index is None: return None return val.convert_getitem(index) if ast.matches.Call: lhs = self.convert_expression_ast(ast.func) if lhs is None: return None for a in ast.args: assert not a.matches.Starred, "not implemented yet" args = [] kwargs = {} for a in ast.args: args.append(self.convert_expression_ast(a)) if args[-1] is None: return None for keywordArg in ast.keywords: argname = keywordArg.arg kwargs[argname] = self.convert_expression_ast(keywordArg.value) if kwargs[argname] is None: return None return lhs.convert_call(args, kwargs) if ast.matches.Compare: assert len( ast.comparators) == 1, "multi-comparison not implemented yet" assert len(ast.ops) == 1 lhs = self.convert_expression_ast(ast.left) if lhs is None: return None r = self.convert_expression_ast(ast.comparators[0]) if r is None: return None return lhs.convert_bin_op(ast.ops[0], r) if ast.matches.Tuple: raise NotImplementedError("not implemented yet") if ast.matches.IfExp: test = self.convert_expression_ast(ast.test) if test is None: return None test = test.toBool() if test is None: return None with self.ifelse(test) as (true_block, false_block): with true_block: true_res = self.convert_expression_ast(ast.body) with false_block: false_res = self.conversion_exception(ast.orelse) if true_res.expr_type != false_res.expr_type: out_type = typeWrapper( OneOf(true_res.expr_type.typeRepresentation, false_res.expr_type.typeRepresentation)) else: out_type = true_res.expr_type out_slot = self.allocateUninitializedSlot(out_type) with true_block: true_res = true_res.convert_to_type(out_type) out_slot.convert_copy_initialize(true_res) self.markUninitializedSlotInitialized(out_slot) with false_block: false_res = false_res.convert_to_type(out_type) out_slot.convert_copy_initialize(false_res) self.markUninitializedSlotInitialized(out_slot) return out_slot raise ConversionException("can't handle python expression type %s" % ast._which)
def convert_statement_ast(self, ast): if ast.matches.Assign or ast.matches.AugAssign: if ast.matches.Assign: assert len(ast.targets) == 1 op = None target = ast.targets[0] else: target = ast.target op = ast.op if target.matches.Name and target.ctx.matches.Store: varname = target.id if varname not in self._varname_to_type: self._varname_to_type[varname] = None subcontext = ExpressionConversionContext(self) val_to_store = subcontext.convert_expression_ast(ast.value) if val_to_store is None: return subcontext.finalize(None), False if op is not None: if varname not in self._varname_to_type: raise NotImplementedError() else: slot_ref = subcontext.named_var_expr(varname) val_to_store = slot_ref.convert_bin_op( op, val_to_store) if val_to_store is None: return subcontext.finalize(None), False self.upsizeVariableType(varname, val_to_store.expr_type) slot_ref = subcontext.named_var_expr(varname) #convert the value to the target type now that we've upsized it val_to_store = val_to_store.convert_to_type(slot_ref.expr_type) assert val_to_store is not None, "We should always be able to upsize" if slot_ref.expr_type.is_pod: slot_ref.convert_copy_initialize(val_to_store) subcontext.pushEffect( subcontext.isInitializedVarExpr(varname).expr.store( native_ast.trueExpr)) else: with subcontext.ifelse( subcontext.isInitializedVarExpr(varname)) as ( true_block, false_block): with true_block: slot_ref.convert_assign(val_to_store) with false_block: slot_ref.convert_copy_initialize(val_to_store) subcontext.pushEffect( subcontext.isInitializedVarExpr( varname).expr.store(native_ast.trueExpr)) return subcontext.finalize(None).with_comment("Assign %s" % (varname)), True if target.matches.Subscript and target.ctx.matches.Store: assert target.slice.matches.Index subcontext = ExpressionConversionContext(self) slicing = subcontext.convert_expression_ast(target.value) if slicing is None: return subcontext.finalize(None), False index = subcontext.convert_expression_ast(target.slice.value) if slicing is None: return subcontext.finalize(None), False val_to_store = subcontext.convert_expression_ast(ast.value) if val_to_store is None: return subcontext.finalize(None), False if op is not None: val_to_store = slicing.convert_getitem( index).convert_bin_op(op, val_to_store) if val_to_store is None: return subcontext.finalize(None), False slicing.convert_setitem(index, val_to_store) return subcontext.finalize(None), True if target.matches.Attribute and target.ctx.matches.Store: subcontext = ExpressionConversionContext(self) slicing = subcontext.convert_expression_ast(target.value) attr = target.attr val_to_store = subcontext.convert_expression_ast(ast.value) if val_to_store is None: return subcontext.finalize(None), False if op is not None: input_val = slicing.convert_attribute(attr) if input_val is None: return subcontext.finalize(None), False val_to_store = input_val.convert_bin_op(op, val_to_store) if val_to_store is None: return subcontext.finalize(None), False slicing.convert_set_attribute(attr, val_to_store) return subcontext.finalize(None), True if ast.matches.Return: subcontext = ExpressionConversionContext(self) if ast.value is None: e = subcontext.convert_expression_ast( python_ast.Expr.Num(n=python_ast.NumericConstant.None_())) else: e = subcontext.convert_expression_ast(ast.value) if e is None: return subcontext.finalize(None), False if not self._functionOutputTypeKnown: if self._varname_to_type.get(FunctionOutput) is None: self._typesAreUnstable = True self._varname_to_type[FunctionOutput] = e.expr_type else: self.upsizeVariableType(FunctionOutput, e.expr_type) if e.expr_type != self._varname_to_type[FunctionOutput]: e = e.convert_to_type(self._varname_to_type[FunctionOutput]) if e is None: return subcontext.finalize(None), False if e.expr_type.is_pass_by_ref: returnTarget = TypedExpression( subcontext, native_ast.Expression.Variable(name=".return"), self._varname_to_type[FunctionOutput], True) returnTarget.convert_copy_initialize(e) subcontext.pushTerminal(native_ast.Expression.Return(arg=None)) else: subcontext.pushTerminal( native_ast.Expression.Return(arg=e.nonref_expr)) return subcontext.finalize(None), False if ast.matches.Expr: subcontext = ExpressionConversionContext(self) result_expr = subcontext.convert_expression_ast(ast.value) return subcontext.finalize(result_expr), result_expr is not None if ast.matches.If: cond_context = ExpressionConversionContext(self) cond = cond_context.convert_expression_ast(ast.test) if cond is None: return cond.finalize(None), False cond = cond.toBool() if cond is None: return cond.finalize(None), False if cond.expr.matches.Constant: truth_val = cond.expr.val.truth_value() branch, flow_returns = self.convert_statement_list_ast( ast.body if truth_val else ast.orelse) return cond.expr + branch, flow_returns true, true_returns = self.convert_statement_list_ast(ast.body) false, false_returns = self.convert_statement_list_ast(ast.orelse) return (native_ast.Expression.Branch( cond=cond_context.finalize(cond.nonref_expr), true=true, false=false), true_returns or false_returns) if ast.matches.Pass: return native_ast.nullExpr, True if ast.matches.While: cond_context = ExpressionConversionContext(self) cond = cond_context.convert_expression_ast(ast.test) if cond is None: return cond_context.finalize(None), False cond = cond.toBool() if cond is None: return cond_context.finalize(None), False true, true_returns = self.convert_statement_list_ast(ast.body) false, false_returns = self.convert_statement_list_ast(ast.orelse) return (native_ast.Expression.While( cond=cond_context.finalize(cond.nonref_expr), while_true=true, orelse=false), true_returns or false_returns) if ast.matches.Try: raise NotImplementedError() if ast.matches.For: raise NotImplementedError() if ast.matches.Raise: raise NotImplementedError() raise ConversionException("Can't handle python ast Statement.%s" % ast._which)
def inputArg(self, type, name): return TypedExpression(self, native_ast.Expression.Variable(name), type, type.is_pass_by_ref)
def pushVoid(self, t=None): if t is None: t = typeWrapper(type(None)) assert t.is_empty, t return TypedExpression(self, native_ast.nullExpr, t, False)