Skip to content

Instantly share code, notes, and snippets.

@weepy
Created January 27, 2010 14:49
Show Gist options
  • Save weepy/287890 to your computer and use it in GitHub Desktop.
Save weepy/287890 to your computer and use it in GitHub Desktop.
def expand input
quote = nil
prev = nil
prevprev = nil
escape = "\\"
dq = "\""
sq = "'"
state = "code"
string = ""
ret = ""
interp = ""
braces = nil
interp_quote = nil
add_bracket = false
code = "#"
add_brackets = false
input.split("").each do |ch|
case state
when "code"
if (ch == dq || ch == sq) && prev != escape
quote = ch
state = "string"
string = ch
else
ret += ch
end
when "string"
if ch == "{" && prevprev != escape && prev == code
state = "interp"
interp = ""
braces = 1
interp_quote = nil
string = string.slice(0,string.length - 1)
elsif ch == quote && prev != escape
state = "code"
ret = ret + string + ch # nothing for the minute !
ret += ")" if add_bracket && add_brackets
add_bracket = false
string = ""
quote = nil
elsif prev==code && prevprev != escape && ch.match(/[a-zA-Z_\$]/)
state = "interp_var"
interp = ch
string = string.slice(0,string.length - 1)
else
string += ch
end
when "interp_var"
if ch.match(/[a-zA-Z_\$0-9]/)
interp += ch
else
string += "#{quote}+(#{interp})+#{quote}"
interp = ""
state = "string"
end
when "interp"
if interp_quote
if ch == interp_quote && prev != escape
interp_quote = nil
end
else
if ch == "{"
braces += 1
elsif ch == "}"
braces -= 1
elsif (ch == dq || ch == sq) && prev != escape
interp_quote = ch
end
end
if braces == 0
if add_brackets
string = "(" + string + "#{quote})+(#{interp})+(#{quote}"
else
string = string + "#{quote}+(#{interp})+#{quote}"
end
add_bracket = true
interp_quote = nil
state = "string"
else
interp += ch
end
end
prevprev = prev
prev = ch
end
ret
end
def exterpolate string
puts "in: " + string
while true
expanded = expand(string)
if expanded == string
puts "out: " + string
puts
return expanded
end
string = expanded
#puts "transform => " + string
end
end
coffee =<<EOF
x: "1 + 2"
x: "1 + \\"2"
y: "1 + ${x}"
y: "1 + $myvar + $someothervar \\${helo}"
y: "1 + \\${x}"
z: "2 + ${fn ? 3 : 2} + etc"
"1 + ${x}"
z: "${join({a:1})} + etc"
z: '${join({a:1})}'
z: '1 + ${if x then join {a: "hello"} }'
z: '1 + ${ {a: "hel${X}lo"}.keys }'
z: '${"${"${"${"${"${"hello!"}"}"}"}"}"}'
z: "${{}"
z: "hello: ${\}}"
'"${x ? y : "${z || '${1 + "${2}" + 1}'}" }"'
EOF
coffee.gsub("$", "#").split("\n").each do |line|
exterpolate(line)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment