Skip to content

Commit b09cb60

Browse files
author
Kristian Larsson
committed
Allow underscore lambda parameters
The parser treats _ as a keyword for ordinary identifiers, but lambda parameters can use it as a throwaway name. After the Text cleanup, that path rejected call arguments containing lambda c, _, err. Accept _ through parameter parsing only, where it is valid. Keep normal identifier diagnostics unchanged and add a parser regression covering the lambda call-argument case.
1 parent c40f685 commit b09cb60

2 files changed

Lines changed: 17 additions & 4 deletions

File tree

compiler/lib/src/Acton/Parser.hs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,8 +1115,9 @@ singleStar = (lexeme . try) (char '*' <* notFollowedBy (char '*'))
11151115
identifier :: Parser Text
11161116
identifier = (lexeme . try) $ do
11171117
off <- getOffset
1118-
void $ lookAhead (satisfy (\c -> isAlpha c || c == '_') <?> "identifier")
1119-
x <- takeWhile1P (Just "identifier") (\c -> isAlphaNum c || c=='_')
1118+
c <- satisfy (\c -> isAlpha c || c == '_') <?> "identifier"
1119+
cs <- hidden (takeWhileP Nothing (\c -> isAlphaNum c || c == '_'))
1120+
let x = T.cons c cs
11201121
if S.isKeywordText x
11211122
then parseError (TrivialError off (Just (Tokens (N.fromList (T.unpack x)))) (Set.fromList [Label (N.fromList "identifier")]))
11221123
else return x
@@ -1130,6 +1131,12 @@ name = do off <- getOffset
11301131

11311132
escname = name <|> addLoc (S.name . head <$> plainstrLiteral) -- Assumes an escname cannot contain hex escape sequences
11321133

1134+
paramName :: Parser S.Name
1135+
paramName = name <|> do
1136+
off <- getOffset
1137+
rword "_"
1138+
return $ S.Name (Loc off (off + 1)) (T.singleton '_')
1139+
11331140
tvarname = do off <- getOffset
11341141
x <- identifier
11351142
if isTypeVarName x
@@ -2448,13 +2455,13 @@ yield_expr = addLoc $ do
24482455
--- Params ---------------------------------------------------------------------
24492456

24502457
parm :: Bool -> Parser (S.Name, Maybe S.Type, Maybe S.Expr)
2451-
parm ann = do n <- name
2458+
parm ann = do n <- paramName
24522459
mbt <- if ann then optional (colon *> ttype) else return Nothing
24532460
mbe <- optional (equals *> expr)
24542461
return (n, mbt, mbe)
24552462

24562463
pstar :: Bool -> Parser S.Type -> Parser (S.Name, Maybe S.Type)
2457-
pstar ann startype = do n <- name
2464+
pstar ann startype = do n <- paramName
24582465
mbt <- if ann then optional (colon *> startype) else return Nothing
24592466
return (n, mbt)
24602467

compiler/lib/test/ActonSpec.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ main = do
113113
completed `shouldSatisfy` monotonic
114114
last progress `shouldBe` (6, 6)
115115

116+
it "allows underscore parameters in lambdas" $ do
117+
let input = "def f():\n rpc(a, lambda c, _, err: cb(c, err))\n"
118+
case parseModuleTest input of
119+
Left err -> expectationFailure $ "Parse failed: " ++ err
120+
Right _ -> return ()
121+
116122
describe "Basic Syntax" $ do
117123
testParse env0 ["syntax1"]
118124

0 commit comments

Comments
 (0)