Skip to content

Instantly share code, notes, and snippets.

@orodio
Created August 13, 2015 01:24
Show Gist options
  • Save orodio/13e1ed9c61f5045a1dfa to your computer and use it in GitHub Desktop.
Save orodio/13e1ed9c61f5045a1dfa to your computer and use it in GitHub Desktop.
function tokenize(input) {
return input
.replace(/[\(]/g, ' ( ')
.replace(/[\)]/g, ' ) ')
.trim()
.split(/\s+/);
}
function nest(input=[], list=[]) {
let token = input.shift()
switch (token) {
case undefined:
return list.pop()
case "(":
return nest(input, [...list, nest(input)])
case ")":
return list
default:
return nest(input, [...list, token])
}
}
function toAst (tree=[], output=[]) {
if (!tree.length) return output
if (typeof tree === "string") return tree
let [current, ...otherBranches] = tree
let [t,...rest] = current
let c = [for (n of rest) if (!(typeof n === "string" && n.indexOf("->") >= 0)) n]
let p = {}
for (let n of rest) if (typeof n === "string" && n.indexOf("->") >= 0) {
let [key, value] = n.split("->")
p[key] = value.split("::")
}
return toAst(otherBranches, [...output, {t, c: toAst(c)}])
}
function Parse (doc) {
doc = `(${doc[0]})`
doc = nest(tokenize(doc))
return toAst(doc)
}
let result = Parse`
(value cursor->status value->default)
(value cursor->fields::product value->162)
(watch status default
(button onClick->submit Join For $1))
(watch status processing
(button (icon spin->true refresh) Processing...))
(watch status success
(button (icon check) Success!))
`
console.log(result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment