Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/python-wasm
Path: blob/main/python/pylang/src/output/statements.py
1398 views
1
# vim:fileencoding=utf-8
2
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3
from __python__ import hash_literals
4
5
from ast_types import (AST_Definitions, AST_Scope, AST_Method, AST_Except,
6
AST_EmptyStatement, AST_Statement, AST_Seq,
7
AST_BaseCall, AST_Dot, AST_Sub, AST_ItemAccess,
8
AST_Conditional, AST_Binary, AST_BlockStatement,
9
is_node_type)
10
11
12
def force_statement(stat, output):
13
if output.options.bracketize:
14
if not stat or is_node_type(stat, AST_EmptyStatement):
15
output.print("{}")
16
elif is_node_type(stat, AST_BlockStatement):
17
stat.print(output)
18
else:
19
20
def f():
21
output.indent()
22
stat.print(output)
23
output.newline()
24
25
output.with_block(f)
26
else:
27
if not stat or is_node_type(stat, AST_EmptyStatement):
28
output.force_semicolon()
29
else:
30
stat.print(output)
31
32
33
# return true if the node at the top of the stack (that means the
34
# innermost node in the current output) is lexically the first in
35
# a statement.
36
def first_in_statement(output):
37
a = output.stack()
38
i = a.length
39
i -= 1
40
node = a[i]
41
i -= 1
42
p = a[i]
43
while i > 0:
44
if is_node_type(p, AST_Statement) and p.body is node:
45
return True
46
if (is_node_type(p, AST_Seq) and p.car is node
47
or is_node_type(p, AST_BaseCall) and p.expression is node
48
or is_node_type(p, AST_Dot) and p.expression is node
49
or is_node_type(p, AST_Sub) and p.expression is node
50
or is_node_type(p, AST_ItemAccess) and p.expression is node
51
or is_node_type(p, AST_Conditional) and p.condition is node
52
or is_node_type(p, AST_Binary) and p.left is node):
53
node = p
54
i -= 1
55
p = a[i]
56
else:
57
return False
58
59
60
def declare_vars(vars, output):
61
# declare all variables as local, unless explictly set otherwise
62
if vars.length:
63
output.indent()
64
output.print("var")
65
output.space()
66
for i, arg in enumerate(vars):
67
if i:
68
output.comma()
69
70
arg.print(output)
71
output.semicolon()
72
output.newline()
73
74
75
def display_body(body, is_toplevel, output):
76
last = body.length - 1
77
for i, stmt in enumerate(body):
78
if not (is_node_type(stmt, AST_EmptyStatement)) and not (is_node_type(
79
stmt, AST_Definitions)):
80
output.indent()
81
stmt.print(output)
82
if not (i is last and is_toplevel):
83
output.newline()
84
85
86
def display_complex_body(node, is_toplevel, output, function_preamble):
87
offset = 0
88
# argument offset
89
# this is a method, add 'var self = this'
90
if is_node_type(node, AST_Method) and not node.static:
91
output.indent()
92
output.print("var")
93
output.space()
94
output.assign(node.argnames[0])
95
output.print("this")
96
output.semicolon()
97
output.newline()
98
offset += 1
99
100
if is_node_type(node, AST_Scope):
101
function_preamble(node, output, offset)
102
declare_vars(node.localvars, output)
103
104
elif is_node_type(node, AST_Except):
105
if node.argname:
106
output.indent()
107
output.print("var")
108
output.space()
109
output.assign(node.argname)
110
output.print("ρσ_Exception")
111
output.semicolon()
112
output.newline()
113
114
display_body(node.body, is_toplevel, output)
115
116
117
def display_lambda_body(node, output, function_preamble):
118
if function_preamble is not None:
119
function_preamble(node, output, 0)
120
output.indent()
121
output.print("return ")
122
node.body.print(output)
123
output.print(";")
124
125
126
def print_bracketed(node, output, complex, function_preamble, before, after):
127
if node.body.length > 0 or node.is_lambda:
128
129
def f():
130
if before:
131
before(output)
132
if node.is_lambda:
133
display_lambda_body(node, output,
134
function_preamble if complex else None)
135
elif complex:
136
display_complex_body(node, False, output, function_preamble)
137
else:
138
display_body(node.body, False, output)
139
if after:
140
after(output)
141
142
output.with_block(f)
143
else:
144
if before or after:
145
146
def f():
147
if before:
148
before(output)
149
if after:
150
after(output)
151
152
output.with_block(f)
153
else:
154
output.print("{}")
155
156
157
def print_with(self, output):
158
exits = []
159
output.assign('ρσ_with_exception'), output.print(
160
'undefined'), output.end_statement()
161
for clause in self.clauses:
162
output.with_counter += 1
163
clause_name = 'ρσ_with_clause_' + output.with_counter
164
exits.push(clause_name)
165
output.indent(), output.print('var '), output.assign(clause_name)
166
clause.expression.print(output)
167
output.end_statement()
168
output.indent()
169
if clause.alias:
170
output.assign(clause.alias.name)
171
output.print(clause_name + '.__enter__()')
172
output.end_statement()
173
output.indent(), output.print('try'), output.space()
174
175
def f_body():
176
output.indent()
177
self._do_print_body(output)
178
output.newline()
179
180
output.with_block(f_body)
181
182
output.space(), output.print('catch(e)')
183
184
def f_with():
185
output.indent()
186
output.assign('ρσ_with_exception')
187
output.print('e')
188
output.end_statement()
189
190
output.with_block(f_with)
191
192
output.newline(), output.indent(), output.spaced('if',
193
'(ρσ_with_exception',
194
'===', 'undefined)')
195
196
def f_exit():
197
for clause in exits:
198
output.indent(), output.print(
199
clause + '.__exit__()'), output.end_statement()
200
201
output.with_block(f_exit)
202
203
output.space(), output.print('else'), output.space()
204
205
def f_suppress():
206
output.indent(), output.assign('ρσ_with_suppress'), output.print(
207
'false'), output.end_statement()
208
for clause in exits:
209
output.indent()
210
output.spaced(
211
'ρσ_with_suppress', '|=', 'ρσ_bool(' + clause +
212
'.__exit__(ρσ_with_exception.constructor,',
213
'ρσ_with_exception,', 'ρσ_with_exception.stack))')
214
output.end_statement()
215
output.indent(), output.spaced(
216
'if', '(!ρσ_with_suppress)',
217
'throw ρσ_with_exception'), output.end_statement()
218
219
output.with_block(f_suppress)
220
221
222
def print_assert(self, output):
223
if output.options.discard_asserts:
224
return
225
output.spaced('if', '(!('), self.condition.print(output), output.spaced(
226
'))', 'throw new AssertionError')
227
if self.message:
228
output.print('(')
229
self.message.print(output)
230
output.print(')')
231
output.end_statement()
232
233