Skip to content

Commit dd82932

Browse files
committed
Implement pairs for TI Mark 5
1 parent e477193 commit dd82932

File tree

5 files changed

+59
-19
lines changed

5 files changed

+59
-19
lines changed

examples/pair.core

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-- Pair test
2+
-- Requires TI Mark 5.
3+
main = fst (snd (fst (MkPair (MkPair 1 (MkPair 2 3)) 4)))

src/CorePrelude.hs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,34 @@ trueExpr = EConstr 1 0
3535
falseExpr = EConstr 2 0
3636

3737
-- Introduced in section 2.3.4.
38-
-- Execise 2.20: definitions for conditionals added.
38+
-- Execise 2.20: Add definitions for conditionals.
39+
-- Exercise 2.22: Add definitions for pair.
3940
extraPreludeDefs :: CoreProgram
4041
extraPreludeDefs =
4142
[
4243
-- Standard definitions for true/false
4344
("True" , [], trueExpr)
4445
, ("False", [], falseExpr)
46+
-- Conditionals
4547
, ( "and"
4648
, ["x", "y"]
47-
, EAp (EAp (EAp (EVar "if") (EVar "x")) (EVar "y")) falseExpr
49+
, EAp (EAp (EAp (EVar "if") (EVar "x")) (EVar "y")) (EVar "False")
4850
)
4951
, ( "or"
5052
, ["x", "y"]
51-
, EAp (EAp (EAp (EVar "if") (EVar "x")) trueExpr) (EVar "y")
53+
, EAp (EAp (EAp (EVar "if") (EVar "x")) (EVar "True")) (EVar "y")
5254
)
5355
, ( "xor"
5456
, ["x", "y"]
5557
, EAp (EAp (EAp (EVar "if") (EVar "x")) (EAp (EVar "not") (EVar "y")))
5658
(EVar "y")
5759
)
58-
, ("not", ["x"], EAp (EAp (EAp (EVar "if") (EVar "x")) falseExpr) trueExpr)
60+
, ( "not"
61+
, ["x"]
62+
, EAp (EAp (EAp (EVar "if") (EVar "x")) (EVar "False")) (EVar "True")
63+
)
64+
-- Pairs
65+
, ("mkPair", [] , EConstr 1 2)
66+
, ("fst", ["p"], EAp (EAp (EVar "casePair") (EVar "p")) (EVar "K"))
67+
, ("snd", ["p"], EAp (EAp (EVar "casePair") (EVar "p")) (EVar "K1"))
5968
]

