2024-12-18 18:55:51 -06:00
|
|
|
module Eval where
|
|
|
|
|
|
|
|
import Parser
|
|
|
|
import Research
|
2024-12-27 12:27:00 -06:00
|
|
|
|
2024-12-31 10:00:52 -06:00
|
|
|
import Data.Map (Map)
|
2024-12-29 20:29:41 -06:00
|
|
|
|
|
|
|
import qualified Data.Map as Map
|
2024-12-27 12:27:00 -06:00
|
|
|
import qualified Data.Set as Set
|
2024-12-27 08:17:06 -06:00
|
|
|
|
2025-01-19 14:41:25 -06:00
|
|
|
evalSingle :: Env -> TricuAST -> Env
|
|
|
|
evalSingle env term
|
|
|
|
| SFunc name [] body <- term =
|
2025-01-24 16:14:33 -06:00
|
|
|
if
|
|
|
|
| Map.member name env ->
|
|
|
|
errorWithoutStackTrace $
|
|
|
|
"Error: Identifier '" ++ name ++ "' is already defined."
|
|
|
|
| otherwise ->
|
|
|
|
let res = evalAST env body
|
|
|
|
in Map.insert "__result" res (Map.insert name res env)
|
2025-01-20 19:20:29 -06:00
|
|
|
| SApp func arg <- term =
|
|
|
|
let res = apply (evalAST env func) (evalAST env arg)
|
|
|
|
in Map.insert "__result" res env
|
|
|
|
| SVar name <- term =
|
|
|
|
case Map.lookup name env of
|
|
|
|
Just v -> Map.insert "__result" v env
|
|
|
|
Nothing -> errorWithoutStackTrace $ "Variable " ++ name ++ " not defined"
|
|
|
|
| otherwise =
|
|
|
|
Map.insert "__result" (evalAST env term) env
|
2024-12-19 18:57:57 -06:00
|
|
|
|
2025-01-19 14:41:25 -06:00
|
|
|
evalTricu :: Env -> [TricuAST] -> Env
|
2025-01-20 19:20:29 -06:00
|
|
|
evalTricu env [] = env
|
|
|
|
evalTricu env [x] =
|
|
|
|
let updatedEnv = evalSingle env x
|
|
|
|
in Map.insert "__result" (result updatedEnv) updatedEnv
|
|
|
|
evalTricu env (x:xs) =
|
|
|
|
evalTricu (evalSingle env x) xs
|
2024-12-19 18:57:57 -06:00
|
|
|
|
2025-01-19 14:41:25 -06:00
|
|
|
evalAST :: Env -> TricuAST -> T
|
|
|
|
evalAST env term
|
2025-01-20 15:16:27 -06:00
|
|
|
| SLambda _ _ <- term = evalAST env (elimLambda term)
|
2025-01-19 14:41:25 -06:00
|
|
|
| SVar name <- term = evalVar name
|
|
|
|
| TLeaf <- term = Leaf
|
|
|
|
| TStem t <- term = Stem (evalAST env t)
|
|
|
|
| TFork t u <- term = Fork (evalAST env t) (evalAST env u)
|
|
|
|
| SApp t u <- term = apply (evalAST env t) (evalAST env u)
|
|
|
|
| SStr s <- term = ofString s
|
|
|
|
| SInt n <- term = ofNumber n
|
|
|
|
| SList xs <- term = ofList (map (evalAST env) xs)
|
|
|
|
| SEmpty <- term = Leaf
|
|
|
|
| otherwise = errorWithoutStackTrace "Unexpected AST term"
|
|
|
|
where
|
2025-01-20 15:16:27 -06:00
|
|
|
evalVar name = Map.findWithDefault
|
2025-01-19 14:41:25 -06:00
|
|
|
(errorWithoutStackTrace $ "Variable " ++ name ++ " not defined")
|
|
|
|
name env
|
2024-12-27 08:17:06 -06:00
|
|
|
|
2024-12-27 15:40:50 -06:00
|
|
|
-- https://github.com/barry-jay-personal/typed_tree_calculus/blob/main/typed_program_analysis.pdf
|
2024-12-29 20:29:41 -06:00
|
|
|
-- Chapter 4: Lambda-Abstraction
|
2025-01-19 14:41:25 -06:00
|
|
|
elimLambda :: TricuAST -> TricuAST
|
|
|
|
elimLambda = go
|
|
|
|
where
|
|
|
|
go (SLambda (v:vs) body)
|
|
|
|
| null vs = toSKI v (elimLambda body)
|
|
|
|
| otherwise = elimLambda (SLambda [v] (SLambda vs body))
|
2025-01-20 16:05:06 -06:00
|
|
|
go (SApp f g) = SApp (elimLambda f) (elimLambda g)
|
2025-01-19 14:41:25 -06:00
|
|
|
go x = x
|
2024-12-27 08:17:06 -06:00
|
|
|
|
2025-01-19 14:41:25 -06:00
|
|
|
toSKI x (SVar y)
|
2025-01-20 16:05:06 -06:00
|
|
|
| x == y = _I
|
|
|
|
| otherwise = SApp _K (SVar y)
|
2025-01-19 14:41:25 -06:00
|
|
|
toSKI x t@(SApp n u)
|
2025-01-20 16:05:06 -06:00
|
|
|
| not (isFree x t) = SApp _K t
|
|
|
|
| otherwise = SApp (SApp _S (toSKI x n)) (toSKI x u)
|
2025-01-19 14:41:25 -06:00
|
|
|
toSKI x t
|
|
|
|
| not (isFree x t) = SApp _K t
|
|
|
|
| otherwise = SApp (SApp _S (toSKI x t)) TLeaf
|
2024-12-27 08:17:06 -06:00
|
|
|
|
2025-01-19 14:41:25 -06:00
|
|
|
_S = parseSingle "t (t (t t t)) t"
|
|
|
|
_K = parseSingle "t t"
|
|
|
|
_I = parseSingle "t (t (t t)) t"
|
|
|
|
|
|
|
|
isFree x = Set.member x . freeVars
|
|
|
|
freeVars (SVar v ) = Set.singleton v
|
|
|
|
freeVars (SInt _ ) = Set.empty
|
|
|
|
freeVars (SStr _ ) = Set.empty
|
|
|
|
freeVars (SList s ) = foldMap freeVars s
|
|
|
|
freeVars (SApp f a ) = freeVars f <> freeVars a
|
|
|
|
freeVars (TLeaf ) = Set.empty
|
|
|
|
freeVars (SFunc _ _ b) = freeVars b
|
|
|
|
freeVars (TStem t ) = freeVars t
|
|
|
|
freeVars (TFork l r ) = freeVars l <> freeVars r
|
|
|
|
freeVars (SLambda v b ) = foldr Set.delete (freeVars b) v
|
2024-12-27 08:17:06 -06:00
|
|
|
|
2025-01-19 14:41:25 -06:00
|
|
|
result :: Env -> T
|
2024-12-27 12:27:00 -06:00
|
|
|
result r = case Map.lookup "__result" r of
|
2024-12-30 14:19:43 -06:00
|
|
|
Just a -> a
|
2025-01-02 19:08:14 -06:00
|
|
|
Nothing -> errorWithoutStackTrace "No __result field found in provided environment"
|