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,373 @@
1
+ import { COMPARISON_OPERATORS, EQUALITY_OPERATORS, UNARY_OPERATORS, makeNode, } from '../ast/index.js';
2
+ import { spanning } from '../span/index.js';
3
+ import { describeToken } from './cursor.js';
4
+ import { atLabel, isMeantAsAName, takeLabel, takeMember, takeName } from './names.js';
5
+ /**
6
+ * The expression grammar, which is the precedence table of language.md 9.1 read
7
+ * from the bottom up.
8
+ *
9
+ * One function per level, in the order the table lists them, so the table can
10
+ * be checked against this file line by line. Precedence ends up in the shape of
11
+ * the tree rather than in a field, which is why nothing downstream ever has to
12
+ * know that `*` binds tighter than `+`.
13
+ *
14
+ * Two levels are deliberately not loops. Comparison and equality take at most
15
+ * one operator, because `a < b < c` has two plausible readings and the language
16
+ * refuses both (9.3). They are written as loops all the same, so that the
17
+ * second operator is reported as OS1008 with a caret on it and the expression
18
+ * still builds, rather than the parser stopping at a shape it cannot hold.
19
+ */
20
+ const ADDITIVE = ['+', '-'];
21
+ const MULTIPLICATIVE = ['*', '/', '%'];
22
+ /** The tokens an expression can begin with, which is what tells two arguments apart. */
23
+ const STARTS_EXPRESSION = new Set([
24
+ 'numberLiteral',
25
+ 'stringLiteral',
26
+ 'hexColor',
27
+ 'identifier',
28
+ 'true',
29
+ 'false',
30
+ 'none',
31
+ '(',
32
+ '[',
33
+ '-',
34
+ '+',
35
+ 'not',
36
+ ]);
37
+ /**
38
+ * Whether an expression can begin here, which is what tells one argument from
39
+ * the next and what keeps a list from reading a closing bracket as an item.
40
+ *
41
+ * A reserved word a reader meant as a name begins one too, because `parsePrimary`
42
+ * reads it as the name it was meant to be rather than leaving it where it sits.
43
+ */
44
+ export function startsExpression(kind) {
45
+ return STARTS_EXPRESSION.has(kind) || isMeantAsAName(kind);
46
+ }
47
+ export function parseExpression(cursor) {
48
+ if (!cursor.deeper(cursor.token.span))
49
+ return missingExpression(cursor);
50
+ const expression = parseTernary(cursor);
51
+ cursor.shallower();
52
+ return expression;
53
+ }
54
+ /**
55
+ * An expression in a position where a value is being tested rather than stored.
56
+ *
57
+ * `if x = 5` is the one typo the language is shaped to catch: assignment is a
58
+ * statement and never an expression (10.1), so there is no reading of the line
59
+ * that compiles, and OS1006 can name the fix instead of a type error arriving
60
+ * three stages later. The `==` is built as though the fix had been applied, so
61
+ * the rest of the file still checks.
62
+ */
63
+ export function parseCondition(cursor) {
64
+ const condition = parseExpression(cursor);
65
+ const assign = cursor.take('=');
66
+ if (assign === undefined)
67
+ return condition;
68
+ cursor.report('OS1006', assign.span, {});
69
+ const right = parseExpression(cursor);
70
+ return makeNode('binary', spanning(condition.span, right.span), {
71
+ operator: '==',
72
+ left: condition,
73
+ right,
74
+ });
75
+ }
76
+ function parseTernary(cursor) {
77
+ const condition = parseOr(cursor);
78
+ const question = cursor.take('?');
79
+ if (question === undefined)
80
+ return condition;
81
+ const whenTrue = parseExpression(cursor);
82
+ if (cursor.take(':') === undefined) {
83
+ cursor.report('OS1015', question.span, {});
84
+ const hole = missingExpression(cursor);
85
+ return makeNode('ternary', spanning(condition.span, whenTrue.span), {
86
+ condition,
87
+ whenTrue,
88
+ whenFalse: hole,
89
+ });
90
+ }
91
+ // Right associative (9.1): the false arm takes the rest of the line, so
92
+ // `x > 0 ? "up" : x < 0 ? "down" : "flat"` nests to the right.
93
+ const whenFalse = parseExpression(cursor);
94
+ return makeNode('ternary', spanning(condition.span, whenFalse.span), {
95
+ condition,
96
+ whenTrue,
97
+ whenFalse,
98
+ });
99
+ }
100
+ function parseOr(cursor) {
101
+ let left = parseAnd(cursor);
102
+ while (cursor.take('or') !== undefined) {
103
+ const right = parseAnd(cursor);
104
+ left = makeNode('binary', spanning(left.span, right.span), { operator: 'or', left, right });
105
+ }
106
+ return left;
107
+ }
108
+ function parseAnd(cursor) {
109
+ let left = parseEquality(cursor);
110
+ while (cursor.take('and') !== undefined) {
111
+ const right = parseEquality(cursor);
112
+ left = makeNode('binary', spanning(left.span, right.span), { operator: 'and', left, right });
113
+ }
114
+ return left;
115
+ }
116
+ function parseEquality(cursor) {
117
+ return parseUnchainable(cursor, EQUALITY_OPERATORS, parseComparison);
118
+ }
119
+ function parseComparison(cursor) {
120
+ return parseUnchainable(cursor, COMPARISON_OPERATORS, parseAdditive);
121
+ }
122
+ /**
123
+ * A level that takes at most one operator, and says so when it is given two.
124
+ *
125
+ * The chain is folded to the left after the report so that the tree holds
126
+ * everything the reader wrote. A parser that stopped here would leave the rest
127
+ * of the line unparsed, and the reader would fix the chain only to be told
128
+ * about the next mistake on the same line one compile later.
129
+ */
130
+ function parseUnchainable(cursor, operators, next) {
131
+ let left = next(cursor);
132
+ let first;
133
+ let chained = false;
134
+ for (;;) {
135
+ const operator = operatorAt(cursor, operators);
136
+ if (operator === undefined)
137
+ return left;
138
+ const token = cursor.advance();
139
+ if (first !== undefined && !chained) {
140
+ chained = true;
141
+ cursor.report('OS1008', token.span, { op1: first, op2: operator });
142
+ }
143
+ first ??= operator;
144
+ const right = next(cursor);
145
+ left = makeNode('binary', spanning(left.span, right.span), { operator, left, right });
146
+ }
147
+ }
148
+ function parseAdditive(cursor) {
149
+ return parseLeftAssociative(cursor, ADDITIVE, parseMultiplicative);
150
+ }
151
+ function parseMultiplicative(cursor) {
152
+ return parseLeftAssociative(cursor, MULTIPLICATIVE, parseUnary);
153
+ }
154
+ function parseLeftAssociative(cursor, operators, next) {
155
+ let left = next(cursor);
156
+ for (;;) {
157
+ const operator = operatorAt(cursor, operators);
158
+ if (operator === undefined)
159
+ return left;
160
+ cursor.advance();
161
+ const right = next(cursor);
162
+ left = makeNode('binary', spanning(left.span, right.span), { operator, left, right });
163
+ }
164
+ }
165
+ /**
166
+ * Unary minus, plus and `not`, right associative.
167
+ *
168
+ * Section 19 writes this level as taking at most one operator. The prose wins:
169
+ * 9.1 calls it right associative, so `not not ready` and `- -x` are shapes the
170
+ * tree can hold and the checker can have an opinion about.
171
+ */
172
+ function parseUnary(cursor) {
173
+ const operator = operatorAt(cursor, UNARY_OPERATORS);
174
+ if (operator === undefined)
175
+ return parsePostfix(cursor);
176
+ const token = cursor.advance();
177
+ if (!cursor.deeper(token.span))
178
+ return missingExpression(cursor);
179
+ const operand = parseUnary(cursor);
180
+ cursor.shallower();
181
+ return makeNode('unary', spanning(token.span, operand.span), { operator, operand });
182
+ }
183
+ /** A call, a history or element read, and a member, applied left to right. */
184
+ function parsePostfix(cursor) {
185
+ let target = parsePrimary(cursor);
186
+ for (;;) {
187
+ const before = cursor.position;
188
+ if (cursor.at('(')) {
189
+ const open = cursor.advance();
190
+ const args = parseBracketedList(cursor, open, parseArgument);
191
+ target = makeNode('call', spanning(target.span, args.end), {
192
+ callee: target,
193
+ args: args.items,
194
+ });
195
+ }
196
+ else if (cursor.at('[')) {
197
+ const open = cursor.advance();
198
+ const index = parseExpression(cursor);
199
+ const end = closeBracket(cursor, open);
200
+ target = makeNode('index', spanning(target.span, end), { target, index });
201
+ }
202
+ else if (cursor.at('.')) {
203
+ cursor.advance();
204
+ const member = takeMember(cursor);
205
+ target = makeNode('member', spanning(target.span, member.span), { object: target, member });
206
+ }
207
+ else {
208
+ return target;
209
+ }
210
+ if (cursor.position === before)
211
+ return target;
212
+ }
213
+ }
214
+ function parsePrimary(cursor) {
215
+ const token = cursor.token;
216
+ switch (token.kind) {
217
+ case 'numberLiteral':
218
+ cursor.advance();
219
+ return makeNode('numberLiteral', token.span, { value: token.value });
220
+ case 'stringLiteral':
221
+ cursor.advance();
222
+ return makeNode('stringLiteral', token.span, { value: token.value });
223
+ case 'true':
224
+ case 'false':
225
+ cursor.advance();
226
+ return makeNode('booleanLiteral', token.span, { value: token.kind === 'true' });
227
+ case 'none':
228
+ cursor.advance();
229
+ return makeNode('noneLiteral', token.span, {});
230
+ // Only `#rrggbb` and `#rrggbbaa`. A named colour is an ordinary global
231
+ // (3.8), so `aqua` arrives here as an identifier and leaves as a reference.
232
+ case 'hexColor':
233
+ cursor.advance();
234
+ return makeNode('colorLiteral', token.span, { text: token.text });
235
+ case 'identifier':
236
+ cursor.advance();
237
+ return makeNode('nameReference', token.span, { name: token.text });
238
+ case '(': {
239
+ cursor.advance();
240
+ const inner = parseExpression(cursor);
241
+ const end = closeBracket(cursor, token);
242
+ return makeNode('grouping', spanning(token.span, end), { expression: inner });
243
+ }
244
+ case '[': {
245
+ cursor.advance();
246
+ const elements = parseBracketedList(cursor, token, parseExpression);
247
+ return makeNode('arrayLiteral', spanning(token.span, elements.end), {
248
+ elements: elements.items,
249
+ });
250
+ }
251
+ default:
252
+ // A reserved word where a value belongs is the name the reader meant, and
253
+ // OS1019 says the language has taken the word. The word is taken here as
254
+ // well as reported on: a rule that reports and then consumes nothing
255
+ // leaves the list and the bracket above it looking at the token it could
256
+ // not read, and the next thing the reader is told is that a bracket they
257
+ // plainly closed was never closed.
258
+ if (isMeantAsAName(token.kind)) {
259
+ const name = takeName(cursor);
260
+ return makeNode('nameReference', name.span, { name: name.text });
261
+ }
262
+ return expressionExpected(cursor);
263
+ }
264
+ }
265
+ /** One argument, with the label of a named one when there is a label. */
266
+ function parseArgument(cursor) {
267
+ if (!atLabel(cursor)) {
268
+ const bare = parseExpression(cursor);
269
+ return makeNode('argument', bare.span, { label: undefined, value: bare });
270
+ }
271
+ const label = takeLabel(cursor);
272
+ cursor.advance();
273
+ const value = parseExpression(cursor);
274
+ return makeNode('argument', spanning(label.span, value.span), { label, value });
275
+ }
276
+ /**
277
+ * A comma separated list inside brackets: an argument list or an array literal.
278
+ *
279
+ * The two shapes are one function because their recovery is the same and has to
280
+ * stay the same: a missing comma is OS1014 and the list carries on, and a list
281
+ * that runs to the end of the line without a closer is the bracket's own error
282
+ * rather than one per item.
283
+ */
284
+ export function parseBracketedList(cursor, open, parseItem) {
285
+ const items = [];
286
+ for (;;) {
287
+ if (atListEnd(cursor))
288
+ break;
289
+ const before = cursor.position;
290
+ items.push(parseItem(cursor));
291
+ const comma = cursor.take(',');
292
+ if (comma !== undefined) {
293
+ if (!atListEnd(cursor))
294
+ continue;
295
+ // A comma promises another item (3.11 continues the line for one), so a
296
+ // list that ends on one has lost it rather than written an empty slot.
297
+ cursor.report('OS1022', cursor.holeSpan(), { token: describeToken(comma) });
298
+ break;
299
+ }
300
+ if (atListEnd(cursor))
301
+ break;
302
+ // The item read nothing, so it has reported its own hole and the token it
303
+ // could not read is still here. Taking it carries the list on to the item
304
+ // after it and, more importantly, to the closing bracket: a list that
305
+ // stopped here would hand the bracket a token that is not a closer, and the
306
+ // reader would be told the bracket was never closed on a line that closes
307
+ // it.
308
+ if (cursor.position === before) {
309
+ cursor.advance();
310
+ continue;
311
+ }
312
+ // What follows could not have begun a second item, so this is the closing
313
+ // bracket's mistake and not a missing comma.
314
+ if (!startsExpression(cursor.kind))
315
+ break;
316
+ cursor.report('OS1014', cursor.token.span, { token: describeToken(cursor.token) });
317
+ }
318
+ return { items, end: closeBracket(cursor, open) };
319
+ }
320
+ function atListEnd(cursor) {
321
+ return cursor.at(')') || cursor.at(']') || cursor.atStatementEnd();
322
+ }
323
+ /**
324
+ * The closing bracket, or the two ways it can be missing.
325
+ *
326
+ * OS1012 is reported at the opening bracket rather than at the end of the file,
327
+ * because an open bracket continues the statement onto every following line
328
+ * (3.11) and the mistake is where the bracket was opened.
329
+ */
330
+ export function closeBracket(cursor, open) {
331
+ const expected = open.kind === '(' ? ')' : ']';
332
+ const closer = cursor.take(expected);
333
+ if (closer !== undefined)
334
+ return closer.span;
335
+ if (cursor.at(')') || cursor.at(']')) {
336
+ const found = cursor.advance();
337
+ cursor.report('OS1013', found.span, {
338
+ found: found.text,
339
+ expected,
340
+ opener: open.text,
341
+ line: open.span.line,
342
+ });
343
+ return found.span;
344
+ }
345
+ cursor.report('OS1012', open.span, { bracket: open.text, line: open.span.line });
346
+ return cursor.previous().span;
347
+ }
348
+ function expressionExpected(cursor) {
349
+ const hole = cursor.holeSpan();
350
+ cursor.report('OS1022', hole, {
351
+ token: describeToken(cursor.previousMeaningful() ?? cursor.token),
352
+ });
353
+ return makeNode('missingExpression', hole, {});
354
+ }
355
+ /**
356
+ * The hole a rule leaves where an expression was required.
357
+ *
358
+ * The span is empty and sits where the expression should have been, so it never
359
+ * takes a caret meant for its neighbour, and everything downstream still has a
360
+ * tree to walk over a file that is being typed.
361
+ */
362
+ export function missingExpression(cursor) {
363
+ return makeNode('missingExpression', cursor.holeSpan(), {});
364
+ }
365
+ function operatorAt(cursor, operators) {
366
+ const kind = cursor.kind;
367
+ return operators.includes(kind) ? kind : undefined;
368
+ }
369
+ /** An argument list, for the three statements that are a call in all but name. */
370
+ export function parseArgumentList(cursor, open) {
371
+ return parseBracketedList(cursor, open, parseArgument);
372
+ }
373
+ //# sourceMappingURL=expressions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expressions.js","sourceRoot":"","sources":["../../../src/core/parse/expressions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { FunctionDeclaration } from '../ast/index.js';
2
+ import type { Cursor } from './cursor.js';
3
+ /**
4
+ * `fn name(parameters) => body`, language.md 11.1.
5
+ *
6
+ * The body is an expression when it is written after the `=>` on one line, and
7
+ * a block when the `=>` ends the line. Both forms exist because the one line
8
+ * form needs the implicit return and an early exit needs the explicit one.
9
+ *
10
+ * The `=>` is two tokens. Section 3.12 does not list it among the punctuation,
11
+ * so it arrives as an `=` and a `>` that touch, and touching is what tells it
12
+ * from a comparison: the lexer suppresses its continuation rule for that exact
13
+ * pair, and the same adjacency test is what matches it here.
14
+ */
15
+ export declare function parseFunctionDeclaration(cursor: Cursor): FunctionDeclaration;
16
+ //# sourceMappingURL=functions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../../src/core/parse/functions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,mBAAmB,EAAmB,MAAM,iBAAiB,CAAC;AAM/F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAK1C;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAsB5E"}
@@ -0,0 +1,92 @@
1
+ import { makeNode } from '../ast/index.js';
2
+ import { spanning } from '../span/index.js';
3
+ import { parseTypeAnnotation } from './annotations.js';
4
+ import { parseBlock } from './blocks.js';
5
+ import { parseBracketedList, parseExpression } from './expressions.js';
6
+ import { takeName } from './names.js';
7
+ import { finishStatement } from './statements.js';
8
+ /**
9
+ * `fn name(parameters) => body`, language.md 11.1.
10
+ *
11
+ * The body is an expression when it is written after the `=>` on one line, and
12
+ * a block when the `=>` ends the line. Both forms exist because the one line
13
+ * form needs the implicit return and an early exit needs the explicit one.
14
+ *
15
+ * The `=>` is two tokens. Section 3.12 does not list it among the punctuation,
16
+ * so it arrives as an `=` and a `>` that touch, and touching is what tells it
17
+ * from a comparison: the lexer suppresses its continuation rule for that exact
18
+ * pair, and the same adjacency test is what matches it here.
19
+ */
20
+ export function parseFunctionDeclaration(cursor) {
21
+ const keyword = cursor.advance();
22
+ const name = takeName(cursor);
23
+ const open = cursor.take('(');
24
+ if (open === undefined)
25
+ cursor.unexpected(cursor.token);
26
+ const parameters = open === undefined ? [] : parseBracketedList(cursor, open, parseParameter).items;
27
+ const arrow = takeArrow(cursor);
28
+ if (arrow === undefined) {
29
+ return declaration(keyword, name, parameters, headerWithNoArrow(cursor, keyword));
30
+ }
31
+ if (!cursor.atStatementEnd()) {
32
+ const body = parseExpression(cursor);
33
+ finishStatement(cursor);
34
+ return declaration(keyword, name, parameters, body);
35
+ }
36
+ finishStatement(cursor);
37
+ return declaration(keyword, name, parameters, parseBlock(cursor, 'fn', keyword.span));
38
+ }
39
+ /**
40
+ * A parameter, which is an ordinary identifier and not a label.
41
+ *
42
+ * `fn f(color = red)` is OS1019, and `plot(v, "V", color = aqua)` is not: the
43
+ * body of a function refers to its parameters, and nothing ever refers to a
44
+ * label (language.md 3.4). `takeName` is the whole of that difference.
45
+ */
46
+ function parseParameter(cursor) {
47
+ const name = takeName(cursor);
48
+ const annotation = cursor.take(':') !== undefined ? parseTypeAnnotation(cursor) : undefined;
49
+ const defaultValue = cursor.take('=') !== undefined ? parseExpression(cursor) : undefined;
50
+ const end = defaultValue?.span ?? annotation?.span ?? name.span;
51
+ return makeNode('parameter', spanning(name.span, end), { name, annotation, defaultValue });
52
+ }
53
+ /** The `=>` of 11.1: an `=` and a `>` written against each other. */
54
+ function takeArrow(cursor) {
55
+ const equals = cursor.token;
56
+ const greater = cursor.peek();
57
+ if (equals.kind !== '=' || greater.kind !== '>')
58
+ return undefined;
59
+ if (equals.span.offset + equals.span.length !== greater.span.offset)
60
+ return undefined;
61
+ cursor.advance();
62
+ return cursor.advance();
63
+ }
64
+ /**
65
+ * A header with no `=>`, which the catalogue has no code of its own for.
66
+ *
67
+ * What is reported is what is true. A token sitting where the arrow belongs is
68
+ * OS1018, whose fix names the operator that was meant to join the two halves. A
69
+ * header that simply ends is OS1010, because that is what it now is: a header
70
+ * with no body, since without the arrow the lexer opened no block under it.
71
+ */
72
+ function headerWithNoArrow(cursor, keyword) {
73
+ if (!cursor.atStatementEnd()) {
74
+ cursor.unexpected(cursor.token);
75
+ const body = parseExpression(cursor);
76
+ finishStatement(cursor);
77
+ return body;
78
+ }
79
+ cursor.report('OS1010', keyword.span, { header: 'fn' });
80
+ finishStatement(cursor);
81
+ if (cursor.at('indent'))
82
+ return parseBlock(cursor, 'fn', keyword.span);
83
+ return makeNode('block', cursor.holeSpan(), { statements: [] });
84
+ }
85
+ function declaration(keyword, name, parameters, body) {
86
+ return makeNode('functionDeclaration', spanning(keyword.span, body.span), {
87
+ name,
88
+ parameters,
89
+ body,
90
+ });
91
+ }
92
+ //# sourceMappingURL=functions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"functions.js","sourceRoot":"","sources":["../../../src/core/parse/functions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The parser: tokens to a syntax tree, and a diagnostic for anything the
3
+ * grammar does not have a shape for.
4
+ *
5
+ * The whole of language.md section 19 lives behind this door, with the prose of
6
+ * sections 9 to 13 winning wherever the two disagree. What comes out is a tree
7
+ * for every file, including a file with mistakes in it: a parse error costs the
8
+ * statement it is on and nothing else, so an editor asking about a half typed
9
+ * line still gets a tree, and a compile reports every mistake in a file rather
10
+ * than the first one.
11
+ */
12
+ export { parse, parseTokens } from './script.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/parse/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The parser: tokens to a syntax tree, and a diagnostic for anything the
3
+ * grammar does not have a shape for.
4
+ *
5
+ * The whole of language.md section 19 lives behind this door, with the prose of
6
+ * sections 9 to 13 winning wherever the two disagree. What comes out is a tree
7
+ * for every file, including a file with mistakes in it: a parse error costs the
8
+ * statement it is on and nothing else, so an editor asking about a half typed
9
+ * line still gets a tree, and a compile reports every mistake in a file rather
10
+ * than the first one.
11
+ */
12
+ export { parse, parseTokens } from './script.js';
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/parse/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { ForInStatement, ForRangeStatement, WhileStatement } from '../ast/index.js';
2
+ import type { Cursor } from './cursor.js';
3
+ /**
4
+ * `for` and `while`, language.md 10.3 and 10.4.
5
+ *
6
+ * There are two loop forms and no third, so a header that is neither is OS1020
7
+ * rather than a cascade of smaller complaints: the message names the two shapes
8
+ * that exist, which is the only thing the reader needs. The body is read either
9
+ * way, so the lines under a header that was not understood are still checked.
10
+ */
11
+ export declare function parseForStatement(cursor: Cursor): ForRangeStatement | ForInStatement;
12
+ export declare function parseWhileStatement(cursor: Cursor): WhileStatement;
13
+ //# sourceMappingURL=loops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loops.d.ts","sourceRoot":"","sources":["../../../src/core/parse/loops.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAK5G,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAM1C;;;;;;;GAOG;AAEH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,cAAc,CA8BpF;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAKlE"}
@@ -0,0 +1,78 @@
1
+ import { makeNode } from '../ast/index.js';
2
+ import { spanning } from '../span/index.js';
3
+ import { parseBlock } from './blocks.js';
4
+ import { describeToken } from './cursor.js';
5
+ import { missingExpression, parseCondition, parseExpression } from './expressions.js';
6
+ import { takeName } from './names.js';
7
+ import { finishStatement } from './statements.js';
8
+ /**
9
+ * `for` and `while`, language.md 10.3 and 10.4.
10
+ *
11
+ * There are two loop forms and no third, so a header that is neither is OS1020
12
+ * rather than a cascade of smaller complaints: the message names the two shapes
13
+ * that exist, which is the only thing the reader needs. The body is read either
14
+ * way, so the lines under a header that was not understood are still checked.
15
+ */
16
+ export function parseForStatement(cursor) {
17
+ const keyword = cursor.advance();
18
+ const variable = takeName(cursor);
19
+ if (cursor.take('in') !== undefined) {
20
+ const iterable = parseExpression(cursor);
21
+ const body = readBody(cursor, keyword);
22
+ return makeNode('forInStatement', spanning(keyword.span, body.span), {
23
+ variable,
24
+ iterable,
25
+ body,
26
+ });
27
+ }
28
+ if (cursor.take('=') === undefined) {
29
+ incompleteHeader(cursor);
30
+ return range(cursor, keyword, variable, missingExpression(cursor), missingExpression(cursor));
31
+ }
32
+ const from = parseExpression(cursor);
33
+ if (cursor.take('to') === undefined) {
34
+ incompleteHeader(cursor);
35
+ return range(cursor, keyword, variable, from, missingExpression(cursor));
36
+ }
37
+ const to = parseExpression(cursor);
38
+ // A missing `step` is one rather than a node the reader did not write, so
39
+ // OS3004 on a step of zero always has a span to point at (10.3).
40
+ const step = cursor.take('step') !== undefined ? parseExpression(cursor) : undefined;
41
+ return range(cursor, keyword, variable, from, to, step);
42
+ }
43
+ export function parseWhileStatement(cursor) {
44
+ const keyword = cursor.advance();
45
+ const condition = parseCondition(cursor);
46
+ const body = readBody(cursor, keyword);
47
+ return makeNode('whileStatement', spanning(keyword.span, body.span), { condition, body });
48
+ }
49
+ function range(cursor, keyword, variable, from, to, step) {
50
+ const body = readBody(cursor, keyword);
51
+ return makeNode('forRangeStatement', spanning(keyword.span, body.span), {
52
+ variable,
53
+ from,
54
+ to,
55
+ step,
56
+ body,
57
+ });
58
+ }
59
+ /**
60
+ * The block under a loop header, with the loop counted while it is read.
61
+ *
62
+ * The count is what `break` and `continue` ask about, so it has to go up before
63
+ * the body is parsed and down after it, including on the paths where the header
64
+ * itself was not understood: a `break` inside a broken `for` is still inside a
65
+ * loop, and reporting OS1009 on it would be a second complaint about the first
66
+ * mistake.
67
+ */
68
+ function readBody(cursor, keyword) {
69
+ finishStatement(cursor);
70
+ cursor.enterLoop();
71
+ const body = parseBlock(cursor, keyword.text, keyword.span);
72
+ cursor.leaveLoop();
73
+ return body;
74
+ }
75
+ function incompleteHeader(cursor) {
76
+ cursor.report('OS1020', cursor.token.span, { token: describeToken(cursor.token) });
77
+ }
78
+ //# sourceMappingURL=loops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loops.js","sourceRoot":"","sources":["../../../src/core/parse/loops.ts"],"names":[],"mappings":"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"}