def _convert(node):
if isinstance(node, ast.Str):
return node.s
elif isinstance(node, ast.Num):
return node.n
elif isinstance(node, ast.Tuple):
return tuple(map(_convert, node.elts))
elif isinstance(node, ast.List):
return list(map(_convert, node.elts))
elif isinstance(node, ast.Dict):
return dict((_convert(k), _convert(v)) for k, v
in zip(node.keys, node.values))
elif isinstance(node, ast.Name):
if node.id in SAFE_CONSTANTS:
return SAFE_CONSTANTS[node.id]
raise ValueError('malformed or disallowed expression')
python类Num()的实例源码
def convert_to_value(item):
if isinstance(item, ast.Str):
return item.s
elif hasattr(ast, 'Bytes') and isinstance(item, ast.Bytes):
return item.s
elif isinstance(item, ast.Tuple):
return tuple(convert_to_value(i) for i in item.elts)
elif isinstance(item, ast.Num):
return item.n
elif isinstance(item, ast.Name):
result = VariableKey(item=item)
constants_lookup = {
'True': True,
'False': False,
'None': None,
}
return constants_lookup.get(
result.name,
result,
)
elif (not PY33) and isinstance(item, ast.NameConstant):
# None, True, False are nameconstants in python3, but names in 2
return item.value
else:
return UnhandledKeyType()
def convert_to_value(item):
if isinstance(item, ast.Str):
return item.s
elif hasattr(ast, 'Bytes') and isinstance(item, ast.Bytes):
return item.s
elif isinstance(item, ast.Tuple):
return tuple(convert_to_value(i) for i in item.elts)
elif isinstance(item, ast.Num):
return item.n
elif isinstance(item, ast.Name):
result = VariableKey(item=item)
constants_lookup = {
'True': True,
'False': False,
'None': None,
}
return constants_lookup.get(
result.name,
result,
)
elif (not PY33) and isinstance(item, ast.NameConstant):
# None, True, False are nameconstants in python3, but names in 2
return item.value
else:
return UnhandledKeyType()
def make_const(arg, lineno=0, col_offset=0):
kw = {'lineno':lineno, 'col_offset':col_offset}
if isinstance(arg, str):
const = _ast.Str(s=arg, **kw)
elif isinstance(arg, (int, float, complex)):
const = _ast.Num(n=arg, **kw)
elif arg is None:
const = _ast.Name(id='None', ctx=_ast.Load(), **kw)
elif isinstance(arg, tuple):
elts = []
for item in arg:
elts.append(make_const(item, **kw))
const = _ast.Tuple(elts=elts, ctx=_ast.Load(), **kw)
else:
const = arg
return const
def _(item, body=None, top=False):
if top and len(item.args) != 0:
if isinstance(item.args[0], _ast.Call):
_transform(item.args[0], body=body, top=top)
if not isinstance(item.args[0], (_ast.Name, _ast.Num)):
syntax = ast.parse('tmpcall{} = b'.format(randint(0, 2**32))).body[0]
syntax.value = item.args[0]
item.args[0] = syntax.targets[0]
body.extend((syntax, item))
return True
return False
def visit_Assign(self, node):
if len(node.targets) > 1:
raise SyntaxError("GPUMAP: multiple assignment not supported")
target_types = map(lambda target: type(target), node.targets)
if tuple in target_types or list in target_types:
raise SyntaxError("GPUMAP: No unpacking allowed")
target = node.targets[0]
# assignment into object field
output = ""
value = self.visit(node.value)
# assignment into variable
if isinstance(target, _ast.Name):
# assignment into new variable
# not sure about the type just yet..
# see if it's a primitive
if target.id not in self.local_vars:
# binops and boolops return primitives
if isinstance(node.value, _ast.Num) or isinstance(node.value, _ast.Compare) or isinstance(node.value, _ast.BinOp) \
or isinstance(node.value, _ast.BoolOp) or isinstance(node.value, _ast.NameConstant):
output += "auto "
# check if referenced list contains primitives
elif isinstance(node.value, _ast.Subscript):
list_name = value[:value.find("[")]
try:
idx = self.func_repr.args.index(list_name)
t = self.func_repr.arg_types[idx]
item_type = t[t.find("<") + 1: t.find(">")]
if item_type in map(lambda t: t.__name__, primitive_map.keys()):
output += "auto "
else:
output += "auto&& "
except:
raise RuntimeError("THIS SHOULD NEVER HAPPEN")
else:
# check if it's an existing variable
try:
idx = self.func_repr.args.index(value)
t = self.func_repr.arg_types[idx]
if t in primitive_map:
output += "auto "
else:
output += "auto&& "
except ValueError:
output += "auto&& "
self.local_vars[target.id] = None
output += self.visit(target)
output += " = " + value
return output
def _get_literal_value(self, literal):
'''Utility function to turn AST literals into native Python types
:param literal: The AST literal to convert
:return: The value of the AST literal
'''
if isinstance(literal, _ast.Num):
literal_value = literal.n
elif isinstance(literal, _ast.Str):
literal_value = literal.s
elif isinstance(literal, _ast.List):
return_list = list()
for li in literal.elts:
return_list.append(self._get_literal_value(li))
literal_value = return_list
elif isinstance(literal, _ast.Tuple):
return_tuple = tuple()
for ti in literal.elts:
return_tuple = return_tuple + (self._get_literal_value(ti),)
literal_value = return_tuple
elif isinstance(literal, _ast.Set):
return_set = set()
for si in literal.elts:
return_set.add(self._get_literal_value(si))
literal_value = return_set
elif isinstance(literal, _ast.Dict):
literal_value = dict(zip(literal.keys, literal.values))
elif isinstance(literal, _ast.Ellipsis):
# what do we want to do with this?
literal_value = None
elif isinstance(literal, _ast.Name):
literal_value = literal.id
# NOTE(sigmavirus24): NameConstants are only part of the AST in Python
# 3. NameConstants tend to refer to things like True and False. This
# prevents them from being re-assigned in Python 3.
elif six.PY3 and isinstance(literal, _ast.NameConstant):
literal_value = str(literal.value)
# NOTE(sigmavirus24): Bytes are only part of the AST in Python 3
elif six.PY3 and isinstance(literal, _ast.Bytes):
literal_value = literal.s
else:
literal_value = None
return literal_value
def while_loop(self, instr, loop_block):
kw = dict(lineno=instr.lineno, col_offset=0)
loop_block_map = {instr.i:instr.op for instr in loop_block}
first_i = loop_block[0].i
func = lambda instr: instr.opname == 'JUMP_ABSOLUTE' and instr.oparg == first_i
body_index = rfind_index(loop_block[:-1], func)
if body_index is None:
const_while = True
body_index = len(loop_block) - 1
else:
if body_index + 1 < len(loop_block):
pop_block = loop_block[body_index + 1]
const_while = pop_block.opname != 'POP_BLOCK'
const_else = True
else:
const_while = True
const_else = False
if const_while:
test = _ast.Num(1, **kw)
body_ = self.decompile_block(loop_block[:body_index]).stmnt()
else_block = loop_block[body_index + 1:]
if else_block:
else_ = self.decompile_block(else_block).stmnt()
else:
else_ = []
else:
pop_block = loop_block[body_index + 1]
func = lambda instr: instr.opname in ['POP_JUMP_IF_FALSE', 'POP_JUMP_IF_TRUE'] and instr.oparg == pop_block.i
idx = rfind_index(loop_block[:body_index], func)
cond_block = loop_block[:idx]
iter_stmnt = self.decompile_block(cond_block).stmnt()
assert len(iter_stmnt) == 1
test = iter_stmnt[0]
body_ = self.decompile_block(loop_block[idx + 1:body_index]).stmnt()
else_block = loop_block[body_index + 2:]
if else_block:
else_ = self.decompile_block(else_block[:]).stmnt()
else:
else_ = []
while_ = _ast.While(test=test, body=body_, orelse=else_, **kw)
self.ast_stack.append(while_)