rapydscript-ns 0.8.0

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 (144) hide show
  1. package/.agignore +1 -0
  2. package/.gitattributes +4 -0
  3. package/.github/workflows/ci.yml +38 -0
  4. package/.github/workflows/web-repl-page-deploy.yml +42 -0
  5. package/=template.pyj +5 -0
  6. package/CHANGELOG.md +456 -0
  7. package/CONTRIBUTORS +13 -0
  8. package/HACKING.md +103 -0
  9. package/LICENSE +24 -0
  10. package/README.md +2512 -0
  11. package/TODO.md +327 -0
  12. package/add-toc-to-readme +2 -0
  13. package/bin/export +75 -0
  14. package/bin/rapydscript +70 -0
  15. package/bin/web-repl-export +102 -0
  16. package/build +3 -0
  17. package/package.json +46 -0
  18. package/publish.py +37 -0
  19. package/release/baselib-plain-pretty.js +4370 -0
  20. package/release/baselib-plain-ugly.js +3 -0
  21. package/release/compiler.js +18394 -0
  22. package/release/signatures.json +31 -0
  23. package/session.vim +4 -0
  24. package/setup.cfg +2 -0
  25. package/src/ast.pyj +1356 -0
  26. package/src/baselib-builtins.pyj +279 -0
  27. package/src/baselib-containers.pyj +723 -0
  28. package/src/baselib-errors.pyj +37 -0
  29. package/src/baselib-internal.pyj +421 -0
  30. package/src/baselib-itertools.pyj +97 -0
  31. package/src/baselib-str.pyj +798 -0
  32. package/src/compiler.pyj +36 -0
  33. package/src/errors.pyj +30 -0
  34. package/src/lib/aes.pyj +646 -0
  35. package/src/lib/collections.pyj +695 -0
  36. package/src/lib/elementmaker.pyj +83 -0
  37. package/src/lib/encodings.pyj +126 -0
  38. package/src/lib/functools.pyj +148 -0
  39. package/src/lib/gettext.pyj +569 -0
  40. package/src/lib/itertools.pyj +580 -0
  41. package/src/lib/math.pyj +193 -0
  42. package/src/lib/numpy.pyj +2101 -0
  43. package/src/lib/operator.pyj +11 -0
  44. package/src/lib/pythonize.pyj +20 -0
  45. package/src/lib/random.pyj +118 -0
  46. package/src/lib/re.pyj +470 -0
  47. package/src/lib/traceback.pyj +63 -0
  48. package/src/lib/uuid.pyj +77 -0
  49. package/src/monaco-language-service/analyzer.js +526 -0
  50. package/src/monaco-language-service/builtins.js +543 -0
  51. package/src/monaco-language-service/completions.js +498 -0
  52. package/src/monaco-language-service/diagnostics.js +643 -0
  53. package/src/monaco-language-service/dts.js +550 -0
  54. package/src/monaco-language-service/hover.js +121 -0
  55. package/src/monaco-language-service/index.js +386 -0
  56. package/src/monaco-language-service/scope.js +162 -0
  57. package/src/monaco-language-service/signature.js +144 -0
  58. package/src/output/__init__.pyj +0 -0
  59. package/src/output/classes.pyj +296 -0
  60. package/src/output/codegen.pyj +492 -0
  61. package/src/output/comments.pyj +45 -0
  62. package/src/output/exceptions.pyj +105 -0
  63. package/src/output/functions.pyj +491 -0
  64. package/src/output/literals.pyj +109 -0
  65. package/src/output/loops.pyj +444 -0
  66. package/src/output/modules.pyj +329 -0
  67. package/src/output/operators.pyj +429 -0
  68. package/src/output/statements.pyj +463 -0
  69. package/src/output/stream.pyj +309 -0
  70. package/src/output/treeshake.pyj +182 -0
  71. package/src/output/utils.pyj +72 -0
  72. package/src/parse.pyj +3106 -0
  73. package/src/string_interpolation.pyj +72 -0
  74. package/src/tokenizer.pyj +702 -0
  75. package/src/unicode_aliases.pyj +576 -0
  76. package/src/utils.pyj +192 -0
  77. package/test/_import_one.pyj +37 -0
  78. package/test/_import_two/__init__.pyj +11 -0
  79. package/test/_import_two/level2/__init__.pyj +0 -0
  80. package/test/_import_two/level2/deep.pyj +4 -0
  81. package/test/_import_two/other.pyj +6 -0
  82. package/test/_import_two/sub.pyj +13 -0
  83. package/test/aes_vectors.pyj +421 -0
  84. package/test/annotations.pyj +80 -0
  85. package/test/baselib.pyj +319 -0
  86. package/test/classes.pyj +452 -0
  87. package/test/collections.pyj +152 -0
  88. package/test/decorators.pyj +77 -0
  89. package/test/dict_spread.pyj +76 -0
  90. package/test/docstrings.pyj +39 -0
  91. package/test/elementmaker_test.pyj +45 -0
  92. package/test/ellipsis.pyj +49 -0
  93. package/test/functions.pyj +151 -0
  94. package/test/generators.pyj +41 -0
  95. package/test/generic.pyj +370 -0
  96. package/test/imports.pyj +72 -0
  97. package/test/internationalization.pyj +73 -0
  98. package/test/lint.pyj +164 -0
  99. package/test/loops.pyj +85 -0
  100. package/test/numpy.pyj +734 -0
  101. package/test/omit_function_metadata.pyj +20 -0
  102. package/test/regexp.pyj +55 -0
  103. package/test/repl.pyj +121 -0
  104. package/test/scoped_flags.pyj +76 -0
  105. package/test/starargs.pyj +506 -0
  106. package/test/starred_assign.pyj +104 -0
  107. package/test/str.pyj +198 -0
  108. package/test/subscript_tuple.pyj +53 -0
  109. package/test/unit/fixtures/fibonacci_expected.js +46 -0
  110. package/test/unit/index.js +2989 -0
  111. package/test/unit/language-service-builtins.js +815 -0
  112. package/test/unit/language-service-completions.js +1067 -0
  113. package/test/unit/language-service-dts.js +543 -0
  114. package/test/unit/language-service-hover.js +455 -0
  115. package/test/unit/language-service-scope.js +833 -0
  116. package/test/unit/language-service-signature.js +458 -0
  117. package/test/unit/language-service.js +705 -0
  118. package/test/unit/run-language-service.js +41 -0
  119. package/test/unit/web-repl.js +484 -0
  120. package/tools/build-language-service.js +190 -0
  121. package/tools/cli.js +547 -0
  122. package/tools/compile.js +219 -0
  123. package/tools/compiler.js +108 -0
  124. package/tools/completer.js +131 -0
  125. package/tools/embedded_compiler.js +251 -0
  126. package/tools/export.js +316 -0
  127. package/tools/gettext.js +185 -0
  128. package/tools/ini.js +65 -0
  129. package/tools/lint.js +705 -0
  130. package/tools/msgfmt.js +187 -0
  131. package/tools/repl.js +223 -0
  132. package/tools/self.js +162 -0
  133. package/tools/test.js +118 -0
  134. package/tools/utils.js +128 -0
  135. package/tools/web_repl.js +95 -0
  136. package/try +41 -0
  137. package/web-repl/env.js +74 -0
  138. package/web-repl/index.html +163 -0
  139. package/web-repl/language-service.js +4084 -0
  140. package/web-repl/main.js +254 -0
  141. package/web-repl/prism.css +139 -0
  142. package/web-repl/prism.js +113 -0
  143. package/web-repl/rapydscript.js +435 -0
  144. package/web-repl/sha1.js +25 -0
