openalgo-script 0.1.0-alpha.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 (266) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +12 -0
  3. package/README.md +255 -0
  4. package/dist/core/ast/annotations.d.ts +56 -0
  5. package/dist/core/ast/annotations.d.ts.map +1 -0
  6. package/dist/core/ast/annotations.js +27 -0
  7. package/dist/core/ast/annotations.js.map +1 -0
  8. package/dist/core/ast/build.d.ts +25 -0
  9. package/dist/core/ast/build.d.ts.map +1 -0
  10. package/dist/core/ast/build.js +26 -0
  11. package/dist/core/ast/build.js.map +1 -0
  12. package/dist/core/ast/children.d.ts +15 -0
  13. package/dist/core/ast/children.d.ts.map +1 -0
  14. package/dist/core/ast/children.js +103 -0
  15. package/dist/core/ast/children.js.map +1 -0
  16. package/dist/core/ast/expressions.d.ts +178 -0
  17. package/dist/core/ast/expressions.d.ts.map +1 -0
  18. package/dist/core/ast/expressions.js +50 -0
  19. package/dist/core/ast/expressions.js.map +1 -0
  20. package/dist/core/ast/header.d.ts +50 -0
  21. package/dist/core/ast/header.d.ts.map +1 -0
  22. package/dist/core/ast/header.js +2 -0
  23. package/dist/core/ast/header.js.map +1 -0
  24. package/dist/core/ast/index.d.ts +30 -0
  25. package/dist/core/ast/index.d.ts.map +1 -0
  26. package/dist/core/ast/index.js +21 -0
  27. package/dist/core/ast/index.js.map +1 -0
  28. package/dist/core/ast/name.d.ts +24 -0
  29. package/dist/core/ast/name.d.ts.map +1 -0
  30. package/dist/core/ast/name.js +2 -0
  31. package/dist/core/ast/name.js.map +1 -0
  32. package/dist/core/ast/node.d.ts +34 -0
  33. package/dist/core/ast/node.d.ts.map +1 -0
  34. package/dist/core/ast/node.js +70 -0
  35. package/dist/core/ast/node.js.map +1 -0
  36. package/dist/core/ast/script.d.ts +57 -0
  37. package/dist/core/ast/script.d.ts.map +1 -0
  38. package/dist/core/ast/script.js +2 -0
  39. package/dist/core/ast/script.js.map +1 -0
  40. package/dist/core/ast/statements.d.ts +161 -0
  41. package/dist/core/ast/statements.d.ts.map +1 -0
  42. package/dist/core/ast/statements.js +10 -0
  43. package/dist/core/ast/statements.js.map +1 -0
  44. package/dist/core/ast/walk.d.ts +39 -0
  45. package/dist/core/ast/walk.d.ts.map +1 -0
  46. package/dist/core/ast/walk.js +54 -0
  47. package/dist/core/ast/walk.js.map +1 -0
  48. package/dist/core/catalogue/catalogue.generated.d.ts +1590 -0
  49. package/dist/core/catalogue/catalogue.generated.d.ts.map +1 -0
  50. package/dist/core/catalogue/catalogue.generated.js +162 -0
  51. package/dist/core/catalogue/catalogue.generated.js.map +1 -0
  52. package/dist/core/catalogue/index.d.ts +15 -0
  53. package/dist/core/catalogue/index.d.ts.map +1 -0
  54. package/dist/core/catalogue/index.js +4 -0
  55. package/dist/core/catalogue/index.js.map +1 -0
  56. package/dist/core/catalogue/lookup.d.ts +14 -0
  57. package/dist/core/catalogue/lookup.d.ts.map +1 -0
  58. package/dist/core/catalogue/lookup.js +19 -0
  59. package/dist/core/catalogue/lookup.js.map +1 -0
  60. package/dist/core/catalogue/template.d.ts +15 -0
  61. package/dist/core/catalogue/template.d.ts.map +1 -0
  62. package/dist/core/catalogue/template.js +33 -0
  63. package/dist/core/catalogue/template.js.map +1 -0
  64. package/dist/core/catalogue/types.d.ts +34 -0
  65. package/dist/core/catalogue/types.d.ts.map +1 -0
  66. package/dist/core/catalogue/types.js +6 -0
  67. package/dist/core/catalogue/types.js.map +1 -0
  68. package/dist/core/catalogue/values.generated.d.ts +565 -0
  69. package/dist/core/catalogue/values.generated.d.ts.map +1 -0
  70. package/dist/core/catalogue/values.generated.js +6 -0
  71. package/dist/core/catalogue/values.generated.js.map +1 -0
  72. package/dist/core/diagnostics/collector.d.ts +46 -0
  73. package/dist/core/diagnostics/collector.d.ts.map +1 -0
  74. package/dist/core/diagnostics/collector.js +55 -0
  75. package/dist/core/diagnostics/collector.js.map +1 -0
  76. package/dist/core/diagnostics/diagnostic.d.ts +40 -0
  77. package/dist/core/diagnostics/diagnostic.d.ts.map +1 -0
  78. package/dist/core/diagnostics/diagnostic.js +29 -0
  79. package/dist/core/diagnostics/diagnostic.js.map +1 -0
  80. package/dist/core/diagnostics/index.d.ts +12 -0
  81. package/dist/core/diagnostics/index.d.ts.map +1 -0
  82. package/dist/core/diagnostics/index.js +3 -0
  83. package/dist/core/diagnostics/index.js.map +1 -0
  84. package/dist/core/index.d.ts +28 -0
  85. package/dist/core/index.d.ts.map +1 -0
  86. package/dist/core/index.js +22 -0
  87. package/dist/core/index.js.map +1 -0
  88. package/dist/core/lex/blocks.d.ts +51 -0
  89. package/dist/core/lex/blocks.d.ts.map +1 -0
  90. package/dist/core/lex/blocks.js +56 -0
  91. package/dist/core/lex/blocks.js.map +1 -0
  92. package/dist/core/lex/characters.d.ts +38 -0
  93. package/dist/core/lex/characters.d.ts.map +1 -0
  94. package/dist/core/lex/characters.js +50 -0
  95. package/dist/core/lex/characters.js.map +1 -0
  96. package/dist/core/lex/comments.d.ts +50 -0
  97. package/dist/core/lex/comments.d.ts.map +1 -0
  98. package/dist/core/lex/comments.js +64 -0
  99. package/dist/core/lex/comments.js.map +1 -0
  100. package/dist/core/lex/index.d.ts +12 -0
  101. package/dist/core/lex/index.d.ts.map +1 -0
  102. package/dist/core/lex/index.js +12 -0
  103. package/dist/core/lex/index.js.map +1 -0
  104. package/dist/core/lex/layout.d.ts +40 -0
  105. package/dist/core/lex/layout.d.ts.map +1 -0
  106. package/dist/core/lex/layout.js +143 -0
  107. package/dist/core/lex/layout.js.map +1 -0
  108. package/dist/core/lex/lexer.d.ts +13 -0
  109. package/dist/core/lex/lexer.d.ts.map +1 -0
  110. package/dist/core/lex/lexer.js +419 -0
  111. package/dist/core/lex/lexer.js.map +1 -0
  112. package/dist/core/lex/numbers.d.ts +22 -0
  113. package/dist/core/lex/numbers.d.ts.map +1 -0
  114. package/dist/core/lex/numbers.js +58 -0
  115. package/dist/core/lex/numbers.js.map +1 -0
  116. package/dist/core/lex/statements.d.ts +24 -0
  117. package/dist/core/lex/statements.d.ts.map +1 -0
  118. package/dist/core/lex/statements.js +90 -0
  119. package/dist/core/lex/statements.js.map +1 -0
  120. package/dist/core/lex/strings.d.ts +27 -0
  121. package/dist/core/lex/strings.d.ts.map +1 -0
  122. package/dist/core/lex/strings.js +92 -0
  123. package/dist/core/lex/strings.js.map +1 -0
  124. package/dist/core/lex/unexpected.d.ts +31 -0
  125. package/dist/core/lex/unexpected.d.ts.map +1 -0
  126. package/dist/core/lex/unexpected.js +114 -0
  127. package/dist/core/lex/unexpected.js.map +1 -0
  128. package/dist/core/parse/annotations.d.ts +4 -0
  129. package/dist/core/parse/annotations.d.ts.map +1 -0
  130. package/dist/core/parse/annotations.js +49 -0
  131. package/dist/core/parse/annotations.js.map +1 -0
  132. package/dist/core/parse/blocks.d.ts +18 -0
  133. package/dist/core/parse/blocks.d.ts.map +1 -0
  134. package/dist/core/parse/blocks.js +47 -0
  135. package/dist/core/parse/blocks.js.map +1 -0
  136. package/dist/core/parse/branches.d.ts +17 -0
  137. package/dist/core/parse/branches.d.ts.map +1 -0
  138. package/dist/core/parse/branches.js +66 -0
  139. package/dist/core/parse/branches.js.map +1 -0
  140. package/dist/core/parse/cursor.d.ts +119 -0
  141. package/dist/core/parse/cursor.d.ts.map +1 -0
  142. package/dist/core/parse/cursor.js +305 -0
  143. package/dist/core/parse/cursor.js.map +1 -0
  144. package/dist/core/parse/expressions.d.ts +57 -0
  145. package/dist/core/parse/expressions.d.ts.map +1 -0
  146. package/dist/core/parse/expressions.js +373 -0
  147. package/dist/core/parse/expressions.js.map +1 -0
  148. package/dist/core/parse/functions.d.ts +16 -0
  149. package/dist/core/parse/functions.d.ts.map +1 -0
  150. package/dist/core/parse/functions.js +92 -0
  151. package/dist/core/parse/functions.js.map +1 -0
  152. package/dist/core/parse/index.d.ts +13 -0
  153. package/dist/core/parse/index.d.ts.map +1 -0
  154. package/dist/core/parse/index.js +13 -0
  155. package/dist/core/parse/index.js.map +1 -0
  156. package/dist/core/parse/loops.d.ts +13 -0
  157. package/dist/core/parse/loops.d.ts.map +1 -0
  158. package/dist/core/parse/loops.js +78 -0
  159. package/dist/core/parse/loops.js.map +1 -0
  160. package/dist/core/parse/names.d.ts +34 -0
  161. package/dist/core/parse/names.d.ts.map +1 -0
  162. package/dist/core/parse/names.js +122 -0
  163. package/dist/core/parse/names.js.map +1 -0
  164. package/dist/core/parse/script.d.ts +23 -0
  165. package/dist/core/parse/script.d.ts.map +1 -0
  166. package/dist/core/parse/script.js +55 -0
  167. package/dist/core/parse/script.js.map +1 -0
  168. package/dist/core/parse/statements.d.ts +14 -0
  169. package/dist/core/parse/statements.d.ts.map +1 -0
  170. package/dist/core/parse/statements.js +292 -0
  171. package/dist/core/parse/statements.js.map +1 -0
  172. package/dist/core/parse/switches.d.ts +16 -0
  173. package/dist/core/parse/switches.d.ts.map +1 -0
  174. package/dist/core/parse/switches.js +98 -0
  175. package/dist/core/parse/switches.js.map +1 -0
  176. package/dist/core/render/index.d.ts +10 -0
  177. package/dist/core/render/index.d.ts.map +1 -0
  178. package/dist/core/render/index.js +10 -0
  179. package/dist/core/render/index.js.map +1 -0
  180. package/dist/core/render/terminal.d.ts +11 -0
  181. package/dist/core/render/terminal.d.ts.map +1 -0
  182. package/dist/core/render/terminal.js +51 -0
  183. package/dist/core/render/terminal.js.map +1 -0
  184. package/dist/core/source/index.d.ts +7 -0
  185. package/dist/core/source/index.d.ts.map +1 -0
  186. package/dist/core/source/index.js +2 -0
  187. package/dist/core/source/index.js.map +1 -0
  188. package/dist/core/source/source.d.ts +41 -0
  189. package/dist/core/source/source.d.ts.map +1 -0
  190. package/dist/core/source/source.js +67 -0
  191. package/dist/core/source/source.js.map +1 -0
  192. package/dist/core/span/index.d.ts +3 -0
  193. package/dist/core/span/index.d.ts.map +1 -0
  194. package/dist/core/span/index.js +2 -0
  195. package/dist/core/span/index.js.map +1 -0
  196. package/dist/core/span/span.d.ts +67 -0
  197. package/dist/core/span/span.d.ts.map +1 -0
  198. package/dist/core/span/span.js +27 -0
  199. package/dist/core/span/span.js.map +1 -0
  200. package/dist/core/tokens/index.d.ts +8 -0
  201. package/dist/core/tokens/index.d.ts.map +1 -0
  202. package/dist/core/tokens/index.js +2 -0
  203. package/dist/core/tokens/index.js.map +1 -0
  204. package/dist/core/tokens/kind.d.ts +53 -0
  205. package/dist/core/tokens/kind.d.ts.map +1 -0
  206. package/dist/core/tokens/kind.js +94 -0
  207. package/dist/core/tokens/kind.js.map +1 -0
  208. package/dist/core/tokens/token.d.ts +36 -0
  209. package/dist/core/tokens/token.d.ts.map +1 -0
  210. package/dist/core/tokens/token.js +2 -0
  211. package/dist/core/tokens/token.js.map +1 -0
  212. package/package.json +52 -0
  213. package/spec/README.md +48 -0
  214. package/spec/errors.json +3204 -0
  215. package/src/core/ast/annotations.ts +68 -0
  216. package/src/core/ast/build.ts +35 -0
  217. package/src/core/ast/children.ts +110 -0
  218. package/src/core/ast/expressions.ts +254 -0
  219. package/src/core/ast/header.ts +53 -0
  220. package/src/core/ast/index.ts +102 -0
  221. package/src/core/ast/name.ts +24 -0
  222. package/src/core/ast/node.ts +120 -0
  223. package/src/core/ast/script.ts +60 -0
  224. package/src/core/ast/statements.ts +193 -0
  225. package/src/core/ast/walk.ts +67 -0
  226. package/src/core/catalogue/catalogue.generated.ts +171 -0
  227. package/src/core/catalogue/index.ts +20 -0
  228. package/src/core/catalogue/lookup.ts +23 -0
  229. package/src/core/catalogue/template.ts +38 -0
  230. package/src/core/catalogue/types.ts +37 -0
  231. package/src/core/catalogue/values.generated.ts +160 -0
  232. package/src/core/diagnostics/collector.ts +87 -0
  233. package/src/core/diagnostics/diagnostic.ts +72 -0
  234. package/src/core/diagnostics/index.ts +12 -0
  235. package/src/core/index.ts +146 -0
  236. package/src/core/lex/blocks.ts +92 -0
  237. package/src/core/lex/characters.ts +56 -0
  238. package/src/core/lex/comments.ts +75 -0
  239. package/src/core/lex/index.ts +11 -0
  240. package/src/core/lex/layout.ts +188 -0
  241. package/src/core/lex/lexer.ts +486 -0
  242. package/src/core/lex/numbers.ts +77 -0
  243. package/src/core/lex/statements.ts +94 -0
  244. package/src/core/lex/strings.ts +119 -0
  245. package/src/core/lex/unexpected.ts +125 -0
  246. package/src/core/parse/annotations.ts +60 -0
  247. package/src/core/parse/blocks.ts +52 -0
  248. package/src/core/parse/branches.ts +77 -0
  249. package/src/core/parse/cursor.ts +348 -0
  250. package/src/core/parse/expressions.ts +441 -0
  251. package/src/core/parse/functions.ts +109 -0
  252. package/src/core/parse/index.ts +12 -0
  253. package/src/core/parse/loops.ts +97 -0
  254. package/src/core/parse/names.ts +135 -0
  255. package/src/core/parse/script.ts +64 -0
  256. package/src/core/parse/statements.ts +329 -0
  257. package/src/core/parse/switches.ts +105 -0
  258. package/src/core/render/index.ts +9 -0
  259. package/src/core/render/terminal.ts +62 -0
  260. package/src/core/source/index.ts +6 -0
  261. package/src/core/source/source.ts +102 -0
  262. package/src/core/span/index.ts +2 -0
  263. package/src/core/span/span.ts +84 -0
  264. package/src/core/tokens/index.ts +15 -0
  265. package/src/core/tokens/kind.ts +123 -0
  266. package/src/core/tokens/token.ts +39 -0
