make more compiler tests pass

This commit is contained in:
Chris Wanstrath 2025-11-25 13:27:53 -08:00 committed by Chris Wanstrath
parent 566beb87ef
commit 579d755205
5 changed files with 54 additions and 10 deletions

View File

@ -58,6 +58,7 @@ export type NodeType =
| 'Import' | 'Import'
| 'Do' | 'Do'
| 'Underscore'
| 'colon' | 'colon'
| 'keyword' | 'keyword'
| 'operator' | 'operator'
@ -272,6 +273,9 @@ class SyntaxNodeType {
case 'Do': case 'Do':
return term.Do return term.Do
case 'Underscore':
return term.Underscore
case 'colon': case 'colon':
return term.colon return term.colon
@ -355,7 +359,7 @@ export class SyntaxNode {
} }
toString(): string { toString(): string {
return this.type return this.type.name
} }
} }

View File

@ -341,7 +341,7 @@ export class Parser {
if (this.is($T.String)) if (this.is($T.String))
return this.string() return this.string()
if (this.isAny($T.Null, $T.Boolean, $T.Number, $T.Identifier, $T.Word, $T.Regex)) if (this.isAny($T.Null, $T.Boolean, $T.Number, $T.Identifier, $T.Word, $T.Regex, $T.Underscore))
return SyntaxNode.from(this.next()) return SyntaxNode.from(this.next())
const next = this.next() const next = this.next()

View File

@ -295,10 +295,10 @@ grep h`).toMatchTree(`
test('lots of pipes', () => { test('lots of pipes', () => {
expect(` expect(`
'this should help readability in long chains' 'this should help readability in long chains'
| split ' ' | split ' '
| map (ref str.to-upper) | map (ref str.to-upper)
| join '-' | join '-'
| echo | echo
`).toMatchTree(` `).toMatchTree(`
PipeExpr PipeExpr
@ -309,7 +309,7 @@ grep h`).toMatchTree(`
Identifier split Identifier split
PositionalArg PositionalArg
String String
StringFragment StringFragment (space)
operator | operator |
FunctionCall FunctionCall
Identifier map Identifier map
@ -333,3 +333,41 @@ grep h`).toMatchTree(`
`) `)
}) })
}) })
describe('Underscore', () => {
test('works in pipes', () => {
expect(`sub 3 1 | div (sub 110 9 | sub 1) _ | div 5`).toMatchTree(`
PipeExpr
FunctionCall
Identifier sub
PositionalArg
Number 3
PositionalArg
Number 1
operator |
FunctionCall
Identifier div
PositionalArg
ParenExpr
PipeExpr
FunctionCall
Identifier sub
PositionalArg
Number 110
PositionalArg
Number 9
operator |
FunctionCall
Identifier sub
PositionalArg
Number 1
PositionalArg
Underscore _
operator |
FunctionCall
Identifier div
PositionalArg
Number 5
`)
})
})

View File

@ -38,7 +38,8 @@ const valueTokens = new Set([
TokenType.Comment, TokenType.Comment,
TokenType.Keyword, TokenType.Operator, TokenType.Keyword, TokenType.Operator,
TokenType.Identifier, TokenType.Word, TokenType.NamedArgPrefix, TokenType.Identifier, TokenType.Word, TokenType.NamedArgPrefix,
TokenType.Boolean, TokenType.Number, TokenType.String, TokenType.Regex TokenType.Boolean, TokenType.Number, TokenType.String, TokenType.Regex,
TokenType.Underscore
]) ])
const operators = new Set([ const operators = new Set([
@ -337,7 +338,7 @@ export class Scanner {
// classify the token based on what we read // classify the token based on what we read
if (word === '_') if (word === '_')
this.pushChar(TokenType.Underscore) this.push(TokenType.Underscore)
else if (word === 'null') else if (word === 'null')
this.push(TokenType.Null) this.push(TokenType.Null)

View File

@ -11,7 +11,8 @@ const nodeToString = (node: SyntaxNode, input: string, depth = 0): string => {
return `${indent}${nodeName}` return `${indent}${nodeName}`
} else { } else {
// Only strip quotes from whole String nodes (legacy DoubleQuote), not StringFragment/EscapeSeq/CurlyString // Only strip quotes from whole String nodes (legacy DoubleQuote), not StringFragment/EscapeSeq/CurlyString
const cleanText = nodeName === 'String' ? text.slice(1, -1) : text let cleanText = nodeName === 'String' ? text.slice(1, -1) : text
if (cleanText === ' ') cleanText = '(space)'
return cleanText ? `${indent}${nodeName} ${cleanText}` : `${indent}${nodeName}` return cleanText ? `${indent}${nodeName} ${cleanText}` : `${indent}${nodeName}`
} }
} }