Path: blob/main/python/pylang/src/output/statements.py
1398 views
# vim:fileencoding=utf-81# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>2from __python__ import hash_literals34from ast_types import (AST_Definitions, AST_Scope, AST_Method, AST_Except,5AST_EmptyStatement, AST_Statement, AST_Seq,6AST_BaseCall, AST_Dot, AST_Sub, AST_ItemAccess,7AST_Conditional, AST_Binary, AST_BlockStatement,8is_node_type)91011def force_statement(stat, output):12if output.options.bracketize:13if not stat or is_node_type(stat, AST_EmptyStatement):14output.print("{}")15elif is_node_type(stat, AST_BlockStatement):16stat.print(output)17else:1819def f():20output.indent()21stat.print(output)22output.newline()2324output.with_block(f)25else:26if not stat or is_node_type(stat, AST_EmptyStatement):27output.force_semicolon()28else:29stat.print(output)303132# return true if the node at the top of the stack (that means the33# innermost node in the current output) is lexically the first in34# a statement.35def first_in_statement(output):36a = output.stack()37i = a.length38i -= 139node = a[i]40i -= 141p = a[i]42while i > 0:43if is_node_type(p, AST_Statement) and p.body is node:44return True45if (is_node_type(p, AST_Seq) and p.car is node46or is_node_type(p, AST_BaseCall) and p.expression is node47or is_node_type(p, AST_Dot) and p.expression is node48or is_node_type(p, AST_Sub) and p.expression is node49or is_node_type(p, AST_ItemAccess) and p.expression is node50or is_node_type(p, AST_Conditional) and p.condition is node51or is_node_type(p, AST_Binary) and p.left is node):52node = p53i -= 154p = a[i]55else:56return False575859def declare_vars(vars, output):60# declare all variables as local, unless explictly set otherwise61if vars.length:62output.indent()63output.print("var")64output.space()65for i, arg in enumerate(vars):66if i:67output.comma()6869arg.print(output)70output.semicolon()71output.newline()727374def display_body(body, is_toplevel, output):75last = body.length - 176for i, stmt in enumerate(body):77if not (is_node_type(stmt, AST_EmptyStatement)) and not (is_node_type(78stmt, AST_Definitions)):79output.indent()80stmt.print(output)81if not (i is last and is_toplevel):82output.newline()838485def display_complex_body(node, is_toplevel, output, function_preamble):86offset = 087# argument offset88# this is a method, add 'var self = this'89if is_node_type(node, AST_Method) and not node.static:90output.indent()91output.print("var")92output.space()93output.assign(node.argnames[0])94output.print("this")95output.semicolon()96output.newline()97offset += 19899if is_node_type(node, AST_Scope):100function_preamble(node, output, offset)101declare_vars(node.localvars, output)102103elif is_node_type(node, AST_Except):104if node.argname:105output.indent()106output.print("var")107output.space()108output.assign(node.argname)109output.print("ρσ_Exception")110output.semicolon()111output.newline()112113display_body(node.body, is_toplevel, output)114115116def display_lambda_body(node, output, function_preamble):117if function_preamble is not None:118function_preamble(node, output, 0)119output.indent()120output.print("return ")121node.body.print(output)122output.print(";")123124125def print_bracketed(node, output, complex, function_preamble, before, after):126if node.body.length > 0 or node.is_lambda:127128def f():129if before:130before(output)131if node.is_lambda:132display_lambda_body(node, output,133function_preamble if complex else None)134elif complex:135display_complex_body(node, False, output, function_preamble)136else:137display_body(node.body, False, output)138if after:139after(output)140141output.with_block(f)142else:143if before or after:144145def f():146if before:147before(output)148if after:149after(output)150151output.with_block(f)152else:153output.print("{}")154155156def print_with(self, output):157exits = []158output.assign('ρσ_with_exception'), output.print(159'undefined'), output.end_statement()160for clause in self.clauses:161output.with_counter += 1162clause_name = 'ρσ_with_clause_' + output.with_counter163exits.push(clause_name)164output.indent(), output.print('var '), output.assign(clause_name)165clause.expression.print(output)166output.end_statement()167output.indent()168if clause.alias:169output.assign(clause.alias.name)170output.print(clause_name + '.__enter__()')171output.end_statement()172output.indent(), output.print('try'), output.space()173174def f_body():175output.indent()176self._do_print_body(output)177output.newline()178179output.with_block(f_body)180181output.space(), output.print('catch(e)')182183def f_with():184output.indent()185output.assign('ρσ_with_exception')186output.print('e')187output.end_statement()188189output.with_block(f_with)190191output.newline(), output.indent(), output.spaced('if',192'(ρσ_with_exception',193'===', 'undefined)')194195def f_exit():196for clause in exits:197output.indent(), output.print(198clause + '.__exit__()'), output.end_statement()199200output.with_block(f_exit)201202output.space(), output.print('else'), output.space()203204def f_suppress():205output.indent(), output.assign('ρσ_with_suppress'), output.print(206'false'), output.end_statement()207for clause in exits:208output.indent()209output.spaced(210'ρσ_with_suppress', '|=', 'ρσ_bool(' + clause +211'.__exit__(ρσ_with_exception.constructor,',212'ρσ_with_exception,', 'ρσ_with_exception.stack))')213output.end_statement()214output.indent(), output.spaced(215'if', '(!ρσ_with_suppress)',216'throw ρσ_with_exception'), output.end_statement()217218output.with_block(f_suppress)219220221def print_assert(self, output):222if output.options.discard_asserts:223return224output.spaced('if', '(!('), self.condition.print(output), output.spaced(225'))', 'throw new AssertionError')226if self.message:227output.print('(')228self.message.print(output)229output.print(')')230output.end_statement()231232233