-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBuiltin.hs
138 lines (116 loc) · 4.9 KB
/
Builtin.hs
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
{-# OPTIONS_GHC -fwarn-tabs #-}
{-# LANGUAGE GADTs, DataKinds, FlexibleInstances #-}
module Builtin where
import Language
import Data.Map (Map)
import qualified Data.Map as Map
arithTy :: FuncType
arithTy = F (S "A" [VIntTy, VIntTy]) (S "A" [VIntTy])
plus :: [Value] -> [Value]
plus (IntVal y : IntVal x : s) = IntVal (x + y) : s
minus :: [Value] -> [Value]
minus (IntVal y : IntVal x : s) = IntVal (x - y) : s
times :: [Value] -> [Value]
times (IntVal y : IntVal x : s) = IntVal (x * y) : s
equal :: [Value] -> [Value]
equal (IntVal y : IntVal x : s) = BoolVal (x == y) : s
equalTy :: FuncType
equalTy = F (S "A" [VIntTy, VIntTy]) (S "A" [VBoolTy])
apply :: [Value] -> [Value]
apply (FuncVal _ f : s) = f s
apply1to1Ty :: FuncType
apply1to1Ty = F (S "A" [VVarTy "a", appliedFuncTy]) (S "A" [VVarTy "b"])
where appliedFuncTy = VFuncTy (F (S "B" [VVarTy "a"]) (S "B" [VVarTy "b"]))
apply2to1Ty :: FuncType
apply2to1Ty = F (S "A" [VVarTy "b", VVarTy "a", appliedFuncTy])
(S "A" [VVarTy "c"])
where appliedFuncTy = VFuncTy (F (S "B" [VVarTy "b", VVarTy "a"])
(S "B" [VVarTy "c"]))
apply2to2Ty :: FuncType
apply2to2Ty = F (S "A" [VVarTy "b", VVarTy "a", appliedFuncTy])
(S "A" [VVarTy "d", VVarTy "c"])
where appliedFuncTy = VFuncTy (F (S "B" [VVarTy "b", VVarTy "a"])
(S "B" [VVarTy "d", VVarTy "c"]))
pop :: [Value] -> [Value]
pop (x : s) = s
popTy :: FuncType
popTy = F (S "A" [VVarTy "a"]) (S "A" [])
dup :: [Value] -> [Value]
dup (x : s) = x : x : s
dupTy :: FuncType
dupTy = F (S "A" [VVarTy "a"]) (S "A" [VVarTy "a", VVarTy "a"])
swap :: [Value] -> [Value]
swap (y : x : s) = x : y : s
swapTy :: FuncType
swapTy = F (S "A" [VVarTy "a", VVarTy "b"]) (S "A" [VVarTy "b", VVarTy "a"])
dip :: [Value] -> [Value]
dip (FuncVal _ f : b : s) = b : f s
dip1to1Ty :: FuncType
dip1to1Ty = F (S "A" [VVarTy "a", VVarTy "b", appliedFuncTy])
(S "A" [VVarTy "c", VVarTy "b"])
where appliedFuncTy = VFuncTy (F (S "B" [VVarTy "a"]) (S "B" [VVarTy "c"]))
dip2to1Ty :: FuncType
dip2to1Ty = F (S "A" [VVarTy "a", VVarTy "b", VVarTy "c", appliedFuncTy])
(S "A" [VVarTy "d", VVarTy "c"])
where appliedFuncTy = VFuncTy (F (S "B" [VVarTy "a", VVarTy "b"])
(S "B" [VVarTy "d"]))
dip2to2Ty :: FuncType
dip2to2Ty = F (S "A" [VVarTy "a", VVarTy "b", VVarTy "c", appliedFuncTy])
(S "A" [VVarTy "d", VVarTy "e", VVarTy "c"])
where appliedFuncTy = VFuncTy (F (S "B" [VVarTy "a", VVarTy "b"])
(S "B" [VVarTy "d", VVarTy "e"]))
-- adapted from https://programmers.stackexchange.com/questions/215712/type-checking-and-recursive-types-writing-the-y-combinator-in-haskell-ocaml
newtype Mu a = Roll { unroll :: Mu a -> a }
fixImpl :: ((a -> b) -> a -> b) -> a -> b
fixImpl f = (\x a -> f (unroll x x) a) $ Roll (\x a -> f (unroll x x) a)
fix :: [Value] -> [Value]
fix (FuncVal ty f : s) = fixImpl (\g a -> f (FuncVal ty g : a)) s
fixTy :: FuncType
fixTy = F (S "A" [VVarTy "a", outerFuncTy]) (S "A" [VVarTy "b"])
where outerFuncTy = VFuncTy (F (S "B" [VVarTy "a", innerFuncTy])
(S "B" [VVarTy "b"]))
innerFuncTy = VFuncTy (F (S "C" [VVarTy "a"]) (S "C" [VVarTy "b"]))
ifFunc :: [Value] -> [Value]
ifFunc (BoolVal b : x : y : s) = (if b then x else y) : s
ifTy :: FuncType
ifTy = F (S "A" [VVarTy "a", VVarTy "a", VBoolTy]) (S "A" [VVarTy "a"])
cons :: [Value] -> [Value]
cons (x : ListVal ty l : s) = ListVal ty (x : l) : s
consTy :: FuncType
consTy = F (S "A" [VListTy $ VVarTy "a", VVarTy "a"])
(S "A" [VListTy $ VVarTy "a"])
listMatch :: [Value] -> [Value]
listMatch (ListVal _ [] : FuncVal _ nilCase : _ : s) =
nilCase [] ++ s
listMatch (ListVal ty (x : xs) : _ : FuncVal _ consCase : s) =
consCase [x, ListVal ty xs] ++ s
listMatchTy :: FuncType
listMatchTy = F (S "A" [consCaseTy, nilCaseTy, VListTy $ VVarTy "a"])
(S "A" [VVarTy "b"])
where consCaseTy = VFuncTy (F (S "B" [VListTy $ VVarTy "a", VVarTy "a"])
(S "B" [VVarTy "b"]))
nilCaseTy = VFuncTy (F (S "C" []) (S "C" [VVarTy "b"]))
builtins :: Map Builtin ([Value] -> [Value], FuncType)
builtins = Map.fromList
[ ("plus", (plus, arithTy))
, ("minus", (minus, arithTy))
, ("times", (times, arithTy))
, ("equal", (equal, equalTy))
, ("apply1to1", (apply, apply1to1Ty))
, ("apply2to1", (apply, apply2to1Ty))
, ("apply2to2", (apply, apply2to2Ty))
, ("pop", (pop, popTy))
, ("dup", (dup, dupTy))
, ("swap", (swap, swapTy))
, ("dip1to1", (dip, dip1to1Ty))
, ("dip2to1", (dip, dip2to1Ty))
, ("dip2to2", (dip, dip2to2Ty))
, ("fix", (fix, fixTy))
, ("if", (ifFunc, ifTy))
, ("cons", (cons, consTy))
, ("listMatch", (listMatch, listMatchTy))
]
builtinFuncs :: Map Builtin ([Value] -> [Value])
builtinFuncs = Map.map fst builtins
builtinTypes :: Map Builtin FuncType
builtinTypes = Map.map snd builtins