@@ -0,0 +1,702 @@
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 unicode_aliases import ALIAS_MAP
6
+ from utils import make_predicate, characters
7
+ from ast import AST_Token
8
+ from errors import SyntaxError
9
+ from string_interpolation import interpolate
10
+
11
+ RE_HEX_NUMBER = /^0x[0-9a-f]+$/i
12
+ RE_OCT_NUMBER = /^0[0-7]+$/
13
+ RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i
14
+
15
+ OPERATOR_CHARS = make_predicate(characters("+-*&%=<>!?|~^@"))
16
+
17
+ ASCII_CONTROL_CHARS = {'a':7, 'b':8, 'f': 12, 'n': 10, 'r': 13, 't': 9, 'v': 11}
18
+ HEX_PAT = /[a-fA-F0-9]/
19
+ NAME_PAT = /[a-zA-Z ]/
20
+
21
+ OPERATORS = make_predicate([
22
+ "in",
23
+ "instanceof",
24
+ "typeof",
25
+ "new",
26
+ "void",
27
+ "del",
28
+ "+",
29
+ "-",
30
+ "not",
31
+ "~",
32
+ "&",
33
+ "|",
34
+ "^",
35
+ "**",
36
+ "*",
37
+ "//",
38
+ "/",
39
+ "%",
40
+ ">>",
41
+ "<<",
42
+ ">>>",
43
+ "<",
44
+ ">",
45
+ "<=",
46
+ ">=",
47
+ "==",
48
+ "is",
49
+ "!=",
50
+ "=",
51
+ "+=",
52
+ "-=",
53
+ "//=",
54
+ "/=",
55
+ "*=",
56
+ "%=",
57
+ ">>=",
58
+ "<<=",
59
+ ">>>=",
60
+ "|=",
61
+ "^=",
62
+ "&=",
63
+ "and",
64
+ "or",
65
+ "@",
66
+ "->",
67
+ ":="
68
+ ])
69
+
70
+ OP_MAP = {
71
+ 'or': "||",
72
+ 'and': "&&",
73
+ 'not': "!",
74
+ 'del': "delete",
75
+ 'None': "null",
76
+ 'is': "===",
77
+ }
78
+
79
+ WHITESPACE_CHARS = make_predicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000"))
80
+
81
+ PUNC_BEFORE_EXPRESSION = make_predicate(characters("[{(,.;:"))
82
+
83
+ PUNC_CHARS = make_predicate(characters("[]{}(),;:?"))
84
+
85
+ KEYWORDS = "as assert async await break class continue def del do elif else except finally for from global if import in is lambda new nonlocal pass raise return yield try while with or and not"
86
+
87
+ KEYWORDS_ATOM = "False None True"
88
+
89
+ # see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar
90
+ RESERVED_WORDS = ("break case class catch const continue debugger default delete do else export extends"
91
+ " finally for function if import in instanceof new return switch this throw try typeof var void"
92
+ " while with yield enum implements static private package let public protected interface await null true false" )
93
+
94
+ KEYWORDS_BEFORE_EXPRESSION = "return yield new del raise elif else if"
95
+
96
+ ALL_KEYWORDS = KEYWORDS + " " + KEYWORDS_ATOM
97
+
98
+ KEYWORDS = make_predicate(KEYWORDS)
99
+ RESERVED_WORDS = make_predicate(RESERVED_WORDS)
100
+ KEYWORDS_BEFORE_EXPRESSION = make_predicate(KEYWORDS_BEFORE_EXPRESSION)
101
+ KEYWORDS_ATOM = make_predicate(KEYWORDS_ATOM)
102
+ IDENTIFIER_PAT = /^[a-z_$][_a-z0-9$]*$/i
103
+
104
+ def is_string_modifier(val):
105
+ for ch in val:
106
+ if 'vrufVRUF'.indexOf(ch) is -1:
107
+ return False
108
+ return True
109
+
110
+ def is_letter(code):
111
+ return code >= 97 and code <= 122 or code >= 65 and code <= 90 or code >= 170 and UNICODE.letter.test(String.fromCharCode(code))
112
+
113
+ def is_digit(code):
114
+ return code >= 48 and code <= 57
115
+
116
+ def is_alphanumeric_char(code):
117
+ return is_digit(code) or is_letter(code)
118
+
119
+ def is_unicode_combining_mark(ch):
120
+ return UNICODE.non_spacing_mark.test(ch) or UNICODE.space_combining_mark.test(ch)
121
+
122
+ def is_unicode_connector_punctuation(ch):
123
+ return UNICODE.connector_punctuation.test(ch)
124
+
125
+ def is_identifier(name):
126
+ return not RESERVED_WORDS[name] and not KEYWORDS[name] and not KEYWORDS_ATOM[name] and IDENTIFIER_PAT.test(name)
127
+
128
+ def is_identifier_start(code):
129
+ return code is 36 or code is 95 or is_letter(code)
130
+
131
+ def is_identifier_char(ch):
132
+ code = ch.charCodeAt(0)
133
+ return is_identifier_start(code) or is_digit(code) or code is 8204 or code is 8205 or is_unicode_combining_mark(ch) or is_unicode_connector_punctuation(ch)
134
+
135
+ def parse_js_number(num):
136
+ if RE_HEX_NUMBER.test(num):
137
+ return parseInt(num.substr(2), 16)
138
+ elif RE_OCT_NUMBER.test(num):
139
+ return parseInt(num.substr(1), 8)
140
+ elif RE_DEC_NUMBER.test(num):
141
+ return parseFloat(num)
142
+
143
+ # regexps adapted from http://xregexp.com/plugins/#unicode
144
+ UNICODE = { # {{{
145
+ 'letter': RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0523\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0621-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971\\u0972\\u097B-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D3D\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC\\u0EDD\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8B\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10D0-\\u10FA\\u10FC\\u1100-\\u1159\\u115F-\\u11A2\\u11A8-\\u11F9\\u1200-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u1676\\u1681-\\u169A\\u16A0-\\u16EA\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19A9\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u2094\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2C6F\\u2C71-\\u2C7D\\u2C80-\\u2CE4\\u2D00-\\u2D25\\u2D30-\\u2D65\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31B7\\u31F0-\\u31FF\\u3400\\u4DB5\\u4E00\\u9FC3\\uA000-\\uA48C\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA65F\\uA662-\\uA66E\\uA67F-\\uA697\\uA717-\\uA71F\\uA722-\\uA788\\uA78B\\uA78C\\uA7FB-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA90A-\\uA925\\uA930-\\uA946\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAC00\\uD7A3\\uF900-\\uFA2D\\uFA30-\\uFA6A\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"),
146
+ 'non_spacing_mark': RegExp("[\\u0300-\\u036F\\u0483-\\u0487\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065E\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0900-\\u0902\\u093C\\u0941-\\u0948\\u094D\\u0951-\\u0955\\u0962\\u0963\\u0981\\u09BC\\u09C1-\\u09C4\\u09CD\\u09E2\\u09E3\\u0A01\\u0A02\\u0A3C\\u0A41\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81\\u0A82\\u0ABC\\u0AC1-\\u0AC5\\u0AC7\\u0AC8\\u0ACD\\u0AE2\\u0AE3\\u0B01\\u0B3C\\u0B3F\\u0B41-\\u0B44\\u0B4D\\u0B56\\u0B62\\u0B63\\u0B82\\u0BC0\\u0BCD\\u0C3E-\\u0C40\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0CBC\\u0CBF\\u0CC6\\u0CCC\\u0CCD\\u0CE2\\u0CE3\\u0D41-\\u0D44\\u0D4D\\u0D62\\u0D63\\u0DCA\\u0DD2-\\u0DD4\\u0DD6\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71-\\u0F7E\\u0F80-\\u0F84\\u0F86\\u0F87\\u0F90-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102D-\\u1030\\u1032-\\u1037\\u1039\\u103A\\u103D\\u103E\\u1058\\u1059\\u105E-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108D\\u109D\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B7-\\u17BD\\u17C6\\u17C9-\\u17D3\\u17DD\\u180B-\\u180D\\u18A9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193B\\u1A17\\u1A18\\u1A56\\u1A58-\\u1A5E\\u1A60\\u1A62\\u1A65-\\u1A6C\\u1A73-\\u1A7C\\u1A7F\\u1B00-\\u1B03\\u1B34\\u1B36-\\u1B3A\\u1B3C\\u1B42\\u1B6B-\\u1B73\\u1B80\\u1B81\\u1BA2-\\u1BA5\\u1BA8\\u1BA9\\u1C2C-\\u1C33\\u1C36\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1DC0-\\u1DE6\\u1DFD-\\u1DFF\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2CEF-\\u2CF1\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F\\uA67C\\uA67D\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA825\\uA826\\uA8C4\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA951\\uA980-\\uA982\\uA9B3\\uA9B6-\\uA9B9\\uA9BC\\uAA29-\\uAA2E\\uAA31\\uAA32\\uAA35\\uAA36\\uAA43\\uAA4C\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uABE5\\uABE8\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE26]"),
147
+ 'space_combining_mark': RegExp("[\\u0903\\u093E-\\u0940\\u0949-\\u094C\\u094E\\u0982\\u0983\\u09BE-\\u09C0\\u09C7\\u09C8\\u09CB\\u09CC\\u09D7\\u0A03\\u0A3E-\\u0A40\\u0A83\\u0ABE-\\u0AC0\\u0AC9\\u0ACB\\u0ACC\\u0B02\\u0B03\\u0B3E\\u0B40\\u0B47\\u0B48\\u0B4B\\u0B4C\\u0B57\\u0BBE\\u0BBF\\u0BC1\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCC\\u0BD7\\u0C01-\\u0C03\\u0C41-\\u0C44\\u0C82\\u0C83\\u0CBE\\u0CC0-\\u0CC4\\u0CC7\\u0CC8\\u0CCA\\u0CCB\\u0CD5\\u0CD6\\u0D02\\u0D03\\u0D3E-\\u0D40\\u0D46-\\u0D48\\u0D4A-\\u0D4C\\u0D57\\u0D82\\u0D83\\u0DCF-\\u0DD1\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0F3E\\u0F3F\\u0F7F\\u102B\\u102C\\u1031\\u1038\\u103B\\u103C\\u1056\\u1057\\u1062-\\u1064\\u1067-\\u106D\\u1083\\u1084\\u1087-\\u108C\\u108F\\u109A-\\u109C\\u17B6\\u17BE-\\u17C5\\u17C7\\u17C8\\u1923-\\u1926\\u1929-\\u192B\\u1930\\u1931\\u1933-\\u1938\\u19B0-\\u19C0\\u19C8\\u19C9\\u1A19-\\u1A1B\\u1A55\\u1A57\\u1A61\\u1A63\\u1A64\\u1A6D-\\u1A72\\u1B04\\u1B35\\u1B3B\\u1B3D-\\u1B41\\u1B43\\u1B44\\u1B82\\u1BA1\\u1BA6\\u1BA7\\u1BAA\\u1C24-\\u1C2B\\u1C34\\u1C35\\u1CE1\\u1CF2\\uA823\\uA824\\uA827\\uA880\\uA881\\uA8B4-\\uA8C3\\uA952\\uA953\\uA983\\uA9B4\\uA9B5\\uA9BA\\uA9BB\\uA9BD-\\uA9C0\\uAA2F\\uAA30\\uAA33\\uAA34\\uAA4D\\uAA7B\\uABE3\\uABE4\\uABE6\\uABE7\\uABE9\\uABEA\\uABEC]"),
148
+ 'connector_punctuation': RegExp("[\\u005F\\u203F\\u2040\\u2054\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFF3F]")
149
+ } # }}}
150
+
151
+
152
+ def is_token(token, type, val):
153
+ return token.type is type and (val is None or val is undefined or token.value is val)
154
+
155
+ EX_EOF = {}
156
+
157
+ def tokenizer(raw_text, filename):
158
+ S = {
159
+ 'text': raw_text.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/\uFEFF/g, ""),
160
+ 'filename': filename,
161
+ 'pos': 0,
162
+ 'tokpos': 0,
163
+ 'line': 1,
164
+ 'tokline': 0,
165
+ 'col': 0,
166
+ 'tokcol': 0,
167
+ 'newline_before': False,
168
+ 'regex_allowed': False,
169
+ 'comments_before': v'[]',
170
+ 'whitespace_before': v'[]',
171
+ 'newblock': False,
172
+ 'endblock': False,
173
+ 'indentation_matters': v'[ true ]',
174
+ 'cached_whitespace': "",
175
+ 'prev': undefined,
176
+ 'index_or_slice': v'[ false ]',
177
+ 'expecting_object_literal_key': False, # This is set by the parser when it is expecting an object literal key
178
+ 'prev_was_comma': False, # True when the previous token was a ',' — used to detect positional-only '/' separator
179
+ }
180
+ def peek():
181
+ return S.text.charAt(S.pos)
182
+
183
+ def prevChar():
184
+ return S.text.charAt(S.tokpos - 1)
185
+
186
+ def next(signal_eof, in_string):
187
+ ch = S.text.charAt(S.pos)
188
+ S.pos += 1
189
+ if signal_eof and not ch:
190
+ raise EX_EOF
191
+
192
+ if ch is "\n":
193
+ S.newline_before = S.newline_before or not in_string
194
+ S.line += 1
195
+ S.col = 0
196
+ else:
197
+ S.col += 1
198
+ return ch
199
+
200
+ def find(what, signal_eof):
201
+ pos = S.text.indexOf(what, S.pos)
202
+ if signal_eof and pos is -1:
203
+ raise EX_EOF
204
+ return pos
205
+
206
+ def start_token():
207
+ S.tokline = S.line
208
+ S.tokcol = S.col
209
+ S.tokpos = S.pos
210
+
211
+ def token(type, value, is_comment, keep_newline):
212
+ S.prev_was_comma = (type is "punc" and value is ",")
213
+ S.regex_allowed = (type is "operator"
214
+ or type is "keyword" and KEYWORDS_BEFORE_EXPRESSION[value]
215
+ or type is "punc" and PUNC_BEFORE_EXPRESSION[value])
216
+
217
+ if type is "operator" and value is "is" and S.text.substr(S.pos).trimLeft().substr(0, 4).trimRight() is "not":
218
+ next_token()
219
+ value = "!=="
220
+
221
+ if type is "operator" and OP_MAP[value]:
222
+ value = OP_MAP[value]
223
+
224
+ ret = {
225
+ 'type': type,
226
+ 'value': value,
227
+ 'line': S.tokline,
228
+ 'col': S.tokcol,
229
+ 'pos': S.tokpos,
230
+ 'endpos': S.pos,
231
+ 'nlb': S.newline_before,
232
+ 'file': filename,
233
+ 'leading_whitespace': S.whitespace_before[-1] or '',
234
+ }
235
+ if not is_comment:
236
+ ret.comments_before = S.comments_before
237
+ S.comments_before = v'[]' # Use a plain JS array for speed
238
+ # make note of any newlines in the comments that came before
239
+ for i in range(ret.comments_before.length):
240
+ ret.nlb = ret.nlb or ret.comments_before[i].nlb
241
+
242
+ if not keep_newline:
243
+ S.newline_before = False
244
+
245
+ if type is "punc":
246
+ # if (value is ":" && peek() is "\n") {
247
+ if value is ":" and not S.index_or_slice[-1]
248
+ and not S.expecting_object_literal_key
249
+ and (not S.text.substring(S.pos + 1, find("\n")).trim() or not S.text.substring(S.pos + 1, find("#")).trim()):
250
+ S.newblock = True
251
+ S.indentation_matters.push(True)
252
+
253
+ if value is "[":
254
+ if S.prev and (
255
+ S.prev.type is "name" or
256
+ (S.prev.type is 'punc' and ')]'.indexOf(S.prev.value) is not -1)
257
+ ):
258
+ S.index_or_slice.push(True)
259
+ else:
260
+ S.index_or_slice.push(False)
261
+ S.indentation_matters.push(False)
262
+ elif value is "{" or value is "(":
263
+ S.indentation_matters.push(False)
264
+ elif value is "]":
265
+ S.index_or_slice.pop()
266
+ S.indentation_matters.pop()
267
+ elif value is "}" or value is ")":
268
+ S.indentation_matters.pop()
269
+ S.prev = AST_Token(ret)
270
+ return S.prev
271
+
272
+ # this will transform leading whitespace to block tokens unless
273
+ # part of array/hash, and skip non-leading whitespace
274
+ def parse_whitespace():
275
+ leading_whitespace = ""
276
+ whitespace_exists = False
277
+ while WHITESPACE_CHARS[peek()]:
278
+ whitespace_exists = True
279
+ ch = next()
280
+ if ch is "\n":
281
+ leading_whitespace = ""
282
+ else:
283
+ leading_whitespace += ch
284
+ if peek() is not "#":
285
+ if not whitespace_exists:
286
+ leading_whitespace = S.cached_whitespace
287
+ else:
288
+ S.cached_whitespace = leading_whitespace
289
+ if S.newline_before or S.endblock:
290
+ return test_indent_token(leading_whitespace)
291
+
292
+ def test_indent_token(leading_whitespace):
293
+ most_recent = S.whitespace_before[-1] or ""
294
+ S.endblock = False
295
+ if S.indentation_matters[-1] and leading_whitespace is not most_recent:
296
+ if S.newblock and leading_whitespace and leading_whitespace.indexOf(most_recent) is 0:
297
+ # positive indent, new block
298
+ S.newblock = False
299
+ S.whitespace_before.push(leading_whitespace)
300
+ return 1
301
+ elif most_recent and most_recent.indexOf(leading_whitespace) is 0:
302
+ # negative indent, block is ending
303
+ S.endblock = True
304
+ S.whitespace_before.pop()
305
+ return -1
306
+ else:
307
+ # indent mismatch, inconsistent indentation
308
+ S.tokline = S.line
309
+ S.tokcol = 0
310
+ parse_error("Inconsistent indentation")
311
+ return 0
312
+
313
+ def read_while(pred):
314
+ ret = ""
315
+ i = 0
316
+ ch = ''
317
+ while (ch = peek()) and pred(ch, i):
318
+ i += 1
319
+ ret += next()
320
+ return ret
321
+
322
+ def parse_error(err, is_eof):
323
+ raise new SyntaxError(err, filename, S.tokline, S.tokcol, S.tokpos, is_eof)
324
+
325
+ def read_num(prefix):
326
+ has_e = False
327
+ has_x = False
328
+ has_dot = prefix is "."
329
+ if not prefix and peek() is '0' and S.text.charAt(S.pos + 1) is 'b':
330
+ next(), next()
331
+ num = read_while(def(ch): return ch is '0' or ch is '1';)
332
+ valid = parseInt(num, 2)
333
+ if isNaN(valid):
334
+ parse_error('Invalid syntax for a binary number')
335
+ return token('num', valid)
336
+ seen = v'[]'
337
+ num = read_while(def(ch, i):
338
+ nonlocal has_dot, has_e, has_x
339
+ seen.push(ch)
340
+ if ch is 'x' or ch is 'X':
341
+ if has_x or seen.length is not 2 or seen[0] is not '0':
342
+ return False
343
+ has_x = True
344
+ return True
345
+ elif ch is 'e' or ch is 'E':
346
+ if has_x:
347
+ return True
348
+ if has_e or i == 0:
349
+ return False
350
+ has_e = True
351
+ return True
352
+ elif ch is '-':
353
+ if i is 0 and not prefix:
354
+ return True
355
+ if has_e and seen[i-1].toLowerCase() is 'e':
356
+ return True
357
+ return False
358
+ elif ch is '+':
359
+ if has_e and seen[i-1].toLowerCase() is 'e':
360
+ return True
361
+ return False
362
+ elif ch is '.':
363
+ return (has_dot = True) if not has_dot and not has_x and not has_e else False
364
+ return is_alphanumeric_char(ch.charCodeAt(0))
365
+ )
366
+ if prefix:
367
+ num = prefix + num
368
+
369
+ valid = parse_js_number(num)
370
+ if not isNaN(valid):
371
+ return token("num", valid)
372
+ else:
373
+ parse_error("Invalid syntax: " + num)
374
+
375
+ def read_hex_digits(count):
376
+ ans = ''
377
+ while count > 0:
378
+ count -= 1
379
+ if not HEX_PAT.test(peek()):
380
+ return ans
381
+ ans += next()
382
+ nval = parseInt(ans, 16)
383
+ if nval > 0x10FFFF:
384
+ return ans
385
+ return nval
386
+
387
+ def read_escape_sequence():
388
+ q = next(True)
389
+ if q is '\n':
390
+ return ''
391
+ if q is '\\':
392
+ return q
393
+ if '"\''.indexOf(q) is not -1:
394
+ return q
395
+ if ASCII_CONTROL_CHARS[q]:
396
+ return String.fromCharCode(ASCII_CONTROL_CHARS[q])
397
+ if '0' <= q <= '7':
398
+ octal = q
399
+ if '0' <= peek() <= '7':
400
+ octal += next()
401
+ if '0' <= peek() <= '7':
402
+ octal += next()
403
+ code = parseInt(octal, 8)
404
+ if isNaN(code):
405
+ return '\\' + octal
406
+ return String.fromCharCode(code)
407
+ if q is 'x':
408
+ code = read_hex_digits(2)
409
+ if jstype(code) is 'number':
410
+ return String.fromCharCode(code)
411
+ return '\\x' + code
412
+ if q is 'u':
413
+ code = read_hex_digits(4)
414
+ if jstype(code) is 'number':
415
+ return String.fromCharCode(code)
416
+ return '\\u' + code
417
+ if q is 'U':
418
+ code = read_hex_digits(8)
419
+ if jstype(code) is 'number':
420
+ if code <= 0xFFFF:
421
+ return String.fromCharCode(code)
422
+ code -= 0x10000
423
+ return String.fromCharCode(0xD800+(code>>10), 0xDC00+(code&0x3FF))
424
+ return '\\U' + code
425
+ if q is 'N' and peek() is '{':
426
+ next()
427
+ name = read_while(def (ch): return NAME_PAT.test(ch);)
428
+ if peek() is not '}':
429
+ return '\\N{' + name
430
+ next()
431
+ key = (name or '').toLowerCase()
432
+ if not name or not Object.prototype.hasOwnProperty.call(ALIAS_MAP, key):
433
+ return '\\N{' + name + '}'
434
+ code = ALIAS_MAP[key]
435
+ if code <= 0xFFFF:
436
+ return String.fromCharCode(code)
437
+ code -= 0x10000
438
+ return String.fromCharCode(0xD800+(code>>10), 0xDC00+(code&0x3FF))
439
+ return '\\' + q
440
+
441
+ def with_eof_error(eof_error, cont):
442
+ return def():
443
+ try:
444
+ return cont.apply(None, arguments)
445
+ except as ex:
446
+ if ex is EX_EOF:
447
+ parse_error(eof_error, True)
448
+ else:
449
+ raise
450
+
451
+ read_string = with_eof_error("Unterminated string constant", def(is_raw_literal, is_js_literal):
452
+ quote = next()
453
+ tok_type = 'js' if is_js_literal else 'string'
454
+ ret = ""
455
+ is_multiline = False
456
+ if peek() is quote:
457
+ # two quotes in a row
458
+ next(True)
459
+ if peek() is quote:
460
+ # multiline string (3 quotes in a row)
461
+ next(True)
462
+ is_multiline = True
463
+ else:
464
+ return token(tok_type, '')
465
+
466
+ while True:
467
+ ch = next(True, True)
468
+ if not ch:
469
+ break
470
+ if ch is "\n" and not is_multiline:
471
+ parse_error("End of line while scanning string literal")
472
+
473
+ if ch is "\\":
474
+ ret += ('\\' + next(True)) if is_raw_literal else read_escape_sequence()
475
+ continue
476
+
477
+ if ch is quote:
478
+ if not is_multiline:
479
+ break
480
+ if peek() is quote:
481
+ next()
482
+ if peek() is quote:
483
+ next()
484
+ break
485
+ else:
486
+ ch += quote
487
+ ret += ch
488
+ return token(tok_type, ret)
489
+ )
490
+
491
+ def handle_interpolated_string(string, start_tok):
492
+ def raise_error(err):
493
+ raise new SyntaxError(err, filename, start_tok.line, start_tok.col, start_tok.pos, False)
494
+ S.text = S.text[:S.pos] + '(' + interpolate(string, raise_error) + ')' + S.text[S.pos:]
495
+ return token('punc', next())
496
+
497
+ def read_line_comment(shebang):
498
+ if not shebang:
499
+ next()
500
+ i = find("\n")
501
+
502
+ if i is -1:
503
+ ret = S.text.substr(S.pos)
504
+ S.pos = S.text.length
505
+ else:
506
+ ret = S.text.substring(S.pos, i)
507
+ S.pos = i
508
+
509
+ return token("shebang" if shebang else "comment1", ret, True)
510
+
511
+ def read_name():
512
+ name = ch = ""
513
+ while (ch = peek()) is not None:
514
+ if ch is "\\":
515
+ if S.text.charAt(S.pos + 1) is "\n":
516
+ S.pos += 2
517
+ continue
518
+ break
519
+ elif is_identifier_char(ch):
520
+ name += next()
521
+ else:
522
+ break
523
+ return name
524
+
525
+ read_regexp = with_eof_error("Unterminated regular expression", def():
526
+ prev_backslash = False
527
+ regexp = ch = ''
528
+ in_class = False
529
+ verbose_regexp = False
530
+ in_comment = False
531
+
532
+ if peek() is '/':
533
+ next(True)
534
+ if peek() is '/':
535
+ verbose_regexp = True
536
+ next(True)
537
+ else: # empty regexp (//)
538
+ mods = read_name()
539
+ return token("regexp", RegExp(regexp, mods))
540
+ while True:
541
+ ch = next(True)
542
+ if not ch:
543
+ break
544
+ if in_comment:
545
+ if ch is '\n':
546
+ in_comment = False
547
+ continue
548
+ if prev_backslash:
549
+ regexp += "\\" + ch
550
+ prev_backslash = False
551
+ elif ch is "[":
552
+ in_class = True
553
+ regexp += ch
554
+ elif ch is "]" and in_class:
555
+ in_class = False
556
+ regexp += ch
557
+ elif ch is "/" and not in_class:
558
+ if verbose_regexp:
559
+ if peek() is not '/':
560
+ regexp += '\\/'
561
+ continue
562
+ next(True)
563
+ if peek() is not '/':
564
+ regexp += '\\/\\/'
565
+ continue
566
+ next(True)
567
+ break
568
+ elif ch is "\\":
569
+ prev_backslash = True
570
+ elif verbose_regexp and not in_class and ' \n\r\t'.indexOf(ch) is not -1:
571
+ pass
572
+ elif verbose_regexp and not in_class and ch is '#':
573
+ in_comment = True
574
+ else:
575
+ regexp += ch
576
+
577
+ mods = read_name()
578
+ return token("regexp", RegExp(regexp, mods))
579
+ )
580
+
581
+ def read_operator(prefix):
582
+ def grow(op):
583
+ if not peek():
584
+ return op
585
+
586
+ bigger = op + peek()
587
+ if OPERATORS[bigger]:
588
+ next()
589
+ return grow(bigger)
590
+ else:
591
+ return op
592
+ op = grow(prefix or next())
593
+ if op is '->':
594
+ # pretend that this is an operator as the tokenizer only allows
595
+ # one character punctuation.
596
+ return token('punc', op)
597
+ return token("operator", op)
598
+
599
+ def handle_slash():
600
+ next()
601
+ if S.regex_allowed:
602
+ # When the previous token was ',' and what follows the '/' (skipping
603
+ # optional whitespace) is ',' or ')', this is the positional-only
604
+ # parameter separator, not a regex literal.
605
+ if S.prev_was_comma:
606
+ i = S.pos
607
+ while i < S.text.length and WHITESPACE_CHARS[S.text.charAt(i)]:
608
+ i += 1
609
+ if i < S.text.length:
610
+ c = S.text.charAt(i)
611
+ if c is ',' or c is ')':
612
+ return read_operator("/")
613
+ return read_regexp("")
614
+ return read_operator("/")
615
+
616
+ def handle_dot():
617
+ next()
618
+ if peek() is '.' and S.text.charAt(S.pos + 1) is '.':
619
+ next() # consume second '.'
620
+ next() # consume third '.'
621
+ return token("atom", "Ellipsis")
622
+ return read_num(".") if is_digit(peek().charCodeAt(0)) else token("punc", ".")
623
+
624
+ def read_word():
625
+ word = read_name()
626
+ return token("atom", word) if KEYWORDS_ATOM[word] else (token("name", word) if not KEYWORDS[word] else (token("operator", word) if OPERATORS[word] and prevChar() is not "." else token("keyword", word)))
627
+
628
+ def next_token():
629
+
630
+ indent = parse_whitespace()
631
+ # if indent is 1:
632
+ # return token("punc", "{")
633
+ if indent is -1:
634
+ return token("punc", "}", False, True)
635
+
636
+ start_token()
637
+ ch = peek()
638
+ if not ch:
639
+ return token("eof")
640
+
641
+ code = ch.charCodeAt(0)
642
+ tmp_ = code
643
+ if tmp_ is 34 or tmp_ is 39: # double-quote (") or single quote (')
644
+ return read_string(False)
645
+ elif tmp_ is 35: # pound-sign (#)
646
+ if S.pos is 0 and S.text.charAt(1) is '!':
647
+ #shebang
648
+ return read_line_comment(True)
649
+ regex_allowed = S.regex_allowed
650
+ S.comments_before.push(read_line_comment())
651
+ S.regex_allowed = regex_allowed
652
+ return next_token()
653
+ elif tmp_ is 46: # dot (.)
654
+ return handle_dot()
655
+ elif tmp_ is 47: # slash (/)
656
+ return handle_slash()
657
+
658
+ if is_digit(code):
659
+ return read_num()
660
+
661
+ if PUNC_CHARS[ch]:
662
+ if ch is ':' and S.text.charAt(S.pos + 1) is '=':
663
+ next() # consume ':'
664
+ next() # consume '='
665
+ return token("operator", ":=")
666
+ return token("punc", next())
667
+
668
+ if OPERATOR_CHARS[ch]:
669
+ return read_operator()
670
+
671
+ if code is 92 and S.text.charAt(S.pos + 1) is "\n":
672
+ # backslash will consume the newline character that follows
673
+ next()
674
+ # backslash
675
+ next()
676
+ # newline
677
+ S.newline_before = False
678
+ return next_token()
679
+
680
+ if is_identifier_start(code):
681
+ tok = read_word()
682
+ if '\'"'.indexOf(peek()) is not -1 and is_string_modifier(tok.value):
683
+ mods = tok.value.toLowerCase()
684
+ start_pos_for_string = S.tokpos
685
+ stok = read_string(mods.indexOf('r') is not -1, mods.indexOf('v') is not -1)
686
+ tok.endpos = stok.endpos
687
+ if stok.type is not 'js' and mods.indexOf('f') is not -1:
688
+ tok.col += start_pos_for_string - tok.pos
689
+ return handle_interpolated_string(stok.value, tok)
690
+ tok.value = stok.value
691
+ tok.type = stok.type
692
+ return tok
693
+
694
+ parse_error("Unexpected character «" + ch + "»")
695
+
696
+ next_token.context = def(nc):
697
+ nonlocal S
698
+ if nc:
699
+ S = nc
700
+ return S
701
+
702
+ return next_token