module Replacer (replaceProgram) where
import Ast
import Matcher (Tail (TaApplication, TaDispatch))
replaceBindings :: [Binding] -> [Expression] -> [Expression] -> ([Binding], [Expression], [Expression])
replaceBindings :: [Binding]
-> [Expression]
-> [Expression]
-> ([Binding], [Expression], [Expression])
replaceBindings [Binding]
bds [] [] = ([Binding]
bds, [], [])
replaceBindings [] [Expression]
ptns [Expression]
repls = ([], [Expression]
ptns, [Expression]
repls)
replaceBindings (BiTau Attribute
attr Expression
expr : [Binding]
bds) [Expression]
ptns [Expression]
repls =
let (Expression
expr', [Expression]
ptns', [Expression]
repls') = Expression
-> [Expression]
-> [Expression]
-> (Expression, [Expression], [Expression])
replaceExpression Expression
expr [Expression]
ptns [Expression]
repls
([Binding]
bds', [Expression]
ptns'', [Expression]
repls'') = [Binding]
-> [Expression]
-> [Expression]
-> ([Binding], [Expression], [Expression])
replaceBindings [Binding]
bds [Expression]
ptns' [Expression]
repls'
in (Attribute -> Expression -> Binding
BiTau Attribute
attr Expression
expr' Binding -> [Binding] -> [Binding]
forall a. a -> [a] -> [a]
: [Binding]
bds', [Expression]
ptns'', [Expression]
repls'')
replaceBindings (Binding
bd : [Binding]
bds) [Expression]
ptns [Expression]
repls =
let ([Binding]
bds', [Expression]
ptns', [Expression]
repls') = [Binding]
-> [Expression]
-> [Expression]
-> ([Binding], [Expression], [Expression])
replaceBindings [Binding]
bds [Expression]
ptns [Expression]
repls
in (Binding
bd Binding -> [Binding] -> [Binding]
forall a. a -> [a] -> [a]
: [Binding]
bds', [Expression]
ptns', [Expression]
repls')
replaceExpression :: Expression -> [Expression] -> [Expression] -> (Expression, [Expression], [Expression])
replaceExpression :: Expression
-> [Expression]
-> [Expression]
-> (Expression, [Expression], [Expression])
replaceExpression Expression
expr [] [] = (Expression
expr, [], [])
replaceExpression Expression
expr [Expression]
ptns [Expression]
repls =
let (Expression
ptn : [Expression]
ptnsRest) = [Expression]
ptns
(Expression
repl : [Expression]
replsRest) = [Expression]
repls
in if Expression
expr Expression -> Expression -> Bool
forall a. Eq a => a -> a -> Bool
== Expression
ptn
then Expression
-> [Expression]
-> [Expression]
-> (Expression, [Expression], [Expression])
replaceExpression Expression
repl [Expression]
ptnsRest [Expression]
replsRest
else case Expression
expr of
ExDispatch Expression
inner Attribute
attr ->
let (Expression
expr', [Expression]
ptns', [Expression]
repls') = Expression
-> [Expression]
-> [Expression]
-> (Expression, [Expression], [Expression])
replaceExpression Expression
inner [Expression]
ptns [Expression]
repls
in (Expression -> Attribute -> Expression
ExDispatch Expression
expr' Attribute
attr, [Expression]
ptns', [Expression]
repls')
ExApplication Expression
inner Binding
tau ->
let (Expression
expr', [Expression]
ptns', [Expression]
repls') = Expression
-> [Expression]
-> [Expression]
-> (Expression, [Expression], [Expression])
replaceExpression Expression
inner [Expression]
ptns [Expression]
repls
([Binding
tau'], [Expression]
ptns'', [Expression]
repls'') = [Binding]
-> [Expression]
-> [Expression]
-> ([Binding], [Expression], [Expression])
replaceBindings [Binding
tau] [Expression]
ptns' [Expression]
repls'
in (Expression -> Binding -> Expression
ExApplication Expression
expr' Binding
tau', [Expression]
ptns'', [Expression]
repls'')
ExFormation [Binding]
bds ->
let ([Binding]
bds', [Expression]
ptns', [Expression]
repls') = [Binding]
-> [Expression]
-> [Expression]
-> ([Binding], [Expression], [Expression])
replaceBindings [Binding]
bds [Expression]
ptns [Expression]
repls
in ([Binding] -> Expression
ExFormation [Binding]
bds', [Expression]
ptns', [Expression]
repls')
Expression
_ -> (Expression
expr, [Expression]
ptns, [Expression]
repls)
replaceProgram :: Program -> [Expression] -> [Expression] -> Maybe Program
replaceProgram :: Program -> [Expression] -> [Expression] -> Maybe Program
replaceProgram (Program Expression
expr) [Expression]
ptns [Expression]
repls
| [Expression] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Expression]
ptns Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [Expression] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Expression]
repls =
let (Expression
expr', [Expression]
_, [Expression]
_) = Expression
-> [Expression]
-> [Expression]
-> (Expression, [Expression], [Expression])
replaceExpression Expression
expr [Expression]
ptns [Expression]
repls
in Program -> Maybe Program
forall a. a -> Maybe a
Just (Expression -> Program
Program Expression
expr')
| Bool
otherwise = Maybe Program
forall a. Maybe a
Nothing