atomo programming language (fork of alex's atomo) — http://atomo-lang.org/
`Match new: (ts contents map: { `(~p -> ~e) | (p, e expand) })
`Match new: (ts contents map: { `(~p -> ~e) | (p, e) })
unquote n m@(EMatch { eTarget = t, eBranches = bs }) = do
nt <- unquote n t
nbs <- forM bs $ \(p, e) -> do
ne <- unquote n e
return (p, ne)
return m { eTarget = nt, eBranches = nbs }
eval (EMatch { eTarget = t, eBranches = bs }) = do
v <- eval t
ids <- gets primitives
matchBranches ids bs v
matchBranches :: IDs -> [(Pattern, Expr)] -> Value -> VM Value
matchBranches _ [] v = raise ["no-match-for"] [v]
matchBranches ids ((p, e):ps) v = do
p' <- matchable' p
if match ids Nothing p' v
then newScope $ set p' v >> eval e
else matchBranches ids ps v
import Text.PrettyPrint (Doc)
import Atomo.Pattern (match)
Expression value <- here "value" >>= findExpression
ids <- gets primitives
return . Expression . EVM Nothing (Just $ prettyMatch value (zip pats exprs)) $
eval value >>= matchBranches ids (zip ps exprs)
Expression value <- here "value" >>= findExpression
return (Expression (EMatch Nothing value (zip ps exprs)))
EMatch {} -> return (particle "match")
EMatch { eTarget = t } ->
return (Expression t)
EMatch { eBranches = bs } ->
liftM list (mapM toValue bs)
matchBranches :: IDs -> [(Pattern, Expr)] -> Value -> VM Value
matchBranches _ [] v = raise ["no-match-for"] [v]
matchBranches ids ((p, e):ps) v = do
p' <- matchable' p
if match ids Nothing p' v
then newScope $ set p' v >> eval e
else matchBranches ids ps v
prettyMatch :: Expr -> [(Expr, Expr)] -> Doc
prettyMatch t bs =
pretty . EDispatch Nothing $
keyword ["match"] [t, EBlock Nothing [] branches]
where
branches = flip map bs $ \(p, e) ->
EDispatch Nothing $ keyword ["->"] [p, e]
doPragmas (EMatch { eTarget = e, eBranches = bs }) = do
doPragmas e
forM_ bs (doPragmas . snd)
macroExpand m@(EMatch { eTarget = t, eBranches = bs }) = do
nt <- macroExpand t
nbs <- forM bs $ \(p, e) -> do
ne <- macroExpand e
return (p, ne)
return m { eTarget = nt, eBranches = nbs }
throughQuotes n f m@(EMatch { eTarget = t, eBranches = bs }) = do
nt <- throughQuotes n f t
nbs <- mapM (\(p, b) -> f n b >>= \nb -> return (p, nb)) bs
f n m { eTarget = nt, eBranches = nbs }
toMacroRole (EDispatch _ (Single { mName = "Match" })) = Just PEMatch
prettyFrom _ PEMatch = text "Match"
prettyFrom _ (EMatch _ t bs) =
prettyFrom CKeyword t <+> text "match:" <+> branches
where
branches = braces . sep . punctuate (text ";") $
flip map bs $ \(p, e) ->
pretty p <+> text "->" <+> pretty e
-- | Matches any @EMatch@ expression.
| PEMatch
| EMatch
{ eLocation :: Maybe SourcePos
, eTarget :: Expr
, eBranches :: [(Pattern, Expr)]
}
(==) PEForMacro PEForMacro = True --
(==) PEForMacro PEForMacro = True
(==) PEMacroQuote PEMacroQuote = True --
(==) PEMacroQuote PEMacroQuote = True
(==) PEMatch PEMatch = True
(==) (EMatch _ at avs) (EMatch _ bt bvs) =
at == bt && avs == bvs
lift (EMatch _ t bs) = [| EMatch Nothing t bs |]
lift PEMatch = [| PEMatch |]
instance Valuable Pattern where
toValue = return . Pattern
fromValue (Pattern x) = return x
fromValue v = raise ["wrong-value", "needed"] [v, string "Pattern"]
instance Valuable Expr where
toValue = return . Expression
fromValue (Expression x) = return x
fromValue v = raise ["wrong-value", "needed"] [v, string "Expression"]