@@ -0,0 +1,34 @@
1
+ import type { Name } from '../ast/index.js';
2
+ import type { TokenKind } from '../tokens/index.js';
3
+ import type { Cursor } from './cursor.js';
4
+ /** Whether a token may stand where a word is expected. */
5
+ export declare function isWordKind(kind: TokenKind): boolean;
6
+ /** Whether a word standing where a value belongs is a name the language has taken. */
7
+ export declare function isMeantAsAName(kind: TokenKind): boolean;
8
+ /**
9
+ * The name at the cursor: an identifier, or a reserved word that is OS1019.
10
+ *
11
+ * The word is taken either way. A script that named something `type` still
12
+ * meant to declare it, and every later diagnostic about that name is more use
13
+ * to the reader than a hole where the declaration should have been.
14
+ */
15
+ export declare function takeName(cursor: Cursor): Name;
16
+ /**
17
+ * The label of a named argument, where a reserved word is legal.
18
+ *
19
+ * A label is matched against the callee's parameter list and is never looked up
20
+ * in a scope, so `plot(v, "V", color = aqua)` is correct and is not OS1019.
21
+ */
22
+ export declare function takeLabel(cursor: Cursor): Name;
23
+ /**
24
+ * The word after a dot.
25
+ *
26
+ * A member is matched against the namespace or the object type it was read
27
+ * from, which is the same kind of published list a label is matched against, so
28
+ * a reserved word is not OS1019 here either. Whether the member exists at all
29
+ * is OS2009, and the checker owns it.
30
+ */
31
+ export declare function takeMember(cursor: Cursor): Name;
32
+ /** Whether the cursor is on a named argument's label: a word, then a bare `=`. */
33
+ export declare function atLabel(cursor: Cursor): boolean;
34
+ //# sourceMappingURL=names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../../src/core/parse/names.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAiB1C,0DAA0D;AAC1D,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAEnD;AAqCD,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAEvD;AAuBD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAY7C;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAG9C;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED,kFAAkF;AAClF,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE/C"}
@@ -0,0 +1,122 @@
1
+ import { makeNode } from '../ast/index.js';
2
+ import { RESERVED_WORDS } from '../tokens/index.js';
3
+ import { describeToken } from './cursor.js';
4
+ /**
5
+ * Reading the places a name is written, which is where OS1019 lives.
6
+ *
7
+ * The lexer cannot make this call. A reserved word before an `=` is a legal
8
+ * label inside a call and is OS1019 inside a parameter list (language.md 3.4),
9
+ * and only the parser knows which of the two lists it is reading. So a reserved
10
+ * word arrives carrying its keyword kind, and the readers below are the
11
+ * answers: `takeName` refuses one, `takeLabel` and `takeMember` accept one,
12
+ * because a label and a member are matched against a published list rather than
13
+ * looked up in a scope.
14
+ */
15
+ const RESERVED = new Set(RESERVED_WORDS);
16
+ /** Whether a token may stand where a word is expected. */
17
+ export function isWordKind(kind) {
18
+ return kind === 'identifier' || RESERVED.has(kind);
19
+ }
20
+ /**
21
+ * The reserved words a reader can only have meant as a name.
22
+ *
23
+ * A reserved word written where a value belongs is one of two things, and which
24
+ * one depends on the word. Six of them are read by a rule standing next to the
25
+ * expression: `and` and `or` join two operands and `not` takes one, and `in`,
26
+ * `to` and `step` are read by a `for` header the moment the expression before
27
+ * them ends. A word that opens a statement is the same answer again, because an
28
+ * unclosed bracket carries the statement onto the lines below it and the `if`
29
+ * down there belongs to its own line rather than to this expression. Taking any
30
+ * of those as a name would swallow a token the rule around it is waiting for,
31
+ * and the second diagnostic would then be about the rule rather than about the
32
+ * mistake.
33
+ *
34
+ * What is left is the four value type names, the two words that build a type,
35
+ * and the six the language reserves and version 1 does not implement. No rule
36
+ * of the grammar reads one of them anywhere near an expression, so a reader who
37
+ * wrote one where a value belongs wrote a name, and the answer is OS1019: the
38
+ * same answer `takeName` gives for the same word written as a target.
39
+ */
40
+ const MEANT_AS_A_NAME = new Set([
41
+ 'array',
42
+ 'as',
43
+ 'bool',
44
+ 'color',
45
+ 'import',
46
+ 'is',
47
+ 'map',
48
+ 'matrix',
49
+ 'number',
50
+ 'series',
51
+ 'string',
52
+ 'type',
53
+ ]);
54
+ /** Whether a word standing where a value belongs is a name the language has taken. */
55
+ export function isMeantAsAName(kind) {
56
+ return MEANT_AS_A_NAME.has(kind);
57
+ }
58
+ /**
59
+ * A name that is not reserved, derived from one that is.
60
+ *
61
+ * OS1019 promises a near name that keeps the meaning, and the derivation has to
62
+ * work for all thirty six words rather than for the five anyone remembers, so
63
+ * it is mechanical: the word is what the reader meant, and the suffix is what
64
+ * makes it theirs to use.
65
+ */
66
+ function unreservedNear(word) {
67
+ return `${word}Value`;
68
+ }
69
+ /** No word where one was required, which leaves the statement without its subject. */
70
+ function missingWord(cursor) {
71
+ const hole = cursor.holeSpan();
72
+ cursor.report('OS1022', hole, {
73
+ token: describeToken(cursor.previousMeaningful() ?? cursor.token),
74
+ });
75
+ return makeNode('name', hole, { text: '' });
76
+ }
77
+ /**
78
+ * The name at the cursor: an identifier, or a reserved word that is OS1019.
79
+ *
80
+ * The word is taken either way. A script that named something `type` still
81
+ * meant to declare it, and every later diagnostic about that name is more use
82
+ * to the reader than a hole where the declaration should have been.
83
+ */
84
+ export function takeName(cursor) {
85
+ const token = cursor.token;
86
+ if (!isWordKind(token.kind))
87
+ return missingWord(cursor);
88
+ cursor.advance();
89
+ if (token.kind !== 'identifier') {
90
+ cursor.report('OS1019', token.span, {
91
+ word: token.text,
92
+ suggestion: unreservedNear(token.text),
93
+ });
94
+ }
95
+ return makeNode('name', token.span, { text: token.text });
96
+ }
97
+ /**
98
+ * The label of a named argument, where a reserved word is legal.
99
+ *
100
+ * A label is matched against the callee's parameter list and is never looked up
101
+ * in a scope, so `plot(v, "V", color = aqua)` is correct and is not OS1019.
102
+ */
103
+ export function takeLabel(cursor) {
104
+ const token = cursor.advance();
105
+ return makeNode('name', token.span, { text: token.text });
106
+ }
107
+ /**
108
+ * The word after a dot.
109
+ *
110
+ * A member is matched against the namespace or the object type it was read
111
+ * from, which is the same kind of published list a label is matched against, so
112
+ * a reserved word is not OS1019 here either. Whether the member exists at all
113
+ * is OS2009, and the checker owns it.
114
+ */
115
+ export function takeMember(cursor) {
116
+ return isWordKind(cursor.kind) ? takeLabel(cursor) : missingWord(cursor);
117
+ }
118
+ /** Whether the cursor is on a named argument's label: a word, then a bare `=`. */
119
+ export function atLabel(cursor) {
120
+ return isWordKind(cursor.kind) && cursor.peek().kind === '=';
121
+ }
122
+ //# sourceMappingURL=names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"names.js","sourceRoot":"","sources":["../../../src/core/parse/names.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { Script } from '../ast/index.js';
2
+ import type { DiagnosticSink } from '../diagnostics/index.js';
3
+ import type { SourceFile } from '../source/index.js';
4
+ import type { Token } from '../tokens/index.js';
5
+ /**
6
+ * A file, which is a list of statements and function declarations.
7
+ *
8
+ * Section 19 writes a file as a version line, a declaration and a limits line
9
+ * followed by the rest. The prose wins: the declaration being missing is
10
+ * OS2007, two of them is OS2008, and a version line that is not first is
11
+ * OS1021, all of which name a line and suggest a move. So every line here is an
12
+ * item in source order, a file with no declaration still has a tree, and the
13
+ * checker is left holding the questions that are its to answer.
14
+ *
15
+ * Nothing in this file throws and nothing stops early. A statement that could
16
+ * not be read costs its own line and, where it opened one, its block; the next
17
+ * line is read as though nothing had happened, which is what lets a file with
18
+ * three mistakes in it produce three diagnostics from one compile.
19
+ */
20
+ export declare function parse(file: SourceFile, diagnostics: DiagnosticSink): Script;
21
+ /** The same, for a host that has already lexed the file and kept the tokens. */
22
+ export declare function parseTokens(file: SourceFile, tokens: readonly Token[], diagnostics: DiagnosticSink): Script;
23
+ //# sourceMappingURL=script.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script.d.ts","sourceRoot":"","sources":["../../../src/core/parse/script.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAgB,MAAM,iBAAiB,CAAC;AAE5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAKhD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,GAAG,MAAM,CAE3E;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CACzB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,WAAW,EAAE,cAAc,GAC1B,MAAM,CA6BR"}
@@ -0,0 +1,55 @@
1
+ import { makeNode } from '../ast/index.js';
2
+ import { lex } from '../lex/index.js';
3
+ import { Cursor } from './cursor.js';
4
+ import { parseFunctionDeclaration } from './functions.js';
5
+ import { parseStatement } from './statements.js';
6
+ /**
7
+ * A file, which is a list of statements and function declarations.
8
+ *
9
+ * Section 19 writes a file as a version line, a declaration and a limits line
10
+ * followed by the rest. The prose wins: the declaration being missing is
11
+ * OS2007, two of them is OS2008, and a version line that is not first is
12
+ * OS1021, all of which name a line and suggest a move. So every line here is an
13
+ * item in source order, a file with no declaration still has a tree, and the
14
+ * checker is left holding the questions that are its to answer.
15
+ *
16
+ * Nothing in this file throws and nothing stops early. A statement that could
17
+ * not be read costs its own line and, where it opened one, its block; the next
18
+ * line is read as though nothing had happened, which is what lets a file with
19
+ * three mistakes in it produce three diagnostics from one compile.
20
+ */
21
+ export function parse(file, diagnostics) {
22
+ return parseTokens(file, lex(file, diagnostics), diagnostics);
23
+ }
24
+ /** The same, for a host that has already lexed the file and kept the tokens. */
25
+ export function parseTokens(file, tokens, diagnostics) {
26
+ const cursor = new Cursor(file, tokens, diagnostics);
27
+ const items = [];
28
+ while (!cursor.at('endOfFile')) {
29
+ const before = cursor.position;
30
+ if (cursor.at('newline') || cursor.at('dedent') || cursor.at('indent')) {
31
+ // Layout with no statement to belong to, which a recovery can leave
32
+ // behind. Taking it here keeps the loop below reading statements only.
33
+ if (cursor.at('indent'))
34
+ cursor.skipBlockBody();
35
+ else
36
+ cursor.advance();
37
+ continue;
38
+ }
39
+ if (cursor.at('fn')) {
40
+ cursor.beginStatement();
41
+ const declaration = parseFunctionDeclaration(cursor);
42
+ cursor.noteStatement(declaration.span.line);
43
+ items.push(declaration);
44
+ }
45
+ else {
46
+ const statement = parseStatement(cursor);
47
+ if (statement !== undefined)
48
+ items.push(statement);
49
+ }
50
+ if (cursor.position === before)
51
+ cursor.skipStatement();
52
+ }
53
+ return makeNode('script', file.spanAt(0, file.text.length), { items });
54
+ }
55
+ //# sourceMappingURL=script.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script.js","sourceRoot":"","sources":["../../../src/core/parse/script.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAGtC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,KAAK,CAAC,IAAgB,EAAE,WAA2B;IACjE,OAAO,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,WAAW,CAAC,CAAC;AAChE,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,WAAW,CACzB,IAAgB,EAChB,MAAwB,EACxB,WAA2B;IAE3B,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IACrD,MAAM,KAAK,GAAmB,EAAE,CAAC;IAEjC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;QAE/B,IAAI,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvE,oEAAoE;YACpE,uEAAuE;YACvE,IAAI,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC;gBAAE,MAAM,CAAC,aAAa,EAAE,CAAC;;gBAC3C,MAAM,CAAC,OAAO,EAAE,CAAC;YACtB,SAAS;QACX,CAAC;QAED,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,WAAW,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC;YACrD,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5C,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,SAAS,KAAK,SAAS;gBAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,MAAM,CAAC,QAAQ,KAAK,MAAM;YAAE,MAAM,CAAC,aAAa,EAAE,CAAC;IACzD,CAAC;IAED,OAAO,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AACzE,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { FunctionDeclaration, Statement } from '../ast/index.js';
2
+ import type { Cursor } from './cursor.js';
3
+ export declare function parseStatement(cursor: Cursor): Statement | FunctionDeclaration | undefined;
4
+ /**
5
+ * The end of a statement: a newline, and OS1018 for anything before it.
6
+ *
7
+ * A line holds at most one statement, so whatever is left over is either a
8
+ * missing operator or a second statement that lost its newline. It is only
9
+ * reported when the statement has nothing else wrong with it, because leftovers
10
+ * are what every other mistake on the line produces and the reader should be
11
+ * told about the mistake rather than about its wreckage.
12
+ */
13
+ export declare function finishStatement(cursor: Cursor): void;
14
+ //# sourceMappingURL=statements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statements.d.ts","sourceRoot":"","sources":["../../../src/core/parse/statements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,mBAAmB,EACnB,SAAS,EAEV,MAAM,iBAAiB,CAAC;AAMzB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAwB1C,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,GACb,SAAS,GAAG,mBAAmB,GAAG,SAAS,CAK7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAKpD"}
@@ -0,0 +1,292 @@
1
+ import { ASSIGNMENT_OPERATORS, makeNode, withoutGrouping } from '../ast/index.js';
2
+ import { spanning } from '../span/index.js';
3
+ import { parseTypeAnnotation } from './annotations.js';
4
+ import { parseIfStatement } from './branches.js';
5
+ import { missingExpression, parseArgumentList, parseExpression } from './expressions.js';
6
+ import { parseFunctionDeclaration } from './functions.js';
7
+ import { parseForStatement, parseWhileStatement } from './loops.js';
8
+ import { isWordKind, takeName } from './names.js';
9
+ import { parseSwitchStatement } from './switches.js';
10
+ /**
11
+ * One statement, and the choice of which one it is.
12
+ *
13
+ * The choice is made from the first token and at most one more, which is what
14
+ * keeps the language readable: a line that begins with `if` is an `if` and
15
+ * nothing else, and the only lookahead anywhere is the token after a word,
16
+ * which says whether the word is being assigned to.
17
+ *
18
+ * Three of the forms here describe the file rather than compute anything. They
19
+ * are statements like the rest and may be written anywhere a statement may be,
20
+ * because the errors for putting one in the wrong place name a line and suggest
21
+ * a move (OS1021, OS2007, OS2008, OS3014), and a tree that refused to hold them
22
+ * could not carry a line number for any of those to report.
23
+ */
24
+ const ASSIGNMENT = new Set(ASSIGNMENT_OPERATORS);
25
+ export function parseStatement(cursor) {
26
+ cursor.beginStatement();
27
+ const statement = dispatch(cursor);
28
+ if (statement !== undefined)
29
+ cursor.noteStatement(statement.span.line);
30
+ return statement;
31
+ }
32
+ /**
33
+ * The end of a statement: a newline, and OS1018 for anything before it.
34
+ *
35
+ * A line holds at most one statement, so whatever is left over is either a
36
+ * missing operator or a second statement that lost its newline. It is only
37
+ * reported when the statement has nothing else wrong with it, because leftovers
38
+ * are what every other mistake on the line produces and the reader should be
39
+ * told about the mistake rather than about its wreckage.
40
+ */
41
+ export function finishStatement(cursor) {
42
+ if (cursor.take('newline') !== undefined)
43
+ return;
44
+ if (cursor.atStatementEnd())
45
+ return;
46
+ if (!cursor.reportedHere)
47
+ cursor.unexpected(cursor.token);
48
+ cursor.skipToEndOfLine();
49
+ }
50
+ function dispatch(cursor) {
51
+ switch (cursor.kind) {
52
+ case 'if':
53
+ return parseIfStatement(cursor);
54
+ case 'for':
55
+ return parseForStatement(cursor);
56
+ case 'while':
57
+ return parseWhileStatement(cursor);
58
+ case 'switch':
59
+ return parseSwitchStatement(cursor);
60
+ case 'break':
61
+ case 'continue':
62
+ return parseJump(cursor);
63
+ case 'return':
64
+ return parseReturn(cursor);
65
+ case 'var':
66
+ return parseVarDeclaration(cursor, false);
67
+ case 'live':
68
+ return cursor.peek().kind === 'var'
69
+ ? parseVarDeclaration(cursor, true)
70
+ : parseSimpleStatement(cursor);
71
+ case 'study':
72
+ case 'strategy':
73
+ return parseScriptDeclaration(cursor);
74
+ case 'else':
75
+ return strayElse(cursor);
76
+ case 'case':
77
+ case 'default':
78
+ return strayArm(cursor);
79
+ case 'fn':
80
+ return nestedFunction(cursor);
81
+ default:
82
+ return parseSimpleStatement(cursor);
83
+ }
84
+ }
85
+ function parseSimpleStatement(cursor) {
86
+ const token = cursor.token;
87
+ // A block whose header was not understood, so nothing is left that could own
88
+ // it. Skipping it whole reports the header once instead of every line of it.
89
+ if (token.kind === 'indent') {
90
+ cursor.skipBlockBody();
91
+ return undefined;
92
+ }
93
+ if (token.kind === 'identifier') {
94
+ const next = cursor.peek();
95
+ // `version` and `limits` are not reserved words: a script written before
96
+ // either existed keeps compiling, so both are recognised by position.
97
+ if (token.text === 'version' && next.kind === 'numberLiteral') {
98
+ return parseVersionLine(cursor, next);
99
+ }
100
+ if (token.text === 'limits' && next.kind === '(')
101
+ return parseLimitsLine(cursor);
102
+ }
103
+ if (isWordKind(token.kind) && ASSIGNMENT.has(cursor.peek().kind)) {
104
+ return parseAssignment(cursor);
105
+ }
106
+ if (cursor.atStatementEnd()) {
107
+ cursor.take('newline');
108
+ return undefined;
109
+ }
110
+ const expression = parseExpression(cursor);
111
+ if (ASSIGNMENT.has(cursor.kind)) {
112
+ const refused = assignmentToSomethingOtherThanAName(cursor, expression);
113
+ if (refused !== undefined)
114
+ return refused;
115
+ }
116
+ finishStatement(cursor);
117
+ return makeNode('expressionStatement', expression.span, { expression });
118
+ }
119
+ /**
120
+ * An assignment whose target is an index or a member: OS1024 and OS1025.
121
+ *
122
+ * The grammar of section 19 has one assignment target and it is an identifier,
123
+ * so what is wrong on this line is the target and not the operator after it.
124
+ * That is why neither of these is OS1018, whose message would say the statement
125
+ * had ended before an operator the reader wrote in the middle of it. Two codes
126
+ * rather than one because the two have different fixes: an array element is
127
+ * written with a call, and a member is not written at all.
128
+ *
129
+ * Anything else the grammar cannot assign to, a literal or a call, is left to
130
+ * the caller and reported as OS1018, which is the nearest true thing the
131
+ * catalogue has for it.
132
+ *
133
+ * The value is read rather than skipped, so a mistake in it is reported on the
134
+ * same compile, and the statement reaches the tree as the target that was
135
+ * written. There is no node for an assignment whose target is not a name, and
136
+ * building one over a name taken out of the target, `prices` out of
137
+ * `prices[0]`, would put a different program in the tree from the one on the
138
+ * page.
139
+ */
140
+ function assignmentToSomethingOtherThanAName(cursor, target) {
141
+ const written = withoutGrouping(target);
142
+ if (written.kind === 'index') {
143
+ cursor.report('OS1024', target.span, { name: cursor.textOf(written.target.span) });
144
+ }
145
+ else if (written.kind === 'member') {
146
+ cursor.report('OS1025', target.span, {
147
+ name: cursor.textOf(written.object.span),
148
+ member: written.member.text,
149
+ });
150
+ }
151
+ else {
152
+ return undefined;
153
+ }
154
+ // The operator, and then the value, which is read so that a mistake inside it
155
+ // is reported on this compile rather than on the one after the target is
156
+ // fixed.
157
+ cursor.advance();
158
+ const value = parseExpression(cursor);
159
+ finishStatement(cursor);
160
+ return makeNode('expressionStatement', spanning(target.span, value.span), {
161
+ expression: target,
162
+ });
163
+ }
164
+ function parseAssignment(cursor) {
165
+ const target = takeName(cursor);
166
+ const operator = cursor.advance().kind;
167
+ const value = parseExpression(cursor);
168
+ finishStatement(cursor);
169
+ return makeNode('assignment', spanning(target.span, value.span), { target, operator, value });
170
+ }
171
+ function parseVarDeclaration(cursor, live) {
172
+ const start = cursor.advance();
173
+ if (live)
174
+ cursor.advance();
175
+ const name = takeName(cursor);
176
+ const annotation = cursor.take(':') !== undefined ? parseTypeAnnotation(cursor) : undefined;
177
+ let initialiser;
178
+ if (cursor.take('=') !== undefined) {
179
+ initialiser = parseExpression(cursor);
180
+ }
181
+ else {
182
+ // The declaration and the first assignment are one statement, so a
183
+ // persistent value always has something in it and no bar can read it
184
+ // before it exists.
185
+ cursor.report('OS1011', spanning(start.span, name.span), { name: name.text });
186
+ initialiser = missingExpression(cursor);
187
+ }
188
+ finishStatement(cursor);
189
+ return makeNode('varDeclaration', spanning(start.span, initialiser.span), {
190
+ live,
191
+ name,
192
+ annotation,
193
+ initialiser,
194
+ });
195
+ }
196
+ function parseScriptDeclaration(cursor) {
197
+ const keyword = cursor.advance();
198
+ const open = cursor.take('(');
199
+ const list = open === undefined ? undefined : parseArgumentList(cursor, open);
200
+ finishStatement(cursor);
201
+ return makeNode('scriptDeclaration', spanning(keyword.span, list?.end ?? keyword.span), {
202
+ form: keyword.kind === 'study' ? 'study' : 'strategy',
203
+ args: list?.items ?? [],
204
+ });
205
+ }
206
+ function parseVersionLine(cursor, number) {
207
+ const word = cursor.advance();
208
+ cursor.advance();
209
+ const span = spanning(word.span, number.span);
210
+ const before = cursor.firstStatementLine;
211
+ if (before !== undefined)
212
+ cursor.report('OS1021', span, { line: before });
213
+ finishStatement(cursor);
214
+ return makeNode('versionLine', span, {
215
+ version: makeNode('numberLiteral', number.span, { value: number.value }),
216
+ });
217
+ }
218
+ function parseLimitsLine(cursor) {
219
+ const word = cursor.advance();
220
+ const list = parseArgumentList(cursor, cursor.advance());
221
+ finishStatement(cursor);
222
+ return makeNode('limitsLine', spanning(word.span, list.end), { args: list.items });
223
+ }
224
+ function parseJump(cursor) {
225
+ const keyword = cursor.advance();
226
+ if (!cursor.insideLoop)
227
+ cursor.report('OS1009', keyword.span, { word: keyword.text });
228
+ finishStatement(cursor);
229
+ return keyword.kind === 'break'
230
+ ? makeNode('breakStatement', keyword.span, {})
231
+ : makeNode('continueStatement', keyword.span, {});
232
+ }
233
+ function parseReturn(cursor) {
234
+ const keyword = cursor.advance();
235
+ // A bare `return` exits with `none`, so the value is genuinely absent here
236
+ // rather than a hole something went missing from.
237
+ const value = cursor.atStatementEnd() ? undefined : parseExpression(cursor);
238
+ finishStatement(cursor);
239
+ return makeNode('returnStatement', value === undefined ? keyword.span : spanning(keyword.span, value.span), { value });
240
+ }
241
+ /**
242
+ * An `else` that no `if` took.
243
+ *
244
+ * `parseIfStatement` takes the `else` that belongs to it, so one that reaches
245
+ * here has no `if` at its own indentation: either the statement above it is
246
+ * something else, or the lexer has already put the two in different blocks.
247
+ */
248
+ function strayElse(cursor) {
249
+ const token = cursor.token;
250
+ cursor.report('OS1016', token.span, {
251
+ found: token.span.column - 1,
252
+ expected: cursor.nearestIfColumn - 1,
253
+ });
254
+ cursor.skipStatement();
255
+ return undefined;
256
+ }
257
+ function strayArm(cursor) {
258
+ const token = cursor.token;
259
+ cursor.report('OS1017', token.span, { word: token.text });
260
+ cursor.skipStatement();
261
+ return undefined;
262
+ }
263
+ /**
264
+ * A `fn` inside a block, which language.md 11.1 forbids: OS1023.
265
+ *
266
+ * It is read and it is kept. Reading it keeps the lines under it from being
267
+ * taken for statements of the block around it. Keeping it is what lets anything
268
+ * after the parser see the function at all: a declaration dropped here is gone
269
+ * from the tree, so a call to it could only ever be reported as a name nobody
270
+ * declared, and a nested function nobody calls would go unreported for good. It
271
+ * stays where the reader wrote it rather than being lifted to the top level,
272
+ * which would compile a file the language refuses.
273
+ *
274
+ * The caret covers `fn` and the name, which is the part of the declaration the
275
+ * reader has to move, and the same span OS1011 puts under `var name`.
276
+ *
277
+ * A header with no name at all has already been told that a name was expected,
278
+ * and the message here has nothing to name, so it waits: the node is kept
279
+ * either way, and the declaration is reported as nested once it has a name for
280
+ * the sentence to use and for the fix to tell the reader to call.
281
+ */
282
+ function nestedFunction(cursor) {
283
+ const keyword = cursor.token;
284
+ const declaration = parseFunctionDeclaration(cursor);
285
+ if (declaration.name.text !== '') {
286
+ cursor.report('OS1023', spanning(keyword.span, declaration.name.span), {
287
+ name: declaration.name.text,
288
+ });
289
+ }
290
+ return declaration;
291
+ }
292
+ //# sourceMappingURL=statements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statements.js","sourceRoot":"","sources":["../../../src/core/parse/statements.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { SwitchStatement } from '../ast/index.js';
2
+ import type { Cursor } from './cursor.js';
3
+ /**
4
+ * `switch`, in both forms of language.md 10.6.
5
+ *
6
+ * With a subject each case value is compared against it, and without one each
7
+ * case value is a condition. The difference is the absent subject and needs no
8
+ * flag beside it.
9
+ *
10
+ * The arms are the whole of a switch body. A `default` that is not last would
11
+ * leave the arms after it unreachable, so the arm that follows one is OS1017,
12
+ * and the arm is kept in the tree all the same: a reader who moves the default
13
+ * should not then be told about the arms one at a time.
14
+ */
15
+ export declare function parseSwitchStatement(cursor: Cursor): SwitchStatement;
16
+ //# sourceMappingURL=switches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"switches.d.ts","sourceRoot":"","sources":["../../../src/core/parse/switches.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyC,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAK9F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAI1C;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CA0DpE"}