73 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Factor
		
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Factor
		
	
	
! Copyright (C) 2008 Slava Pestov.
 | 
						|
! See http://factorcode.org/license.txt for BSD license.
 | 
						|
USING: kernel assocs namespaces make splitting sequences
 | 
						|
strings math.parser lexer accessors ;
 | 
						|
IN: strings.parser
 | 
						|
 | 
						|
ERROR: bad-escape ;
 | 
						|
 | 
						|
: escape ( escape -- ch )
 | 
						|
    H{
 | 
						|
        { CHAR: a  CHAR: \a }
 | 
						|
        { CHAR: e  CHAR: \e }
 | 
						|
        { CHAR: n  CHAR: \n }
 | 
						|
        { CHAR: r  CHAR: \r }
 | 
						|
        { CHAR: t  CHAR: \t }
 | 
						|
        { CHAR: s  CHAR: \s }
 | 
						|
        { CHAR: \s CHAR: \s }
 | 
						|
        { CHAR: 0  CHAR: \0 }
 | 
						|
        { CHAR: \\ CHAR: \\ }
 | 
						|
        { CHAR: \" CHAR: \" }
 | 
						|
    } at [ bad-escape ] unless* ;
 | 
						|
 | 
						|
SYMBOL: name>char-hook
 | 
						|
 | 
						|
name>char-hook global [
 | 
						|
    [ "Unicode support not available" throw ] or
 | 
						|
] change-at
 | 
						|
 | 
						|
: unicode-escape ( str -- ch str' )
 | 
						|
    "{" ?head-slice [
 | 
						|
        CHAR: } over index cut-slice
 | 
						|
        [ >string name>char-hook get call ] dip
 | 
						|
        rest-slice
 | 
						|
    ] [
 | 
						|
        6 cut-slice [ hex> ] dip
 | 
						|
    ] if ;
 | 
						|
 | 
						|
: next-escape ( str -- ch str' )
 | 
						|
    "u" ?head-slice [
 | 
						|
        unicode-escape
 | 
						|
    ] [
 | 
						|
        unclip-slice escape swap
 | 
						|
    ] if ;
 | 
						|
 | 
						|
: (parse-string) ( str -- m )
 | 
						|
    dup [ "\"\\" member? ] find dup [
 | 
						|
        [ cut-slice [ % ] dip rest-slice ] dip
 | 
						|
        dup CHAR: " = [
 | 
						|
            drop from>>
 | 
						|
        ] [
 | 
						|
            drop next-escape [ , ] dip (parse-string)
 | 
						|
        ] if
 | 
						|
    ] [
 | 
						|
        "Unterminated string" throw
 | 
						|
    ] if ;
 | 
						|
 | 
						|
: parse-string ( -- str )
 | 
						|
    lexer get [
 | 
						|
        [ swap tail-slice (parse-string) ] "" make swap
 | 
						|
    ] change-lexer-column ;
 | 
						|
 | 
						|
: (unescape-string) ( str -- str' )
 | 
						|
    dup [ CHAR: \\ = ] find [
 | 
						|
        cut-slice [ % ] dip rest-slice
 | 
						|
        next-escape [ , ] dip
 | 
						|
        (unescape-string)
 | 
						|
    ] [
 | 
						|
        drop %
 | 
						|
    ] if ;
 | 
						|
 | 
						|
: unescape-string ( str -- str' )
 | 
						|
    [ (unescape-string) ] "" make ;
 |