repos / machines.hs.git


commit
7ae50ab
parent
b3d223c
author
Evgenii Akentev
date
2024-09-07 19:16:54 +0400 +04
Add Virtual VEC machine
2 files changed,  +65, -0
M machines.cabal
+1, -0
1@@ -22,6 +22,7 @@ library
2                       Virtual.CEK,
3                       Virtual.Krivine,
4                       Virtual.CAM,
5+                      Virtual.VEC,
6     build-depends:    base ^>=4.18.2.1
7     hs-source-dirs:   src
8     default-language: Haskell2010
A src/Virtual/VEC.hs
+64, -0
 1@@ -0,0 +1,64 @@
 2+{-# language LambdaCase #-}
 3+
 4+module Virtual.VEC where
 5+
 6+-- From Interpreter to Compiler and
 7+-- Virtual Machine: A Functional Derivation
 8+-- https://pdfs.semanticscholar.org/08f9/c12239dd720cb28a1039db9ce706cc7ee3b2.pdf
 9+
10+data Term = App Term Term | CBNLam String Term | CBVLam String Term | Var String | Lit Literal | Succ Term | IfThenElse Term Term Term 
11+data Literal = BoolLit Bool | NumLit Int
12+  deriving (Show)
13+data Inst = Pushclosure [Inst] | Pushconst Literal | Call | Return | Push String | Bind String | Incr | Test [Inst] [Inst]
14+  deriving (Show)
15+type Env = [(String, Val)]
16+data Val = Closure [Inst] Env | Primitive Literal
17+  deriving (Show)
18+
19+compile :: Term -> [Inst]
20+compile = \case
21+  (App t0 t1) -> Pushclosure (compile t1 ++ [Return]) : compile t0 ++ [Call] 
22+  (CBNLam x t) -> [Pushclosure (Bind x : compile t ++ [Return])]
23+  (CBVLam x t) -> [Pushclosure (Call : Bind x : compile t ++ [Return])]
24+  (Var x) -> [Push x]
25+  (Lit l) -> [Pushconst l]
26+  (Succ t) -> compile t ++ [Incr]
27+  (IfThenElse t0 t1 t2) -> compile t0 ++ [Test (compile t1) (compile t2)]
28+
29+run :: [Val] -> [Env] -> [Inst] -> Val
30+run vs (e : es) (Pushclosure c':cs) = run (Closure c' e : vs) (e : es) cs
31+run vs es (Pushconst l : cs) = run (Primitive l:vs) es cs
32+run (Closure c' e : vs) es (Call : cs) = run vs (e : es) (c' ++ cs)
33+run vs (_:es) (Return : cs) = run vs es cs
34+run vs (e:es) (Push x : cs) = case lookup x e of
35+  Just v@(Primitive _) -> run (v : vs) (e : es) cs
36+  Just (Closure c' e') -> run vs (e' : e : es) (c' ++ cs) 
37+  Nothing -> error "var not in scope"
38+run (v : vs) (e : es) (Bind x : cs) = run vs (((x, v):e) : es) cs
39+run (Primitive (NumLit n) : vs) es (Incr : cs) = run (Primitive (NumLit $ n + 1) : vs) es cs
40+run (Primitive (BoolLit True) : vs) es (Test c1 _ : cs) = run vs es (c1 ++ cs)
41+run (Primitive (BoolLit False) : vs) es (Test _ c2 : cs) = run vs es (c2 ++ cs)
42+run (v:_) _ [] = v 
43+run _ _ _ = error "Impossible"
44+
45+eval :: Term -> Val
46+eval t = run [] [[]] $ compile t
47+
48+t1 :: Term
49+t1 = Succ $ (Lit $ NumLit 2)
50+
51+ex1 :: Val 
52+ex1 = eval t1
53+
54+--((λ 0) (λ 0)) (λ 0)
55+t2 :: Term
56+t2 = App (App (CBNLam "x" $ Var "x") (CBNLam "x" $ Var "x")) (CBNLam "x" $ Var "x")
57+
58+ex2 :: Val 
59+ex2 = eval t2
60+
61+t3 :: Term
62+t3 = App (App (App (CBNLam "x" $ CBNLam "y" $ CBNLam "z" $ IfThenElse (Var "x") (Succ $ Var "y") (Var "z")) (Lit $ BoolLit True)) (Lit $ NumLit 2)) (Lit $ NumLit 7)
63+
64+ex3 :: Val
65+ex3 = eval t3