From cda64ae4e38c4cc4f2d721c798515c9a36833e44 Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Wed, 5 Jun 2019 22:59:34 +0100 Subject: [PATCH] Parse for loops Watch out for the <++: this tries to parse whatever is on the left first, and then only if it fails tries whatever is on the right. This is different from <|>, which will include both in all the possible final parsings. --- AST.hs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/AST.hs b/AST.hs index ae18a52..b019a2a 100644 --- a/AST.hs +++ b/AST.hs @@ -2,13 +2,14 @@ module AST where import Data.Char import Text.Read -import Text.ParserCombinators.ReadP hiding ((+++), choice) +import Text.ParserCombinators.ReadP hiding ((+++), (<++), choice) data Expr = Num Double | Var String | BinOp BinOp Expr Expr | Call String [Expr] | If Expr Expr Expr + | For String Expr Expr (Maybe Expr) Expr deriving Show data BinOp = Add | Sub | Mul | Cmp Ordering @@ -19,6 +20,7 @@ instance Read Expr where , parseVar , parseCall , parseIf + , parseFor , parseBinOp "<" 10 (Cmp LT) , parseBinOp ">" 10 (Cmp GT) , parseBinOp "==" 10 (Cmp EQ) @@ -47,6 +49,18 @@ instance Read Expr where spaced $ string "else" elseE <- readPrec return (If cond thenE elseE) + parseFor = do + spaced $ string "for" + identifier <- lift (munch1 isAlpha) + spaced $ char '=' + start <- readPrec + spaced $ char ',' + cond <- readPrec + stp <- (spaced (char ',') >> Just <$> step readPrec) + <++ pure Nothing + spaced $ string "in" + body <- readPrec + return (For identifier start cond stp body) spaced f = lift $ skipSpaces >> f >> skipSpaces data Prototype = Prototype String [String] -- 2.30.2