rapydscript-ng 0.7.24 → 0.8.1

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 (132) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +80 -26
  3. package/bin/build.ts +117 -0
  4. package/bin/package.json +1 -0
  5. package/bin/rapydscript +65 -62
  6. package/build_wheels.py +133 -0
  7. package/editor-plugins/README.md +80 -0
  8. package/editor-plugins/nvim.lua +321 -0
  9. package/local-agent.md +28 -0
  10. package/package.json +4 -5
  11. package/publish.py +27 -17
  12. package/release/baselib-plain-pretty.js +448 -326
  13. package/release/baselib-plain-ugly.js +3 -3
  14. package/release/compiler.js +9027 -8139
  15. package/release/signatures.json +27 -27
  16. package/release/stdlib_modules.json +1 -0
  17. package/src/ast.pyj +428 -280
  18. package/src/baselib-builtins.pyj +49 -28
  19. package/src/baselib-containers.pyj +241 -226
  20. package/src/baselib-errors.pyj +8 -1
  21. package/src/baselib-internal.pyj +38 -23
  22. package/src/baselib-itertools.pyj +13 -7
  23. package/src/baselib-str.pyj +59 -84
  24. package/src/compiler.pyj +4 -4
  25. package/src/errors.pyj +3 -4
  26. package/src/lib/aes.pyj +46 -32
  27. package/src/lib/elementmaker.pyj +11 -9
  28. package/src/lib/encodings.pyj +15 -5
  29. package/src/lib/gettext.pyj +9 -4
  30. package/src/lib/math.pyj +106 -45
  31. package/src/lib/operator.pyj +10 -10
  32. package/src/lib/pythonize.pyj +2 -1
  33. package/src/lib/random.pyj +28 -21
  34. package/src/lib/re.pyj +492 -19
  35. package/src/lib/traceback.pyj +171 -29
  36. package/src/lib/uuid.pyj +2 -2
  37. package/src/output/classes.pyj +28 -27
  38. package/src/output/codegen.pyj +87 -83
  39. package/src/output/comments.pyj +8 -8
  40. package/src/output/exceptions.pyj +20 -21
  41. package/src/output/functions.pyj +66 -64
  42. package/src/output/literals.pyj +24 -23
  43. package/src/output/loops.pyj +84 -142
  44. package/src/output/modules.pyj +55 -68
  45. package/src/output/operators.pyj +40 -29
  46. package/src/output/statements.pyj +21 -15
  47. package/src/output/stream.pyj +82 -56
  48. package/src/output/utils.pyj +12 -8
  49. package/src/parse.pyj +971 -620
  50. package/src/string_interpolation.pyj +5 -3
  51. package/src/tokenizer.pyj +188 -148
  52. package/src/utils.pyj +32 -15
  53. package/test/_treeshake_mod.pyj +30 -0
  54. package/test/_treeshake_side_effect.pyj +9 -0
  55. package/test/ast_serialization.pyj +392 -0
  56. package/test/async.pyj +95 -0
  57. package/test/baselib.pyj +1 -2
  58. package/test/embedded_compiler.pyj +57 -0
  59. package/test/fmt.pyj +291 -0
  60. package/test/generic.pyj +16 -3
  61. package/test/imports.pyj +8 -6
  62. package/test/internationalization.pyj +38 -37
  63. package/test/lint.pyj +120 -117
  64. package/test/lsp.pyj +257 -0
  65. package/test/repl.pyj +70 -65
  66. package/test/sourcemaps.pyj +315 -0
  67. package/test/starargs.pyj +46 -39
  68. package/test/str.pyj +8 -0
  69. package/test/traceback.pyj +263 -0
  70. package/test/treeshaking.pyj +181 -0
  71. package/test/web_repl_export.pyj +88 -0
  72. package/tools/ast_serialize.mjs +557 -0
  73. package/tools/cli.mjs +531 -0
  74. package/tools/compile.mjs +205 -0
  75. package/tools/compiler.mjs +159 -0
  76. package/tools/{completer.js → completer.mjs} +6 -6
  77. package/tools/{embedded_compiler.js → embedded_compiler.mjs} +17 -13
  78. package/tools/export.js +109 -56
  79. package/tools/fmt.mjs +975 -0
  80. package/tools/{gettext.js → gettext.mjs} +46 -53
  81. package/tools/ini.mjs +175 -0
  82. package/tools/{lint.js → lint.mjs} +78 -55
  83. package/tools/lsp.mjs +964 -0
  84. package/tools/lsp_protocol.mjs +259 -0
  85. package/tools/lsp_symbols.mjs +418 -0
  86. package/tools/{msgfmt.js → msgfmt.mjs} +18 -18
  87. package/tools/{repl.js → repl.mjs} +56 -42
  88. package/tools/{self.js → self.mjs} +71 -46
  89. package/tools/sourcemap.mjs +123 -0
  90. package/tools/test.mjs +252 -0
  91. package/tools/treeshake.mjs +400 -0
  92. package/tools/{utils.js → utils.mjs} +26 -23
  93. package/tools/{web_repl.js → web_repl.mjs} +15 -13
  94. package/tools/web_repl_export.mjs +97 -0
  95. package/tree-sitter/README.md +101 -0
  96. package/tree-sitter/grammar.js +992 -0
  97. package/tree-sitter/package.json +43 -0
  98. package/tree-sitter/queries/highlights.scm +232 -0
  99. package/tree-sitter/queries/indents.scm +64 -0
  100. package/tree-sitter/queries/injections.scm +14 -0
  101. package/tree-sitter/queries/locals.scm +108 -0
  102. package/tree-sitter/src/grammar.json +4976 -0
  103. package/tree-sitter/src/node-types.json +2901 -0
  104. package/tree-sitter/src/parser.c +196465 -0
  105. package/tree-sitter/src/scanner.c +294 -0
  106. package/tree-sitter/src/tree_sitter/alloc.h +54 -0
  107. package/tree-sitter/src/tree_sitter/array.h +330 -0
  108. package/tree-sitter/src/tree_sitter/parser.h +286 -0
  109. package/tree-sitter/test/corpus/chaining.txt +99 -0
  110. package/tree-sitter/test/corpus/classes.txt +147 -0
  111. package/tree-sitter/test/corpus/comprehensions.txt +155 -0
  112. package/tree-sitter/test/corpus/containers.txt +242 -0
  113. package/tree-sitter/test/corpus/control_flow.txt +361 -0
  114. package/tree-sitter/test/corpus/decorators.txt +64 -0
  115. package/tree-sitter/test/corpus/existential.txt +102 -0
  116. package/tree-sitter/test/corpus/functions.txt +293 -0
  117. package/tree-sitter/test/corpus/imports.txt +117 -0
  118. package/tree-sitter/test/corpus/literals.txt +135 -0
  119. package/tree-sitter/test/corpus/operators.txt +296 -0
  120. package/tree-sitter/test/corpus/statements.txt +189 -0
  121. package/tree-sitter/test/corpus/strings.txt +90 -0
  122. package/tree-sitter/test/corpus/subscripts.txt +227 -0
  123. package/tree-sitter/tree-sitter.json +36 -0
  124. package/web-repl/env.js +35 -23
  125. package/web-repl/main.js +8 -8
  126. package/bin/export +0 -75
  127. package/bin/web-repl-export +0 -102
  128. package/tools/cli.js +0 -523
  129. package/tools/compile.js +0 -184
  130. package/tools/compiler.js +0 -84
  131. package/tools/ini.js +0 -65
  132. package/tools/test.js +0 -110
