Massive: completed parser and show

Now parse and show finally works properly.  Now I have to do the laws,
fun part.
This commit is contained in:
Pranshu Sharma 2025-05-19 22:54:13 +10:00
parent 549fecacfc
commit 953c0d2298

View file

@ -124,6 +124,59 @@ data Atom = Var VarName | Con ConName [Expr]
type VarName = String
type ConName = String
-- Main parsing
{-
Example:
map (f . g) . foo f g . (bar * bar)
-}
expr :: Parser Expr
expr = simple >>= rest
where
rest l = do op <- operator
r <- simple
return (Compose [Con op [l, r]])
<|> return l
operator :: Parser String
operator = do op <- token (some (sat symbolic))
guard (op /= "." && op /= "=")
return op
symbolic = (`elem` symbolic_ops)
symbolic_ops = "!@#$%^&*+./<=>?\\^|:-~"
simple :: Parser Expr
simple = do es <- somewith (symbol ".") term
return (Compose (concatMap deCompose es))
deCompose :: Expr -> [Atom]
deCompose (Compose at) = at
term :: Parser Expr
term = ident args <|> paren expr
args = many (ident none <|> paren expr)
ident :: Parser [Expr] -> Parser Expr
ident args =
do x <- token (some (sat isAlphaNum))
guard (isAlpha (head x))
if isVar x
then return (Compose [Var x])
else if (x == "id")
then return (Compose [])
else do as <- args
return (Compose [Con x as])
isVar [x] = True
isVar [x,d] = isDigit d
isVar _ = False
-- Showing
instance Show Expr where
showsPrec p (Compose []) = showString "id"
showsPrec p (Compose [a]) = showsPrec p a
@ -154,48 +207,3 @@ intersperse :: a -> [a] -> [a]
intersperse _ [x] = [x]
intersperse s (x : xs)
= x : s : intersperse s xs
-- Main parsing
expr :: Parser Expr
expr = simple >>= rest
where
rest l = do op <- operator
r <- simple
return (Compose [Con op [l, r]])
<|> return l
operator :: Parser String
operator = do op <- token (some (sat symbolic))
guard (op /= "." && op /= "=")
return op
symbolic = (`elem` symbolic_ops)
symbolic_ops = "!@#$%^&*+./<=>?\\^|:-~"
simple :: Parser Expr
simple = do es <- somewith (symbol ".") term
return (Compose (concatMap deCompose es))
term :: Parser Expr
term = ident args <|> paren expr
args = many (ident none <|> paren expr)
deCompose :: Expr -> [Atom]
deCompose (Compose at) = at
ident :: Parser [Expr] -> Parser Expr
ident args =
do x <- token (some (sat isAlphaNum))
guard (isAlpha (head x))
if isVar x
then return (Compose [Var x])
else if (x == "id")
then return (Compose [])
else do as <- args
return (Compose [Con x as])
isVar [x] = True
isVar [x,d] = isDigit d
isVar _ = False