rapydscript-ns 0.9.3 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/.agignore +1 -1
  2. package/.github/workflows/ci.yml +38 -38
  3. package/=template.pyj +5 -5
  4. package/CHANGELOG.md +18 -0
  5. package/HACKING.md +103 -103
  6. package/LICENSE +24 -24
  7. package/PYTHON_GAPS.md +52 -142
  8. package/README.md +51 -21
  9. package/TODO.md +1 -26
  10. package/add-toc-to-readme +2 -2
  11. package/bin/export +75 -75
  12. package/bin/rapydscript +0 -0
  13. package/bin/web-repl-export +102 -102
  14. package/build +2 -2
  15. package/language-service/index.js +88 -36
  16. package/package.json +1 -1
  17. package/publish.py +37 -37
  18. package/release/baselib-plain-pretty.js +157 -31
  19. package/release/baselib-plain-ugly.js +5 -5
  20. package/release/compiler.js +724 -426
  21. package/release/signatures.json +29 -29
  22. package/session.vim +4 -4
  23. package/setup.cfg +2 -2
  24. package/src/ast.pyj +7 -0
  25. package/src/baselib-containers.pyj +41 -4
  26. package/src/baselib-errors.pyj +4 -3
  27. package/src/baselib-internal.pyj +47 -18
  28. package/src/baselib-str.pyj +16 -3
  29. package/src/compiler.pyj +36 -36
  30. package/src/errors.pyj +30 -30
  31. package/src/lib/aes.pyj +646 -646
  32. package/src/lib/collections.pyj +227 -3
  33. package/src/lib/copy.pyj +120 -120
  34. package/src/lib/elementmaker.pyj +83 -83
  35. package/src/lib/encodings.pyj +126 -126
  36. package/src/lib/gettext.pyj +569 -569
  37. package/src/lib/itertools.pyj +580 -580
  38. package/src/lib/math.pyj +193 -193
  39. package/src/lib/operator.pyj +11 -11
  40. package/src/lib/pprint.pyj +455 -0
  41. package/src/lib/random.pyj +118 -118
  42. package/src/lib/react.pyj +74 -74
  43. package/src/lib/statistics.pyj +0 -0
  44. package/src/lib/traceback.pyj +63 -63
  45. package/src/lib/uuid.pyj +77 -77
  46. package/src/monaco-language-service/completions.js +21 -14
  47. package/src/monaco-language-service/diagnostics.js +2 -2
  48. package/src/monaco-language-service/dts.js +58 -15
  49. package/src/monaco-language-service/package.json +3 -0
  50. package/src/output/classes.pyj +25 -2
  51. package/src/output/codegen.pyj +4 -1
  52. package/src/output/comments.pyj +45 -45
  53. package/src/output/exceptions.pyj +201 -201
  54. package/src/output/jsx.pyj +164 -164
  55. package/src/output/treeshake.pyj +182 -182
  56. package/src/output/utils.pyj +72 -72
  57. package/src/parse.pyj +42 -7
  58. package/src/string_interpolation.pyj +72 -72
  59. package/src/tokenizer.pyj +18 -2
  60. package/src/unicode_aliases.pyj +576 -576
  61. package/src/utils.pyj +192 -192
  62. package/test/_import_one.pyj +37 -37
  63. package/test/_import_two/__init__.pyj +11 -11
  64. package/test/_import_two/level2/deep.pyj +4 -4
  65. package/test/_import_two/other.pyj +6 -6
  66. package/test/_import_two/sub.pyj +13 -13
  67. package/test/aes_vectors.pyj +421 -421
  68. package/test/annotations.pyj +80 -80
  69. package/test/baselib.pyj +23 -0
  70. package/test/chainmap.pyj +185 -0
  71. package/test/dataclasses.pyj +3 -4
  72. package/test/decorators.pyj +77 -77
  73. package/test/docstrings.pyj +39 -39
  74. package/test/elementmaker_test.pyj +45 -45
  75. package/test/enum.pyj +1 -1
  76. package/test/functions.pyj +151 -151
  77. package/test/generators.pyj +41 -41
  78. package/test/generic.pyj +370 -370
  79. package/test/internationalization.pyj +73 -73
  80. package/test/lint.pyj +164 -164
  81. package/test/loops.pyj +85 -85
  82. package/test/numpy.pyj +734 -734
  83. package/test/pprint.pyj +232 -0
  84. package/test/python_features.pyj +1 -1
  85. package/test/repl.pyj +121 -121
  86. package/test/scoped_flags.pyj +76 -76
  87. package/test/statistics.pyj +224 -0
  88. package/test/str.pyj +4 -4
  89. package/test/unit/index.js +455 -0
  90. package/test/unit/language-service-completions.js +2 -0
  91. package/test/unit/language-service-dts.js +113 -0
  92. package/test/unit/language-service-hover.js +455 -455
  93. package/test/unit/language-service.js +135 -2
  94. package/test/unit/web-repl.js +349 -1
  95. package/tools/compiler.d.ts +367 -367
  96. package/tools/completer.js +131 -131
  97. package/tools/export.js +4 -2
  98. package/tools/gettext.js +185 -185
  99. package/tools/ini.js +65 -65
  100. package/tools/msgfmt.js +187 -187
  101. package/tools/repl.js +223 -223
  102. package/tools/test.js +118 -118
  103. package/tools/utils.js +141 -128
  104. package/tools/web_repl.js +95 -95
  105. package/try +41 -41
  106. package/web-repl/env.js +196 -196
  107. package/web-repl/index.html +163 -163
  108. package/web-repl/prism.css +139 -139
  109. package/web-repl/prism.js +113 -113
  110. package/web-repl/rapydscript.js +228 -226
  111. package/web-repl/sha1.js +25 -25
