)
numberRegex := Regex with("^-?[0-9]+$")
+ stringRegex := Regex with("^\"(?:[\\\\].|[^\\\\\"])*\"$")
read_string := method(token,
- (token endsWithSeq("\"")) ifFalse(Exception raise("expected '\"', got EOF"))
placeholder := 127 asCharacter
token exSlice(1, -1) replaceSeq("\\\\", placeholder) replaceSeq("\\\"", "\"") replaceSeq("\\n", "\n") replaceSeq(placeholder, "\\")
)
(token == "false") ifTrue(return(false))
(token == "nil") ifTrue(return(nil))
(token beginsWithSeq(":")) ifTrue(return(MalKeyword with(token exSlice(1))))
- (token beginsWithSeq("\"")) ifTrue(return(read_string(token)))
+ (token hasMatchOfRegex(stringRegex)) ifTrue(return(read_string(token)))
+ (token beginsWithSeq("\"")) ifTrue(Exception raise("expected '\"', got EOF"))
MalSymbol with(token)
)
token = reader.peek!
if token in constants
{type: \const, value: reader.next!}
- else if token[0] == '"'
- if not token.endsWith '"'
- parse-error "expected '\"', got EOF"
+ else if token.match /^"(?:\\.|[^\\"])*"$/
{type: \string, value: decode-string reader.next!}
+ else if token[0] == '"'
+ parse-error "expected '\"', got EOF"
else if token.match /^-?\d+$/
{type: \int, value: parseInt reader.next!}
else if token != '~@' and token not in special_chars