Skip to content

Instantly share code, notes, and snippets.

@audinue
Created December 27, 2020 11:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save audinue/3d33412181e96864d5d62bc78bde99d2 to your computer and use it in GitHub Desktop.
Save audinue/3d33412181e96864d5d62bc78bde99d2 to your computer and use it in GitHub Desktop.
function parseTokens (code) {
return code
.split(/([()]|"(?:\\.|[^"])*"|;[^\n]*|\s+)/)
.filter(token => !/^;|^\s|^$/.test(token))
}
function parseArray (tokens) {
const array = []
if (tokens.shift() !== '(') {
throw new Error(`Expected '('`)
}
while (true) {
if (!tokens.length) {
throw new Error(`Expected ')'`)
}
if (tokens[0] === '(') {
array.push(parseArray(tokens))
} else {
const token = tokens.shift()
if (token === ')') {
break
} else {
array.push(token)
}
}
}
return array
}
function renderProgram (array) {
return array
.map(renderExpression)
.join(';\n\n')
}
function renderExpression (element) {
return Array.isArray(element)
? renderCall(...element)
: element
}
function renderCall (head, ...tail) {
return `${renderExpression(head)}(${tail.map(renderExpression).join(', ')})`
}
const code = `
(console.log "Hello world!")
((console.log.bind console) "Hello world!")
`
const wrapped = `(${code})`
const tokens = parseTokens(wrapped)
const array = parseArray(tokens)
const program = renderProgram(array)
console.log(program)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment