module AstEval
( evalAst,
evalBiValOp,
evalBiBoolOp,
evalBiCompValOp,
)
where
import AST
import Data.Bifunctor
import Scope
noEvaluationError :: String -> String
noEvaluationError :: String -> String
noEvaluationError String
s = String
"No evaluation in one or more parameters of " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s
invalidParamsBiOp :: String -> String
invalidParamsBiOp :: String -> String
invalidParamsBiOp String
op =
String
"One or more parameters of binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is invalid"
tooMuchParams :: String -> String
tooMuchParams :: String -> String
tooMuchParams String
s = String
"Too much parameters for " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s
notEnoughParams :: String -> String
notEnoughParams :: String -> String
notEnoughParams String
s = String
"Not enough parameters for " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s
recursionLimit :: Int
recursionLimit :: Int
recursionLimit = Int
2000
evalAst :: [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst :: [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst (ScopeBegin Int
depth : [ScopeMb]
xs) Ast
_
| Int
depth Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
recursionLimit =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"Recursion limit reached", Int -> ScopeMb
ScopeBegin Int
depth ScopeMb -> [ScopeMb] -> [ScopeMb]
forall a. a -> [a] -> [a]
: [ScopeMb]
xs)
evalAst (Variable String
s Ast
ast Int
depth : [ScopeMb]
xs) Ast
_
| Int
depth Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
recursionLimit =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"Recursion limit reached", String -> Ast -> Int -> ScopeMb
Variable String
s Ast
ast Int
depth ScopeMb -> [ScopeMb] -> [ScopeMb]
forall a. a -> [a] -> [a]
: [ScopeMb]
xs)
evalAst [ScopeMb]
stack (Define String
s Ast
v) = case ([ScopeMb] -> String -> Ast -> [ScopeMb])
-> [ScopeMb] -> String -> Ast -> Either String [ScopeMb]
defineVar [ScopeMb] -> String -> Ast -> [ScopeMb]
defineFunc [ScopeMb]
stack String
s Ast
v of
Left String
err -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err, [ScopeMb]
stack)
Right [ScopeMb]
stack' -> (Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right Maybe Ast
forall a. Maybe a
Nothing, [ScopeMb]
stack')
where
defineFunc :: [ScopeMb] -> String -> Ast -> [ScopeMb]
defineFunc = case [ScopeMb] -> String -> Maybe Ast
getVarInScope [ScopeMb]
stack String
s of
Maybe Ast
Nothing -> [ScopeMb] -> String -> Ast -> [ScopeMb]
addVarToScope
Just Ast
_ -> [ScopeMb] -> String -> Ast -> [ScopeMb]
updateVar
evalAst [ScopeMb]
stack (AST.Value Int
i) = (Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just (Int -> Ast
AST.Value Int
i)), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (AST.Symbol String
s Maybe [Ast]
asts) = case [ScopeMb] -> String -> Maybe Ast
getVarInScope [ScopeMb]
stack String
s of
Maybe Ast
Nothing -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String
"Symbol '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++
String
"' doesn't exist in the current or global scope"), [ScopeMb]
stack)
Just (FunctionValue [String]
params Ast
ast Maybe [Ast]
Nothing) ->
[ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack ([String] -> Ast -> Maybe [Ast] -> Ast
FunctionValue [String]
params Ast
ast Maybe [Ast]
asts)
Just Ast
value -> case Maybe [Ast]
asts of
Maybe [Ast]
Nothing -> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack Ast
value
Maybe [Ast]
_ -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String
"Symbol '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' isn't a function"), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (AST.List [Ast]
l) = case [ScopeMb] -> [Ast] -> Either String (Maybe [Ast])
evalSubParams [ScopeMb]
stack [Ast]
l of
(Left String
err) -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err, [ScopeMb]
stack)
(Right (Just [Ast]
l')) -> (Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just ([Ast] -> Ast
AST.List [Ast]
l')), [ScopeMb]
stack)
(Right Maybe [Ast]
Nothing) -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"Cannot have Nothing in a list", [ScopeMb]
stack)
evalAst [ScopeMb]
stack (AST.String String
str) = (Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just (String -> Ast
AST.String String
str)), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Boolean Bool
b) = (Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just (Bool -> Ast
Boolean Bool
b)), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Call String
"+" [AST.String String
s1, AST.String String
s2]) =
(Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just (String -> Ast
AST.String (String
s1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s2))), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Call String
"+" [Ast]
astList) = (Int -> Int -> Int)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiValOp Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"+" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"-" [Ast]
astList) = (Int -> Int -> Int)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiValOp (-) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"-" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"*" [Ast]
astList) = (Int -> Int -> Int)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiValOp Int -> Int -> Int
forall a. Num a => a -> a -> a
(*) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"*" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"/" [Ast
_, AST.Value Int
0]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"Cannot divide by zero", [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Call String
"/" [Ast]
astList) = (Int -> Int -> Int)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiValOp Int -> Int -> Int
forall a. Integral a => a -> a -> a
div [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"/" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"%" [Ast
_, AST.Value Int
0]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"Cannot divide by zero", [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Call String
"%" [Ast]
astList) = (Int -> Int -> Int)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiValOp Int -> Int -> Int
forall a. Integral a => a -> a -> a
mod [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"%" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"==" [Ast]
astList) =
(Int -> Int -> Bool)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiCompValOp Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
(==) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"==" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"!=" [Ast]
astList) =
(Int -> Int -> Bool)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiCompValOp Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
(/=) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"!=" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"<" [Ast]
astList) =
(Int -> Int -> Bool)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiCompValOp Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(<) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"<" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"<=" [Ast]
astList) =
(Int -> Int -> Bool)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiCompValOp Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(<=) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"<=" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
">" [Ast]
astList) =
(Int -> Int -> Bool)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiCompValOp Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(>) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
">" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
">=" [Ast]
astList) =
(Int -> Int -> Bool)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiCompValOp Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(>=) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
">=" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"&&" [Ast]
astList) =
(Bool -> Bool -> Bool)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiBoolOp Bool -> Bool -> Bool
(&&) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"&&" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"||" [Ast]
astList) =
(Bool -> Bool -> Bool)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiBoolOp Bool -> Bool -> Bool
(||) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"||" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"^^" [Ast]
astList) =
(Bool -> Bool -> Bool)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiBoolOp (\Bool
a Bool
b -> (Bool
a Bool -> Bool -> Bool
|| Bool
b) Bool -> Bool -> Bool
&& Bool -> Bool
not (Bool
a Bool -> Bool -> Bool
&& Bool
b)) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"||" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"!" [AST.Boolean Bool
b]) =
(Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just (Bool -> Ast
AST.Boolean (Bool -> Bool
not Bool
b))), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Call String
"!" [Ast
ast]) = case [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack Ast
ast of
(Left String
err, [ScopeMb]
_) -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err, [ScopeMb]
stack)
(Right (Just (Boolean Bool
b)), [ScopeMb]
_) -> (Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just (Bool -> Ast
AST.Boolean (Bool -> Bool
not Bool
b))), [ScopeMb]
stack)
(Right Maybe Ast
Nothing, [ScopeMb]
_) ->
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"No evaluation in parameter of unary operator '!'", [ScopeMb]
stack)
(Right Maybe Ast
_, [ScopeMb]
_) ->
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"Parameter of unary operator '!' isn't a boolean", [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Call String
"!" [Ast]
_) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"Invalid number of parameter for unary operator '!'", [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Call String
"@" [Ast
ast]) = case [ScopeMb] -> Ast -> Either String Ast
astToString [ScopeMb]
stack Ast
ast of
Left String
err -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err, [ScopeMb]
stack)
Right Ast
ast' -> (Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just Ast
ast'), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Call String
"@" (Ast
_ : [Ast]
_)) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
tooMuchParams String
"string conversion"), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Call String
"@" []) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
notEnoughParams String
"string conversion"), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Call String
"++" [Ast]
astList) =
([Ast] -> Ast -> [Ast])
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiListOp (\[Ast]
l Ast
el -> [Ast]
l [Ast] -> [Ast] -> [Ast]
forall a. [a] -> [a] -> [a]
++ [Ast
el]) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"++" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"--" [Ast]
astList) =
([Ast] -> Ast -> [Ast])
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiListOp (\[Ast]
l Ast
el -> (Ast -> Bool) -> [Ast] -> [Ast]
forall a. (a -> Bool) -> [a] -> [a]
filter (Ast -> Ast -> Bool
forall a. Eq a => a -> a -> Bool
/= Ast
el) [Ast]
l) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"++" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"!!" [Ast]
astList) =
case [ScopeMb] -> Ast -> Either String Ast
getElemInAstList [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"!!" [Ast]
astList) of
Left String
err -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err, [ScopeMb]
stack)
Right Ast
ast' -> (Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just Ast
ast'), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Call String
"~" [Ast]
astList) =
([Ast] -> Ast)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalUnListOp (Int -> Ast
AST.Value (Int -> Ast) -> ([Ast] -> Int) -> [Ast] -> Ast
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Ast] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length) [ScopeMb]
stack (String -> [Ast] -> Ast
Call String
"~" [Ast]
astList)
evalAst [ScopeMb]
stack (Call String
"$" [Ast
ast1, Ast
ast2]) = case [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack Ast
ast1 of
(Left String
err, [ScopeMb]
_) -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err, [ScopeMb]
stack)
(Right Maybe Ast
_, [ScopeMb]
stack') -> case [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack' Ast
ast2 of
(Left String
err', [ScopeMb]
_) -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err', [ScopeMb]
stack)
(Right Maybe Ast
ast, [ScopeMb]
stack'') -> (Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right Maybe Ast
ast, [ScopeMb]
stack'')
evalAst [ScopeMb]
stack (Call String
"$" (Ast
_ : [Ast]
_)) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
tooMuchParams String
"operator $ (needs 2)"), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Call String
"$" []) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
notEnoughParams String
"operator $ (needs 2)"), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Call String
unknown [Ast]
_) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String
"Unknown operator: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
unknown), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (FunctionValue [String]
params Ast
ast Maybe [Ast]
Nothing) =
(Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just ([String] -> Ast -> Maybe [Ast] -> Ast
FunctionValue [String]
params Ast
ast Maybe [Ast]
forall a. Maybe a
Nothing)), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (FunctionValue [] Ast
ast (Just [])) =
([ScopeMb] -> [ScopeMb])
-> (Either String (Maybe Ast), [ScopeMb])
-> (Either String (Maybe Ast), [ScopeMb])
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
Data.Bifunctor.second [ScopeMb] -> [ScopeMb]
clearScope ([ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst ([ScopeMb] -> [ScopeMb]
beginScope [ScopeMb]
stack) Ast
ast)
evalAst [ScopeMb]
stack (FunctionValue [String]
params Ast
ast (Just [])) =
(Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just ([String] -> Ast -> Maybe [Ast] -> Ast
FunctionValue [String]
params Ast
ast Maybe [Ast]
forall a. Maybe a
Nothing)), [ScopeMb]
stack)
evalAst [ScopeMb]
stack (FunctionValue [String]
params Ast
ast (Just [Ast]
asts))
| [String] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
params Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< [Ast] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Ast]
asts =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String
"Expression takes " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ([String] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
params) String -> String -> String
forall a. [a] -> [a] -> [a]
++
String
" parameters, got " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ([Ast] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Ast]
asts)), [ScopeMb]
stack)
| Bool
otherwise = case [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack ([Ast] -> Ast
forall a. HasCallStack => [a] -> a
head [Ast]
asts) of
(Left String
err, [ScopeMb]
_) -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err, [ScopeMb]
stack)
(Right Maybe Ast
Nothing, [ScopeMb]
_) -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
noEvaluationError String
"expression"), [ScopeMb]
stack)
(Right (Just Ast
ast'), [ScopeMb]
_) -> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack
([String] -> Ast -> Maybe [Ast] -> Ast
FunctionValue ([String] -> [String]
forall a. HasCallStack => [a] -> [a]
tail [String]
params)
(String -> [Ast] -> Ast
Call String
"$" [String -> Ast -> Ast
Define ([String] -> String
forall a. HasCallStack => [a] -> a
head [String]
params) Ast
ast', Ast
ast]) ([Ast] -> Maybe [Ast]
forall a. a -> Maybe a
Just ([Ast] -> [Ast]
forall a. HasCallStack => [a] -> [a]
tail [Ast]
asts)))
evalAst [ScopeMb]
stack (Cond (AST.Boolean Bool
b) Ast
a1 (Just Ast
a2))
| Bool
b = [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack Ast
a1
| Bool
otherwise = [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack Ast
a2
evalAst [ScopeMb]
stack (Cond (AST.Boolean Bool
b) Ast
a1 Maybe Ast
Nothing)
| Bool
b = [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack Ast
a1
| Bool
otherwise = (Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right Maybe Ast
forall a. Maybe a
Nothing, [ScopeMb]
stack)
evalAst [ScopeMb]
stack (Cond Ast
ast Ast
a1 Maybe Ast
a2) = case (Either String (Maybe Ast), [ScopeMb]) -> Either String (Maybe Ast)
forall a b. (a, b) -> a
fst ([ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack Ast
ast) of
Left String
err -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err, [ScopeMb]
stack)
Right Maybe Ast
mEAst -> case Maybe Ast
mEAst of
Maybe Ast
Nothing -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"No evaluation in condition", [ScopeMb]
stack)
Just Ast
eAst
| Ast
eAst Ast -> Ast -> Bool
forall a. Eq a => a -> a -> Bool
== Ast
ast -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"Condition isn't a boolean", [ScopeMb]
stack)
| Bool
otherwise -> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack (Ast -> Ast -> Maybe Ast -> Ast
Cond Ast
eAst Ast
a1 Maybe Ast
a2)
evalBiValOp ::
(Int -> Int -> Int) ->
[ScopeMb] ->
Ast ->
(Either String (Maybe Ast), [ScopeMb])
evalBiValOp :: (Int -> Int -> Int)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiValOp Int -> Int -> Int
_ [ScopeMb]
stack (Call String
op [AST.Boolean Bool
_, Ast
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiValOp Int -> Int -> Int
_ [ScopeMb]
stack (Call String
op [Ast
_, AST.Boolean Bool
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiValOp Int -> Int -> Int
_ [ScopeMb]
stack (Call String
op [AST.String String
_, Ast
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiValOp Int -> Int -> Int
_ [ScopeMb]
stack (Call String
op [Ast
_, AST.String String
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiValOp Int -> Int -> Int
_ [ScopeMb]
stack (Call String
op [AST.List [Ast]
_, Ast
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiValOp Int -> Int -> Int
_ [ScopeMb]
stack (Call String
op [Ast
_, AST.List [Ast]
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiValOp Int -> Int -> Int
_ [ScopeMb]
stack (Call String
op [AST.FunctionValue [String]
_ Ast
_ Maybe [Ast]
Nothing, Ast
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiValOp Int -> Int -> Int
_ [ScopeMb]
stack (Call String
op [Ast
_, AST.FunctionValue [String]
_ Ast
_ Maybe [Ast]
Nothing]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiValOp Int -> Int -> Int
f [ScopeMb]
stack (Call String
_ [AST.Value Int
a, AST.Value Int
b]) =
(Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just (Int -> Ast
AST.Value (Int -> Int -> Int
f Int
a Int
b))), [ScopeMb]
stack)
evalBiValOp Int -> Int -> Int
_ [ScopeMb]
stack (Call String
op [Ast
ast1, Ast
ast2]) =
case [ScopeMb] -> [Ast] -> Either String (Maybe [Ast])
evalSubParams [ScopeMb]
stack [Ast
ast1, Ast
ast2] of
Left String
err -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err, [ScopeMb]
stack)
Right Maybe [Ast]
asts ->
(Either String (Maybe Ast), [ScopeMb])
-> ([Ast] -> (Either String (Maybe Ast), [ScopeMb]))
-> Maybe [Ast]
-> (Either String (Maybe Ast), [ScopeMb])
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
noEvaluationError String
"binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
([ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack (Ast -> (Either String (Maybe Ast), [ScopeMb]))
-> ([Ast] -> Ast)
-> [Ast]
-> (Either String (Maybe Ast), [ScopeMb])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [Ast] -> Ast
Call String
op)
Maybe [Ast]
asts
evalBiValOp Int -> Int -> Int
_ [ScopeMb]
stack (Call String
op (Ast
_ : Ast
_ : [Ast]
_)) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
tooMuchParams String
"binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
evalBiValOp Int -> Int -> Int
_ [ScopeMb]
stack (Call String
op [Ast]
_) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
notEnoughParams String
"binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
evalBiValOp Int -> Int -> Int
_ [ScopeMb]
stack Ast
_ = (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"Ast isn't a Call", [ScopeMb]
stack)
evalBiBoolOp ::
(Bool -> Bool -> Bool) ->
[ScopeMb] ->
Ast ->
(Either String (Maybe Ast), [ScopeMb])
evalBiBoolOp :: (Bool -> Bool -> Bool)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiBoolOp Bool -> Bool -> Bool
_ [ScopeMb]
stack (Call String
op [AST.Value Int
_, Ast
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiBoolOp Bool -> Bool -> Bool
_ [ScopeMb]
stack (Call String
op [Ast
_, AST.Value Int
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiBoolOp Bool -> Bool -> Bool
_ [ScopeMb]
stack (Call String
op [AST.String String
_, Ast
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiBoolOp Bool -> Bool -> Bool
_ [ScopeMb]
stack (Call String
op [Ast
_, AST.String String
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiBoolOp Bool -> Bool -> Bool
_ [ScopeMb]
stack (Call String
op [AST.List [Ast]
_, Ast
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiBoolOp Bool -> Bool -> Bool
_ [ScopeMb]
stack (Call String
op [Ast
_, AST.List [Ast]
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiBoolOp Bool -> Bool -> Bool
_ [ScopeMb]
stack (Call String
op [AST.FunctionValue [String]
_ Ast
_ Maybe [Ast]
Nothing, Ast
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiBoolOp Bool -> Bool -> Bool
_ [ScopeMb]
stack (Call String
op [Ast
_, AST.FunctionValue [String]
_ Ast
_ Maybe [Ast]
Nothing]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiBoolOp Bool -> Bool -> Bool
f [ScopeMb]
stack (Call String
_ [AST.Boolean Bool
a, AST.Boolean Bool
b]) =
(Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just (Bool -> Ast
AST.Boolean (Bool -> Bool -> Bool
f Bool
a Bool
b))), [ScopeMb]
stack)
evalBiBoolOp Bool -> Bool -> Bool
_ [ScopeMb]
stack (Call String
op [Ast
ast1, Ast
ast2]) =
case [ScopeMb] -> [Ast] -> Either String (Maybe [Ast])
evalSubParams [ScopeMb]
stack [Ast
ast1, Ast
ast2] of
Left String
err -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err, [ScopeMb]
stack)
Right Maybe [Ast]
asts ->
(Either String (Maybe Ast), [ScopeMb])
-> ([Ast] -> (Either String (Maybe Ast), [ScopeMb]))
-> Maybe [Ast]
-> (Either String (Maybe Ast), [ScopeMb])
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
noEvaluationError String
"binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
([ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack (Ast -> (Either String (Maybe Ast), [ScopeMb]))
-> ([Ast] -> Ast)
-> [Ast]
-> (Either String (Maybe Ast), [ScopeMb])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [Ast] -> Ast
Call String
op)
Maybe [Ast]
asts
evalBiBoolOp Bool -> Bool -> Bool
_ [ScopeMb]
stack (Call String
op (Ast
_ : Ast
_ : [Ast]
_)) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
tooMuchParams String
"binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
evalBiBoolOp Bool -> Bool -> Bool
_ [ScopeMb]
stack (Call String
op [Ast]
_) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
notEnoughParams String
"binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
evalBiBoolOp Bool -> Bool -> Bool
_ [ScopeMb]
stack Ast
_ = (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"Ast isn't a Call", [ScopeMb]
stack)
evalBiCompValOp ::
(Int -> Int -> Bool) ->
[ScopeMb] ->
Ast ->
(Either String (Maybe Ast), [ScopeMb])
evalBiCompValOp :: (Int -> Int -> Bool)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiCompValOp Int -> Int -> Bool
_ [ScopeMb]
stack (Call String
op [AST.Boolean Bool
_, Ast
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiCompValOp Int -> Int -> Bool
_ [ScopeMb]
stack (Call String
op [Ast
_, AST.Boolean Bool
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiCompValOp Int -> Int -> Bool
_ [ScopeMb]
stack (Call String
op [AST.String String
_, Ast
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiCompValOp Int -> Int -> Bool
_ [ScopeMb]
stack (Call String
op [Ast
_, AST.String String
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiCompValOp Int -> Int -> Bool
_ [ScopeMb]
stack (Call String
op [AST.List [Ast]
_, Ast
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiCompValOp Int -> Int -> Bool
_ [ScopeMb]
stack (Call String
op [Ast
_, AST.List [Ast]
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiCompValOp Int -> Int -> Bool
_ [ScopeMb]
stack (Call String
op [AST.FunctionValue [String]
_ Ast
_ Maybe [Ast]
Nothing, Ast
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiCompValOp Int -> Int -> Bool
_ [ScopeMb]
stack (Call String
op [Ast
_, AST.FunctionValue [String]
_ Ast
_ Maybe [Ast]
Nothing]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
op), [ScopeMb]
stack)
evalBiCompValOp Int -> Int -> Bool
f [ScopeMb]
stack (Call String
_ [AST.Value Int
a, AST.Value Int
b]) =
(Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just (Bool -> Ast
AST.Boolean (Int -> Int -> Bool
f Int
a Int
b))), [ScopeMb]
stack)
evalBiCompValOp Int -> Int -> Bool
_ [ScopeMb]
stack (Call String
op [Ast
ast1, Ast
ast2]) =
case [ScopeMb] -> [Ast] -> Either String (Maybe [Ast])
evalSubParams [ScopeMb]
stack [Ast
ast1, Ast
ast2] of
Left String
err -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err, [ScopeMb]
stack)
Right Maybe [Ast]
asts ->
(Either String (Maybe Ast), [ScopeMb])
-> ([Ast] -> (Either String (Maybe Ast), [ScopeMb]))
-> Maybe [Ast]
-> (Either String (Maybe Ast), [ScopeMb])
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
noEvaluationError String
"binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
([ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack (Ast -> (Either String (Maybe Ast), [ScopeMb]))
-> ([Ast] -> Ast)
-> [Ast]
-> (Either String (Maybe Ast), [ScopeMb])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [Ast] -> Ast
Call String
op)
Maybe [Ast]
asts
evalBiCompValOp Int -> Int -> Bool
_ [ScopeMb]
stack (Call String
op (Ast
_ : Ast
_ : [Ast]
_)) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
tooMuchParams String
"binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
evalBiCompValOp Int -> Int -> Bool
_ [ScopeMb]
stack (Call String
op [Ast]
_) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
notEnoughParams String
"binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
evalBiCompValOp Int -> Int -> Bool
_ [ScopeMb]
stack Ast
_ = (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"Ast isn't a Call", [ScopeMb]
stack)
evalBiListOp ::
([Ast] -> Ast -> [Ast]) ->
[ScopeMb] ->
Ast ->
(Either String (Maybe Ast), [ScopeMb])
evalBiListOp :: ([Ast] -> Ast -> [Ast])
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalBiListOp [Ast] -> Ast -> [Ast]
_ [ScopeMb]
stack (Call String
op [AST.Boolean Bool
_, Ast
_]) =
( String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String
"First parameter of binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is invalid"),
[ScopeMb]
stack
)
evalBiListOp [Ast] -> Ast -> [Ast]
_ [ScopeMb]
stack (Call String
op [AST.Value Int
_, Ast
_]) =
( String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String
"First parameter of binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is invalid"),
[ScopeMb]
stack
)
evalBiListOp [Ast] -> Ast -> [Ast]
_ [ScopeMb]
stack (Call String
op [AST.String String
_, Ast
_]) =
( String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String
"First parameter of binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is invalid"),
[ScopeMb]
stack
)
evalBiListOp [Ast] -> Ast -> [Ast]
_ [ScopeMb]
stack (Call String
op [AST.FunctionValue [String]
_ Ast
_ Maybe [Ast]
Nothing, Ast
_]) =
( String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String
"First parameter of binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is invalid"),
[ScopeMb]
stack
)
evalBiListOp [Ast] -> Ast -> [Ast]
f [ScopeMb]
stack (Call String
_ [AST.List [Ast]
a, Ast
ast]) =
(Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just ([Ast] -> Ast
AST.List ([Ast] -> Ast -> [Ast]
f [Ast]
a Ast
ast))), [ScopeMb]
stack)
evalBiListOp [Ast] -> Ast -> [Ast]
_ [ScopeMb]
stack (Call String
op [Ast
ast1, Ast
ast2]) =
case [ScopeMb] -> [Ast] -> Either String (Maybe [Ast])
evalSubParams [ScopeMb]
stack [Ast
ast1, Ast
ast2] of
Left String
err -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err, [ScopeMb]
stack)
Right Maybe [Ast]
asts ->
(Either String (Maybe Ast), [ScopeMb])
-> ([Ast] -> (Either String (Maybe Ast), [ScopeMb]))
-> Maybe [Ast]
-> (Either String (Maybe Ast), [ScopeMb])
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
noEvaluationError String
"binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
([ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack (Ast -> (Either String (Maybe Ast), [ScopeMb]))
-> ([Ast] -> Ast)
-> [Ast]
-> (Either String (Maybe Ast), [ScopeMb])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [Ast] -> Ast
Call String
op)
Maybe [Ast]
asts
evalBiListOp [Ast] -> Ast -> [Ast]
_ [ScopeMb]
stack (Call String
op (Ast
_ : Ast
_ : [Ast]
_)) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
tooMuchParams String
"binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
evalBiListOp [Ast] -> Ast -> [Ast]
_ [ScopeMb]
stack (Call String
op [Ast]
_) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
notEnoughParams String
"binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
evalBiListOp [Ast] -> Ast -> [Ast]
_ [ScopeMb]
stack Ast
_ = (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"Ast isn't a Call", [ScopeMb]
stack)
getElemInAstList :: [ScopeMb] -> Ast -> Either String Ast
getElemInAstList :: [ScopeMb] -> Ast -> Either String Ast
getElemInAstList [ScopeMb]
_ (Call String
"!!" [AST.Boolean Bool
_, Ast
_]) =
String -> Either String Ast
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
"!!")
getElemInAstList [ScopeMb]
_ (Call String
"!!" [Ast
_, AST.Boolean Bool
_]) =
String -> Either String Ast
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
"!!")
getElemInAstList [ScopeMb]
_ (Call String
"!!" [Ast
_, AST.String String
_]) =
String -> Either String Ast
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
"!!")
getElemInAstList [ScopeMb]
_ (Call String
"!!" [Ast
_, AST.List [Ast]
_]) =
String -> Either String Ast
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
"!!")
getElemInAstList [ScopeMb]
_ (Call String
"!!" [AST.Value Int
_, Ast
_]) =
String -> Either String Ast
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
"!!")
getElemInAstList [ScopeMb]
_ (Call String
"!!" [AST.FunctionValue [String]
_ Ast
_ Maybe [Ast]
Nothing, Ast
_]) =
String -> Either String Ast
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
"!!")
getElemInAstList [ScopeMb]
_ (Call String
"!!" [Ast
_, AST.FunctionValue [String]
_ Ast
_ Maybe [Ast]
Nothing]) =
String -> Either String Ast
forall a b. a -> Either a b
Left (String -> String
invalidParamsBiOp String
"!!")
getElemInAstList [ScopeMb]
_ (Call String
"!!" [AST.List [Ast]
a, AST.Value Int
b])
| Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = String -> Either String Ast
forall a b. a -> Either a b
Left String
"Index out of range"
| [Ast] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Ast]
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
b = Ast -> Either String Ast
forall a b. b -> Either a b
Right ([Ast]
a [Ast] -> Int -> Ast
forall a. HasCallStack => [a] -> Int -> a
!! Int
b)
| Bool
otherwise = String -> Either String Ast
forall a b. a -> Either a b
Left String
"Index out of range"
getElemInAstList [ScopeMb]
_ (Call String
"!!" [AST.String String
a, AST.Value Int
b])
| Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = String -> Either String Ast
forall a b. a -> Either a b
Left String
"Index out of range"
| String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
b = Ast -> Either String Ast
forall a b. b -> Either a b
Right (String -> Ast
AST.String [String
a String -> Int -> Char
forall a. HasCallStack => [a] -> Int -> a
!! Int
b])
| Bool
otherwise = String -> Either String Ast
forall a b. a -> Either a b
Left String
"Index out of range"
getElemInAstList [ScopeMb]
stack (Call String
"!!" [Ast
ast1, Ast
ast2]) =
case [ScopeMb] -> [Ast] -> Either String (Maybe [Ast])
evalSubParams [ScopeMb]
stack [Ast
ast1, Ast
ast2] of
Left String
err -> String -> Either String Ast
forall a b. a -> Either a b
Left String
err
Right Maybe [Ast]
asts -> case (Either String (Maybe Ast), [ScopeMb])
-> ([Ast] -> (Either String (Maybe Ast), [ScopeMb]))
-> Maybe [Ast]
-> (Either String (Maybe Ast), [ScopeMb])
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
noEvaluationError String
"binary operator '!!'"), [ScopeMb]
stack)
([ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack (Ast -> (Either String (Maybe Ast), [ScopeMb]))
-> ([Ast] -> Ast)
-> [Ast]
-> (Either String (Maybe Ast), [ScopeMb])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [Ast] -> Ast
Call String
"!!") Maybe [Ast]
asts of
(Left String
err, [ScopeMb]
_) -> String -> Either String Ast
forall a b. a -> Either a b
Left String
err
(Right Maybe Ast
ast, [ScopeMb]
_) ->
Either String Ast
-> (Ast -> Either String Ast) -> Maybe Ast -> Either String Ast
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> Either String Ast
forall a b. a -> Either a b
Left (String -> String
noEvaluationError String
"binary operator '!!'"))
Ast -> Either String Ast
forall a b. b -> Either a b
Right Maybe Ast
ast
getElemInAstList [ScopeMb]
_ (Call String
"!!" (Ast
_ : Ast
_ : [Ast]
_)) =
String -> Either String Ast
forall a b. a -> Either a b
Left (String -> String
tooMuchParams String
"binary operator '!!'")
getElemInAstList [ScopeMb]
_ (Call String
"!!" [Ast]
_) =
String -> Either String Ast
forall a b. a -> Either a b
Left (String -> String
notEnoughParams String
"binary operator '!!'")
getElemInAstList [ScopeMb]
_ Ast
_ = String -> Either String Ast
forall a b. a -> Either a b
Left String
"Ast isn't a '!!' Call"
evalUnListOp ::
([Ast] -> Ast) ->
[ScopeMb] ->
Ast ->
(Either String (Maybe Ast), [ScopeMb])
evalUnListOp :: ([Ast] -> Ast)
-> [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalUnListOp [Ast] -> Ast
_ [ScopeMb]
stack (Call String
op [AST.Boolean Bool
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String
"The parameter of unary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is invalid"), [ScopeMb]
stack)
evalUnListOp [Ast] -> Ast
_ [ScopeMb]
stack (Call String
op [AST.String String
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String
"The parameter of unary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is invalid"), [ScopeMb]
stack)
evalUnListOp [Ast] -> Ast
_ [ScopeMb]
stack (Call String
op [AST.Value Int
_]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String
"The parameter of unary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is invalid"), [ScopeMb]
stack)
evalUnListOp [Ast] -> Ast
_ [ScopeMb]
stack (Call String
op [AST.FunctionValue [String]
_ Ast
_ Maybe [Ast]
Nothing]) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String
"The parameter of unary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is invalid"), [ScopeMb]
stack)
evalUnListOp [Ast] -> Ast
f [ScopeMb]
stack (Call String
_ [AST.List [Ast]
a]) =
(Maybe Ast -> Either String (Maybe Ast)
forall a b. b -> Either a b
Right (Ast -> Maybe Ast
forall a. a -> Maybe a
Just ([Ast] -> Ast
f [Ast]
a)), [ScopeMb]
stack)
evalUnListOp [Ast] -> Ast
_ [ScopeMb]
stack (Call String
op [Ast
ast]) =
case [ScopeMb] -> [Ast] -> Either String (Maybe [Ast])
evalSubParams [ScopeMb]
stack [Ast
ast] of
Left String
err -> (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
err, [ScopeMb]
stack)
Right Maybe [Ast]
asts ->
(Either String (Maybe Ast), [ScopeMb])
-> ([Ast] -> (Either String (Maybe Ast), [ScopeMb]))
-> Maybe [Ast]
-> (Either String (Maybe Ast), [ScopeMb])
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
noEvaluationError String
"binary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
([ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack (Ast -> (Either String (Maybe Ast), [ScopeMb]))
-> ([Ast] -> Ast)
-> [Ast]
-> (Either String (Maybe Ast), [ScopeMb])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [Ast] -> Ast
Call String
op)
Maybe [Ast]
asts
evalUnListOp [Ast] -> Ast
_ [ScopeMb]
stack (Call String
op (Ast
_ : Ast
_ : [Ast]
_)) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
tooMuchParams String
"unary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
evalUnListOp [Ast] -> Ast
_ [ScopeMb]
stack (Call String
op [Ast]
_) =
(String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left (String -> String
notEnoughParams String
"unary operator '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'"), [ScopeMb]
stack)
evalUnListOp [Ast] -> Ast
_ [ScopeMb]
stack Ast
_ = (String -> Either String (Maybe Ast)
forall a b. a -> Either a b
Left String
"Ast isn't a Call", [ScopeMb]
stack)
evalSubParams :: [ScopeMb] -> [Ast] -> Either String (Maybe [Ast])
evalSubParams :: [ScopeMb] -> [Ast] -> Either String (Maybe [Ast])
evalSubParams [ScopeMb]
stack [Ast]
astList = case (Ast -> Either String (Maybe Ast))
-> [Ast] -> Either String [Maybe Ast]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ((Either String (Maybe Ast), [ScopeMb]) -> Either String (Maybe Ast)
forall a b. (a, b) -> a
fst ((Either String (Maybe Ast), [ScopeMb])
-> Either String (Maybe Ast))
-> (Ast -> (Either String (Maybe Ast), [ScopeMb]))
-> Ast
-> Either String (Maybe Ast)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack) [Ast]
astList of
Left String
err -> String -> Either String (Maybe [Ast])
forall a b. a -> Either a b
Left String
err
Right [Maybe Ast]
asts -> Maybe [Ast] -> Either String (Maybe [Ast])
forall a b. b -> Either a b
Right ([Maybe Ast] -> Maybe [Ast]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence [Maybe Ast]
asts)
astToString :: [ScopeMb] -> Ast -> Either String Ast
astToString :: [ScopeMb] -> Ast -> Either String Ast
astToString [ScopeMb]
_ (AST.String String
str) = Ast -> Either String Ast
forall a b. b -> Either a b
Right (String -> Ast
AST.String String
str)
astToString [ScopeMb]
_ (AST.Value Int
val) = Ast -> Either String Ast
forall a b. b -> Either a b
Right (String -> Ast
AST.String (Int -> String
forall a. Show a => a -> String
show Int
val))
astToString [ScopeMb]
_ (AST.Boolean Bool
bool) = Ast -> Either String Ast
forall a b. b -> Either a b
Right (String -> Ast
AST.String (Bool -> String
forall a. Show a => a -> String
show Bool
bool))
astToString [ScopeMb]
_ (AST.FunctionValue [String]
_ Ast
_ Maybe [Ast]
Nothing) =
String -> Either String Ast
forall a b. a -> Either a b
Left String
"Cannot convert lambda to string"
astToString [ScopeMb]
_ (AST.List [Ast]
_) =
String -> Either String Ast
forall a b. a -> Either a b
Left String
"Cannot convert list to string"
astToString [ScopeMb]
stack Ast
ast = case [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack Ast
ast of
(Left String
err, [ScopeMb]
_) -> String -> Either String Ast
forall a b. a -> Either a b
Left String
err
(Right Maybe Ast
ast', [ScopeMb]
_) ->
Either String Ast
-> (Ast -> Either String Ast) -> Maybe Ast -> Either String Ast
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(String -> Either String Ast
forall a b. a -> Either a b
Left String
"Cannot convert no evaluation to string")
([ScopeMb] -> Ast -> Either String Ast
astToString [ScopeMb]
stack)
Maybe Ast
ast'
defineVar ::
([ScopeMb] -> String -> Ast -> [ScopeMb]) ->
[ScopeMb] ->
String ->
Ast ->
Either String [ScopeMb]
defineVar :: ([ScopeMb] -> String -> Ast -> [ScopeMb])
-> [ScopeMb] -> String -> Ast -> Either String [ScopeMb]
defineVar [ScopeMb] -> String -> Ast -> [ScopeMb]
f [ScopeMb]
stack String
name Ast
ast = case [ScopeMb] -> Ast -> (Either String (Maybe Ast), [ScopeMb])
evalAst [ScopeMb]
stack Ast
ast of
(Left String
err, [ScopeMb]
_) -> String -> Either String [ScopeMb]
forall a b. a -> Either a b
Left String
err
(Right (Just Ast
ast'), [ScopeMb]
_) -> [ScopeMb] -> Either String [ScopeMb]
forall a b. b -> Either a b
Right ([ScopeMb] -> String -> Ast -> [ScopeMb]
f [ScopeMb]
stack String
name Ast
ast')
(Right Maybe Ast
Nothing, [ScopeMb]
_) -> String -> Either String [ScopeMb]
forall a b. a -> Either a b
Left String
"Cannot define with no value"