-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStackMachine1.idr
More file actions
59 lines (40 loc) · 1.94 KB
/
StackMachine1.idr
File metadata and controls
59 lines (40 loc) · 1.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
module StackMachine1
import Data.Nat
import Data.List
import Data.Maybe
data Binop = Plus | Times
data Instr = IConst Nat | IBinop Binop
data Exp = EConst Nat | EBinop Binop Exp Exp
Prog = List Instr
Stack = List Nat
binopDenote : Binop -> Nat -> Nat -> Nat
binopDenote Plus = (+)
binopDenote Times = (*)
expDenote : Exp -> Nat
expDenote (EConst n) = n
expDenote (EBinop b e1 e2) = (binopDenote b) (expDenote e1) (expDenote e2)
instrDenote : Instr -> Stack -> Maybe Stack
instrDenote (IConst n) s = Just (n :: s)
instrDenote (IBinop b) (x :: (y :: zs)) = let h = ((binopDenote b) x y) in
Just (h :: zs)
instrDenote (IBinop _) _ = Nothing
progDenote : Prog -> Stack -> Maybe Stack
progDenote [] s = Just s
progDenote (i :: p) s = case instrDenote i s of
(Just s') => progDenote p s'
Nothing => Nothing
compile : Exp -> Prog
compile (EConst n) = [IConst n]
compile (EBinop b e1 e2) = compile e2 ++ compile e1 ++ [IBinop b ]
compilerHelper1 : (b : Binop) -> (e1 , e2 : Exp) -> (p : Prog) -> (s : Stack)
-> progDenote (compile (EBinop b e1 e2) ++ p) s
= progDenote ((compile e2 ++ (compile e1 ++ [IBinop b])) ++ p) s
compilerHelper1 e1 e2 b p s = Refl
compilerCorrect : (e : Exp) -> (p : Prog) -> (s : Stack)
-> progDenote (compile e ++ p) s = progDenote p (expDenote e :: s)
compilerCorrect (EConst n) p s = Refl
compilerCorrect (EBinop b e1 e2) p s =
rewrite sym (appendAssociative (compile e2) (compile e1 ++ [IBinop b]) p) in
rewrite compilerCorrect e2 ((compile e1 ++ [IBinop b]) ++ p) s in
rewrite sym (appendAssociative (compile e1) [IBinop b] p) in
rewrite compilerCorrect e1 ([IBinop b] ++ p) (expDenote e2 :: s) in Refl