Skip to content

Commit 8766b75

Browse files
committed
Refactor TI and add examples for lists
1 parent aaeac47 commit 8766b75

File tree

17 files changed

+356
-167
lines changed

17 files changed

+356
-167
lines changed

README.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
1-
# Fun Lazy Compiler (flc)
1+
# Fun Lazy Compiler (`flc`)
22
A (simulated) compiler for a lazy functional language, following the tutorial by Simon Peyton Jones
33

44
See tutorial (for [students][student.pdf]; for [tutors][tutor.pdf])
55

6+
### Usage
7+
```text
8+
fun-lazy-compiler -- a compiler and runtime for the Core lazy functional
9+
language
10+
11+
Usage: flc [FILES] [-v|--verbose]
12+
Compile and evaluate a program in the Core language
13+
14+
Available options:
15+
FILES Source file(s)
16+
-v,--verbose Print extra debugging information
17+
-h,--help Show this help text
18+
```
19+
20+
Source files may be a path to a file or `-` to read from stdin. If no source files are specified, `flc` will read a from stdin until EOF.
21+
622
### Build instructions
723
This project uses the Haskell [Stack][stack] build environment. To build or run tests:
824
```bash
@@ -25,7 +41,8 @@ All Haskell code is auto-formatted using the [brittany][brittany] formatter.
2541
Sample source files are listed in the `examples/` directory.
2642

2743
```bash
28-
$ flc examples/cons.core examples/fibs.core
44+
$ flc nats.core map.core pe1.core
45+
233168
2946
```
3047

3148
### Journal

app/Main.hs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Control.Exception
88
import System.IO.Error
99

1010
import CorePrelude
11-
import Evaluators.TemplateInstantiation.Evaluator
11+
import Evaluators.TemplateInstantiation
1212
import Evaluators.TemplateInstantiation.State
1313
import Language
1414
import Lexer
@@ -24,7 +24,7 @@ data FLCConfig = FLCConfig
2424
flcConfig :: Parser FLCConfig
2525
flcConfig =
2626
FLCConfig
27-
<$> many (argument str (metavar "FILES" <> help "source files"))
27+
<$> many (argument str (metavar "FILES" <> help "Source file(s)"))
2828
<*> switch
2929
(long "verbose" <> short 'v' <> help
3030
"Print extra debugging information"
@@ -72,7 +72,7 @@ performCompileAndPrint FLCConfig { verbose = True } fileContents = mapM_
7272
, ("Parsed AST" , show program)
7373
, ("Prelude", pprint $ preludeDefs ++ extraPreludeDefs)
7474
, ("Pretty-printed program", pprint program)
75-
, ("Evaluation trace" , showResults results)
75+
, ("Evaluation trace" , showTrace results)
7676
, ("Program output" , result)
7777
]
7878
(tokens, program, results, result) = performCompile fileContents
@@ -81,11 +81,13 @@ performCompileAndPrint _ fileContents = putStrLn result
8181

8282
-- Helper to get outputs of compilation stages
8383
-- Note: separately lexes and parses each files, and joins together
84-
-- the scDefs into one program.
84+
-- the scDefs into one program. Does not simply concatenate files due
85+
-- to the specifics of the grammar (strict interleaving of semicolons
86+
-- between supercombinators, and no trailing semicolons).
8587
performCompile :: [String] -> ([Token], CoreProgram, [TiState], String)
8688
performCompile fileContents = (concat tokens, program, results, result)
8789
where
88-
result = showDataNode . getResult $ results
90+
result = showOutput results
8991
results = eval . compile $ program
9092
program = concat asts
9193
asts = syntax <$> tokens

examples/cons.core

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,16 @@
1+
-- Church encoding for `Cons`.
12
-- This file will not compile standalone because there
23
-- is no `main`. Need to include a driver file.
4+
-- Can be used alongside `cons.core`.
35
-- Requires TI Mark 1.
46

5-
-- Church encoding for `cons`.
6-
cons x y z = z x y ;
7-
car x = x K ;
8-
cdr x = x K1 ;
7+
-- Note: no definition of `Nil`, because we haven't
8+
-- defined structured data until TI Mark 5, and we don't
9+
-- actually need `Nil` until we deal with finite lists.
910

10-
-- LISP-style.....
11-
caar = compose car car ;
12-
cadr = compose car cdr ;
13-
cdar = compose cdr car ;
14-
cddr = compose cdr cdr ;
15-
caadr = compose car cadr ;
16-
caaar = compose car caar ;
17-
cdadr = compose cdr cadr ;
18-
cdaar = compose cdr caar ;
19-
caddr = compose car cddr ;
20-
cadar = compose car cdar ;
21-
cdddr = compose cdr cddr ;
22-
cddar = compose cdr cdar ;
23-
24-
getTenth = compose car (compose cdddr (compose cdddr cdddr))
11+
-- This will overwrite the list primitives in TI Mark 5.
12+
-- `cons2.core` may be used without this file to avoid
13+
-- overwritting the `Cons` primitive.
14+
Cons x y z = z x y ;
15+
fst x = x K ;
16+
snd x = x K1

examples/cons2.core

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
-- This file will not compile standalone because there
2+
-- is no `main`. Need to include a driver file.
3+
-- Requires TI Mark 5, or `cons.core` and TI Mark 1.
4+
5+
-- LISP-style.....
6+
car = fst ;
7+
cdr = snd ;
8+
9+
caar = compose car car ;
10+
cadr = compose car cdr ;
11+
cdar = compose cdr car ;
12+
cddr = compose cdr cdr ;
13+
caadr = compose car cadr ;
14+
caaar = compose car caar ;
15+
cdadr = compose cdr cadr ;
16+
cdaar = compose cdr caar ;
17+
caddr = compose car cddr ;
18+
cadar = compose car cdar ;
19+
cdddr = compose cdr cddr ;
20+
cddar = compose cdr cdar ;
21+
22+
getTenth = compose car (compose cdddr (compose cdddr cdddr))

examples/fibs.core

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
-- Infinite stream of fibonacci numbers.
2-
-- Need to import `cons.core`.
3-
-- Requires TI Mark 4.
4-
fibsRec a b = cons a (fibsRec b (a + b)) ;
2+
-- Requires TI Mark 5, or TI Mark 4 with `cons.core`.
3+
fibsRec a b = Cons a (fibsRec b (a + b)) ;
54
fibs = fibsRec 0 1 ;
5+
6+
-- Requires `cons2.core`
67
main = getTenth fibs

examples/map.core

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
-- Common list primitives: `map`, `filter`, `fold`, `take`, `drop`, `nth`.
2+
-- Requires TI Mark 5.
3+
4+
map f xs = caseList xs Nil (map2 f) ;
5+
map2 f x xs = Cons (f x) (map f xs) ;
6+
7+
filter p xs = caseList xs Nil (filter2 p) ;
8+
filter2 p x xs =
9+
let next = filter p xs in
10+
if (p x) (Cons x next) next ;
11+
12+
-- fold(l) :: (a -> b -> a) -> a -> [b] -> [a]
13+
fold f acc xs = caseList xs acc (fold2 f acc) ;
14+
fold2 f acc x xs = fold f (f acc x) xs ;
15+
16+
take n xs = if (n <= 0) Nil (caseList xs Nil (take2 n)) ;
17+
take2 n x xs = Cons x (take (n - 1) xs) ;
18+
19+
takeWhile p xs = caseList xs Nil (takeWhile2 p) ;
20+
takeWhile2 p x xs = if (p x) (Cons x (takeWhile p xs)) Nil ;
21+
22+
drop n xs = if (n <= 0) xs (caseList xs Nil (drop2 n)) ;
23+
drop2 n x xs = drop (n - 1) xs ;
24+
25+
nth n xs = caseList xs abort (nth2 n) ;
26+
nth2 n x xs = if (n <= 0) x (nth (n - 1) xs) ;
27+
28+
-- Sample functions to use with `map`
29+
inc x = x + 1 ;
30+
double x = x * 2 ;
31+
32+
-- Sample predicates to use with `filter`
33+
mod m n = m - (m / n) * n ; -- should be a primitive
34+
even x = mod x 2 == 0 ;
35+
odd x = not (even x) ;
36+
37+
-- Sample accumulators to use with `fold`
38+
add acc val = acc + val ;
39+
mul acc val = acc * val ;
40+
41+
-- Example: sum and product of a list
42+
sum = fold add 0 ;
43+
prod = fold mul 1 ;
44+
45+
-- Example: generate a linear range from a to b, inclusive
46+
range a b = map (add a) (take ((b - a) + 1) nats) ;
47+
48+
-- Example: alternative way to write factorial
49+
-- Requires `nats.core`
50+
fac2 n =
51+
let finiteNats = take n (drop 1 nats) in
52+
prod finiteNats
53+
54+
-- Example programs:
55+
-- main = nth 10 fibs -- requires `fibs.core`
56+
-- main = fac2 10
57+
-- main = length (range 5 10)
58+
-- main = fold add 0 (filter even (range 5 10))
59+
60+
-- Would be nice to have a function that can force a list
61+
-- (because I'm not sure how to do that in this framework
62+
-- at the moment -- is probably similar to the print list
63+
-- functionality described at the end of Mark 5 of the TI).

examples/nats.core

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
-- Infinite stream of natural numbers.
2-
-- Need to import `cons.core`.
3-
-- Requires TI Mark 4.
4-
numsFrom x = cons x (numsFrom (x + 1)) ;
2+
-- Requires TI Mark 5, or TI Mark 4 with `cons.core`.
3+
numsFrom x = Cons x (numsFrom (x + 1)) ;
54
nats = numsFrom 0 ;
5+
6+
-- Requires `cons2.core`
67
main = getTenth nats

examples/ones.core

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
-- Infinite stream of ones.
2-
-- Need to import `cons.core`
3-
-- Requires TI Mark 2.
4-
main = letrec ones = cons 1 ones in getTenth ones
2+
-- Requires TI Mark 5, or TI Mark 2 with `cons.core`.
3+
-- Also requires `cons2.core`.
4+
ones = Cons 1 ones ;
5+
6+
-- Requires `cons2.core`
7+
main = letrec ones = Cons 1 ones in getTenth ones

examples/pe1.core

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- Project Euler 1. Very slow on the TI evaluator :(
2+
-- Requires `nats.core`, `map.core`
3+
N = 1000 ;
4+
5+
ltN x = x < N ;
6+
7+
sumMultsOfMUnderN m =
8+
let multsOfM = map (mul m) nats in
9+
let multsOfMUnderN = takeWhile ltN multsOfM in
10+
sum multsOfMUnderN ;
11+
12+
main =
13+
let f = sumMultsOfMUnderN
14+
in f 3 + f 5 - f 15

fun-lazy-compiler.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ library
2828
exposed-modules:
2929
Alloc
3030
CorePrelude
31+
Evaluators.TemplateInstantiation
3132
Evaluators.TemplateInstantiation.Evaluator
3233
Evaluators.TemplateInstantiation.Node
34+
Evaluators.TemplateInstantiation.Primitives
3335
Evaluators.TemplateInstantiation.PrintUtils
3436
Evaluators.TemplateInstantiation.State
3537
Evaluators.TemplateInstantiation.Statistics

0 commit comments

Comments
 (0)