From e3ff59c30366f1888441ab0fe4d77a06504269f3 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Sun, 20 Sep 2009 14:18:19 -0500 Subject: [PATCH] the last character on a multiline string cannot be a backslash --- core/strings/parser/parser-tests.factor | 9 ++++++- core/strings/parser/parser.factor | 32 +++++++++++++++++++------ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/core/strings/parser/parser-tests.factor b/core/strings/parser/parser-tests.factor index c7ce142269..c9e5fe1aca 100644 --- a/core/strings/parser/parser-tests.factor +++ b/core/strings/parser/parser-tests.factor @@ -1,4 +1,5 @@ -USING: strings.parser tools.test ; +USING: accessors eval strings.parser strings.parser.private +tools.test ; IN: strings.parser.tests [ "Hello\n\rworld" ] [ "Hello\\n\\rworld" unescape-string ] unit-test @@ -12,3 +13,9 @@ IN: strings.parser.tests [ "Hello\n\rworld\n" "hi" ] [ """Hello\n\rworld """ """hi""" ] unit-test [ "Hello\n\rworld\"" "hi" ] [ """Hello\n\rworld\"""" """hi""" ] unit-test + +[ + "\"\"\"Hello\n\rworld\\\n\"\"\"" eval( -- obj ) +] [ + error>> escaped-char-expected? +] must-fail-with diff --git a/core/strings/parser/parser.factor b/core/strings/parser/parser.factor index 22b84c830e..e25b640db8 100644 --- a/core/strings/parser/parser.factor +++ b/core/strings/parser/parser.factor @@ -91,11 +91,26 @@ name>char-hook [ : rest-of-line ( -- seq ) lexer get [ line-text>> ] [ column>> ] bi tail-slice ; +: current-char ( lexer -- ch ) + [ column>> ] [ line-text>> ] bi nth ; + +: advance-char ( lexer -- ) + [ 1 + ] change-column drop ; + +ERROR: escaped-char-expected ; + +: next-char ( lexer -- ch ) + dup still-parsing-line? [ + [ current-char ] [ advance-char ] bi + ] [ + escaped-char-expected + ] if ; + : parse-escape ( i -- ) lexer-advance % CHAR: \ , lexer get - [ [ 2 + ] change-column drop ] - [ [ column>> 1 - ] [ line-text>> ] bi nth , ] bi ; + [ advance-char ] + [ next-char , ] bi ; : next-string-line ( obj -- ) drop rest-of-line % @@ -135,15 +150,18 @@ DEFER: (parse-long-string) unexpected-eof ] if ; -PRIVATE> - : parse-long-string ( string -- string' ) - [ (parse-long-string) ] "" make unescape-string ; + [ (parse-long-string) ] "" make ; + +: parse-long-string-escaped ( string -- string' ) + parse-long-string unescape-string ; + +PRIVATE> : parse-multiline-string ( -- string ) rest-of-line "\"\"" head? [ lexer get [ 2 + ] change-column drop - "\"\"\"" parse-long-string + "\"\"\"" parse-long-string-escaped ] [ - "\"" parse-long-string + "\"" parse-long-string-escaped ] if ;