@@ -2,26 +2,163 @@
2
2
  # License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3
3
  # globals: ρσ_str, ρσ_last_exception
4
4
 
5
+ _traceback_state = {'source_map': None, 'decoded': None}
6
+
7
+ _VLQ_BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
8
+
9
+
10
+ def set_source_map_data(data):
11
+ _traceback_state['source_map'] = data
12
+ _traceback_state['decoded'] = None
13
+
14
+
15
+ def serialize_error_for_formatting(err):
16
+ return {
17
+ 'name': err.name or 'Error',
18
+ 'stack': err.stack or '',
19
+ 'message': err.message or '',
20
+ }
21
+
22
+
23
+ def unserialize_error_for_formatting(err):
24
+ ans = new Error()
25
+ ans.name = err.name
26
+ ans.stack = err.stack
27
+ ans.message = err.message
28
+ return ans
29
+
30
+
31
+ def _vlq_decode(encoded):
32
+ result = v'[]'
33
+ i = 0
34
+ n = encoded.length
35
+ while i < n:
36
+ value = 0
37
+ shift = 0
38
+ has_more = True
39
+ while has_more:
40
+ digit = _VLQ_BASE64.indexOf(encoded[i])
41
+ i += 1
42
+ has_more = (digit & 32) != 0
43
+ value += (digit & 31) << shift
44
+ shift += 5
45
+ if value & 1:
46
+ value = -(value >> 1)
47
+ else:
48
+ value = value >> 1
49
+ result.push(value)
50
+ return result
51
+
52
+
53
+ def _decode_source_map(smap):
54
+ sources = smap.sources or v'[]'
55
+ source_root = smap.sourceRoot or ''
56
+ mappings_str = smap.mappings or ''
57
+ mapping_lines = mappings_str.split(';')
58
+ decoded = v'[]'
59
+ prev_src_idx = 0
60
+ prev_src_line = 0
61
+ prev_src_col = 0
62
+ for gen_line in range(mapping_lines.length):
63
+ line_str = mapping_lines[gen_line]
64
+ line_entries = v'[]'
65
+ if line_str:
66
+ segments = line_str.split(',')
67
+ prev_col = 0
68
+ for seg_str in segments:
69
+ if not seg_str:
70
+ continue
71
+ fields = _vlq_decode(seg_str)
72
+ if fields.length >= 4:
73
+ gen_col = prev_col + fields[0]
74
+ prev_col = gen_col
75
+ src_idx = prev_src_idx + fields[1]
76
+ prev_src_idx = src_idx
77
+ src_line = prev_src_line + fields[2]
78
+ prev_src_line = src_line
79
+ src_col = prev_src_col + fields[3]
80
+ prev_src_col = src_col
81
+ src_file = sources[src_idx] if src_idx >= 0 and src_idx < sources.length else ''
82
+ if source_root and src_file:
83
+ src_file = source_root + src_file
84
+ line_entries.push({'gen_col': gen_col, 'src_file': src_file, 'src_line': src_line, 'src_col': src_col})
85
+ elif fields.length >= 1:
86
+ prev_col += fields[0]
87
+ decoded.push(line_entries)
88
+ return decoded
89
+
90
+
91
+ def _find_mapping(decoded, gen_line, gen_col):
92
+ if not decoded or gen_line < 0 or gen_line >= decoded.length:
93
+ return None
94
+ line_entries = decoded[gen_line]
95
+ if not line_entries or not line_entries.length:
96
+ return None
97
+ best = None
98
+ for entry in line_entries:
99
+ if entry.gen_col <= gen_col:
100
+ if best is None or entry.gen_col > best.gen_col:
101
+ best = entry
102
+ return best
103
+
104
+
105
+ def _parse_stack_frame(line):
106
+ # Chrome/Node: " at functionName (file:line:col)"
107
+ m = /^\s*at\s+(.*?)\s+\((.+):(\d+):(\d+)\)/.exec(line)
108
+ if m:
109
+ return {'func': m[1] or None, 'file': m[2], 'line': parseInt(m[3], 10) - 1, 'col': parseInt(m[4], 10) - 1}
110
+ # Chrome/Node: " at file:line:col"
111
+ m = /^\s*at (.+):(\d+):(\d+)$/.exec(line)
112
+ if m:
113
+ return {'func': None, 'file': m[1], 'line': parseInt(m[2], 10) - 1, 'col': parseInt(m[3], 10) - 1}
114
+ # Firefox: "functionName@file:line:col"
115
+ m = /^(.*?)@(.+):(\d+):(\d+)$/.exec(line)
116
+ if m:
117
+ return {'func': m[1] or None, 'file': m[2], 'line': parseInt(m[3], 10) - 1, 'col': parseInt(m[4], 10) - 1}
118
+ return None
119
+
120
+
121
+ def _get_decoded_map():
122
+ if _traceback_state['decoded'] is None and _traceback_state['source_map']:
123
+ _traceback_state['decoded'] = _decode_source_map(_traceback_state['source_map'])
124
+ return _traceback_state['decoded']
125
+
5
126
 
