Skip to content

Instantly share code, notes, and snippets.

@tiye
Created April 9, 2012 06:01
Show Gist options
  • Save tiye/2341815 to your computer and use it in GitHub Desktop.
Save tiye/2341815 to your computer and use it in GitHub Desktop.
sibliantjs 解释 S 表达式
# code from https://github.com/jbr/sibilant/blob/a5d43850eeb86d7859b04016e955a02690246f20/speech_therapist.js
ll = console.log
plat = (arr) ->
str = ''
arr = arr.map (x) ->
if typeof x is 'object'
return plat x
else return x
return "[#{arr.join ' '}]"
tokenize = (string) ->
tokens = []
parseStack = [tokens]
lp = (msg) ->
ll msg, '::', plat parseStack
acceptToken = (t) ->
lp 'acc b:'
ll 'acc <-', t
parseStack[0].push t
lp 'acc e:'
increaseNesting = ->
lp 'inc b:'
ll 'inc <-', '('
newArr = []
acceptToken newArr
parseStack.unshift newArr
lp 'inc e:'
decreaseNesting = ->
lp 'dec b:'
ll 'dec <-', ')'
parseStack.shift()
if parseStack.length is 0
throw new Error 'unbalanced parens:\n' +
sys.inspect parseStack
lp 'dec e:'
handleToken = (token) ->
if token is '(' then increaseNesting()
else if token is ')' then decreaseNesting()
else if token.match /^-?[0-9.]+$/
acceptToken (parseFloat token)
else acceptToken token
tmp = string.replace(/([^\\])\n/, '$1 ')
.replace(/\s+\\\n/, '\\n')
console.log tmp
tmp = tmp.match(///
(;.*)
| ("([^"]
| (\\"))*?[^\\]")
| [&']?[.a-z-]+
| [><=!\+\/\*-]+
| -?[0-9.]+
| ([`']?\()
| \)
///g)
console.log tmp
tmp.forEach handleToken
return tokens
str = '(+ (* (- 4 1) 5) 6)'
console.log (tokenize str)
$ coffee token.coffee
(+ (* (- 4 1) 5) 6)
[ '(', '+', '(', '*', '(', '-', '4', '1', ')', '5', ')', '6', ')' ]
inc b: :: [[]]
inc <- (
acc b: :: [[]]
acc <- []
acc e: :: [[[]]]
inc e: :: [[] [[]]]
acc b: :: [[] [[]]]
acc <- +
acc e: :: [[+] [[+]]]
inc b: :: [[+] [[+]]]
inc <- (
acc b: :: [[+] [[+]]]
acc <- []
acc e: :: [[+ []] [[+ []]]]
inc e: :: [[] [+ []] [[+ []]]]
acc b: :: [[] [+ []] [[+ []]]]
acc <- *
acc e: :: [[*] [+ [*]] [[+ [*]]]]
inc b: :: [[*] [+ [*]] [[+ [*]]]]
inc <- (
acc b: :: [[*] [+ [*]] [[+ [*]]]]
acc <- []
acc e: :: [[* []] [+ [* []]] [[+ [* []]]]]
inc e: :: [[] [* []] [+ [* []]] [[+ [* []]]]]
acc b: :: [[] [* []] [+ [* []]] [[+ [* []]]]]
acc <- -
acc e: :: [[-] [* [-]] [+ [* [-]]] [[+ [* [-]]]]]
acc b: :: [[-] [* [-]] [+ [* [-]]] [[+ [* [-]]]]]
acc <- 4
acc e: :: [[- 4] [* [- 4]] [+ [* [- 4]]] [[+ [* [- 4]]]]]
acc b: :: [[- 4] [* [- 4]] [+ [* [- 4]]] [[+ [* [- 4]]]]]
acc <- 1
acc e: :: [[- 4 1] [* [- 4 1]] [+ [* [- 4 1]]] [[+ [* [- 4 1]]]]]
dec b: :: [[- 4 1] [* [- 4 1]] [+ [* [- 4 1]]] [[+ [* [- 4 1]]]]]
dec <- )
dec e: :: [[* [- 4 1]] [+ [* [- 4 1]]] [[+ [* [- 4 1]]]]]
acc b: :: [[* [- 4 1]] [+ [* [- 4 1]]] [[+ [* [- 4 1]]]]]
acc <- 5
acc e: :: [[* [- 4 1] 5] [+ [* [- 4 1] 5]] [[+ [* [- 4 1] 5]]]]
dec b: :: [[* [- 4 1] 5] [+ [* [- 4 1] 5]] [[+ [* [- 4 1] 5]]]]
dec <- )
dec e: :: [[+ [* [- 4 1] 5]] [[+ [* [- 4 1] 5]]]]
acc b: :: [[+ [* [- 4 1] 5]] [[+ [* [- 4 1] 5]]]]
acc <- 6
acc e: :: [[+ [* [- 4 1] 5] 6] [[+ [* [- 4 1] 5] 6]]]
dec b: :: [[+ [* [- 4 1] 5] 6] [[+ [* [- 4 1] 5] 6]]]
dec <- )
dec e: :: [[[+ [* [- 4 1] 5] 6]]]
[ [ '+', [ '*', [Object], 5 ], 6 ] ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment