Repository navigation
Expand file tree
/
Copy pathmain.myca
More file actions
142 lines (115 loc) · 2.37 KB
/
Copy pathmain.myca
File metadata and controls
142 lines (115 loc) · 2.37 KB
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Lib C
//--------------------------------------------------------------------
struct c_void { _: Never }
struct c_char { _: i8 }
extern proc malloc(size: usize) -> ^mut c_void;
extern proc free(ptr: ^mut c_void);
extern proc puts(str: [bare]c_char) -> i32;
extern proc fatal(msg: [bare]c_char);
// Main
//--------------------------------------------------------------------
proc main() -> i32
{
let mut arr = Array'i32();
let mut i = 1;
while i <= 10 {
push(&mut arr, i);
i := i + 1;
}
let result = sum(&arr);
destroy(&mut arr);
return result;
}
proc sum(arr: ^Array'i32) -> i32
{
let mut sum = 0;
let mut i: usize = 0;
while i < arr^.length {
sum := sum + get(arr, i);
i := i + 1;
}
return sum;
}
// Array
//--------------------------------------------------------------------
struct Array'T
{
items: ?[bare]mut T = None,
length: usize = 0,
capacity: usize = 0,
}
proc length'T (arr: ^Array'T) -> usize
{
return arr^.length;
}
proc push'T (arr: ^mut Array'T, val: T)
{
if arr^.length + 1 > arr^.capacity {
let new_cap = max(arr^.capacity * 2, 1);
grow_capacity(arr, new_cap);
}
unwrap(arr^.items)[arr^.length] := val;
arr^.length := arr^.length + 1;
}
proc grow_capacity'T (arr: ^mut Array'T, target_cap: usize)
{
let new_items = malloc(target_cap * size_of(T)) as [bare]mut T;
let mut i: usize = 0;
while i < arr^.length {
new_items[i] := unwrap(arr^.items)[i];
i := i + 1;
}
_free_items(arr);
arr^.items := new_items;
arr^.capacity := target_cap;
}
proc get'T (arr: ^Array'T, i: usize) -> T
{
return unwrap(arr^.items)[i];
}
proc destroy'T (arr: ^mut Array'T)
{
_free_items(arr);
arr^.items := None;
arr^.length := 0;
arr^.capacity := 0;
}
proc _free_items'T (arr: ^mut Array'T)
{
match arr^.items {
case Some(let items) { free(items as ^mut c_void); }
case None {}
}
}
proc max(a: usize, b: usize) -> usize
{
if a < b {
return b;
}
return a;
}
// Option
//--------------------------------------------------------------------
struct Option'T
{
case implicit Some{value: T},
case None,
}
typealias Some'T = Option'(T).Some;
typealias None'T = Option'(T).None;
proc unwrap'T(opt: ?T) -> T
{
match opt
{
case Some(let value) { return value; }
case None { fatal(c"empty option\n"); }
}
}
proc unwrap_or'T(opt: ?T, fallback: T) -> T
{
match opt
{
case Some(let value) { return value; }
case None { return fallback; }
}
}