Skip to content

Commit 121ed74

Browse files
author
Pascal "Pixel" Rigaux
committed
1 parent 66c3a4f commit 121ed74

File tree

5 files changed

+45
-15
lines changed

5 files changed

+45
-15
lines changed

Perl5Parser/Lines.hs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Perl5Parser.Types
66
import Perl5Parser.ParserHelper
77
import Perl5Parser.Term
88
import Perl5Parser.Expr
9+
import Perl5Parser.Prototype
910
import qualified Perl5Parser.Token
1011
import qualified Perl5Parser.Token.Number
1112

@@ -40,29 +41,42 @@ format = newNode"format"$ seQ
4041
spaces_comments_token
4142
]
4243

43-
sub_declaration = newNode"Statement::Sub"$ seQ
44-
[ try$ seQ [ symbol_ "sub", toNodes$ Perl5Parser.Token.p_Ident_sure ] -- ^ try needed for anonymous_sub
45-
, prototype
46-
, subattrlist
47-
, block <|> op ";"
48-
]
44+
sub_declaration = newNode"Statement::Sub" p
45+
where p = do (ident, l1) <- try sub_xxx -- ^ try needed for anonymous_sub
46+
(proto, l2) <- option_prototype
47+
case proto of
48+
Nothing -> return ()
49+
Just proto -> set_prototype ident proto
50+
l3 <- subattrlist
51+
l4 <- block <|> op ";"
52+
return (l1 ++ l2 ++ l3 ++ l4)
53+
sub_xxx = do l1 <- symbol_ "sub"
54+
(fq, i) <- Perl5Parser.Token.p_Ident_sure_raw
55+
l2 <- spaces_comments_token
56+
return ((fq, i), l1 ++ [Tokens (Ident fq i : l2)])
57+
4958

5059
scheduled_declaration = newNode"Statement::Scheduled"$ seQ
5160
[ choice $ map local_ident [ "BEGIN", "CHECK", "INIT", "END", "AUTOLOAD" ] -- ^ cf AutoLoader.pm for such an AUTOLOAD example
52-
, prototype
61+
, fmap snd option_prototype
5362
, subattrlist
5463
, block <|> op ";"
5564
]
5665

5766
anonymous_sub = newNode"anonymous_sub"$ seQ
5867
[ notFollowedBy_ (string "=>") (symbol_ "sub")
59-
, prototype
68+
, fmap snd option_prototype
6069
, subattrlist
6170
, block
6271
]
6372

64-
prototype = option [] (toNodes $ pcons prototype_ spaces_comments_token)
65-
where prototype_ = fmap Prototype $ seQ [ charl '(' , anyTill (charl ')') ]
73+
option_prototype = option (Nothing, []) prototype
74+
prototype :: Perl5Parser (Maybe String, [Node])
75+
prototype = do char '('
76+
proto <- many (satisfy (/= ')'))
77+
char ')'
78+
l <- spaces_comments_token
79+
return (Just proto, [Tokens (Prototype proto : l)])
6680

6781
subattrlist = option [] (toNodes Perl5Parser.Token.p_Attributes)
6882
package = newNode"package"$ pcons (symbol_node "package") (toNodes Perl5Parser.Token.p_Ident)

Perl5Parser/Prototype.hs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module Perl5Parser.Prototype
22
( parse_prototype
33
, get_prototype
4+
, set_prototype
45
, builtin_prototypes
56
, filetest_functions
67
) where
@@ -18,6 +19,16 @@ get_prototype (LocalIdent, f) = do state <- getState
1819
get_prototype (fq, f) = do state <- getState
1920
return$ Map.lookup (fq_canonical fq, f) (per_pkg_prototypes (prototypes state))
2021

