Skip to content

Commit 59365ad

Browse files
Revamped examples
1 parent 436659b commit 59365ad

File tree

11 files changed

+351
-4
lines changed

11 files changed

+351
-4
lines changed

examples/array_list.csh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
include "stdlib/buffer.csh";
2+
3+
record list<T> {
4+
array<T> elems = new T[15];
5+
int count = 0;
6+
}
7+
8+
proc listAdd<T>(list<T> l, T elem) {
9+
if(l.count == #l.elems)
10+
l.elems = realloc<T>(l.elems, l.count + 5);
11+
l.elems[l.count] = elem;
12+
l.count = l.count + 1;
13+
}
14+
15+
proc listInsert<T>(list<T> l, int i, T elem) {
16+
if(l.count == #l.elems)
17+
l.elems = realloc<T>(l.elems, l.count + 5);
18+
memswap<T>(l.elems, i + 1, i, l.count - i);
19+
l.elems[i] = elem;
20+
l.count = l.count + 1;
21+
}
22+
23+
proc listRemoveAt<T>(list<T> l, int i) => memswap<T>(l.elems, i, i + 1, (l.count = l.count - 1) - i);
24+
25+
proc listToArray<T>(list<T> l) {
26+
array<T> buf = new T[l.count];
27+
memcpy<T>(buf, l.elems, 0, 0, l.count);
28+
return buf;
29+
}
30+
31+
proc listGet<T>(list<T> l, int i) => l.elems[i];
32+
proc listSet<T>(list<T> l, int i, T elem) => l.elems[i] = elem;
33+
34+
record searchableList<T> extends list<T> {
35+
readonly proc<bool, T, T> equals;
36+
}
37+
38+
proc listIndexOf<T>(searchableList<T> l, T elem) {
39+
for(int i = 0; i < l.count; i++)
40+
if(l.equals(l.elems[i], elem))
41+
return i;
42+
return -1;
43+
}
44+
45+
proc listRemove<T>(searchableList<T> l, T elem) {
46+
int i = listIndexOf(l, elem);
47+
if(i < 0)
48+
return false;
49+
listRemoveAt<T>(l, i);
50+
return true;
51+
}

examples/binary_tree.csh

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
include "stdlib/std.csh";
2+
3+
abstract record leaf<elemType>;
4+
5+
final record empty_leaf<elemType> extends leaf<elemType>; $this is way better than a potentially unsafe "null"
6+
7+
final record node<elemType> extends leaf<elemType> {
8+
leaf<elemType> left = new empty_leaf<elemType>;
9+
leaf<elemType> right = new empty_leaf<elemType>;
10+
readonly elemType elem;
11+
}
12+
13+
final record tree<elemType> {
14+
leaf<elemType> head = new empty_leaf<elemType>;
15+
readonly proc<int, elemType, elemType> compare;
16+
}
17+
18+
proc insert<elemType>(tree<elemType> t, elemType elem) {
19+
if(t.head is empty_leaf<any>)
20+
return t.head = new node<elemType> {
21+
elem = elem;
22+
};
23+
else {
24+
node<elemType> current = dynamic_cast<node<elemType>>(t.head);
25+
while(true) {
26+
int comp_res = t.compare(elem, current.elem);
27+
if(comp_res > 0) { $elem > current.elem
28+
if(current.right is empty_leaf<any>)
29+
return current.right = new node<elemType> {
30+
elem = elem;
31+
};
32+
current = dynamic_cast<node<elemType>>(current.right);
33+
}
34+
else if(comp_res < 0) { $elem < current.elem
35+
if(current.left is empty_leaf<any>)
36+
return current.left = new node<elemType> {
37+
elem = elem;
38+
};
39+
current = dynamic_cast<node<elemType>>(current.left);
40+
}
41+
else
42+
return current;
43+
}
44+
}
45+
}
46+
47+
final record elem_not_found<elemType> extends error<node<elemType>> {
48+
msg = "Element not found";
49+
}
50+
51+
proc find<elemType>(tree<elemType> t, elemType elem) return fallible<node<elemType>> {
52+
leaf<elemType> current = t.head;
53+
while(current is node<elemType>) {
54+
node<elemType> current_node = dynamic_cast<node<elemType>>(current);
55+
int comp_res = t.compare(elem, current_node.elem);
56+
if(comp_res > 0) $elem > node.elem
57+
current = current_node.right;
58+
else if(comp_res < 0) $elem < node.elem
59+
current = current_node.left;
60+
else
61+
return new success<node<elemType>> {
62+
result = current_node;
63+
};
64+
}
65+
$if the program made it to this point, no value has been found
66+
return new elem_not_found<elemType>;
67+
}

examples/bintree-test.csh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
include "stdlib/std.csh";
2+
include "stdlib/io.csh";
3+
include "stdlib/random.csh";
4+
include "examples/binary_tree.csh";
5+
6+
proc print_tree<elemType>(tree<elemType> e, proc<nothing, elemType> printElem) {
7+
proc print_leaf<elemType>(leaf<elemType> l, proc<nothing, elemType> printElem, int depth) {
8+
for(int i = 0; i < depth; i++)
9+
putChar('\t');
10+
11+
if(l is empty_leaf<any>)
12+
println("empty");
13+
else {
14+
node<elemType> node = dynamic_cast<node<elemType>>(l);
15+
printElem(node.elem);
16+
putChar('\n');
17+
thisproc<elemType>(node.left, printElem, depth + 1);
18+
thisproc<elemType>(node.right, printElem, depth + 1);
19+
}
20+
}
21+
print_leaf<elemType>(e.head, printElem, 0);
22+
}
23+
24+
auto tree = new tree<int> {
25+
compare = proc(int a, int b) return int {
26+
return a - b;
27+
};
28+
};
29+
30+
for(int i = 0; i < 100; i++)
31+
insert<int>(tree, randirange(0, 100));
32+
33+
print_tree<int>(tree, proc(int i)
34+
print(itos(i));
35+
);

examples/factorial.csh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
include "stdlib/io.sf";
2+
include "stdlib/std.sf";
3+
4+
proc fact(int n) {
5+
if(n == 0)
6+
return 1;
7+
return n * thisproc(n - 1);
8+
}
9+
10+
println(itos(fact(100)));

examples/fib.csh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
include "stdlib/io.sf";
2+
include "stdlib/std.sf";
3+
4+
proc fib(int n) {
5+
if(n <= 1)
6+
return n;
7+
return thisproc(n - 1) + thisproc(n - 2);
8+
}
9+
10+
println(itos(fib(35));

examples/fizzbuzz.csh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
include "stdlib/io.csh";
2+
include "stdlib/std.csh";
3+
4+
auto msgs = memset<array<char>>(new array<char>[15], 0, 15, "\n");
5+
msgs[3] = msgs[6] = msgs[9] = msgs[12] = "fizz";
6+
msgs[5] = msgs[10] = "buzz";
7+
msgs[0] = "fizzbuzz";
8+
9+
for(int i = 0; i < 100; i++)
10+
println(msgs[i % 15]);

examples/linked_list.csh

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
include "stdlib/std.csh";
2+
3+
abstract record listBucket<T>;
4+
5+
final record emptyBucket<T> extends listBucket<T>;
6+
7+
final record elemListBucket<T> extends listBucket<T> {
8+
T elem;
9+
listBucket<T> next = new emptyBucket<T>;
10+
}
11+
12+
final record linkedList<T> {
13+
listBucket<T> head = new emptyBucket<T>;
14+
int count = 0;
15+
}
16+
17+
proc pushFront<T>(linkedList<T> l, T elem) {
18+
l.count = l.count + 1;
19+
return l.head = new elemListBucket<T> {
20+
elem = elem;
21+
next = l.head;
22+
};
23+
};
24+
25+
proc popFront<T>(linkedList<T> l) return fallible<T> {
26+
if(l.head is emptyBucket<any>)
27+
return new invalidOperation<T> {
28+
msg = "Cannot pop from empty list.";
29+
};
30+
else {
31+
l.count = l.count - 1;
32+
auto elemHead = dynamic_cast<elemListBucket<T>>(l.head);
33+
l.head = elemHead.next;
34+
return new success<T> {
35+
result = elemHead.elem;
36+
};
37+
}
38+
};
39+
40+
proc linkedListForAll<T>(linkedList<T> l, proc<nothing, T> todo)
41+
for(listBucket<T> current = l.head; current is elemListBucket<T>; current = dynamic_cast<elemListBucket<T>>(current).next)
42+
todo(dynamic_cast<elemListBucket<T>>(current).elem);
43+
44+
proc linkedListToArray<T>(linkedList<T> l) {
45+
array<T> buffer = new T[l.count];
46+
listBucket<T> current = l.head;
47+
for(int i = 0; i < #buffer; i++) {
48+
auto elemBucket = dynamic_cast<elemListBucket<T>>(current);
49+
buffer[i] = elemBucket.elem;
50+
current = elemBucket.next;
51+
}
52+
return buffer;
53+
};

examples/map.csh

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
include "stdlib/buffer.sf";
2+
include "stdlib/std.sf";
3+
4+
abstract record mapBucket<K, V>;
5+
6+
final record emptyMapBucket<K, V> extends mapBucket<K, V>;
7+
8+
final record keyValuePair<K, V> extends mapBucket<K, V> {
9+
readonly K key;
10+
readonly V value;
11+
12+
readonly int keyHash;
13+
}
14+
15+
record map<K, V> {
16+
array<mapBucket<K, V>> buckets = memset<mapBucket<K, V>>(new mapBucket<K, V>[50], 0, 50, new emptyMapBucket<K, V>);
17+
proc<int, K> hasher;
18+
}
19+
20+
proc mapEmplace<K, V>(map<K, V> m, K key, V value) {
21+
proc emplace<K, V>(map<K, V> m, keyValuePair<K, V> pair) {
22+
for(int i = pair.keyHash % #m.buckets; i < #m.buckets; i++)
23+
if(m.buckets[i] is emptyMapBucket<any, any>)
24+
return m.buckets[i] = pair;
25+
else {
26+
auto kvBucket = dynamic_cast<keyValuePair<K, V>>(m.buckets[i]);
27+
if(kvBucket.keyHash == pair.keyHash)
28+
return m.buckets[i] = pair;
29+
}
30+
31+
auto oldBuckets = m.buckets;
32+
m.buckets = memset<mapBucket<K, V>>(new mapBucket<K, V>[#oldBuckets + 5], 0, #oldBuckets + 5, new emptyMapBucket<K, V>);
33+
for(int i = 0; i < #oldBuckets; i++)
34+
if(oldBuckets[i] is keyValuePair<K, V>)
35+
thisproc<K, V>(m, dynamic_cast<keyValuePair<K, V>>(oldBuckets[i]));
36+
return thisproc<K, V>(m, pair);
37+
}
38+
39+
emplace<K, V>(m, new keyValuePair<K, V> {
40+
key = key;
41+
value = value;
42+
keyHash = m.hasher(key);
43+
});
44+
}
45+
46+
final record keyNotFound<K, V> extends error<V> {
47+
readonly K key;
48+
msg = "Key not found.";
49+
}
50+
51+
proc mapFind<K, V>(map<K, V> m, K key) return fallible<V> {
52+
int keyHash = m.hasher(key);
53+
for(int i = keyHash % #m.buckets; i < #m.buckets; i++)
54+
if(m.buckets[i] is keyValuePair<K, V>) {
55+
auto kvBucket = dynamic_cast<keyValuePair<K, V>>(m.buckets[i]);
56+
if(kvBucket.keyHash == keyHash)
57+
return new success<V> {
58+
result = kvBucket.value;
59+
};
60+
}
61+
62+
return new keyNotFound<K, V> {
63+
key = key;
64+
};
65+
}

examples/sumtypes.csh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
abstract record fallible<TReturn>;
2+
3+
record error<TReturn> extends fallible<TReturn> {
4+
readonly array<char> msg;
5+
}
6+
7+
final record success<TReturn> extends fallible<TReturn> {
8+
readonly TReturn result;
9+
}
10+
11+
proc fallibleFunction(int i) return fallible<int> {
12+
if(i % 5 == 2)
13+
return new error<int> {
14+
msg = "I don't like 5 and 2";
15+
};
16+
return success<int> {
17+
result = 7;
18+
};
19+
}
20+
21+
auto err = fallibleFunction(52);
22+
if(err is error<any>)
23+
println(dynamic_cast<error<any>>(err).msg);
24+
else
25+
println("I am happy!");
26+
27+
abstract record nullable<Ttype>;
28+
final record null<Ttype> extends nullable<Ttype>
29+
final record notnull<Ttype> extends nullable<Ttype> {
30+
Ttype value;
31+
}
32+
33+
abstract record ipAddr;
34+
final record ipv4 extends ipAddr {
35+
int addr;
36+
}
37+
final record ivp6 extends ipAddr {
38+
array<int> data;
39+
}
40+
41+
proc doSomeIpStuff<addrType extends ipAddr>(addrType addr) {
42+
if(addrType is ipv4)
43+
println("Ipv4 stuff....");
44+
else if(addrType is ipv6)
45+
println("Ipv6 stuff.....");
46+
}

stdlib/random.csh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
proc randirange(int start, int stop) =>
2-
(foreign[10] % (stop - start)) + stop;
2+
(foreign[10] % (stop - start)) + stop
33

44
proc randbool() =>
5-
(foreign[10] % 2) == 0;
5+
(foreign[10] % 2) == 0

0 commit comments

Comments
 (0)