[ "\"abc" eval( -- string ) ] [ error>> "Unterminated string" = ] must-fail-with
[ "\"abc\n\n" eval( -- string ) ] [ error>> "Unterminated string" = ] must-fail-with
+[ "\"hello\"length" eval( -- string ) ] [ error>> "Invalid string" = ] must-fail-with
+
{ "\"\\" } [ "\"\\" ] unit-test
{ "\e" } [ "\u00001b" ] unit-test
: find-next-token ( lexer -- i elt )
{ lexer } declare
[ column>> ] [ line-text>> ] bi
- [ "\"\\" member? ] find-from ;
+ [ "\"\\" member-eq? ] find-from ;
DEFER: (parse-string)
: parse-found-token ( accum lexer i elt -- )
{ sbuf lexer fixnum fixnum } declare
[ over lexer-subseq pick push-all ] dip
- CHAR: \ = [
+ CHAR: \ eq? [
dup dup [ next-char ] bi@
[ [ pick push ] bi@ ]
[ drop 2dup next-line% ] if*
(parse-string)
] [
- advance-char drop
+ dup advance-char
+ dup current-char forbid-tab {
+ { CHAR: \s [ advance-char ] }
+ { f [ drop ] }
+ [ "Invalid string" throw ]
+ } case drop
] if ;
-
+
: (parse-string) ( accum lexer -- )
{ sbuf lexer } declare
dup still-parsing? [
"Unterminated string" throw
] if ;
-: rewind-lexer-on-error ( quot -- )
- lexer get [ line>> ] [ line-text>> ] [ column>> ] tri
- [
- lexer get [ column<< ] [ line-text<< ] [ line<< ] tri
- rethrow
- ] 3curry recover ; inline
-
PRIVATE>
: parse-string ( -- str )
- [
- SBUF" " clone [
- lexer get (parse-string)
- ] keep unescape-string
- ] rewind-lexer-on-error ;
+ SBUF" " clone [
+ lexer get (parse-string)
+ ] keep unescape-string ;