src/Evaluators/TemplateInstantiation/Evaluator.hs

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,18 +91,19 @@ allocateSc h (name, args, body) = (h', (name, a))
9191
-- Add primitives to the heap
9292
primitives :: AssocList Name Primitive
9393
primitives =
94-
[ ("negate", Neg)
95-
, ("+" , Add)
96-
, ("-" , Sub)
97-
, ("*" , Mul)
98-
, ("/" , Div)
99-
, ("if" , If)
100-
, (">" , Greater)
101-
, (">=" , GreaterEq)
102-
, ("<" , Less)
103-
, ("<=" , LessEq)
104-
, ("==" , Eq)
105-
, ("~=" , NotEq)
94+
[ ("negate" , Neg)
95+
, ("+" , Add)
96+
, ("-" , Sub)
97+
, ("*" , Mul)
98+
, ("/" , Div)
99+
, ("if" , If)
100+
, (">" , Greater)
101+
, (">=" , GreaterEq)
102+
, ("<" , Less)
103+
, ("<=" , LessEq)
104+
, ("==" , Eq)
105+
, ("~=" , NotEq)
106+
, ("casePair", CasePair)
106107
]
107108

108109
allocatePrim :: TiHeap -> (Name, Primitive) -> (TiHeap, (Name, Addr))
@@ -225,6 +226,7 @@ primStep state Eq = primComp state (==)
225226
primStep state NotEq = primComp state (/=)
226227
primStep state (Constr tag arity) = primConstr state tag arity
227228
primStep state If = primIf state
229+
primStep state CasePair = primCasePair state
228230

229231
-- Exercise 2.16: evaluation of `negate` (the only unary primitive)
230232
primNeg :: TiState -> TiState
@@ -331,11 +333,33 @@ primIf (s, d, h, e, stats) = state' where
331333
| otherwise = error "primIf: conditional is not a boolean"
332334
-- Stack and dump if argument is not evaluated
333335
s'' = [condAddr]
334-
d' = s' : d
336+
d' = tail s : d
335337
-- Get arguments
336338
condAddr : thenAddr : elseAddr : _ = getArgs h s
337339
cond = hLookup h condAddr
338340

341+
-- Exercise 2.22: implement `casePair` primitive. This is fairly similar
342+
-- to the evaluation of primIf
343+
primCasePair :: TiState -> TiState
344+
primCasePair (s, d, h, e, stats) = state' where
345+
state' | s' == [] = error "primCasePair: not enough arguments to casePair"
346+
| isDataNode pair = (s', d, h'', e, stats)
347+
| otherwise = (s'', d', h, e, stats)
348+
-- Stack, heap, and n if conditional is already evaluated
349+
s' = drop 2 s
350+
rootAddr : _ = s'
351+
(h', ap) = hAlloc h $ NAp handlerAddr pair1Addr
352+
h'' = hUpdate h' rootAddr $ NAp ap pair2Addr
353+
-- Stack and dump if argument is not evaluated
354+
s'' = [pairAddr]
355+
d' = tail s : d
356+
-- Get arguments
357+
(pair1Addr, pair2Addr) = getPairAddrs pair
358+
getPairAddrs (NData 1 [pair1Addr', pair2Addr']) = (pair1Addr', pair2Addr')
359+
getPairAddrs _ = error "primCasePair: argument is not a pair"
360+
pairAddr : handlerAddr : _ = getArgs h s
361+
pair = hLookup h pairAddr
362+
339363
-- Looks up all the arguments (names) for NAp nodes on the spine
340364
getArgs :: TiHeap -> TiStack -> [Addr]
341365
getArgs _ [] = error "getArgs: empty stack"

src/Evaluators/TemplateInstantiation/Node.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ data Node = NAp Addr Addr -- Application
1919
deriving (Eq, Show)
2020

2121
data Primitive = Neg | Add | Sub | Mul | Div
22-
| Constr Int Int | If
22+
| Constr Int Int | If | CasePair
2323
| Greater | GreaterEq | Less | LessEq | Eq | NotEq
2424
deriving (Eq, Show)
2525

test/Evaluators/TemplateInstantiation/EvaluatorTests.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ progChurch, progCons, progInfinite1, progInfinite2, progInfinite3 :: String
1212
progAnd1, progAnd2, progAnd3, progAnd4 :: String
1313
progOr1, progOr2, progOr3, progOr4 :: String
1414
progXor1, progXor2, progXor3, progXor4 :: String
15-
progFac, progFib :: String
15+
progFac, progFib, progPair :: String
1616

1717
-- Exercise 2.4
1818
progSKK3 = "main = S K K 3"
@@ -108,6 +108,9 @@ progFac = "fac n = if (n == 0) 1 (n * fac (n - 1)) ;\
108108
progFib = "fib n = if (n < 2) n (fib (n - 1) + fib (n - 2)) ;\
109109
\main = fib 6"
110110

111+
-- Exercise 2.22: Pair
112+
progPair = "main = fst (snd (fst (MkPair (MkPair 1 (MkPair 2 3)) 4)))"
113+
111114
tests :: Test
112115
tests = test
113116
[ "exercise 2.4" ~: runGetNumResult progSKK3 ~=? 3
@@ -141,4 +144,5 @@ tests = test
141144
, "xor T T" ~: not (runGetBoolResult progXor4) ~? ""
142145
, "factorial" ~: runGetNumResult progFac ~=? 6
143146
, "naive fib" ~: runGetNumResult progFib ~=? 8
147+
, "pairs" ~: runGetNumResult progPair ~=? 2
144148
]

0 commit comments

Comments
 (0)