Index: t/02atoms.t =================================================================== --- t/02atoms.t (revision 266) +++ t/02atoms.t (working copy) @@ -25,6 +25,20 @@ eval ' $bar = %MY::<$foo> '; todo_ok ($bar, 'hash deref on lexical scope'); +my $str; +eval '$str = "hello"'; +ok($str eq 'hello', "basic quote"); +eval '$str = qq[world]'; +ok($str eq 'world', "qq bracket"); +eval '$str = qq{hello}'; +ok($str eq 'hello', "qq brace"); +eval '$str = qq'; +ok($str eq 'world', "qq angle"); +eval '$str = qq>hello<'; +ok($str eq 'hello', "qq backwards angle"); +eval '$str = qq/world/'; +ok($str eq 'world', "qq slash"); + my @array; eval ' @array = qw/"foo" "bar"/ '; ok(@array, 'qw//'); Index: src/Lexer.hs =================================================================== --- src/Lexer.hs (revision 266) +++ src/Lexer.hs (working copy) @@ -55,6 +55,7 @@ braces = P.braces perl6Lexer brackets = P.brackets perl6Lexer angles = P.angles perl6Lexer +balanced = P.balanced perl6Lexer symbol s | isWordAny (last s) = try $ do Index: src/Parser.hs =================================================================== --- src/Parser.hs (revision 266) +++ src/Parser.hs (working copy) @@ -623,7 +623,7 @@ qqLiteral = try $ do string "qq" - str <- brackets (many $ satisfy (/= ']')) + str <- balanced return $ Val (VStr str) namedLiteral n v = do { symbol n; return $ Val v } Index: src/Rule/Token.hs =================================================================== --- src/Rule/Token.hs (revision 266) +++ src/Rule/Token.hs (working copy) @@ -72,6 +72,7 @@ , brackets :: forall a. CharParser st a -> CharParser st a -- "squares" is deprecated , squares :: forall a. CharParser st a -> CharParser st a + , balanced :: CharParser st String , semi :: CharParser st String , comma :: CharParser st String @@ -112,6 +113,7 @@ , angles = angles , brackets = brackets , squares = brackets + , balanced = balanced , semi = semi , comma = comma , colon = colon @@ -126,11 +128,31 @@ ----------------------------------------------------------- -- Bracketing ----------------------------------------------------------- + parens p = between (symbol "(") (symbol ")") p braces p = between (symbol "{") (symbol "}") p angles p = between (symbol "<") (symbol ">") p brackets p = between (symbol "[") (symbol "]") p + balancedDelim :: Char -> Char + balancedDelim c = case c of + '(' -> ')' + ')' -> '(' + '{' -> '}' + '}' -> '{' + '<' -> '>' + '>' -> '<' + '[' -> ']' + ']' -> '[' + _ -> c + + -- balanced: parses an open/close delimited expression of any non-alphanumeric character + balanced = do notFollowedBy alphaNum + opendelim <- anyChar + contents <- many $ satisfy (/= balancedDelim opendelim) + char $ balancedDelim opendelim + return contents + semi = symbol ";" comma = symbol "," dot = symbol "."