72 lines
2.2 KiB
Text
72 lines
2.2 KiB
Text
isdigit = (c): 47 < c ord and c ord < 58.
|
|
iswhitespace = (c): c ord == 10 or c ord == 13 or c == " ".
|
|
|
|
# str: a string of the form "...<nondigit>[{<symb>}]..."
|
|
# i: index to start at (must be the index of <nondigit>)
|
|
# => returns (<the symbol as a string>, <index after the last char>)
|
|
parsesymbol = (str, i) :
|
|
datum = ()
|
|
while (str(i) != "(" and str(i) != ")" and not iswhitespace(str(i)) and str(i) != "\"") :
|
|
datum append(str(i++))
|
|
.
|
|
(datum join, i)
|
|
.
|
|
|
|
# str: a string of the form "...[<minus>]{<digit>}[<dot>{<digit>}]..."
|
|
# i: index to start at (must be the index of the first token)
|
|
# => returns (<float or int>, <index after the last digit>)
|
|
parsenumber = (str, i) :
|
|
datum = ()
|
|
dot = false
|
|
while (str(i) != "(" and str(i) != ")" and not iswhitespace(str(i)) and str(i) != "\"") :
|
|
if (str(i) == "."): dot = true.
|
|
datum append(str(i++))
|
|
.
|
|
if (dot): (datum join number, i).
|
|
else: (datum join number integer, i).
|
|
.
|
|
|
|
# str: a string of the form "...\"....\"..."
|
|
# i: index to start at (must be the index of the first quote)
|
|
# => returns (<the string>, <index after the last quote>)
|
|
parsestring = (str, i) :
|
|
datum = ("\"")
|
|
while (str(++i) != "\"") :
|
|
datum append(str(i))
|
|
.
|
|
datum append("\"")
|
|
(datum join, ++i)
|
|
.
|
|
|
|
# str: a string of the form "...(...)..."
|
|
# i: index to start at
|
|
# => returns (<tuple/list>, <index after the last paren>)
|
|
parselist = (str, i) :
|
|
lst = ()
|
|
data = ()
|
|
while (str(i) != "("): i++.
|
|
i++
|
|
while (str(i) != ")") :
|
|
if (not iswhitespace(str(i))) :
|
|
if (isdigit(str(i)) or (str(i) == "-" and isdigit(str(i + 1)))): data = parsenumber(str, i).
|
|
elsif (str(i) == "\""): data = parsestring(str, i).
|
|
elsif (str(i) == "("): data = parselist(str, i).
|
|
else: data = parsesymbol(str, i).
|
|
lst append(data(0))
|
|
i = data(1)
|
|
. else :
|
|
++i
|
|
.
|
|
.
|
|
(lst, ++i)
|
|
.
|
|
|
|
parsesexpr = (str) :
|
|
parselist(str, 0)(0)
|
|
.
|
|
|
|
parsesexpr("(define (factorial x) \"compute factorial\" (version 2.0) (apply * (range 1 x)))") string print
|
|
"\n" print
|
|
parsesexpr("((data \"quoted data\" 123 4.5)
|
|
(data (!@# (4.5) \"(more\" \"data)\")))") string print
|
|
"\n" print
|