module V3.UntypedInterpreter where
open import Library
open import V3.AST
data Val : Set where
intV : ℤ → Val
boolV : Boolean → Val
instance
PrintVal : Print Val
print {{PrintVal}} = λ where
(intV i) → print i
(boolV b) → print b
Env : Set
Env = List (Id × Val)
lookupId : Env → Id → Maybe Val
lookupId [] y = nothing
lookupId ((x , v) ∷ xs) y =
if x == y
then just v
else lookupId xs y
updateEnv : Id → Val → Env → Env
updateEnv x v [] = (x , v) ∷ []
updateEnv x v ((y , w) ∷ ρ) =
if x == y
then (x , v) ∷ ρ
else (y , w) ∷ updateEnv x v ρ
bNot : Boolean → Boolean
bNot true = false
bNot false = true
bAnd : Boolean → Boolean → Boolean
bAnd true b = b
bAnd false _ = false
bIf : {A : Set} → Boolean → A → A → A
bIf true x y = x
bIf false x y = y
iGt : (i j : ℤ) → Boolean
iGt i j = case i Integer.<= j of λ where
false → true
true → false
module EvalExp (ρ : Env) where
eval : Exp → Maybe Val
eval (eId x) = lookupId ρ x
eval (eInt i) = just (intV i)
eval (eBool b) = just (boolV b)
eval (ePlus e₁ e₂) = case (eval e₁ , eval e₂) of λ where
(just (intV i) , just (intV j)) → just (intV (i + j))
_ → nothing
eval (eGt e₁ e₂) = case (eval e₁ , eval e₂) of λ where
(just (intV i) , just (intV j)) → just (boolV (iGt i j))
_ → nothing
eval (eAnd e₁ e₂) = case (eval e₁ , eval e₂) of λ where
(just (boolV b₁) , just (boolV b₂)) → just (boolV (bAnd b₁ b₂))
_ → nothing
eval (eCond e₁ e₂ e₃) = case (eval e₁) of λ where
(just (boolV b)) → bIf b (eval e₂) (eval e₃)
_ → nothing
open EvalExp
execDecl : Decl → Env → Maybe Env
execDecl (dInit t x e) ρ = case eval ρ e of λ where
(just v) → just ((x , v) ∷ ρ)
nothing → nothing
execDecls : List Decl → Env → Maybe Env
execDecls [] ρ = just ρ
execDecls (d ∷ ds) ρ = case execDecl d ρ of λ where
(just ρ') → execDecls ds ρ'
nothing → nothing
module ExecStm where
mutual
execStm : (fuel : ℕ) → Stm → Env → Maybe Env
execStm _ (sAss x e) ρ = case eval ρ e of λ where
(just v) → just (updateEnv x v ρ)
nothing → nothing
execStm 0 (sWhile e ss) ρ = nothing
execStm (suc fuel) (sWhile e ss) ρ = case eval ρ e of λ where
(just (boolV true)) → case execStms fuel ss ρ of λ where
(just ρ') → execStm fuel (sWhile e ss) ρ'
nothing → nothing
(just (boolV false)) → just ρ
_ → nothing
execStms : (fuel : ℕ) → List Stm → Env → Maybe Env
execStms _ [] ρ = just ρ
execStms fuel (s ∷ ss) ρ = case execStm fuel s ρ of λ where
(just ρ') → execStms fuel ss ρ'
nothing → nothing
evalPrg : (fuel : ℕ) → Program → Maybe ℤ
evalPrg fuel (program ds ss e) = case execDecls ds [] of λ where
(just ρ₀) → case execStms fuel ss ρ₀ of λ where
(just ρ) → case eval ρ e of λ where
(just (intV v)) → just v
_ → nothing
nothing → nothing
nothing → nothing