module Scope
( ScopeMb (..),
beginScope,
clearScope,
addVarToScope,
getVarInScope,
addVarsToScope,
updateVar,
)
where
import AST
import Stack
data ScopeMb
= ScopeBegin Int
| Variable String Ast Int
deriving (ScopeMb -> ScopeMb -> Bool
(ScopeMb -> ScopeMb -> Bool)
-> (ScopeMb -> ScopeMb -> Bool) -> Eq ScopeMb
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ScopeMb -> ScopeMb -> Bool
== :: ScopeMb -> ScopeMb -> Bool
$c/= :: ScopeMb -> ScopeMb -> Bool
/= :: ScopeMb -> ScopeMb -> Bool
Eq, Int -> ScopeMb -> ShowS
[ScopeMb] -> ShowS
ScopeMb -> String
(Int -> ScopeMb -> ShowS)
-> (ScopeMb -> String) -> ([ScopeMb] -> ShowS) -> Show ScopeMb
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ScopeMb -> ShowS
showsPrec :: Int -> ScopeMb -> ShowS
$cshow :: ScopeMb -> String
show :: ScopeMb -> String
$cshowList :: [ScopeMb] -> ShowS
showList :: [ScopeMb] -> ShowS
Show)
getDepth :: [ScopeMb] -> Int
getDepth :: [ScopeMb] -> Int
getDepth [ScopeMb]
s = case [ScopeMb] -> Maybe ScopeMb
forall a. [a] -> Maybe a
top [ScopeMb]
s of
Just (ScopeBegin Int
depth) -> Int
depth
Just (Variable String
_ Ast
_ Int
depth) -> Int
depth
Maybe ScopeMb
Nothing -> -Int
1
beginScope :: [ScopeMb] -> [ScopeMb]
beginScope :: [ScopeMb] -> [ScopeMb]
beginScope [ScopeMb]
s = [ScopeMb] -> ScopeMb -> [ScopeMb]
forall a. [a] -> a -> [a]
push [ScopeMb]
s (Int -> ScopeMb
ScopeBegin ([ScopeMb] -> Int
getDepth [ScopeMb]
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
clearScope :: [ScopeMb] -> [ScopeMb]
clearScope :: [ScopeMb] -> [ScopeMb]
clearScope [] = []
clearScope [ScopeMb]
s = case [ScopeMb] -> (Maybe ScopeMb, [ScopeMb])
forall a. [a] -> (Maybe a, [a])
pop [ScopeMb]
s of
(Maybe ScopeMb
Nothing, [ScopeMb]
s') -> [ScopeMb]
s'
(Just (ScopeBegin Int
_), [ScopeMb]
s') -> [ScopeMb]
s'
(Just ScopeMb
_, [ScopeMb]
s') -> [ScopeMb] -> [ScopeMb]
clearScope [ScopeMb]
s'
addVarToScope :: [ScopeMb] -> String -> Ast -> [ScopeMb]
addVarToScope :: [ScopeMb] -> String -> Ast -> [ScopeMb]
addVarToScope [ScopeMb]
stack String
s Ast
v = [ScopeMb] -> ScopeMb -> [ScopeMb]
forall a. [a] -> a -> [a]
push [ScopeMb]
stack (String -> Ast -> Int -> ScopeMb
Variable String
s Ast
v (case [ScopeMb] -> Int
getDepth [ScopeMb]
stack of
-1 -> Int
0
Int
depth -> Int
depth
))
addVarsToScope :: [ScopeMb] -> [String] -> [Ast] -> [ScopeMb]
addVarsToScope :: [ScopeMb] -> [String] -> [Ast] -> [ScopeMb]
addVarsToScope [ScopeMb]
stack [] [Ast]
_ = [ScopeMb]
stack
addVarsToScope [ScopeMb]
stack [String]
_ [] = [ScopeMb]
stack
addVarsToScope [ScopeMb]
stack (String
s : [String]
xs1) (Ast
v : [Ast]
xs2) =
[ScopeMb] -> ScopeMb -> [ScopeMb]
forall a. [a] -> a -> [a]
push
([ScopeMb] -> [String] -> [Ast] -> [ScopeMb]
addVarsToScope [ScopeMb]
stack [String]
xs1 [Ast]
xs2)
(String -> Ast -> Int -> ScopeMb
Variable String
s Ast
v ([ScopeMb] -> Int
getDepth [ScopeMb]
stack))
seekAndUpdate :: [ScopeMb] -> Int -> String -> Ast -> [ScopeMb]
seekAndUpdate :: [ScopeMb] -> Int -> String -> Ast -> [ScopeMb]
seekAndUpdate (ScopeMb
h:[ScopeMb]
xs) Int
depth String
name Ast
ast
| String -> Int -> ScopeMb -> Bool
isSearchedVar String
name Int
depth ScopeMb
h = String -> Ast -> Int -> ScopeMb
Variable String
name Ast
ast Int
depth ScopeMb -> [ScopeMb] -> [ScopeMb]
forall a. a -> [a] -> [a]
: [ScopeMb]
xs
| Bool
otherwise = ScopeMb
h ScopeMb -> [ScopeMb] -> [ScopeMb]
forall a. a -> [a] -> [a]
: [ScopeMb] -> Int -> String -> Ast -> [ScopeMb]
seekAndUpdate [ScopeMb]
xs Int
depth String
name Ast
ast
seekAndUpdate [] Int
_ String
_ Ast
_ = []
updateVar :: [ScopeMb] -> String -> Ast -> [ScopeMb]
updateVar :: [ScopeMb] -> String -> Ast -> [ScopeMb]
updateVar [ScopeMb]
stack = [ScopeMb] -> Int -> String -> Ast -> [ScopeMb]
seekAndUpdate [ScopeMb]
stack ([ScopeMb] -> Int
getDepth [ScopeMb]
stack)
getVarInScope :: [ScopeMb] -> String -> Maybe Ast
getVarInScope :: [ScopeMb] -> String -> Maybe Ast
getVarInScope [ScopeMb]
stack String
s =
ScopeMb -> Maybe Ast
getAst (ScopeMb -> Maybe Ast) -> Maybe ScopeMb -> Maybe Ast
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (ScopeMb -> Bool) -> [ScopeMb] -> Maybe ScopeMb
forall a. (a -> Bool) -> [a] -> Maybe a
seek (String -> Int -> ScopeMb -> Bool
isSearchedVar String
s ([ScopeMb] -> Int
getDepth [ScopeMb]
stack)) [ScopeMb]
stack
getAst :: ScopeMb -> Maybe Ast
getAst :: ScopeMb -> Maybe Ast
getAst (Variable String
_ Ast
ast Int
_) = Ast -> Maybe Ast
forall a. a -> Maybe a
Just Ast
ast
getAst ScopeMb
_ = Maybe Ast
forall a. Maybe a
Nothing
isSearchedVar :: String -> Int -> ScopeMb -> Bool
isSearchedVar :: String -> Int -> ScopeMb -> Bool
isSearchedVar String
s2 Int
currentDepth (Variable String
s1 Ast
_ Int
depth) =
String
s1 String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
s2 Bool -> Bool -> Bool
&& (Int
depth Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
|| Int
depth Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
currentDepth)
isSearchedVar String
_ Int
_ ScopeMb
_ = Bool
False