()
| 277 | } |
| 278 | |
| 279 | private parsePrefix(): Json { |
| 280 | const t = this.next(); |
| 281 | if (t.kind === 'pattern') { |
| 282 | // `a_` → ["Blank","a"], `x_Symbol` → ["Blank","x","Symbol"], |
| 283 | // `b_.` → ["BlankOptional","b"], `_` → ["Blank",""] |
| 284 | const node: Json[] = [ |
| 285 | t.optional ? 'BlankOptional' : 'Blank', |
| 286 | mapSymbol(t.name), |
| 287 | ]; |
| 288 | if (t.head) node.push(t.head); |
| 289 | return this.parsePostfix(node); |
| 290 | } |
| 291 | if (t.kind === 'punct') { |
| 292 | if (t.value === '-') { |
| 293 | const arg = this.parseExpression(PREC_UNARY_MINUS + 1); |
| 294 | return negate(arg); |
| 295 | } |
| 296 | if (t.value === '+') return this.parseExpression(PREC_UNARY_MINUS + 1); |
| 297 | if (t.value === '!') return ['Not', this.parseExpression(PREC_NOT + 1)]; |
| 298 | if (t.value === '(') { |
| 299 | const e = this.parseExpression(0); |
| 300 | this.expect(')'); |
| 301 | return this.parsePostfix(e); |
| 302 | } |
| 303 | if (t.value === '{') { |
| 304 | const items: Json[] = []; |
| 305 | if (!(this.peek()?.kind === 'punct' && this.peek()!.value === '}')) { |
| 306 | items.push(this.parseExpression(0)); |
| 307 | while (this.peek()?.kind === 'punct' && this.peek()!.value === ',') { |
| 308 | this.next(); |
| 309 | items.push(this.parseExpression(0)); |
| 310 | } |
| 311 | } |
| 312 | this.expect('}'); |
| 313 | return this.parsePostfix(['List', ...items]); |
| 314 | } |
| 315 | throw new Error(`unexpected token '${t.value}'`); |
| 316 | } |
| 317 | if (t.kind === 'number') { |
| 318 | // strip precision marks like 1.5`20 |
| 319 | const v = t.value.split('`')[0]; |
| 320 | return this.parsePostfix(v.includes('.') ? parseFloat(v) : parseInt(v)); |
| 321 | } |
| 322 | if (t.kind === 'string') return ['Str', t.value]; |
| 323 | // symbol — possibly a function call F[...] |
| 324 | return this.parsePostfix(mapSymbol(t.value), t.value); |
| 325 | } |
| 326 | |
| 327 | // Handles postfix forms after a head: calls F[a, b][c]…, Part |
| 328 | // `lst[[1]]`, and derivative marks `F'[x]`. |
no test coverage detected