6
127
  def _get_internal_traceback(err):
7
- if isinstance(err, Exception) and err.stack:
8
- lines = ρσ_str.splitlines(err.stack)
9
- final_lines = v'[]'
10
- found_sentinel = False
11
- for i, line in enumerate(lines):
12
- sline = ρσ_str.strip(line)
13
- if i is 0:
14
- final_lines.push(line)
15
- continue
16
- if found_sentinel:
17
- final_lines.push(line)
18
- continue
19
- # These two conditions work on desktop Chrome and Firefox to identify the correct
20
- # line in the traceback.
21
- if sline.startsWith('at new ' + err.name) or sline.startsWith(err.name + '@'):
22
- found_sentinel = True
23
- return final_lines.join('\n')
24
- return err and err.stack
128
+ lines = ρσ_str.splitlines(err.stack or '')
129
+ final_lines = v'[]'
130
+ start_line_idx = -1
131
+ for i, line in enumerate(lines):
132
+ if i > 0:
133
+ line = line.trim()
134
+ if line.startsWith('at new ' + err.name) or line.startsWith(err.name + '@'):
135
+ # this is the constructor for a RapydScript Exception
136
+ start_line_idx = i + 1
137
+ break
138
+ if start_line_idx < 0:
139
+ start_line_idx = 1
140
+ for i, xline in enumerate(lines):
141
+ if i > 0:
142
+ line = xline.trim()
143
+ if v"line.startsWith('at ') || line.includes('@') || /:\d+:\d+$/.test(line)":
144
+ start_line_idx = i
145
+ break
146
+ frame_lines = lines[start_line_idx:]
147
+ final_lines = final_lines.concat(frame_lines)
148
+ decoded = _get_decoded_map()
149
+ mapped_lines = v'[]'
150
+ if decoded:
151
+ for frame_line in frame_lines:
152
+ frame = _parse_stack_frame(frame_line)
153
+ if frame:
154
+ mapping = _find_mapping(decoded, frame.line, frame.col)
155
+ if mapping:
156
+ loc = ' File "' + mapping.src_file + '", line ' + (mapping.src_line + 1) + ', col ' + (mapping.src_col + 1)
157
+ if frame.func:
158
+ loc += ', in ' + frame.func
159
+ mapped_lines.push(loc)
160
+ return lines[0], final_lines, mapped_lines
161
+
25
162
 