22+
updatePrototypes :: (Prototypes -> Prototypes) -> Perl5Parser ()
23+
updatePrototypes f = updateState (\state -> state { prototypes = f (prototypes state) })
24+
25+
set_prototype :: (IdentT, String) -> String -> Perl5Parser ()
26+
set_prototype (LocalIdent, f) proto = updatePrototypes update
27+
where update protos = protos { local_prototypes = Map.insert f proto (local_prototypes protos) }
28+
set_prototype (fq, f) proto = updatePrototypes update
29+
where update protos = protos { per_pkg_prototypes = Map.insert (fq_canonical fq, f) proto (per_pkg_prototypes protos) }
30+
31+
2132

2233
parse_prototype :: String -> Maybe (Int, Int)
2334
parse_prototype = parse parser () ""

Perl5Parser/Serialize.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ instance Serialize TokenT where
4848
verbatim (Word s) = s
4949
verbatim (SpaceComment l) = verbatim l
5050
verbatim (PictureFormat s) = s
51-
verbatim (Prototype s) = s
51+
verbatim (Prototype s) = "(" ++ s ++ ")"
5252
verbatim (Ident fq i) = to_s_IdentT fq ++ i
5353
verbatim (Symbol s) = s
5454
verbatim (Operator s) = s

Perl5Parser/Token.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module Perl5Parser.Token
33
, p_Pod
44
, p_Label
55
, p_Attributes
6-
, p_Ident, p_Ident_sure, p_Ident_raw, p_Filetest_raw
6+
, p_Ident, p_Ident_sure, p_Ident_raw, p_Ident_sure_raw, p_Filetest_raw
77
) where
88

99
import Perl5Parser.Common
@@ -44,13 +44,13 @@ p_Ident = pcons (fmap (\(pkg, i) -> Ident pkg i) p_Ident_raw) spaces_comments_to
4444

4545
-- | same as p_Ident with also 'b (::b)
4646
p_Ident_sure :: Perl5Parser [TokenT]
47-
p_Ident_sure = pcons (fmap (\(pkg, i) -> Ident pkg i) p_Ident_raw_sure) spaces_comments_token
47+
p_Ident_sure = pcons (fmap (\(pkg, i) -> Ident pkg i) p_Ident_sure_raw) spaces_comments_token
4848

4949
p_Ident_raw :: Perl5Parser (IdentT, String)
5050
p_Ident_raw = fmap to_Ident (p_Ident_raw_sep1 "" <|> p_Ident_raw_word word_raw)
5151

52-
p_Ident_raw_sure :: Perl5Parser (IdentT, String)
53-
p_Ident_raw_sure = fmap to_Ident (p_Ident_raw_seps "" <|> p_Ident_raw_word word_raw)
52+
p_Ident_sure_raw :: Perl5Parser (IdentT, String)
53+
p_Ident_sure_raw = fmap to_Ident (p_Ident_raw_seps "" <|> p_Ident_raw_word word_raw)
5454

5555
p_Ident_raw_word p = do w <- p
5656
p_Ident_raw_sep1 w <|> p_Ident_raw_sep2 w <|> return ([], w)

test.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,14 @@ ok_exprs = [
123123
, ("/\\//", "/\\//")
124124
, ("$s =~ s {1} {2}", "$s =~ s {1} {2}")
125125
, ("s:^f::", "s:^f::")
126+
-- various
127+
, ("foo: 1", "foo: 1")
126128
, ("`foo`", "`foo`")
127129
, ("our $z = 1", "(our $z )= 1")
128130
, ("our $z : unique = 1", "(our $z : unique )= 1")
131+
, ("f + 2, 3; sub f () {} f + 2, 3", "f ((+ 2), 3); sub f () {} ((f )+ 2), 3")
132+
, ("f + 2, 3; sub f ($) {} f + 2, 3", "f ((+ 2), 3); sub f ($) {} (f (+ 2)), 3")
133+
, ("sub ff($\\@%) {}", "sub ff($\\@%) {}")
129134
-- weird function calls or keyword disambiguation
130135
, ("map {1}&a", "map {(1)}((&a))")
131136
, ("eval {1}&a", "(eval {(1)})&a")

0 commit comments

Comments
 (0)