Skip to content

Commit

Permalink
add: dynamic For loops
Browse files Browse the repository at this point in the history
  • Loading branch information
oriollinan committed Jan 16, 2025
1 parent 279358e commit 723d679
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 48 deletions.
15 changes: 8 additions & 7 deletions lib/Ast/Parser/Expr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ parseTerm =
M.choice
[ parseIf,
parseWhile,
parseFor,
parseFrom,
parseReturn,
parseBreak,
parseContinue,
Expand Down Expand Up @@ -197,16 +197,17 @@ parseWhile = do
body <- parseBlock id
return $ AT.While {AT.whileLoc = srcLoc, AT.whileCond = cond, AT.whileBody = body}

parseFor :: PU.Parser AT.Expr
parseFor = do
parseFrom :: PU.Parser AT.Expr
parseFrom = do
srcLoc <- PU.parseSrcLoc
start <- PU.symbol "from" *> PU.lexeme parseExpr
end <- PU.symbol "to" *> PU.lexeme parseExpr
step <- M.optional $ M.try $ PU.symbol "by" *> PU.lexeme parseExpr
(name, type') <- M.between (PU.symbol "|") (PU.symbol "|") $ do
name <- PU.identifier
type' <- PU.symbol ":" *> PT.parseType
return (name, type')
(name, type') <-
M.between (PU.symbol "[") (PU.symbol "]") $ do
name <- PU.identifier
type' <- PU.symbol ":" *> PT.parseType
return (name, type')
let var = AT.Declaration srcLoc name type' $ Just start
S.modify (PS.insertVar name type')
body <- parseBlock id
Expand Down
65 changes: 24 additions & 41 deletions test/Ast/Parser/ExprSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ spec = do
(PU.normalizeExpr <$> result) `shouldBe` expected

it "parses a for loop" $ do
let input = "from 0 to 10 by 2 |i: int| { i = 0 }"
let input = "from 0 to 10 by 2 [i: int] { i = 0 }"
let env = PS.parserState
result <- parseWithCustom env input
let startValue = AT.Lit PU.normalizeLoc $ AT.LInt 0
Expand All @@ -258,46 +258,29 @@ spec = do
)
(PU.normalizeExpr <$> result) `shouldBe` expected

-- it "parses a for loop with a dynamic range" $ do
-- let input = "from 0 to 10 by x |i: int| { i = 0 }"
-- let env = PS.insertVar "x" (AT.TInt 32) PS.parserState
-- result <- parseWithCustom env input
-- let expected =
-- Right $
-- AT.For
-- { AT.forLoc = PU.normalizeLoc,
-- AT.forInit =
-- AT.Declaration
-- PU.normalizeLoc
-- "i"
-- (AT.TInt 32)
-- (Just (AT.Lit PU.normalizeLoc (AT.LInt 0))),
-- AT.forCond =
-- AT.Op
-- PU.normalizeLoc
-- AT.Lt
-- (AT.Var PU.normalizeLoc "i" (AT.TInt 32))
-- (AT.Lit PU.normalizeLoc (AT.LInt 10)),
-- AT.forStep =
-- AT.Assignment
-- PU.normalizeLoc
-- (AT.Var PU.normalizeLoc "i" (AT.TInt 32))
-- ( AT.Op
-- PU.normalizeLoc
-- AT.Add
-- (AT.Var PU.normalizeLoc "i" (AT.TInt 32))
-- (AT.Var PU.normalizeLoc "x" (AT.TInt 32))
-- ),
-- AT.forBody =
-- AT.Block
-- [ AT.Assignment
-- PU.normalizeLoc
-- (AT.Var PU.normalizeLoc "i" (AT.TInt 32))
-- ( AT.Lit PU.normalizeLoc (AT.LInt 0)
-- )
-- ]
-- }
-- (PU.normalizeExpr <$> result) `shouldBe` expected
it "parses a for loop with a dynamic range" $ do
let input = "from 0 to 10 by x [i: int] { i = 0 }"
let var = AT.Var PU.normalizeLoc "x" (AT.TInt 32)
let env = PS.insertVar "x" (AT.TInt 32) PS.parserState
result <- parseWithCustom env input
let startValue = AT.Lit PU.normalizeLoc $ AT.LInt 0
let expected =
Right $
AT.From
PU.normalizeLoc
startValue
(AT.Lit PU.normalizeLoc $ AT.LInt 10)
(Just var)
(AT.Declaration PU.normalizeLoc "i" (AT.TInt 32) $ Just startValue)
( AT.Block
[ AT.Assignment
PU.normalizeLoc
(AT.Var PU.normalizeLoc "i" (AT.TInt 32))
( AT.Lit PU.normalizeLoc (AT.LInt 0)
)
]
)
(PU.normalizeExpr <$> result) `shouldBe` expected

it "parses a break statement" $ do
let input = "stop"
Expand Down

0 comments on commit 723d679

Please sign in to comment.