72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
import { Tree, TreeCursor } from '@lezer/common'
|
|
import { type Value, fromValue } from 'reefvm'
|
|
import { SyntaxNode } from '#parser/node'
|
|
|
|
const nodeToString = (node: SyntaxNode, input: string, depth = 0): string => {
|
|
const indent = ' '.repeat(depth)
|
|
const text = input.slice(node.from, node.to)
|
|
const nodeName = node.name
|
|
|
|
if (node.firstChild) {
|
|
return `${indent}${nodeName}`
|
|
} else {
|
|
// Only strip quotes from whole String nodes (legacy DoubleQuote), not StringFragment/EscapeSeq/CurlyString
|
|
const cleanText = nodeName === 'String' ? text.slice(1, -1) : text
|
|
return `${indent}${nodeName} ${cleanText}`
|
|
}
|
|
}
|
|
|
|
export const treeToString2 = (tree: SyntaxNode, input: string, depth = 0): string => {
|
|
let lines = []
|
|
let node: SyntaxNode | null = tree
|
|
|
|
if (node.name === 'Program') node = node.firstChild
|
|
|
|
while (node) {
|
|
lines.push(nodeToString(node, input, depth))
|
|
|
|
if (node.firstChild)
|
|
lines.push(treeToString2(node.firstChild, input, depth + 1))
|
|
|
|
node = node.nextSibling
|
|
}
|
|
|
|
return lines.join('\n')
|
|
}
|
|
|
|
export const treeToString = (tree: Tree, input: string): string => {
|
|
const lines: string[] = []
|
|
|
|
const addNode = (cursor: TreeCursor, depth: number) => {
|
|
if (!cursor.name) return
|
|
|
|
const indent = ' '.repeat(depth)
|
|
const text = input.slice(cursor.from, cursor.to)
|
|
const nodeName = cursor.name // Save the node name before moving cursor
|
|
|
|
if (cursor.firstChild()) {
|
|
lines.push(`${indent}${nodeName}`)
|
|
do {
|
|
addNode(cursor, depth + 1)
|
|
} while (cursor.nextSibling())
|
|
cursor.parent()
|
|
} else {
|
|
const cleanText = nodeName === 'String' ? text.slice(1, -1) : text
|
|
lines.push(`${indent}${nodeName} ${cleanText}`)
|
|
}
|
|
}
|
|
|
|
const cursor = tree.cursor()
|
|
if (cursor.firstChild()) {
|
|
do {
|
|
addNode(cursor, 0)
|
|
} while (cursor.nextSibling())
|
|
}
|
|
|
|
return lines.join('\n')
|
|
}
|
|
|
|
export const VMResultToValue = (result: Value): unknown => {
|
|
return result.type === 'function' ? Function : fromValue(result)
|
|
}
|