26
163
  def format_exception(exc, limit):
27
164
  if jstype(exc) is 'undefined':
@@ -30,25 +167,29 @@ def format_exception(exc, limit):
30
167
  if exc and exc.toString:
31
168
  return [exc.toString()]
32
169
  return []
33
- tb = _get_internal_traceback(exc)
34
- if tb:
35
- lines = ρσ_str.splitlines(tb)
36
- e = lines[0]
37
- lines = lines[1:]
170
+ e, js_lines, rs_lines = _get_internal_traceback(exc)
171
+ if js_lines.length > 0:
38
172
  if limit:
39
- lines = lines[:limit+1] if limit > 0 else lines[limit:]
40
- lines.reverse()
41
- lines.push(e)
42
- lines.insert(0, 'Traceback (most recent call last):')
43
- return [l+'\n' for l in lines]
173
+ js_lines = js_lines[:limit] if limit > 0 else js_lines[limit:]
174
+ rs_lines = rs_lines[:limit] if limit > 0 else rs_lines[limit:]
175
+ js_lines.reverse()
176
+ rs_lines.reverse()
177
+ js_lines.push(e)
178
+ js_lines = v"['Traceback (most recent call last):'].concat(js_lines)"
179
+ if rs_lines.length > 0:
180
+ js_lines = js_lines.concat(['', 'Mapped Traceback (RapydScript):']).concat(rs_lines)
181
+ return [l + '\n' for l in js_lines]
44
182
  return [exc.toString()]
45
183
 
184
+
46
185
  def format_exc(limit):
47
186
  return format_exception(ρσ_last_exception, limit).join('')
48
187
 
188
+
49
189
  def print_exc(limit):
50
190
  print(format_exc(limit))
51
191
 
192
+
52
193
  def format_stack(limit):
53
194
  stack = Error().stack
54
195
  if not stack:
@@ -56,8 +197,9 @@ def format_stack(limit):
56
197
  lines = str.splitlines(stack)[2:]
57
198
  lines.reverse()
58
199
  if limit:
59
- lines = lines[:limit+1] if limit > 0 else lines[limit:]
200
+ lines = lines[:limit + 1] if limit > 0 else lines[limit:]
60
201
  return [l + '\n' for l in lines]
61
202
 
203
+
62
204
  def print_stack(limit):