@@ -125,8 +125,8 @@ def print_class(output):
125
125
  output.indent()
126
126
  output.spaced('if', '(this.ρσ_object_id', '===', 'undefined)', 'Object.defineProperty(this,', '"ρσ_object_id",', '{"value":++ρσ_object_counter})')
127
127
  output.end_statement()
128
- if self.has_attr_dunders:
129
- # Wrap in a Proxy so __getattr__/__setattr__/__delattr__/__getattribute__ are triggered.
128
+ if self.has_attr_dunders or self.slots:
129
+ # Wrap in a Proxy so __getattr__/__setattr__/__delattr__/__getattribute__/__slots__ are triggered.
130
130
  output.indent()
131
131
  output.print('var ρσ_proxy = ρσ_JS_Proxy ? new ρσ_JS_Proxy(this, ρσ_attr_proxy_handler) : this')
132
132
  output.end_statement()
@@ -330,6 +330,29 @@ def print_class(output):
330
330
  output.print('.prototype, "__class__", {get: function() { return this.constructor; }, configurable: true})')
331
331
  output.end_statement()
332
332
 
333
+ # __slots__ enforcement: emit allowed attribute set on prototype
334
+ if self.slots:
335
+ output.indent()
336
+ self.name.print(output)
337
+ # Merge parent slots (if any) with this class's slots + bound methods
338
+ slot_obj = '{'
339
+ for i in range(self.slots.length):
340
+ if i > 0:
341
+ slot_obj += ', '
342
+ slot_obj += JSON.stringify(self.slots[i]) + ': true'
343
+ for i in range(self.bound.length):
344
+ if self.slots.length or i > 0:
345
+ slot_obj += ', '
346
+ slot_obj += JSON.stringify(self.bound[i]) + ': true'
347
+ slot_obj += '}'
348
+ if self.parent:
349
+ output.print('.prototype.__ρσ_slots__ = Object.assign({}, ')
350
+ self.parent.print(output)
351
+ output.print('.prototype.__ρσ_slots__, ' + slot_obj + ')')
352
+ else:
353
+ output.print('.prototype.__ρσ_slots__ = Object.assign({}, ' + slot_obj + ')')
354
+ output.end_statement()
355
+
333
356
  # Other statements in the class context (including nested class definitions).
