summaryrefslogtreecommitdiff
path: root/test/example1.spl
blob: d896c3d2744eb05067ecc6dd89144ee9189e25f7 (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
/*
	Three ways to implement the factorial function in SPL.
	First the recursive version.
*/
facR(n) :: Int -> Int {
	if (n < 2) {
		return 1;
	} else {
		return n * facR(n - 1);
	}
}

// The iterative version of the factorial function
faclI(n) :: Int -> Int {
	var r = 1;
	while(n > 1) {
		r = r * n;
		n = n - 1;
	}
	return r;
}

// A min function to check the results
// It takes no arguments, so the type looks like this:
main() :: -> Void {
	var n = 0;
	var facN = 1;
	var ok = True;
	while(n < 20) {
		facN = facR(n);
		if(facN != facI(n) || facN != facL(n)) {
			print(n : facN : facI(n) : facL(n) : []);
			ok = False;
		}
		n = n + 1;
	}
	print(ok);
}

// A list based factorial function
// Defined here to show that functions can be given in any order (unlike C)
facL(n) :: Int -> Int {
	return product(fromTo(1,n));
}

// Computes the product of a list of integers
product(list) :: [Int] -> Int {
	if(isEmpty(list)) {
		return 1;
	} else {
		return list.hd * product(list.tl);
	}
}

// Generates a list of integers from the first to the last argument
fromTo(from, to) :: Int Int -> [Int] {
	if(from <= to) {
		return from : fromTo(from + 1, to);
	} else {
		return [];
	}
}

// Make a reversed copy of any list
reverse(list) :: [t] -> [t] {
	var accu = [];
	while(!isEmpty(list)) {
		accu = list.hd : accu;
		list = list.tl;
	}
	return accu;
}

// Absolute value, in a strange layout
abs ( n ) :: Int -> Int {if ( n<0 ) return -n; else return n; }

// make a copy of a tuple with swapped elements
swapCopy(pair) :: (a, b) -> (b, a) {
	return (pair.snd, pair.fst);
}

swap(tuple) :: (a, a) -> (a, a) {
	var tmp = tuple.fst;
	tuple.fst = tuple.snd;
	tuple.snd = tmp;
	return tuple;
}

// list append
append(l1, l2) :: [t] [t] -> [t] {
	if(isEmpty(l1)) {
		return l2;
	} else {
		l1.tl = append(l1.tl, l2);
		return l1;
	}
}

// square the odd numbers in a list and remove the even numbers
squareOddNumbers(list) :: [Int] -> [Int] {
	while(!isEmpty(list) && list.hd % 2 == 0) {
		list = list.tl;
	}
	if(!isEmpty(list)) {
		list.hd = list.hd * list.hd;
		list.tl = squareOddNumbers(list.tl);
	}
	return list;
}