63
205
  print(format_stack(limit).join(''))
package/src/lib/uuid.pyj CHANGED
@@ -47,11 +47,11 @@ def uuid4():
47
47
  def num_to_string(numbers, alphabet, pad_to_length):
48
48
  ans = v'[]'
49
49
  alphabet_len = alphabet.length
50
- numbers = Array.prototype.slice.call(numbers)
50
+ numbers = Array.from (numbers)
51
51
  for v'var i = 0; i < numbers.length - 1; i++':
52
52
  x = divmod(numbers[i], alphabet_len)
53
53
  numbers[i] = x[0]
54
- numbers[i+1] += x[1]
54
+ numbers[i + 1] += x[1]
55
55
  for v'var i = 0; i < numbers.length; i++':
56
56
  number = numbers[i]
57
57
  while number:
@@ -7,6 +7,7 @@ from output.functions import decorate, function_definition, function_annotation
7
7
  from output.utils import create_doctring
8
8
  from utils import has_prop
9
9
 
10
+
10
11
  def print_class(output):
11
12
  self = this
12
13
  if self.external:
@@ -16,12 +17,12 @@ def print_class(output):
16
17
  output.indent()
17
18
  self.name.print(output)
18
19
  if not is_var and method and has_prop(self.static, method):
19
- output.assign("." + method)
20
+ output.assign('.' + method)
20
21
  else:
21
22
  if is_var:
22
- output.assign(".prototype[" + method + "]")
23
+ output.assign('.prototype[' + method + ']')
23
24
  else:
24
- output.assign(".prototype" + (("." + method) if method else ""))
25
+ output.assign('.prototype' + (('.' + method) if method else ''))
25
26
 
26
27
  def define_method(stmt, is_property):
27
28
  name = stmt.name.name
@@ -33,7 +34,7 @@ def print_class(output):
33
34
 
34
35
  # decorate the method
35
36
  if stmt.decorators and stmt.decorators.length:
36
- decorate(stmt.decorators, output, def():function_definition(stmt, output, strip_first, True);)
37
+ decorate(stmt.decorators, output, def (): function_definition(stmt, output, strip_first, True);)
37
38
  output.end_statement()
38
39
  else:
39
40
  function_definition(stmt, output, strip_first)
@@ -45,7 +46,7 @@ def print_class(output):
45
46
  def define_default_method(name, body):
46
47
  class_def(name)
47
48
  output.spaced('function', name, '()', '')
48
- output.with_block(def(): output.indent(), body();)
49
+ output.with_block(def (): output.indent(), body();)
49
50
  output.end_statement()
50
51
 
51
52
  def add_hidden_property(name, proceed):
@@ -55,23 +56,23 @@ def print_class(output):
55
56
 
56
57
  # generate constructor
57
58
  def write_constructor():
58
- output.print("function")
59
+ output.print('function')
59
60
  output.space()
60
61
  self.name.print(output)
61
- output.print("()")
62
+ output.print('()')
62
63
  output.space()
63
64
 
