Detect more cases of strings being unterminated.
SOURCES_LISP = env.coffee core.coffee stepA_mal.coffee
SOURCES = $(SOURCES_BASE) $(SOURCES_LISP)
+STEPS = step0_repl.coffee step1_read_print.coffee \
+ step2_eval.coffee step3_env.coffee step4_if_fn_do.coffee \
+ step5_tco.coffee step6_file.coffee step7_quote.coffee \
+ step8_macros.coffee step9_try.coffee stepA_mal.coffee
+
all: node_modules dist
node_modules:
npm install
+$(STEPS): node_modules
+
dist: mal.coffee mal
mal.coffee: $(SOURCES)
token = rdr.next()
if token.match /^-?[0-9]+$/ then parseInt token,10
else if token.match /^-?[0-9][0-9.]*$/ then parseFloat token,10
- else if token[0] == '"'
- throw new Error "expected '\"', got EOF" if token[-1..-1] != '"'
+ else if token.match /^"(?:\\.|[^\\"])*"$/
token.slice(1, token.length-1)
.replace(/\\(.)/g, (_, c) -> if c == 'n' then '\n' else c)
+ else if token[0] == '"'
+ throw new Error "expected '\"', got EOF"
else if token[0] == ':' then types._keyword(token[1..])
else if token == "nil" then null
else if token == "true" then true
final malRegExp = new RegExp(
r"""[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"?|;.*|[^\s\[\]{}('"`,;)]*)""");
+final strRegExp = new RegExp(
+ r"""^"(?:\\.|[^\\"])*"$""");
class Reader {
final List<String> tokens;
return new MalInt(intAtom);
}
- if (token[0] == '"') {
- if (token[token.length -1 ] != '"') {
- throw new ParseException("expected '\"', got EOF");
- }
+ if (strRegExp.matchAsPrefix(token) != null) {
var sanitizedToken = token
// remove surrounding quotes
.substring(1, token.length - 1)
return new MalString(sanitizedToken);
}
+ if (token[0] == '"') {
+ throw new ParseException("expected '\"', got EOF");
+ }
+
if (token[0] == ':') {
return new MalKeyword(token.substring(1));
}
defp read_atom(":" <> rest), do: String.to_atom(rest)
defp read_atom(token) do
cond do
- String.starts_with?(token, "\"") and String.ends_with?(token, "\"") ->
+ String.match?(token, ~r/^"(?:\\.|[^\\"])*"$/) ->
token
|> Code.string_to_quoted
|> elem(1)
-}
strString : Parser s String
strString =
- regex "\"(\\\\\"|[^\"])*\"" <?> "string"
+ regex "\"(\\\\.|[^\\\\\"])*\"" <?> "string"