334
357
  # Emitted BEFORE __init_subclass__ so that the hook can see class variables.
335
358
  # This matches Python's behaviour: the class body executes first, then the
@@ -7,7 +7,7 @@ from __python__ import hash_literals
7
7
  from utils import noop
8
8
  from parse import PRECEDENCE
9
9
  from ast import (
10
- AST_Array, AST_Assign, AST_BaseCall, AST_Binary, AST_BlockStatement, AST_Break,
10
+ AST_Array, AST_Assign, AST_BaseCall, AST_BigInt, AST_Binary, AST_BlockStatement, AST_Break,
11
11
  AST_Class, AST_Conditional, AST_Constant, AST_Continue,
12
12
  AST_Debugger, AST_Definitions, AST_Directive, AST_Do, AST_Dot, is_node_type,
13
13
  AST_EmptyStatement, AST_Exit, AST_ExpressiveObject, AST_ForIn,
@@ -530,6 +530,9 @@ def generate_code():
530
530
  DEFPRINT(AST_Number, def(self, output):
531
531
  output.print(make_num(self.value))
532
532
  )
533
+ DEFPRINT(AST_BigInt, def(self, output):
534
+ output.print(self.value + "n")
535
+ )
533
536
  DEFPRINT(AST_RegExp, print_regexp)
534
537
 
535
538
  # -----[ JSX ]-----
@@ -1,45 +1,45 @@
1
- # vim:fileencoding=utf-8
2
- # License: BSD Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
3
- from __python__ import hash_literals
4
-
5
- from ast import AST_Exit, is_node_type
6
-
7
-
8
- def output_comments(comments, output, nlb):
9
- for comm in comments:
10
- if comm.type is "comment1":
11
- output.print("//" + comm.value + "\n")
12
- output.indent()
13
- elif comm.type is "comment2":
14
- output.print("/*" + comm.value + "*/")
15
- if nlb:
16
- output.print("\n")
17
- output.indent()
18
- else:
19
- output.space()
20
-
21
-
22
- def print_comments(self, output):
23
- c = output.options.comments
24
- if c:
25
- start = self.start
26
- if start and not start._comments_dumped:
27
- start._comments_dumped = True
28
- comments = start.comments_before
29
- # XXX: ugly fix for https://github.com/mishoo/RapydScript2/issues/112
30
- # if this node is `return` or `throw`, we cannot allow comments before
31
- # the returned or thrown value.
32
- if is_node_type(self, AST_Exit) and self.value and self.value.start.comments_before and self.value.start.comments_before.length > 0:
33
- comments = (comments or v'[]').concat(self.value.start.comments_before)
34
- self.value.start.comments_before = v'[]'
35
-
36
- if c.test:
37
- comments = comments.filter(def(comment):
38
- return c.test(comment.value)
39
- )
40
- elif jstype(c) is "function":
41
- comments = comments.filter(def(comment):
42
- return c(self, comment)
43
- )
44
-
45
- output_comments(comments, output, start.nlb)
1
+ # vim:fileencoding=utf-8
2
+ # License: BSD Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
3
+ from __python__ import hash_literals
4
+
5
+ from ast import AST_Exit, is_node_type
6
+
7
+
8
+ def output_comments(comments, output, nlb):
9
+ for comm in comments:
10
+ if comm.type is "comment1":
11
+ output.print("//" + comm.value + "\n")
12
+ output.indent()
13
+ elif comm.type is "comment2":
14
+ output.print("/*" + comm.value + "*/")
15
+ if nlb:
16
+ output.print("\n")
17
+ output.indent()
18
+ else:
19
+ output.space()
20
+
21
+
22
+ def print_comments(self, output):
23
+ c = output.options.comments
24
+ if c:
25
+ start = self.start
26
+ if start and not start._comments_dumped:
27
+ start._comments_dumped = True
28
+ comments = start.comments_before
29
+ # XXX: ugly fix for https://github.com/mishoo/RapydScript2/issues/112
30
+ # if this node is `return` or `throw`, we cannot allow comments before
31
+ # the returned or thrown value.
32
+ if is_node_type(self, AST_Exit) and self.value and self.value.start.comments_before and self.value.start.comments_before.length > 0:
33
+ comments = (comments or v'[]').concat(self.value.start.comments_before)
34
+ self.value.start.comments_before = v'[]'
35
+
36
+ if c.test:
37
+ comments = comments.filter(def(comment):
38
+ return c.test(comment.value)
39
+ )
40
+ elif jstype(c) is "function":
41
+ comments = comments.filter(def(comment):
42
+ return c(self, comment)
43
+ )
44
+
45
+ output_comments(comments, output, start.nlb)
@@ -1,201 +1,201 @@
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 output.statements import print_bracketed, display_body
6
-
7
-
8
- def print_try(self, output):
9
- else_var_name = None
10
- def update_output_var(output):
11
- output.indent(), output.assign(else_var_name), output.print('true'), output.end_statement()
12
- if self.belse:
13
- else_var_name = output.new_try_else_counter()
14
- output.assign('var ' + else_var_name), output.print('false'), output.end_statement(), output.indent()
15
- output.print("try")
16
- output.space()
17
- print_bracketed(self, output, False, None, None, update_output_var if else_var_name else None)
18
- if self.bcatch:
19
- output.space()
20
- print_catch(self.bcatch, output)
21
-
22
- if self.bfinally:
23
- output.space()
24
- print_finally(self.bfinally, output, self.belse, else_var_name)
25
- elif self.belse:
26
- output.newline()
27
- print_else(self.belse, else_var_name, output)
28
-
29
-
30
- def print_catch(self, output):
31
- # Dispatch to except* handler when any clause is an exception group handler
32
- if self.body.length and self.body[0].is_star:
33
- print_catch_star(self, output)
34
- return
35
- output.print("catch")
36
- output.space()
37
- output.with_parens(def():
38
- output.print("ρσ_Exception")
39
- )
40
- output.space()
41
- output.with_block(def():
42
- output.indent()
43
- output.spaced('ρσ_last_exception', '=', 'ρσ_Exception'), output.end_statement()
44
- output.indent()
45
- no_default = True
46
- for i, exception in enumerate(self.body):
47
- if i:
48
- output.print("else ")
49
-
50
- if exception.errors.length:
51
- output.print("if")
52
- output.space()
53
- output.with_parens(def():
54
- for i, err in enumerate(exception.errors):
55
- if i:
56
- output.newline()
57
- output.indent()
58
- output.print("||")
59
- output.space()
60
-
61
- output.print("ρσ_Exception")
62
- output.space()
63
- output.print("instanceof")
64
- output.space()
65
- if err.name is 'Exception':
66
- output.print('Error')
67
- else:
68
- err.print(output)
69
- )
70
- output.space()
71
- else:
72
- no_default = False
73
- print_bracketed(exception, output, True)
74
- output.space()
75
- if no_default:
76
- output.print("else")
77
- output.space()
78
- output.with_block(def():
79
- output.indent()
80
- output.print("throw")
81
- output.space()
82
- output.print("ρσ_Exception")
83
- output.semicolon()
84
- output.newline()
85
- )
86
- output.newline()
87
- )
88
-
89
-
90
- def _eg_type_cond(errors, varname):
91
- # Build a JS condition string testing varname against each error type
92
- parts = []
93
- for err in errors:
94
- if err.name is 'Exception':
95
- parts.push(varname + " instanceof Error")
96
- else:
97
- parts.push(varname + " instanceof " + err.name)
98
- return parts.join(" || ")
99
-
100
-
101
- def print_catch_star(self, output):
102
- output.print("catch")
103
- output.space()
104
- output.with_parens(def():
105
- output.print("ρσ_Exception")
106
- )
107
- output.space()
108
- output.with_block(def():
109
- output.indent()
110
- output.spaced('ρσ_last_exception', '=', 'ρσ_Exception'), output.end_statement()
111
-
112
- # Normalise: wrap non-ExceptionGroup exception into a one-element array
113
- output.indent()
114
- output.print("var ρσ_eg_exceptions = (ρσ_Exception instanceof ExceptionGroup) ? ρσ_Exception.exceptions.slice() : [ρσ_Exception]")
115
- output.semicolon(), output.newline()
116
- output.indent()
117
- output.print("var ρσ_eg_raised = []")
118
- output.semicolon(), output.newline()
119
-
120
- for ei, exception in enumerate(self.body):
121
- idx = str(ei)
122
- if exception.errors.length:
123
- cond = _eg_type_cond(exception.errors, "ρσ_et")
124
- output.indent()
125
- output.print("var ρσ_eg_matched_" + idx + " = ρσ_eg_exceptions.filter(function(ρσ_et) { return " + cond + "; })")
126
- output.semicolon(), output.newline()
127
- output.indent()
128
- output.print("ρσ_eg_exceptions = ρσ_eg_exceptions.filter(function(ρσ_et) { return !(" + cond + "); })")
129
- output.semicolon(), output.newline()
130
- else:
131
- # Bare except*: take all remaining
132
- output.indent()
133
- output.print("var ρσ_eg_matched_" + idx + " = ρσ_eg_exceptions.slice()")
134
- output.semicolon(), output.newline()
135
- output.indent()
136
- output.print("ρσ_eg_exceptions = []")
137
- output.semicolon(), output.newline()
138
-
139
- output.indent()
140
- output.print("if (ρσ_eg_matched_" + idx + ".length > 0)")
141
- output.space()
142
- output.with_block(def():
143
- if exception.argname:
144
- output.indent()
145
- output.print("var ")
146
- output.assign(exception.argname)
147
- output.print("(ρσ_Exception instanceof ExceptionGroup) ? new ExceptionGroup(ρσ_Exception.message, ρσ_eg_matched_" + idx + ") : ρσ_eg_matched_" + idx + "[0]")
148
- output.semicolon(), output.newline()
149
- output.indent()
150
- output.print("try")
151
- output.space()
152
- output.with_block(def():
153
- display_body(exception.body, False, output)
154
- )
155
- output.print(" catch (ρσ_eg_exc_" + idx + ")")
156
- output.space()
157
- output.with_block(def():
158
- output.indent()
159
- output.print("ρσ_eg_raised.push(ρσ_eg_exc_" + idx + ")")
160
- output.semicolon(), output.newline()
161
- )
162
- output.newline()
163
- )
164
- output.newline()
165
-
166
- # Re-raise unmatched exceptions and any raised by handlers
167
- output.indent()
168
- output.print("var ρσ_eg_unhandled = ρσ_eg_exceptions.concat(ρσ_eg_raised)")
169
- output.semicolon(), output.newline()
170
- output.indent()
171
- output.print("if (ρσ_eg_unhandled.length > 0)")
172
- output.space()
173
- output.with_block(def():
174
- output.indent()
175
- output.print("throw (ρσ_eg_unhandled.length === 1 && !(ρσ_Exception instanceof ExceptionGroup)) ? ρσ_eg_unhandled[0] : new ExceptionGroup((ρσ_Exception instanceof ExceptionGroup) ? ρσ_Exception.message : \"unhandled exceptions\", ρσ_eg_unhandled)")
176
- output.semicolon(), output.newline()
177
- )
178
- output.newline()
179
- )
180
-
181
-
182
- def print_finally(self, output, belse, else_var_name):
183
- output.print("finally")
184
- output.space()
185
- if else_var_name:
186
- output.with_block(def():
187
- output.indent(), output.print("try")
188
- output.space()
189
- output.with_block(def():
190
- print_else(belse, else_var_name, output)
191
- )
192
- print_finally(self, output)
193
- )
194
- else:
195
- print_bracketed(self, output)
196
-
197
-
198
- def print_else(self, else_var_name, output):
199
- output.indent(), output.spaced('if', '(' + else_var_name + ')')
200
- output.space()
201
- print_bracketed(self, output)
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 output.statements import print_bracketed, display_body
6
+
7
+
8
+ def print_try(self, output):
9
+ else_var_name = None
10
+ def update_output_var(output):
11
+ output.indent(), output.assign(else_var_name), output.print('true'), output.end_statement()
12
+ if self.belse:
13
+ else_var_name = output.new_try_else_counter()
14
+ output.assign('var ' + else_var_name), output.print('false'), output.end_statement(), output.indent()
15
+ output.print("try")
16
+ output.space()
17
+ print_bracketed(self, output, False, None, None, update_output_var if else_var_name else None)
18
+ if self.bcatch:
19
+ output.space()
20
+ print_catch(self.bcatch, output)
21
+
22
+ if self.bfinally:
23
+ output.space()
24
+ print_finally(self.bfinally, output, self.belse, else_var_name)
25
+ elif self.belse:
26
+ output.newline()
27
+ print_else(self.belse, else_var_name, output)
28
+
29
+
30
+ def print_catch(self, output):
31
+ # Dispatch to except* handler when any clause is an exception group handler
32
+ if self.body.length and self.body[0].is_star:
33
+ print_catch_star(self, output)
34
+ return
35
+ output.print("catch")
36
+ output.space()
37
+ output.with_parens(def():
38
+ output.print("ρσ_Exception")
39
+ )
40
+ output.space()
41
+ output.with_block(def():
42
+ output.indent()
43
+ output.spaced('ρσ_last_exception', '=', 'ρσ_Exception'), output.end_statement()
44
+ output.indent()
45
+ no_default = True
46
+ for i, exception in enumerate(self.body):
47
+ if i:
48
+ output.print("else ")
49
+
50
+ if exception.errors.length:
51
+ output.print("if")
52
+ output.space()
53
+ output.with_parens(def():
54
+ for i, err in enumerate(exception.errors):
55
+ if i:
56
+ output.newline()
57
+ output.indent()
58
+ output.print("||")
59
+ output.space()
60
+
61
+ output.print("ρσ_Exception")
62
+ output.space()
63
+ output.print("instanceof")
64
+ output.space()
65
+ if err.name is 'Exception':
66
+ output.print('Error')
67
+ else:
68
+ err.print(output)
69
+ )
70
+ output.space()
71
+ else:
72
+ no_default = False
73
+ print_bracketed(exception, output, True)
74
+ output.space()
75
+ if no_default:
76
+ output.print("else")
77
+ output.space()
78
+ output.with_block(def():
79
+ output.indent()
80
+ output.print("throw")
81
+ output.space()
82
+ output.print("ρσ_Exception")
83
+ output.semicolon()
84
+ output.newline()
85
+ )
86
+ output.newline()
87
+ )
88
+
89
+
90
+ def _eg_type_cond(errors, varname):
91
+ # Build a JS condition string testing varname against each error type
92
+ parts = []
93
+ for err in errors:
94
+ if err.name is 'Exception':
95
+ parts.push(varname + " instanceof Error")
96
+ else:
97
+ parts.push(varname + " instanceof " + err.name)
98
+ return parts.join(" || ")
99
+
100
+
101
+ def print_catch_star(self, output):
102
+ output.print("catch")
103
+ output.space()
104
+ output.with_parens(def():
105
+ output.print("ρσ_Exception")
106
+ )
107
+ output.space()
108
+ output.with_block(def():
109
+ output.indent()
110
+ output.spaced('ρσ_last_exception', '=', 'ρσ_Exception'), output.end_statement()
111
+
112
+ # Normalise: wrap non-ExceptionGroup exception into a one-element array
113
+ output.indent()
114
+ output.print("var ρσ_eg_exceptions = (ρσ_Exception instanceof ExceptionGroup) ? ρσ_Exception.exceptions.slice() : [ρσ_Exception]")
115
+ output.semicolon(), output.newline()
116
+ output.indent()
117
+ output.print("var ρσ_eg_raised = []")
118
+ output.semicolon(), output.newline()
119
+
120
+ for ei, exception in enumerate(self.body):
121
+ idx = str(ei)
122
+ if exception.errors.length:
123
+ cond = _eg_type_cond(exception.errors, "ρσ_et")
124
+ output.indent()
125
+ output.print("var ρσ_eg_matched_" + idx + " = ρσ_eg_exceptions.filter(function(ρσ_et) { return " + cond + "; })")
126
+ output.semicolon(), output.newline()
127
+ output.indent()
128
+ output.print("ρσ_eg_exceptions = ρσ_eg_exceptions.filter(function(ρσ_et) { return !(" + cond + "); })")
129
+ output.semicolon(), output.newline()
130
+ else:
131
+ # Bare except*: take all remaining
132
+ output.indent()
133
+ output.print("var ρσ_eg_matched_" + idx + " = ρσ_eg_exceptions.slice()")
134
+ output.semicolon(), output.newline()
135
+ output.indent()
136
+ output.print("ρσ_eg_exceptions = []")
137
+ output.semicolon(), output.newline()
138
+
139
+ output.indent()
140
+ output.print("if (ρσ_eg_matched_" + idx + ".length > 0)")
141
+ output.space()
142
+ output.with_block(def():
143
+ if exception.argname:
144
+ output.indent()
145
+ output.print("var ")
146
+ output.assign(exception.argname)
147
+ output.print("(ρσ_Exception instanceof ExceptionGroup) ? new ExceptionGroup(ρσ_Exception.message, ρσ_eg_matched_" + idx + ") : ρσ_eg_matched_" + idx + "[0]")
148
+ output.semicolon(), output.newline()
149
+ output.indent()
150
+ output.print("try")
151
+ output.space()
152
+ output.with_block(def():
153
+ display_body(exception.body, False, output)
154
+ )
155
+ output.print(" catch (ρσ_eg_exc_" + idx + ")")
156
+ output.space()
157
+ output.with_block(def():
158
+ output.indent()
159
+ output.print("ρσ_eg_raised.push(ρσ_eg_exc_" + idx + ")")
160
+ output.semicolon(), output.newline()
161
+ )
162
+ output.newline()
163
+ )
164
+ output.newline()
165
+
166
+ # Re-raise unmatched exceptions and any raised by handlers
167
+ output.indent()
168
+ output.print("var ρσ_eg_unhandled = ρσ_eg_exceptions.concat(ρσ_eg_raised)")
169
+ output.semicolon(), output.newline()
170
+ output.indent()
171
+ output.print("if (ρσ_eg_unhandled.length > 0)")
172
+ output.space()
173
+ output.with_block(def():
174
+ output.indent()
175
+ output.print("throw (ρσ_eg_unhandled.length === 1 && !(ρσ_Exception instanceof ExceptionGroup)) ? ρσ_eg_unhandled[0] : new ExceptionGroup((ρσ_Exception instanceof ExceptionGroup) ? ρσ_Exception.message : \"unhandled exceptions\", ρσ_eg_unhandled)")
176
+ output.semicolon(), output.newline()
177
+ )
178
+ output.newline()
179
+ )
180
+
181
+
182
+ def print_finally(self, output, belse, else_var_name):
183
+ output.print("finally")
184
+ output.space()
185
+ if else_var_name:
186
+ output.with_block(def():
187
+ output.indent(), output.print("try")
188
+ output.space()
189
+ output.with_block(def():
190
+ print_else(belse, else_var_name, output)
191
+ )
192
+ print_finally(self, output)
193
+ )
194
+ else:
195
+ print_bracketed(self, output)
196
+
197
+
198
+ def print_else(self, else_var_name, output):
199
+ output.indent(), output.spaced('if', '(' + else_var_name + ')')
200
+ output.space()
201
+ print_bracketed(self, output)