64
- output.with_block(def():
65
+ output.with_block(def ():
65
66
  output.indent()
66
67
  output.spaced('if', '(this.ρσ_object_id', '===', 'undefined)', 'Object.defineProperty(this,', '"ρσ_object_id",', '{"value":++ρσ_object_counter})')
67
68
  output.end_statement()
68
69
  if self.bound.length:
69
70
  output.indent()
70
- self.name.print(output), output.print(".prototype.__bind_methods__.call(this)")
71
+ self.name.print(output), output.print('.prototype.__bind_methods__.call(this)')
71
72
  output.end_statement()
72
73
  output.indent()
73
74
  self.name.print(output)
74
- output.print(".prototype.__init__.apply(this"), output.comma(), output.print('arguments)')
75
+ output.print('.prototype.__init__.apply(this'), output.comma(), output.print('arguments)')
75
76
  output.end_statement()
76
77
  )
77
78
 
@@ -98,8 +99,8 @@ def print_class(output):
98
99
  # inheritance
99
100
  if self.parent:
100
101
  output.indent()
101
- output.print("ρσ_extends")
102
- output.with_parens(def():
102
+ output.print('ρσ_extends')
103
+ output.with_parens(def ():
103
104
  self.name.print(output)
104
105
  output.comma()
105
106
  self.parent.print(output)
@@ -109,9 +110,9 @@ def print_class(output):
109
110
  # method binding
110
111
  if self.bound.length:
111
112
  seen_methods = Object.create(None)
112
- add_hidden_property('__bind_methods__', def():
113
+ add_hidden_property('__bind_methods__', def ():
113
114
  output.spaced('function', '()', '')
114
- output.with_block(def():
115
+ output.with_block(def ():
115
116
  if self.bases.length:
116
117
  for v'var i = self.bases.length - 1; i >= 0; i--':
117
118
  base = self.bases[i]
@@ -133,12 +134,12 @@ def print_class(output):
133
134
  if property_names.length:
134
135
  output.indent()
135
136
  output.print('Object.defineProperties')
136
- output.with_parens(def():
137
- self.name.print(output), output.print('.prototype'), output.comma(), output.space(), output.with_block(def():
137
+ output.with_parens(def ():
138
+ self.name.print(output), output.print('.prototype'), output.comma(), output.space(), output.with_block(def ():
138
139
  for name in property_names:
139
140
  prop = self.dynamic_properties[name]
140
141
  output.indent(), output.print(JSON.stringify(name) + ':'), output.space()
141
- output.with_block(def():
142
+ output.with_block(def ():
142
143
  output.indent(), output.print('"enumerable":'), output.space(), output.print('true'), output.comma(), output.newline()
143
144
  if prop.getter:
144
145
  output.indent(), output.print('"get":'), output.space()
@@ -157,16 +158,16 @@ def print_class(output):
157
158
  # actual methods
158
159
  if not self.init:
159
160
  # Create a default __init__ method
160
- define_default_method('__init__', def():
161
+ define_default_method('__init__', def ():
161
162
  if self.parent:
162
163
  self.parent.print(output)
163
164
  output.spaced('.prototype.__init__', '&&')
164
165
  output.space(), self.parent.print(output)
165
- output.print(".prototype.__init__.apply")
166
- output.with_parens(def():
167
- output.print("this")
166
+ output.print('.prototype.__init__.apply')
167
+ output.with_parens(def ():
168
+ output.print('this')
168
169
  output.comma()
169
- output.print("arguments")
170
+ output.print('arguments')
170
171
  )
171
172
  output.end_statement()
172
173
  )
@@ -195,7 +196,7 @@ def print_class(output):
195
196
  console.error('Nested classes aren\'t supported yet') # noqa:undef
196
197
 
197
198
  if not defined_methods['__repr__']:
198
- define_default_method('__repr__', def():
199
+ define_default_method('__repr__', def ():
199
200
  if self.parent:
200
201
  output.print('if('), self.parent.print(output), output.spaced('.prototype.__repr__)', 'return', self.parent)
201
202
  output.print('.prototype.__repr__.call(this)'), output.end_statement()
@@ -205,7 +206,7 @@ def print_class(output):
205
206
  )
206
207
 
207
208
  if not defined_methods['__str__']:
208
- define_default_method('__str__', def():
209
+ define_default_method('__str__', def ():
209
210
  if self.parent:
210
211
  output.print('if('), self.parent.print(output), output.spaced('.prototype.__str__)', 'return', self.parent)
211
212
  output.print('.prototype.__str__.call(this)'), output.end_statement()
@@ -214,7 +215,7 @@ def print_class(output):
214
215
  )
215
216
 
216
217
  # Multiple inheritance
217
- add_hidden_property('__bases__', def():
218
+ add_hidden_property('__bases__', def ():
218
219
  output.print('[')
219
220
  for v'var i = 0; i < self.bases.length; i++':
220
221
  self.bases[i].print(output)
@@ -225,7 +226,7 @@ def print_class(output):
225
226
 
226
227
  if self.bases.length > 1:
227
228
  output.indent()
228
- output.print("ρσ_mixin(")
229
+ output.print('ρσ_mixin(')
229
230
  self.name.print(output)
230
231
  for v'var i = 1; i < self.bases.length; i++':
231
232
  output.comma()
@@ -234,7 +235,7 @@ def print_class(output):
234
235
 
235
236
  # Docstring
236
237
  if self.docstrings and self.docstrings.length and output.options.keep_docstrings:
237
- add_hidden_property('__doc__', def():
238
+ add_hidden_property('__doc__', def ():
238
239
  output.print(JSON.stringify(create_doctring(self.docstrings)))
239
240
  )
240
241