60 lines
1.8 KiB
Text
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
|