summaryrefslogtreecommitdiff
path: root/pascal.icl
blob: d916aa88c8d1cdca29aed59f0c52d98a85f89984 (plain) (blame)
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
module pascal

/*
The Triangle of Pascal.

The result of this program is a real triangle of Pascal of height
Height, not just a list representing such a triangle:

        1
       1 1
      1 2 1
     1 3 3 1
    1 4 6 4 1    etc.
	
Run the program using the "Basic Values Only" option (Application options).
Use a non-proportional font for the output (e.g. Monaco 9).
*/

import _SystemArray

(+) infixl 6 :: !Int !Int -> Int
(+) a b = code inline {
	addI
}

(-) infixl 6 :: !Int !Int -> Int
(-) a b = code inline {
	subI
}

(/) infixl 7 :: !Int !Int -> Int
(/) a b = code inline {
	divI
}

inc :: !Int -> Int
inc a = a + 1

take :: Int [a] -> [a]
take 0 _      = []
take n [x:xs] = [x:take (n-1) xs]
 
(+++) infixr 5 :: !{#Char} !{#Char} -> {#Char}
(+++) a b = code inline {
	.d 2 0
		jsr catAC
	.o 1 0
}

repeat :: a -> [a]
repeat x = cons
where cons = [x:cons]

repeatn :: !.Int a -> [a]
repeatn n x	= take n (repeat x)

spaces :: !.Int -> [Char]
spaces n = repeatn n ' '

class toString a :: !a -> String

instance toString [Char] where toString a = {c \\ c <- a}
instance toString Int where toString a = code inline {
	.d 0 1 i
		jsr ItoAC
	.o 1 0
}

//import StdEnv

/*	A row of the triangle is represented by a list of integers,
	the triangle as a list of rows:
*/

::Row		:== [Int]
::Triangle	:== [Row]

//	Some constants

NrRows :== 18	//	Number of rows to be shown.
Middle :== 40	//	The middle of a 80 character line.

//	Miscellaneous functions

NrOfDigits:: Int -> Int
NrOfDigits 0	=  0
NrOfDigits n	=  NrOfDigits (n / 10) + 1

//	Calculating the Triangle.

Pascal::Triangle
Pascal = p 
where 
	p = [[1] : [Next a \\ a <- p]]

	Next x =  AddRows [0:x] x

	AddRows::Row Row -> Row
	AddRows [a:x] [b:y] =  [a + b : AddRows x y]
	AddRows [a]   []    =  [a]
	AddRows []    []    =  []

//	Formatting the list representing the triangle as a real triangle.

FormatRows::Triangle -> [String]
FormatRows [f:r] =  [ FormatRow f  +++ "\n" : FormatRows r]
where
	FormatRow::Row -> String
	FormatRow row
		=   toString (spaces (Middle - Length_new row/2 ))  +++  FormatElems row 

	FormatElems::Row -> String
	FormatElems [f:r] =  " " +++ toString f +++  FormatElems r  
	FormatElems []    =  ""

	Length_new::Row -> Int
	Length_new [f:r] =  NrOfDigits f +  Length_new r + 1
	Length_new []	 =  -1
FormatRows []    =  []

/*	The Start rule: The first NrRows rows of the (infinite) triangle
	returned by Pascal are taken and shown on the screen as a
	triangle by means of FormatRows.
*/

Start::[String]
Start = FormatRows (take NrRows Pascal)