PageRenderTime 43ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/interpreter/astcompiler/codegen.py

https://bitbucket.org/dac_io/pypy
Python | 1295 lines | 1189 code | 71 blank | 35 comment | 110 complexity | ff3e58694743db0ba71130bed17e5f93 MD5 | raw file
  1. """
  2. Generate Python bytecode from a Abstract Syntax Tree.
  3. """
  4. # NOTE TO READERS: All the ugly and "obvious" isinstance assertions here are to
  5. # help the annotator. To it, unfortunately, everything is not so obvious. If
  6. # you figure out a way to remove them, great, but try a translation first,
  7. # please.
  8. from pypy.interpreter.astcompiler import ast, assemble, symtable, consts, misc
  9. from pypy.interpreter.astcompiler import optimize # For side effects
  10. from pypy.interpreter.pyparser.error import SyntaxError
  11. from pypy.tool import stdlib_opcode as ops
  12. from pypy.interpreter.error import OperationError
  13. def compile_ast(space, module, info):
  14. """Generate a code object from AST."""
  15. symbols = symtable.SymtableBuilder(space, module, info)
  16. return TopLevelCodeGenerator(space, module, symbols, info).assemble()
  17. name_ops_default = misc.dict_to_switch({
  18. ast.Load : ops.LOAD_NAME,
  19. ast.Store : ops.STORE_NAME,
  20. ast.Del : ops.DELETE_NAME
  21. })
  22. name_ops_fast = misc.dict_to_switch({
  23. ast.Load : ops.LOAD_FAST,
  24. ast.Store : ops.STORE_FAST,
  25. ast.Del : ops.DELETE_FAST
  26. })
  27. name_ops_deref = misc.dict_to_switch({
  28. ast.Load : ops.LOAD_DEREF,
  29. ast.Store : ops.STORE_DEREF,
  30. })
  31. name_ops_global = misc.dict_to_switch({
  32. ast.Load : ops.LOAD_GLOBAL,
  33. ast.Store : ops.STORE_GLOBAL,
  34. ast.Del : ops.DELETE_GLOBAL
  35. })
  36. unary_operations = misc.dict_to_switch({
  37. ast.Invert : ops.UNARY_INVERT,
  38. ast.Not : ops.UNARY_NOT,
  39. ast.UAdd : ops.UNARY_POSITIVE,
  40. ast.USub : ops.UNARY_NEGATIVE
  41. })
  42. binary_operations = misc.dict_to_switch({
  43. ast.Add : ops.BINARY_ADD,
  44. ast.Sub : ops.BINARY_SUBTRACT,
  45. ast.Mult : ops.BINARY_MULTIPLY,
  46. ast.Mod : ops.BINARY_MODULO,
  47. ast.Pow : ops.BINARY_POWER,
  48. ast.LShift : ops.BINARY_LSHIFT,
  49. ast.RShift : ops.BINARY_RSHIFT,
  50. ast.BitOr : ops.BINARY_OR,
  51. ast.BitAnd : ops.BINARY_AND,
  52. ast.BitXor : ops.BINARY_XOR,
  53. ast.FloorDiv : ops.BINARY_FLOOR_DIVIDE
  54. })
  55. inplace_operations = misc.dict_to_switch({
  56. ast.Add : ops.INPLACE_ADD,
  57. ast.Sub : ops.INPLACE_SUBTRACT,
  58. ast.Mult : ops.INPLACE_MULTIPLY,
  59. ast.Mod : ops.INPLACE_MODULO,
  60. ast.Pow : ops.INPLACE_POWER,
  61. ast.LShift : ops.INPLACE_LSHIFT,
  62. ast.RShift : ops.INPLACE_RSHIFT,
  63. ast.BitOr : ops.INPLACE_OR,
  64. ast.BitAnd : ops.INPLACE_AND,
  65. ast.BitXor : ops.INPLACE_XOR,
  66. ast.FloorDiv : ops.INPLACE_FLOOR_DIVIDE
  67. })
  68. compare_operations = misc.dict_to_switch({
  69. ast.Eq : 2,
  70. ast.NotEq : 3,
  71. ast.Lt : 0,
  72. ast.LtE : 1,
  73. ast.Gt : 4,
  74. ast.GtE : 5,
  75. ast.In : 6,
  76. ast.NotIn : 7,
  77. ast.Is : 8,
  78. ast.IsNot : 9
  79. })
  80. subscr_operations = misc.dict_to_switch({
  81. ast.AugLoad : ops.BINARY_SUBSCR,
  82. ast.Load : ops.BINARY_SUBSCR,
  83. ast.AugStore : ops.STORE_SUBSCR,
  84. ast.Store : ops.STORE_SUBSCR,
  85. ast.Del : ops.DELETE_SUBSCR
  86. })
  87. slice_operations = misc.dict_to_switch({
  88. ast.AugLoad : ops.SLICE,
  89. ast.Load : ops.SLICE,
  90. ast.AugStore : ops.STORE_SLICE,
  91. ast.Store : ops.STORE_SLICE,
  92. ast.Del : ops.DELETE_SLICE
  93. })
  94. class __extend__(ast.GeneratorExp):
  95. def build_container(self, codegen):
  96. pass
  97. def get_generators(self):
  98. return self.generators
  99. def accept_comp_iteration(self, codegen, index):
  100. self.elt.walkabout(codegen)
  101. codegen.emit_op(ops.YIELD_VALUE)
  102. codegen.emit_op(ops.POP_TOP)
  103. class __extend__(ast.SetComp):
  104. def build_container(self, codegen):
  105. codegen.emit_op_arg(ops.BUILD_SET, 0)
  106. def get_generators(self):
  107. return self.generators
  108. def accept_comp_iteration(self, codegen, index):
  109. self.elt.walkabout(codegen)
  110. codegen.emit_op_arg(ops.SET_ADD, index + 1)
  111. class __extend__(ast.DictComp):
  112. def build_container(self, codegen):
  113. codegen.emit_op_arg(ops.BUILD_MAP, 0)
  114. def get_generators(self):
  115. return self.generators
  116. def accept_comp_iteration(self, codegen, index):
  117. self.value.walkabout(codegen)
  118. self.key.walkabout(codegen)
  119. codegen.emit_op_arg(ops.MAP_ADD, index + 1)
  120. # These are frame blocks.
  121. F_BLOCK_LOOP = 0
  122. F_BLOCK_EXCEPT = 1
  123. F_BLOCK_FINALLY = 2
  124. F_BLOCK_FINALLY_END = 3
  125. class PythonCodeGenerator(assemble.PythonCodeMaker):
  126. """Base code generator.
  127. A subclass of this is created for every scope to be compiled. It walks
  128. across the AST tree generating bytecode as needed.
  129. """
  130. def __init__(self, space, name, tree, lineno, symbols, compile_info):
  131. self.scope = symbols.find_scope(tree)
  132. assemble.PythonCodeMaker.__init__(self, space, name, lineno,
  133. self.scope, compile_info)
  134. self.symbols = symbols
  135. self.frame_blocks = []
  136. self.interactive = False
  137. self.temporary_name_counter = 1
  138. self._compile(tree)
  139. def _compile(self, tree):
  140. """Override in subclasses to compile a scope."""
  141. raise NotImplementedError
  142. def current_temporary_name(self):
  143. """Return the name of the current temporary variable.
  144. This must be in sync with the one during symbol table building.
  145. """
  146. name = "_[%d]" % (self.temporary_name_counter,)
  147. self.temporary_name_counter += 1
  148. assert self.scope.lookup(name) != symtable.SCOPE_UNKNOWN
  149. return name
  150. def sub_scope(self, kind, name, node, lineno):
  151. """Convenience function for compiling a sub scope."""
  152. generator = kind(self.space, name, node, lineno, self.symbols,
  153. self.compile_info)
  154. return generator.assemble()
  155. def push_frame_block(self, kind, block):
  156. self.frame_blocks.append((kind, block))
  157. def pop_frame_block(self, kind, block):
  158. actual_kind, old_block = self.frame_blocks.pop()
  159. assert actual_kind == kind and old_block is block, \
  160. "mismatched frame blocks"
  161. def error(self, msg, node):
  162. raise SyntaxError(msg, node.lineno, node.col_offset,
  163. filename=self.compile_info.filename)
  164. def name_op(self, identifier, ctx):
  165. """Generate an operation appropiate for the scope of the identifier."""
  166. scope = self.scope.lookup(identifier)
  167. op = ops.NOP
  168. container = self.names
  169. if scope == symtable.SCOPE_LOCAL:
  170. if self.scope.can_be_optimized:
  171. container = self.var_names
  172. op = name_ops_fast(ctx)
  173. elif scope == symtable.SCOPE_FREE:
  174. op = name_ops_deref(ctx)
  175. container = self.free_vars
  176. elif scope == symtable.SCOPE_CELL:
  177. try:
  178. op = name_ops_deref(ctx)
  179. except KeyError:
  180. assert ctx == ast.Del
  181. raise SyntaxError("Can't delete variable used in "
  182. "nested scopes: '%s'" % (identifier,))
  183. container = self.cell_vars
  184. elif scope == symtable.SCOPE_GLOBAL_IMPLICIT:
  185. if self.scope.locals_fully_known:
  186. op = name_ops_global(ctx)
  187. elif scope == symtable.SCOPE_GLOBAL_EXPLICIT:
  188. op = name_ops_global(ctx)
  189. if op == ops.NOP:
  190. op = name_ops_default(ctx)
  191. self.emit_op_arg(op, self.add_name(container, identifier))
  192. def possible_docstring(self, node):
  193. if isinstance(node, ast.Expr):
  194. expr_value = node.value
  195. if isinstance(expr_value, ast.Str):
  196. return expr_value
  197. return None
  198. def _get_code_flags(self):
  199. # Default for everything but module scopes.
  200. return consts.CO_NEWLOCALS
  201. def _handle_body(self, body):
  202. """Compile a list of statements, handling doc strings if needed."""
  203. if body:
  204. start = 0
  205. doc_expr = self.possible_docstring(body[0])
  206. if doc_expr is not None:
  207. start = 1
  208. doc_expr.walkabout(self)
  209. self.name_op("__doc__", ast.Store)
  210. for i in range(start, len(body)):
  211. body[i].walkabout(self)
  212. return True
  213. else:
  214. return False
  215. def visit_Module(self, mod):
  216. if not self._handle_body(mod.body):
  217. self.first_lineno = self.lineno = 1
  218. def visit_Interactive(self, mod):
  219. self.interactive = True
  220. self.visit_sequence(mod.body)
  221. def visit_Expression(self, mod):
  222. self.add_none_to_final_return = False
  223. mod.body.walkabout(self)
  224. def _make_function(self, code, num_defaults=0):
  225. """Emit the opcodes to turn a code object into a function."""
  226. code_index = self.add_const(code)
  227. if code.co_freevars:
  228. # Load cell and free vars to pass on.
  229. for free in code.co_freevars:
  230. free_scope = self.scope.lookup(free)
  231. if free_scope == symtable.SCOPE_CELL:
  232. index = self.cell_vars[free]
  233. else:
  234. index = self.free_vars[free]
  235. self.emit_op_arg(ops.LOAD_CLOSURE, index)
  236. self.emit_op_arg(ops.BUILD_TUPLE, len(code.co_freevars))
  237. self.emit_op_arg(ops.LOAD_CONST, code_index)
  238. self.emit_op_arg(ops.MAKE_CLOSURE, num_defaults)
  239. else:
  240. self.emit_op_arg(ops.LOAD_CONST, code_index)
  241. self.emit_op_arg(ops.MAKE_FUNCTION, num_defaults)
  242. def visit_FunctionDef(self, func):
  243. self.update_position(func.lineno, True)
  244. # Load decorators first, but apply them after the function is created.
  245. self.visit_sequence(func.decorator_list)
  246. args = func.args
  247. assert isinstance(args, ast.arguments)
  248. self.visit_sequence(args.defaults)
  249. num_defaults = len(args.defaults) if args.defaults is not None else 0
  250. code = self.sub_scope(FunctionCodeGenerator, func.name, func,
  251. func.lineno)
  252. self._make_function(code, num_defaults)
  253. # Apply decorators.
  254. if func.decorator_list:
  255. for i in range(len(func.decorator_list)):
  256. self.emit_op_arg(ops.CALL_FUNCTION, 1)
  257. self.name_op(func.name, ast.Store)
  258. def visit_Lambda(self, lam):
  259. self.update_position(lam.lineno)
  260. args = lam.args
  261. assert isinstance(args, ast.arguments)
  262. self.visit_sequence(args.defaults)
  263. default_count = len(args.defaults) if args.defaults is not None else 0
  264. code = self.sub_scope(LambdaCodeGenerator, "<lambda>", lam, lam.lineno)
  265. self._make_function(code, default_count)
  266. def visit_ClassDef(self, cls):
  267. self.update_position(cls.lineno, True)
  268. self.visit_sequence(cls.decorator_list)
  269. self.load_const(self.space.wrap(cls.name))
  270. self.visit_sequence(cls.bases)
  271. bases_count = len(cls.bases) if cls.bases is not None else 0
  272. self.emit_op_arg(ops.BUILD_TUPLE, bases_count)
  273. code = self.sub_scope(ClassCodeGenerator, cls.name, cls, cls.lineno)
  274. self._make_function(code, 0)
  275. self.emit_op_arg(ops.CALL_FUNCTION, 0)
  276. self.emit_op(ops.BUILD_CLASS)
  277. if cls.decorator_list:
  278. for i in range(len(cls.decorator_list)):
  279. self.emit_op_arg(ops.CALL_FUNCTION, 1)
  280. self.name_op(cls.name, ast.Store)
  281. def _op_for_augassign(self, op):
  282. if op == ast.Div:
  283. if self.compile_info.flags & consts.CO_FUTURE_DIVISION:
  284. return ops.INPLACE_TRUE_DIVIDE
  285. else:
  286. return ops.INPLACE_DIVIDE
  287. return inplace_operations(op)
  288. def visit_AugAssign(self, assign):
  289. self.update_position(assign.lineno, True)
  290. target = assign.target
  291. if isinstance(target, ast.Attribute):
  292. attr = ast.Attribute(target.value, target.attr, ast.AugLoad,
  293. target.lineno, target.col_offset)
  294. attr.walkabout(self)
  295. assign.value.walkabout(self)
  296. self.emit_op(self._op_for_augassign(assign.op))
  297. attr.ctx = ast.AugStore
  298. attr.walkabout(self)
  299. elif isinstance(target, ast.Subscript):
  300. sub = ast.Subscript(target.value, target.slice, ast.AugLoad,
  301. target.lineno, target.col_offset)
  302. sub.walkabout(self)
  303. assign.value.walkabout(self)
  304. self.emit_op(self._op_for_augassign(assign.op))
  305. sub.ctx = ast.AugStore
  306. sub.walkabout(self)
  307. elif isinstance(target, ast.Name):
  308. self.name_op(target.id, ast.Load)
  309. assign.value.walkabout(self)
  310. self.emit_op(self._op_for_augassign(assign.op))
  311. self.name_op(target.id, ast.Store)
  312. else:
  313. self.error("illegal expression for augmented assignment", assign)
  314. def visit_Assert(self, asrt):
  315. self.update_position(asrt.lineno)
  316. end = self.new_block()
  317. asrt.test.accept_jump_if(self, True, end)
  318. self.emit_op_name(ops.LOAD_GLOBAL, self.names, "AssertionError")
  319. if asrt.msg:
  320. asrt.msg.walkabout(self)
  321. self.emit_op_arg(ops.RAISE_VARARGS, 2)
  322. else:
  323. self.emit_op_arg(ops.RAISE_VARARGS, 1)
  324. self.use_next_block(end)
  325. def _binop(self, op):
  326. if op == ast.Div:
  327. if self.compile_info.flags & consts.CO_FUTURE_DIVISION:
  328. return ops.BINARY_TRUE_DIVIDE
  329. else:
  330. return ops.BINARY_DIVIDE
  331. return binary_operations(op)
  332. def visit_BinOp(self, binop):
  333. self.update_position(binop.lineno)
  334. binop.left.walkabout(self)
  335. binop.right.walkabout(self)
  336. self.emit_op(self._binop(binop.op))
  337. def visit_Return(self, ret):
  338. self.update_position(ret.lineno, True)
  339. if ret.value:
  340. ret.value.walkabout(self)
  341. else:
  342. self.load_const(self.space.w_None)
  343. self.emit_op(ops.RETURN_VALUE)
  344. def visit_Print(self, pr):
  345. self.update_position(pr.lineno, True)
  346. have_dest = bool(pr.dest)
  347. if have_dest:
  348. pr.dest.walkabout(self)
  349. if pr.values:
  350. for value in pr.values:
  351. if have_dest:
  352. self.emit_op(ops.DUP_TOP)
  353. value.walkabout(self)
  354. self.emit_op(ops.ROT_TWO)
  355. self.emit_op(ops.PRINT_ITEM_TO)
  356. else:
  357. value.walkabout(self)
  358. self.emit_op(ops.PRINT_ITEM)
  359. if pr.nl:
  360. if have_dest:
  361. self.emit_op(ops.PRINT_NEWLINE_TO)
  362. else:
  363. self.emit_op(ops.PRINT_NEWLINE)
  364. elif have_dest:
  365. self.emit_op(ops.POP_TOP)
  366. def visit_Delete(self, delete):
  367. self.update_position(delete.lineno, True)
  368. self.visit_sequence(delete.targets)
  369. def visit_If(self, if_):
  370. self.update_position(if_.lineno, True)
  371. end = self.new_block()
  372. test_constant = if_.test.as_constant_truth(self.space)
  373. if test_constant == optimize.CONST_FALSE:
  374. self.visit_sequence(if_.orelse)
  375. elif test_constant == optimize.CONST_TRUE:
  376. self.visit_sequence(if_.body)
  377. else:
  378. if if_.orelse:
  379. otherwise = self.new_block()
  380. else:
  381. otherwise = end
  382. if_.test.accept_jump_if(self, False, otherwise)
  383. self.visit_sequence(if_.body)
  384. self.emit_jump(ops.JUMP_FORWARD, end)
  385. if if_.orelse:
  386. self.use_next_block(otherwise)
  387. self.visit_sequence(if_.orelse)
  388. self.use_next_block(end)
  389. def visit_Break(self, br):
  390. self.update_position(br.lineno, True)
  391. for f_block in self.frame_blocks:
  392. if f_block[0] == F_BLOCK_LOOP:
  393. break
  394. else:
  395. self.error("'break' outside loop", br)
  396. self.emit_op(ops.BREAK_LOOP)
  397. def visit_Continue(self, cont):
  398. self.update_position(cont.lineno, True)
  399. if not self.frame_blocks:
  400. self.error("'continue' not properly in loop", cont)
  401. current_block, block = self.frame_blocks[-1]
  402. # Continue cannot be in a finally block.
  403. if current_block == F_BLOCK_LOOP:
  404. self.emit_jump(ops.JUMP_ABSOLUTE, block, True)
  405. elif current_block == F_BLOCK_EXCEPT or \
  406. current_block == F_BLOCK_FINALLY:
  407. for i in range(len(self.frame_blocks) - 2, -1, -1):
  408. f_type, block = self.frame_blocks[i]
  409. if f_type == F_BLOCK_LOOP:
  410. self.emit_jump(ops.CONTINUE_LOOP, block, True)
  411. break
  412. if self.frame_blocks[i][0] == F_BLOCK_FINALLY_END:
  413. self.error("'continue' not supported inside 'finally' " \
  414. "clause",
  415. cont)
  416. else:
  417. self.error("'continue' not properly in loop", cont)
  418. elif current_block == F_BLOCK_FINALLY_END:
  419. self.error("'continue' not supported inside 'finally' clause", cont)
  420. def visit_For(self, fr):
  421. self.update_position(fr.lineno, True)
  422. start = self.new_block()
  423. cleanup = self.new_block()
  424. end = self.new_block()
  425. self.emit_jump(ops.SETUP_LOOP, end)
  426. self.push_frame_block(F_BLOCK_LOOP, start)
  427. fr.iter.walkabout(self)
  428. self.emit_op(ops.GET_ITER)
  429. self.use_next_block(start)
  430. # This adds another line, so each for iteration can be traced.
  431. self.lineno_set = False
  432. self.emit_jump(ops.FOR_ITER, cleanup)
  433. fr.target.walkabout(self)
  434. self.visit_sequence(fr.body)
  435. self.emit_jump(ops.JUMP_ABSOLUTE, start, True)
  436. self.use_next_block(cleanup)
  437. self.emit_op(ops.POP_BLOCK)
  438. self.pop_frame_block(F_BLOCK_LOOP, start)
  439. self.visit_sequence(fr.orelse)
  440. self.use_next_block(end)
  441. def visit_While(self, wh):
  442. self.update_position(wh.lineno, True)
  443. test_constant = wh.test.as_constant_truth(self.space)
  444. if test_constant == optimize.CONST_FALSE:
  445. self.visit_sequence(wh.orelse)
  446. else:
  447. end = self.new_block()
  448. anchor = None
  449. if test_constant == optimize.CONST_NOT_CONST:
  450. anchor = self.new_block()
  451. self.emit_jump(ops.SETUP_LOOP, end)
  452. loop = self.new_block()
  453. self.push_frame_block(F_BLOCK_LOOP, loop)
  454. self.use_next_block(loop)
  455. if test_constant == optimize.CONST_NOT_CONST:
  456. # Force another lineno to be set for tracing purposes.
  457. self.lineno_set = False
  458. wh.test.accept_jump_if(self, False, anchor)
  459. self.visit_sequence(wh.body)
  460. self.emit_jump(ops.JUMP_ABSOLUTE, loop, True)
  461. if test_constant == optimize.CONST_NOT_CONST:
  462. self.use_next_block(anchor)
  463. self.emit_op(ops.POP_BLOCK)
  464. self.pop_frame_block(F_BLOCK_LOOP, loop)
  465. self.visit_sequence(wh.orelse)
  466. self.use_next_block(end)
  467. def visit_TryExcept(self, te):
  468. self.update_position(te.lineno, True)
  469. exc = self.new_block()
  470. otherwise = self.new_block()
  471. end = self.new_block()
  472. self.emit_jump(ops.SETUP_EXCEPT, exc)
  473. body = self.use_next_block()
  474. self.push_frame_block(F_BLOCK_EXCEPT, body)
  475. self.visit_sequence(te.body)
  476. self.emit_op(ops.POP_BLOCK)
  477. self.pop_frame_block(F_BLOCK_EXCEPT, body)
  478. self.emit_jump(ops.JUMP_FORWARD, otherwise)
  479. self.use_next_block(exc)
  480. for handler in te.handlers:
  481. assert isinstance(handler, ast.ExceptHandler)
  482. self.update_position(handler.lineno, True)
  483. next_except = self.new_block()
  484. if handler.type:
  485. self.emit_op(ops.DUP_TOP)
  486. handler.type.walkabout(self)
  487. self.emit_op_arg(ops.COMPARE_OP, 10)
  488. self.emit_jump(ops.POP_JUMP_IF_FALSE, next_except, True)
  489. self.emit_op(ops.POP_TOP)
  490. if handler.name:
  491. handler.name.walkabout(self)
  492. else:
  493. self.emit_op(ops.POP_TOP)
  494. self.emit_op(ops.POP_TOP)
  495. self.visit_sequence(handler.body)
  496. self.emit_jump(ops.JUMP_FORWARD, end)
  497. self.use_next_block(next_except)
  498. self.emit_op(ops.END_FINALLY)
  499. self.use_next_block(otherwise)
  500. self.visit_sequence(te.orelse)
  501. self.use_next_block(end)
  502. def visit_TryFinally(self, tf):
  503. self.update_position(tf.lineno, True)
  504. end = self.new_block()
  505. self.emit_jump(ops.SETUP_FINALLY, end)
  506. body = self.use_next_block()
  507. self.push_frame_block(F_BLOCK_FINALLY, body)
  508. self.visit_sequence(tf.body)
  509. self.emit_op(ops.POP_BLOCK)
  510. self.pop_frame_block(F_BLOCK_FINALLY, body)
  511. # Indicates there was no exception.
  512. self.load_const(self.space.w_None)
  513. self.use_next_block(end)
  514. self.push_frame_block(F_BLOCK_FINALLY_END, end)
  515. self.visit_sequence(tf.finalbody)
  516. self.emit_op(ops.END_FINALLY)
  517. self.pop_frame_block(F_BLOCK_FINALLY_END, end)
  518. def _import_as(self, alias):
  519. source_name = alias.name
  520. dot = source_name.find(".")
  521. if dot > 0:
  522. while True:
  523. start = dot + 1
  524. dot = source_name.find(".", start)
  525. if dot < 0:
  526. end = len(source_name)
  527. else:
  528. end = dot
  529. attr = source_name[start:end]
  530. self.emit_op_name(ops.LOAD_ATTR, self.names, attr)
  531. if dot < 0:
  532. break
  533. self.name_op(alias.asname, ast.Store)
  534. def visit_Import(self, imp):
  535. self.update_position(imp.lineno, True)
  536. for alias in imp.names:
  537. assert isinstance(alias, ast.alias)
  538. if self.compile_info.flags & consts.CO_FUTURE_ABSOLUTE_IMPORT:
  539. level = 0
  540. else:
  541. level = -1
  542. self.load_const(self.space.wrap(level))
  543. self.load_const(self.space.w_None)
  544. self.emit_op_name(ops.IMPORT_NAME, self.names, alias.name)
  545. # If there's no asname then we store the root module. If there is
  546. # an asname, _import_as stores the last module of the chain into it.
  547. if alias.asname:
  548. self._import_as(alias)
  549. else:
  550. dot = alias.name.find(".")
  551. if dot < 0:
  552. store_name = alias.name
  553. else:
  554. store_name = alias.name[:dot]
  555. self.name_op(store_name, ast.Store)
  556. def visit_ImportFrom(self, imp):
  557. self.update_position(imp.lineno, True)
  558. space = self.space
  559. first = imp.names[0]
  560. assert isinstance(first, ast.alias)
  561. star_import = len(imp.names) == 1 and first.name == "*"
  562. # Various error checking for future imports.
  563. if imp.module == "__future__":
  564. last_line, last_offset = self.compile_info.last_future_import
  565. if imp.lineno > last_line or \
  566. imp.lineno == last_line and imp.col_offset > last_offset:
  567. self.error("__future__ statements must appear at beginning " \
  568. "of file", imp)
  569. if star_import:
  570. self.error("* not valid in __future__ imports", imp)
  571. compiler = space.createcompiler()
  572. for alias in imp.names:
  573. assert isinstance(alias, ast.alias)
  574. if alias.name not in compiler.future_flags.compiler_features:
  575. if alias.name == "braces":
  576. self.error("not a chance", imp)
  577. self.error("future feature %s is not defined" %
  578. (alias.name,), imp)
  579. if imp.level == 0 and \
  580. not self.compile_info.flags & consts.CO_FUTURE_ABSOLUTE_IMPORT:
  581. level = -1
  582. else:
  583. level = imp.level
  584. self.load_const(space.wrap(level))
  585. names_w = [None]*len(imp.names)
  586. for i in range(len(imp.names)):
  587. alias = imp.names[i]
  588. assert isinstance(alias, ast.alias)
  589. names_w[i] = space.wrap(alias.name)
  590. self.load_const(space.newtuple(names_w))
  591. if imp.module:
  592. mod_name = imp.module
  593. else:
  594. # In the case of a relative import.
  595. mod_name = ""
  596. self.emit_op_name(ops.IMPORT_NAME, self.names, mod_name)
  597. if star_import:
  598. self.emit_op(ops.IMPORT_STAR)
  599. else:
  600. for alias in imp.names:
  601. assert isinstance(alias, ast.alias)
  602. self.emit_op_name(ops.IMPORT_FROM, self.names, alias.name)
  603. if alias.asname:
  604. store_name = alias.asname
  605. else:
  606. store_name = alias.name
  607. self.name_op(store_name, ast.Store)
  608. self.emit_op(ops.POP_TOP)
  609. def visit_Assign(self, assign):
  610. self.update_position(assign.lineno, True)
  611. if self._optimize_unpacking(assign):
  612. return
  613. assign.value.walkabout(self)
  614. duplications = len(assign.targets) - 1
  615. for i in range(len(assign.targets)):
  616. if i < duplications:
  617. self.emit_op(ops.DUP_TOP)
  618. assign.targets[i].walkabout(self)
  619. def _optimize_unpacking(self, assign):
  620. """Try to optimize out BUILD_TUPLE and UNPACK_SEQUENCE opcodes."""
  621. if len(assign.targets) != 1:
  622. return False
  623. targets = assign.targets[0].as_node_list(self.space)
  624. if targets is None:
  625. return False
  626. values = assign.value.as_node_list(self.space)
  627. if values is None:
  628. return False
  629. targets_count = len(targets)
  630. values_count = len(values)
  631. if targets_count != values_count:
  632. return False
  633. for target in targets:
  634. if not isinstance(target, ast.Name):
  635. break
  636. else:
  637. self.visit_sequence(values)
  638. seen_names = {}
  639. for i in range(targets_count - 1, -1, -1):
  640. target = targets[i]
  641. assert isinstance(target, ast.Name)
  642. if target.id not in seen_names:
  643. seen_names[target.id] = True
  644. self.name_op(target.id, ast.Store)
  645. else:
  646. self.emit_op(ops.POP_TOP)
  647. return True
  648. if values_count > 3:
  649. return False
  650. self.visit_sequence(values)
  651. if values_count == 2:
  652. self.emit_op(ops.ROT_TWO)
  653. elif values_count == 3:
  654. self.emit_op(ops.ROT_THREE)
  655. self.emit_op(ops.ROT_TWO)
  656. self.visit_sequence(targets)
  657. return True
  658. def visit_With(self, wih):
  659. self.update_position(wih.lineno, True)
  660. body_block = self.new_block()
  661. cleanup = self.new_block()
  662. wih.context_expr.walkabout(self)
  663. self.emit_jump(ops.SETUP_WITH, cleanup)
  664. self.use_next_block(body_block)
  665. self.push_frame_block(F_BLOCK_FINALLY, body_block)
  666. if wih.optional_vars:
  667. wih.optional_vars.walkabout(self)
  668. else:
  669. self.emit_op(ops.POP_TOP)
  670. self.visit_sequence(wih.body)
  671. self.emit_op(ops.POP_BLOCK)
  672. self.pop_frame_block(F_BLOCK_FINALLY, body_block)
  673. self.load_const(self.space.w_None)
  674. self.use_next_block(cleanup)
  675. self.push_frame_block(F_BLOCK_FINALLY_END, cleanup)
  676. self.emit_op(ops.WITH_CLEANUP)
  677. self.emit_op(ops.END_FINALLY)
  678. self.pop_frame_block(F_BLOCK_FINALLY_END, cleanup)
  679. def visit_Raise(self, rais):
  680. self.update_position(rais.lineno, True)
  681. arg = 0
  682. if rais.type:
  683. rais.type.walkabout(self)
  684. arg += 1
  685. if rais.inst:
  686. rais.inst.walkabout(self)
  687. arg += 1
  688. if rais.tback:
  689. rais.tback.walkabout(self)
  690. arg += 1
  691. self.emit_op_arg(ops.RAISE_VARARGS, arg)
  692. def visit_Exec(self, exc):
  693. self.update_position(exc.lineno, True)
  694. exc.body.walkabout(self)
  695. if exc.globals:
  696. exc.globals.walkabout(self)
  697. if exc.locals:
  698. exc.locals.walkabout(self)
  699. else:
  700. self.emit_op(ops.DUP_TOP)
  701. else:
  702. self.load_const(self.space.w_None)
  703. self.emit_op(ops.DUP_TOP)
  704. self.emit_op(ops.EXEC_STMT)
  705. def visit_Global(self, glob):
  706. # Handled in symbol table building.
  707. pass
  708. def visit_Pass(self, pas):
  709. self.update_position(pas.lineno, True)
  710. def visit_Expr(self, expr):
  711. self.update_position(expr.lineno, True)
  712. if self.interactive:
  713. expr.value.walkabout(self)
  714. self.emit_op(ops.PRINT_EXPR)
  715. # Only compile if the expression isn't constant.
  716. elif not expr.value.constant:
  717. expr.value.walkabout(self)
  718. self.emit_op(ops.POP_TOP)
  719. def visit_Yield(self, yie):
  720. self.update_position(yie.lineno)
  721. if yie.value:
  722. yie.value.walkabout(self)
  723. else:
  724. self.load_const(self.space.w_None)
  725. self.emit_op(ops.YIELD_VALUE)
  726. def visit_Num(self, num):
  727. self.update_position(num.lineno)
  728. self.load_const(num.n)
  729. def visit_Str(self, string):
  730. self.update_position(string.lineno)
  731. self.load_const(string.s)
  732. def visit_Const(self, const):
  733. self.update_position(const.lineno)
  734. space = self.space
  735. self.load_const(const.value)
  736. def visit_UnaryOp(self, op):
  737. self.update_position(op.lineno)
  738. op.operand.walkabout(self)
  739. self.emit_op(unary_operations(op.op))
  740. def visit_BoolOp(self, op):
  741. self.update_position(op.lineno)
  742. if op.op == ast.And:
  743. instr = ops.JUMP_IF_FALSE_OR_POP
  744. else:
  745. instr = ops.JUMP_IF_TRUE_OR_POP
  746. end = self.new_block()
  747. for value in op.values[:-1]:
  748. value.walkabout(self)
  749. self.emit_jump(instr, end, True)
  750. op.values[-1].walkabout(self)
  751. self.use_next_block(end)
  752. def visit_Compare(self, comp):
  753. self.update_position(comp.lineno)
  754. comp.left.walkabout(self)
  755. ops_count = len(comp.ops)
  756. cleanup = None
  757. if ops_count > 1:
  758. cleanup = self.new_block()
  759. comp.comparators[0].walkabout(self)
  760. for i in range(1, ops_count):
  761. self.emit_op(ops.DUP_TOP)
  762. self.emit_op(ops.ROT_THREE)
  763. op_kind = compare_operations(comp.ops[i - 1])
  764. self.emit_op_arg(ops.COMPARE_OP, op_kind)
  765. self.emit_jump(ops.JUMP_IF_FALSE_OR_POP, cleanup, True)
  766. if i < (ops_count - 1):
  767. comp.comparators[i].walkabout(self)
  768. comp.comparators[-1].walkabout(self)
  769. last_kind = compare_operations(comp.ops[-1])
  770. self.emit_op_arg(ops.COMPARE_OP, last_kind)
  771. if ops_count > 1:
  772. end = self.new_block()
  773. self.emit_jump(ops.JUMP_FORWARD, end)
  774. self.use_next_block(cleanup)
  775. self.emit_op(ops.ROT_TWO)
  776. self.emit_op(ops.POP_TOP)
  777. self.use_next_block(end)
  778. def visit_IfExp(self, ifexp):
  779. self.update_position(ifexp.lineno)
  780. end = self.new_block()
  781. otherwise = self.new_block()
  782. ifexp.test.accept_jump_if(self, False, otherwise)
  783. ifexp.body.walkabout(self)
  784. self.emit_jump(ops.JUMP_FORWARD, end)
  785. self.use_next_block(otherwise)
  786. ifexp.orelse.walkabout(self)
  787. self.use_next_block(end)
  788. def visit_Tuple(self, tup):
  789. self.update_position(tup.lineno)
  790. elt_count = len(tup.elts) if tup.elts is not None else 0
  791. if tup.ctx == ast.Store:
  792. self.emit_op_arg(ops.UNPACK_SEQUENCE, elt_count)
  793. self.visit_sequence(tup.elts)
  794. if tup.ctx == ast.Load:
  795. self.emit_op_arg(ops.BUILD_TUPLE, elt_count)
  796. def visit_List(self, l):
  797. self.update_position(l.lineno)
  798. elt_count = len(l.elts) if l.elts is not None else 0
  799. if l.ctx == ast.Store:
  800. self.emit_op_arg(ops.UNPACK_SEQUENCE, elt_count)
  801. self.visit_sequence(l.elts)
  802. if l.ctx == ast.Load:
  803. self.emit_op_arg(ops.BUILD_LIST, elt_count)
  804. def visit_Dict(self, d):
  805. self.update_position(d.lineno)
  806. self.emit_op_arg(ops.BUILD_MAP, 0)
  807. if d.values:
  808. for i in range(len(d.values)):
  809. d.values[i].walkabout(self)
  810. d.keys[i].walkabout(self)
  811. self.emit_op(ops.STORE_MAP)
  812. def visit_Set(self, s):
  813. self.update_position(s.lineno)
  814. self.visit_sequence(s.elts)
  815. self.emit_op_arg(ops.BUILD_SET, len(s.elts))
  816. def visit_Name(self, name):
  817. self.update_position(name.lineno)
  818. self.name_op(name.id, name.ctx)
  819. def visit_keyword(self, keyword):
  820. self.load_const(self.space.wrap(keyword.arg))
  821. keyword.value.walkabout(self)
  822. def visit_Call(self, call):
  823. self.update_position(call.lineno)
  824. if self._optimize_method_call(call):
  825. return
  826. call.func.walkabout(self)
  827. arg = len(call.args) if call.args is not None else 0
  828. call_type = 0
  829. self.visit_sequence(call.args)
  830. if call.keywords:
  831. self.visit_sequence(call.keywords)
  832. arg |= len(call.keywords) << 8
  833. if call.starargs:
  834. call.starargs.walkabout(self)
  835. call_type |= 1
  836. if call.kwargs:
  837. call.kwargs.walkabout(self)
  838. call_type |= 2
  839. op = 0
  840. if call_type == 0:
  841. op = ops.CALL_FUNCTION
  842. elif call_type == 1:
  843. op = ops.CALL_FUNCTION_VAR
  844. elif call_type == 2:
  845. op = ops.CALL_FUNCTION_KW
  846. elif call_type == 3:
  847. op = ops.CALL_FUNCTION_VAR_KW
  848. self.emit_op_arg(op, arg)
  849. def _call_has_no_star_args(self, call):
  850. return not call.starargs and not call.kwargs
  851. def _call_has_simple_args(self, call):
  852. return self._call_has_no_star_args(call) and not call.keywords
  853. def _optimize_method_call(self, call):
  854. if not self.space.config.objspace.opcodes.CALL_METHOD or \
  855. not self._call_has_no_star_args(call) or \
  856. not isinstance(call.func, ast.Attribute):
  857. return False
  858. attr_lookup = call.func
  859. assert isinstance(attr_lookup, ast.Attribute)
  860. attr_lookup.value.walkabout(self)
  861. self.emit_op_name(ops.LOOKUP_METHOD, self.names, attr_lookup.attr)
  862. self.visit_sequence(call.args)
  863. arg_count = len(call.args) if call.args is not None else 0
  864. self.visit_sequence(call.keywords)
  865. kwarg_count = len(call.keywords) if call.keywords is not None else 0
  866. self.emit_op_arg(ops.CALL_METHOD, (kwarg_count << 8) | arg_count)
  867. return True
  868. def _listcomp_generator(self, gens, gen_index, elt, single=False):
  869. start = self.new_block()
  870. skip = self.new_block()
  871. if_cleanup = self.new_block()
  872. anchor = self.new_block()
  873. gen = gens[gen_index]
  874. assert isinstance(gen, ast.comprehension)
  875. gen.iter.walkabout(self)
  876. if single:
  877. self.emit_op_arg(ops.BUILD_LIST_FROM_ARG, 0)
  878. self.emit_op(ops.GET_ITER)
  879. self.use_next_block(start)
  880. self.emit_jump(ops.FOR_ITER, anchor)
  881. self.use_next_block()
  882. gen.target.walkabout(self)
  883. if gen.ifs:
  884. if_count = len(gen.ifs)
  885. for if_ in gen.ifs:
  886. if_.accept_jump_if(self, False, if_cleanup)
  887. self.use_next_block()
  888. else:
  889. if_count = 0
  890. gen_index += 1
  891. if gen_index < len(gens):
  892. self._listcomp_generator(gens, gen_index, elt)
  893. else:
  894. elt.walkabout(self)
  895. self.emit_op_arg(ops.LIST_APPEND, gen_index + 1)
  896. self.use_next_block(skip)
  897. self.use_next_block(if_cleanup)
  898. self.emit_jump(ops.JUMP_ABSOLUTE, start, True)
  899. self.use_next_block(anchor)
  900. def visit_ListComp(self, lc):
  901. self.update_position(lc.lineno)
  902. if len(lc.generators) != 1 or lc.generators[0].ifs:
  903. single = False
  904. self.emit_op_arg(ops.BUILD_LIST, 0)
  905. else:
  906. single = True
  907. self._listcomp_generator(lc.generators, 0, lc.elt, single=single)
  908. def _comp_generator(self, node, generators, gen_index):
  909. start = self.new_block()
  910. skip = self.new_block()
  911. if_cleanup = self.new_block()
  912. anchor = self.new_block()
  913. gen = generators[gen_index]
  914. assert isinstance(gen, ast.comprehension)
  915. if gen_index == 0:
  916. self.argcount = 1
  917. self.emit_op_arg(ops.LOAD_FAST, 0)
  918. else:
  919. gen.iter.walkabout(self)
  920. self.emit_op(ops.GET_ITER)
  921. self.use_next_block(start)
  922. self.emit_jump(ops.FOR_ITER, anchor)
  923. self.use_next_block()
  924. gen.target.walkabout(self)
  925. if gen.ifs:
  926. ifs_count = len(gen.ifs)
  927. for if_ in gen.ifs:
  928. if_.accept_jump_if(self, False, if_cleanup)
  929. self.use_next_block()
  930. else:
  931. ifs_count = 0
  932. gen_index += 1
  933. if gen_index < len(generators):
  934. self._comp_generator(node, generators, gen_index)
  935. else:
  936. node.accept_comp_iteration(self, gen_index)
  937. self.use_next_block(if_cleanup)
  938. self.emit_jump(ops.JUMP_ABSOLUTE, start, True)
  939. self.use_next_block(anchor)
  940. def _compile_comprehension(self, node, name, sub_scope):
  941. code = self.sub_scope(sub_scope, name, node, node.lineno)
  942. self.update_position(node.lineno)
  943. self._make_function(code)
  944. first_comp = node.get_generators()[0]
  945. assert isinstance(first_comp, ast.comprehension)
  946. first_comp.iter.walkabout(self)
  947. self.emit_op(ops.GET_ITER)
  948. self.emit_op_arg(ops.CALL_FUNCTION, 1)
  949. def visit_GeneratorExp(self, genexp):
  950. self._compile_comprehension(genexp, "<genexpr>", GenExpCodeGenerator)
  951. def visit_SetComp(self, setcomp):
  952. self._compile_comprehension(setcomp, "<setcomp>",
  953. ComprehensionCodeGenerator)
  954. def visit_DictComp(self, dictcomp):
  955. self._compile_comprehension(dictcomp, "<dictcomp>",
  956. ComprehensionCodeGenerator)
  957. def visit_Repr(self, rep):
  958. self.update_position(rep.lineno)
  959. rep.value.walkabout(self)
  960. self.emit_op(ops.UNARY_CONVERT)
  961. def visit_Attribute(self, attr):
  962. self.update_position(attr.lineno)
  963. names = self.names
  964. ctx = attr.ctx
  965. if ctx != ast.AugStore:
  966. attr.value.walkabout(self)
  967. if ctx == ast.AugLoad:
  968. self.emit_op(ops.DUP_TOP)
  969. self.emit_op_name(ops.LOAD_ATTR, names, attr.attr)
  970. elif ctx == ast.Load:
  971. self.emit_op_name(ops.LOAD_ATTR, names, attr.attr)
  972. elif ctx == ast.AugStore:
  973. self.emit_op(ops.ROT_TWO)
  974. self.emit_op_name(ops.STORE_ATTR, names, attr.attr)
  975. elif ctx == ast.Store:
  976. self.emit_op_name(ops.STORE_ATTR, names, attr.attr)
  977. elif ctx == ast.Del:
  978. self.emit_op_name(ops.DELETE_ATTR, names, attr.attr)
  979. else:
  980. raise AssertionError("unknown context")
  981. def _simple_slice(self, slc, ctx):
  982. slice_offset = 0
  983. stack_count = 0
  984. if slc.lower:
  985. slice_offset += 1
  986. stack_count += 1
  987. if ctx != ast.AugStore:
  988. slc.lower.walkabout(self)
  989. if slc.upper:
  990. slice_offset += 2
  991. stack_count += 1
  992. if ctx != ast.AugStore:
  993. slc.upper.walkabout(self)
  994. if ctx == ast.AugLoad:
  995. if stack_count == 0:
  996. self.emit_op(ops.DUP_TOP)
  997. elif stack_count == 1:
  998. self.emit_op_arg(ops.DUP_TOPX, 2)
  999. elif stack_count == 2:
  1000. self.emit_op_arg(ops.DUP_TOPX, 3)
  1001. elif ctx == ast.AugStore:
  1002. if stack_count == 0:
  1003. self.emit_op(ops.ROT_TWO)
  1004. elif stack_count == 1:
  1005. self.emit_op(ops.ROT_THREE)
  1006. elif stack_count == 2:
  1007. self.emit_op(ops.ROT_FOUR)
  1008. self.emit_op(slice_operations(ctx) + slice_offset)
  1009. def _complex_slice(self, slc, ctx):
  1010. if slc.lower:
  1011. slc.lower.walkabout(self)
  1012. else:
  1013. self.load_const(self.space.w_None)
  1014. if slc.upper:
  1015. slc.upper.walkabout(self)
  1016. else:
  1017. self.load_const(self.space.w_None)
  1018. arg = 2
  1019. if slc.step:
  1020. slc.step.walkabout(self)
  1021. arg += 1
  1022. self.emit_op_arg(ops.BUILD_SLICE, arg)
  1023. def _nested_slice(self, slc, ctx):
  1024. if isinstance(slc, ast.Ellipsis):
  1025. self.load_const(self.space.w_Ellipsis)
  1026. elif isinstance(slc, ast.Slice):
  1027. self._complex_slice(slc, ctx)
  1028. elif isinstance(slc, ast.Index):
  1029. slc.value.walkabout(self)
  1030. else:
  1031. raise AssertionError("unknown nested slice type")
  1032. def _compile_slice(self, slc, ctx):
  1033. if isinstance(slc, ast.Index):
  1034. kind = "index"
  1035. if ctx != ast.AugStore:
  1036. slc.value.walkabout(self)
  1037. elif isinstance(slc, ast.Ellipsis):
  1038. kind = "ellipsis"
  1039. if ctx != ast.AugStore:
  1040. self.load_const(self.space.w_Ellipsis)
  1041. elif isinstance(slc, ast.Slice):
  1042. kind = "slice"
  1043. if not slc.step:
  1044. self._simple_slice(slc, ctx)
  1045. return
  1046. elif ctx != ast.AugStore:
  1047. self._complex_slice(slc, ctx)
  1048. elif isinstance(slc, ast.ExtSlice):
  1049. kind = "extended slice"
  1050. if ctx != ast.AugStore:
  1051. for dim in slc.dims:
  1052. self._nested_slice(dim, ctx)
  1053. self.emit_op_arg(ops.BUILD_TUPLE, len(slc.dims))
  1054. else:
  1055. raise AssertionError("unknown slice type")
  1056. if ctx == ast.AugLoad:
  1057. self.emit_op_arg(ops.DUP_TOPX, 2)
  1058. elif ctx == ast.AugStore:
  1059. self.emit_op(ops.ROT_THREE)
  1060. self.emit_op(subscr_operations(ctx))
  1061. def visit_Subscript(self, sub):
  1062. self.update_position(sub.lineno)
  1063. if sub.ctx != ast.AugStore:
  1064. sub.value.walkabout(self)
  1065. self._compile_slice(sub.slice, sub.ctx)
  1066. class TopLevelCodeGenerator(PythonCodeGenerator):
  1067. def __init__(self, space, tree, symbols, compile_info):
  1068. PythonCodeGenerator.__init__(self, space, "<module>", tree, -1,
  1069. symbols, compile_info)
  1070. def _compile(self, tree):
  1071. tree.walkabout(self)
  1072. def _get_code_flags(self):
  1073. return 0
  1074. class AbstractFunctionCodeGenerator(PythonCodeGenerator):
  1075. def _handle_nested_args(self, args):
  1076. for i in range(len(args)):
  1077. arg = args[i]
  1078. if isinstance(arg, ast.Tuple):
  1079. self.update_position(arg.lineno)
  1080. self.name_op(".%d" % (i,), ast.Load)
  1081. arg.walkabout(self)
  1082. def _get_code_flags(self):
  1083. scope = self.scope
  1084. assert isinstance(scope, symtable.FunctionScope)
  1085. flags = 0
  1086. if scope.locals_fully_known:
  1087. flags |= consts.CO_OPTIMIZED
  1088. if scope.nested:
  1089. flags |= consts.CO_NESTED
  1090. if scope.is_generator:
  1091. flags |= consts.CO_GENERATOR
  1092. if scope.has_variable_arg:
  1093. flags |= consts.CO_VARARGS
  1094. if scope.has_keywords_arg:
  1095. flags |= consts.CO_VARKEYWORDS
  1096. if not self.cell_vars and not self.free_vars:
  1097. flags |= consts.CO_NOFREE
  1098. return PythonCodeGenerator._get_code_flags(self) | flags
  1099. class FunctionCodeGenerator(AbstractFunctionCodeGenerator):
  1100. def _compile(self, func):
  1101. assert isinstance(func, ast.FunctionDef)
  1102. # If there's a docstring, store it as the first constant.
  1103. if func.body:
  1104. doc_expr = self.possible_docstring(func.body[0])
  1105. else:
  1106. doc_expr = None
  1107. if doc_expr is not None:
  1108. self.add_const(doc_expr.s)
  1109. start = 1
  1110. else:
  1111. self.add_const(self.space.w_None)
  1112. start = 0
  1113. args = func.args
  1114. assert isinstance(args, ast.arguments)
  1115. if args.args:
  1116. self._handle_nested_args(args.args)
  1117. self.argcount = len(args.args)
  1118. if func.body:
  1119. for i in range(start, len(func.body)):
  1120. func.body[i].walkabout(self)
  1121. class LambdaCodeGenerator(AbstractFunctionCodeGenerator):
  1122. def _compile(self, lam):
  1123. assert isinstance(lam, ast.Lambda)
  1124. args = lam.args
  1125. assert isinstance(args, ast.arguments)
  1126. if args.args:
  1127. self._handle_nested_args(args.args)
  1128. self.argcount = len(args.args)
  1129. # Prevent a string from being the first constant and thus a docstring.
  1130. self.add_const(self.space.w_None)
  1131. lam.body.walkabout(self)
  1132. self.emit_op(ops.RETURN_VALUE)
  1133. class ComprehensionCodeGenerator(AbstractFunctionCodeGenerator):
  1134. def _compile(self, node):
  1135. assert isinstance(node, ast.expr)
  1136. self.update_position(node.lineno)
  1137. node.build_container(self)
  1138. self._comp_generator(node, node.get_generators(), 0)
  1139. self._end_comp()
  1140. def _end_comp(self):
  1141. self.emit_op(ops.RETURN_VALUE)
  1142. class GenExpCodeGenerator(ComprehensionCodeGenerator):
  1143. def _end_comp(self):
  1144. pass
  1145. def _get_code_flags(self):
  1146. flags = ComprehensionCodeGenerator._get_code_flags(self)
  1147. return flags | consts.CO_GENERATOR
  1148. class ClassCodeGenerator(PythonCodeGenerator):
  1149. def _compile(self, cls):
  1150. assert isinstance(cls, ast.ClassDef)
  1151. self.lineno = self.first_lineno
  1152. self.name_op("__name__", ast.Load)
  1153. self.name_op("__module__", ast.Store)
  1154. self._handle_body(cls.body)
  1155. self.emit_op(ops.LOAD_LOCALS)
  1156. self.emit_op(ops.RETURN_VALUE)