RosettaCodeData/Task/S-Expressions/Icon/s-expressions.icon
Ingy döt Net b83f433714 tasks a-s
2013-04-10 23:57:08 -07:00

60 lines
1.8 KiB
Text

link ximage
procedure main()
in := "((data 'quoted data' 123 4.5) (data (!@# (4.5) '(more' 'data)')))"
# in := map(in,"'","\"") # uncomment to put back double quotes if desired
write("Input: ",image(in))
write("Structure: \n",ximage(S := string2sexp(in)))
write("Output: ",image(sexp2string(S)))
end
procedure sexp2string(S) #: return a string representing the s-expr
s := ""
every t := !S do {
if type(t) == "list" then
s ||:= "(" || trim(sexp2string(t)) || ")"
else
if upto('() \t\r\n',t) then
s ||:= "'" || t || "'"
else
s ||:= t
s ||:= " "
}
return trim(s)
end
procedure string2sexp(s) #: return a s-expression nested list
if s ? ( sexptokenize(T := []), pos(0) ) then
return sexpnest(T)
else
write("Malformed: ",s)
end
procedure sexpnest(T,L) #: transform s-expr token list to nested list
/L := []
while t := get(T) do
case t of {
"(" : {
put(L,[])
sexpnest(T,L[*L])
}
")" : return L
default : put(L, numeric(t) | t)
}
return L
end
procedure sexptokenize(T) #: return list of tokens parsed from an s-expr string
static sym
initial sym := &letters++&digits++'~`!@#$%^&*_-+|;:.,<>[]{}'
until pos(0) do
case &subject[&pos] of {
" " : tab(many(' \t\r\n')) # consume whitespace
"'"|"\"" :
(q := move(1)) & put(T,tab(find(q))) & move(1) # quotes
"(" : put(T,move(1)) & sexptokenize(T) # open
")" : put(T,move(1)) &return T # close
default : put(T, tab(many(sym))) # other symbols
}
return T
end