~repos /plum

#treesitter#compiler#wasm

git clone https://pyrossh.dev/repos/plum.git

A statically typed, imperative programming language inspired by rust, python


e502e58c pyrossh

1 year ago
add more code
Files changed (9) hide show
  1. readme.md +31 -10
  2. scratch.pc +67 -1
  3. std/bool.mi +1 -3
  4. std/http.mi +9 -9
  5. std/json.mi +339 -0
  6. std/list.mi +9 -0
  7. std/map.mi +19 -10
  8. std/math.mi +47 -3
  9. std/result.mi +10 -10
readme.md CHANGED
@@ -81,6 +81,17 @@ fn (c: Cat) talk() =
81
81
  fn (c: Cat) toStr(): str =
82
82
  "Cat<{c.fullname()}, ${c.age}>"
83
83
 
84
+ enum Temperature =
85
+ | celsius(float)
86
+ | fahrenheit(float)
87
+
88
+ fn (s: Temperature) to_str(): str =
89
+ match s
90
+ celsius(t) && t > 30 -> "${t}C is above 30 celsius"
91
+ celsius(t) -> "${t}C is below 30 celsius"
92
+ fahrenheit(t) && t > 86 -> "${t}F is above 86 fahrenheit"
93
+ fahrenheit(t) -> "${t}F is below 86 fahrenheit"
94
+
84
95
  type MapCallback = fn(v: a): v
85
96
 
86
97
  trait Comparable(
@@ -91,17 +102,27 @@ trait ToStr(
91
102
  fn to_str(): str
92
103
  )
93
104
 
94
- enum Temperature =
105
+ fn connect_db(conn_url: str): DB! =
95
- | celsius(float)
96
- | fahrenheit(float)
106
+ db := postgres_connect(conn_url)?
107
+ db.exec("select 1")?
97
108
 
98
- fn (s: Temperature) to_str(): str =
109
+ fn db_select(conn_url: str): void! =
99
- match s
100
- celsius(t) && t > 30 -> "${t}C is above 30 celsius"
110
+ db := new_db(conn_url)?
101
- celsius(t) -> "${t}C is below 30 celsius"
111
+ db.exec("select 1")?
102
- fahrenheit(t) && t > 86 -> "${t}F is above 86 fahrenheit"
112
+
103
- fahrenheit(t) -> "${t}F is below 86 fahrenheit"
113
+ record DB(conn_url: str)
104
114
 
115
+ error DatabaseError
116
+ DatabaseNotOnline(conn_url: str)
117
+ RowReadFailure(query: str)
118
+
119
+ fn new_db(conn_url: str) DB! =
120
+ db := DB(conn_url: str)
121
+ online := db.check()?
122
+ if !online
123
+ Err(errors.DatabaseNotOnline(conn_url))
124
+ else
125
+ db
105
126
 
106
127
  test("talks") |t|
107
128
  c := Cat(name: "123", age: 1)
@@ -343,7 +364,7 @@ for v := range list
343
364
  sum += k + v
344
365
  ```
345
366
 
346
- **For Custom Iterator**
367
+ **Range Over Function**
347
368
 
348
369
  ```rb
349
370
  type Seq0 = fn(yield: fn(): bool): bool
scratch.pc CHANGED
@@ -215,4 +215,70 @@ repeat(|_| i < 9) |i|
215
215
  pass
216
216
 
217
217
  repeat(|_| a > b && c < d) |i|
218
- pass
218
+ pass
219
+
220
+ let v = list.of(1, 2, 3)
221
+ |> list.add(1, 2)
222
+ |> list.get(0)
223
+
224
+ let v = list.of(1, 2, 3)
225
+ ..add(1, 2)
226
+ ..get(0)
227
+
228
+ if v == nil
229
+ error.Error
230
+ else
231
+ c * 20
232
+
233
+ if v == None
234
+ error.Error
235
+ else
236
+ Some(c) := v
237
+ c * 20
238
+
239
+ match v
240
+ None -> return error.Error
241
+ Some(c) ->
242
+ return c * 20
243
+
244
+
245
+ #[json]
246
+ record UserData(
247
+ id: int,
248
+ name: str,
249
+ roles: List[str]
250
+ )
251
+
252
+ `This is to follow the http standards
253
+ trait Error(
254
+ fn code(): int
255
+ fn msg(): str
256
+ )
257
+
258
+ `derive implements this func
259
+ `Derive is a compiler plugin/generator similar to dart
260
+ `which runs automatically. Its not a macro more like a decorator.
261
+ fn UserData.fromJsonStr(data: str): UserData | JsonParseError =
262
+ // JsonParseError(line: line, pos: post, object: "UserData")
263
+ pass
264
+
265
+ type FetchDataError = FetchError | IOError | JsonParseError
266
+
267
+ fn fetch_data(route: str): map[str, any] | UserData | FetchError | IOError | JsonParseError =
268
+ res := fetch(route)?
269
+ data := res.body.read_all()?
270
+ parse_json(data)?
271
+
272
+ fn main() =
273
+ res := fetch_data()
274
+ if res is UserData
275
+ printLn("Success ${res.id}")
276
+ else if res is IOError
277
+ printLn("IO failed")
278
+ else if res is Error
279
+ printLn("generic error ${res.msg()}")
280
+
281
+ when res
282
+ UserData -> printLn("Success ${res.id}")
283
+ IOError -> printLn("IO failed")
284
+ _ -> printLn("generic error ${res.msg()}")
std/bool.mi CHANGED
@@ -1,8 +1,6 @@
1
1
  module std
2
2
 
3
- enum bool =
3
+ type bool = true | false
4
- | true
5
- | false
6
4
 
7
5
  fn (x: bool) op_eq(y: bool) = x == y
8
6
  fn (x: bool) op_ne(y: bool) = x != y
std/http.mi CHANGED
@@ -1,21 +1,21 @@
1
+ module std/http
2
+
1
3
  import std/path
2
4
  import std/os
3
5
  import std/http/content_type
4
6
 
5
7
  #[builder]
6
8
  record Response(
7
- headers: map[str, str]
9
+ headers: Map[str, str]
8
- body: Buffer
10
+ body: str | Buffer | IO
9
11
  status: int
10
12
  )
11
13
 
12
- fn file_response(file: str): Response! =
14
+ fn file_response(path: str): Response | IOError =
13
- ext := path::ext(file)
14
- content := contentTypeFromExt(ext)
15
+ content := contentTypeFromExt(path.ext())
15
- data := try os.read_file(file)
16
+ data := os.readFile(file)?
16
17
  Response()
17
18
  .header("Content-Type", content)
18
- .header("Content-Length", "2")
19
19
  .body(data)
20
20
  .status(200)
21
21
 
@@ -24,10 +24,10 @@ fn index(): Response! =
24
24
  file_response("index.html")
25
25
 
26
26
  #[get("/public/<...>")]
27
- fn public(file: str): Response! =
27
+ fn public(file: str): Response | IOError =
28
28
  ext := path::ext(file)
29
29
  content := contentTypeFromExt(ext)
30
- data := os.readFile?(file)
30
+ data := os.readFile(file)?
31
31
  Response()
32
32
  .header("Content-Type", content)
33
33
  .body(data)
std/json.mi ADDED
@@ -0,0 +1,339 @@
1
+ module std/json
2
+
3
+ type Json = Map[str, Json] | List[Json] | int | float | str | bool | nil
4
+
5
+ fn Json.parse(src: str | Buffer | IO): Json | ParseError =
6
+ JsonParser.withSrc(src).parse()
7
+
8
+ #[error(400, "Failed to parse json ${object} at: ${line} ${pos}")]
9
+ record ParseError(
10
+ line: str
11
+ pos: str
12
+ )
13
+
14
+ record JsonParser(
15
+ cur: int = ' '
16
+ _pos: int = 0
17
+ _next: int = ' '
18
+ _buf: str | Buffer | IO
19
+ )
20
+
21
+ fn JsonParser.withSrc(src: str | Buffer | IO): JsonParser =
22
+ JsonParser(_buf = src)
23
+
24
+ fn _is_space(c: U32): Bool => (c == ' ') or ((c >= '\t') and (c <= '\r'))
25
+
26
+ fn _is_delim(c: U32): Bool =>
27
+ (c == ',') or (c == '}') or (c == ':') or (c == ']') or (_is_space(c)) or (c == 0)
28
+
29
+ fn _is_digit(c: U32): Bool => (c >= '0') and (c <= '9')
30
+
31
+ fn (p: Parser) _err(msg: str) => printLn(msg)
32
+
33
+ fn _get_next_raw(): U32 =>
34
+ try
35
+ _inc_pos()
36
+ let chr: (U32, U8) = _buf.utf32(_pos-1)?
37
+ cur = _next = chr._1
38
+ else
39
+ cur = _next = 0
40
+ end
41
+
42
+ fn _get_next(): U32 =>
43
+ try
44
+ repeat
45
+ _inc_pos()
46
+ let chr: (U32, U8) = _buf.utf32(_pos-1)?
47
+ cur = _next = chr._1
48
+ until not _is_space(cur) end
49
+ cur
50
+ else
51
+ cur = _next = 0
52
+ end
53
+
54
+
55
+ fn _expect(chr: U32, msg: String): Bool =>
56
+ if cur == chr then
57
+ _get_next()
58
+ true
59
+ else
60
+ _err(msg)
61
+ false
62
+ end
63
+
64
+
65
+ fn _inc_pos(i: ISize = 1) => _pos = _pos.add(i)
66
+
67
+ fn (p JsonParser) parse(): Json =
68
+ match parser.get_next()
69
+ '{' -> p.parseObject()
70
+ '[' -> p.parseList()
71
+ _ -> nil
72
+
73
+ fn (p JsonParser) parseObject(): Map[str, Json] =
74
+ object := Map[str, Json]()
75
+ p._get_next() // '{'
76
+ while true
77
+ if p.cur != '"'
78
+ p._err("JSON: Object: expected '\"'\n")
79
+ break
80
+
81
+ val_key := p.parse_string()
82
+ if !p._expect(':', "JSON: Object: expected ':'\n")
83
+ break
84
+
85
+ val_val := Json(nil)
86
+ when p.cur
87
+ '{' ->
88
+ val_val = parse_object(p)
89
+ p._expect('}', "JSON: Object: expected '}'\n")
90
+ '[' ->
91
+ val_val = parse_array(p)
92
+ p._expect(']', "JSON: Object: expected ']'\n")
93
+ '"' ->
94
+ val_val = p.parseString()
95
+ 'n' ->
96
+ val_val = try p._get_n()? end // null?
97
+ 't' ->
98
+ val_val = try p._get_t()? end // true?
99
+ 'f' ->
100
+ val_val = try p._get_f()? end // false?
101
+ ch ->
102
+ if p._is_digit(ch) || ch == '.'
103
+ val_val = p.parseNum()
104
+ else
105
+ p._err("invalid value\n")
106
+ break
107
+
108
+ object.set(val_key, val_val)
109
+ if p.cur == '}'
110
+ break
111
+ if !p._expect(',', "JSON: Object: expected ','\n")
112
+ printLn("failed at: %s\n".cstring(), val_key.cstring())
113
+ object
114
+
115
+ fn (p: JsonParser) parseList(): List[Json] =
116
+ p._get_next() // '['
117
+ while true
118
+ when p.cur
119
+ '{' -> _values.push(JSONObject.create_with_parser(p)); p._expect('}', "JSON: Array: expected object delimiter\n")
120
+ '[' -> _values.push(JSONArray.create_with_parser(p)); p._expect(']', "JSON: Array: expected array delimiter\n")
121
+ '"' -> _values.push(p.parseString())
122
+ 't' ->
123
+ t: Bool := p._get_t()?
124
+ _values.push(t)
125
+ 'f' ->
126
+ f: Bool := p._get_f()?
127
+ _values.push(f)
128
+ 'n' ->
129
+ n: None := p._get_n()?
130
+ _values.push(n)
131
+ _ ->
132
+ if p._is_digit(p.cur)
133
+ let n = p.parseNum()
134
+ _values.push(n)
135
+
136
+ if p.cur == ']'
137
+ break
138
+ if !p._expect(',', "JSON: Array: expected ','\n")
139
+ break
140
+
141
+ fn (p: Parser) parseUtf16(): int =
142
+ result := 0
143
+ count := 0
144
+ while count <= 4
145
+ p._get_next_raw()
146
+ if _is_digit(cur)
147
+ result = ((result << 4) or (cur - '0').i32())
148
+ else if (cur >= 'a') and (cur <= 'f')
149
+ result = ((result << 4) or ((cur - 'a').i32() + 10))
150
+ else if (cur >= 'A') and (cur <= 'F')
151
+ result = ((result << 4) or ((cur - 'A').i32() + 10))
152
+ count = count+1
153
+ result
154
+
155
+ fn (p: JsonParser) parseStr(): str =
156
+ result := ""
157
+ while true
158
+ p._get_next_raw()
159
+ match cur
160
+ 0 -> _err("JSON: parseString: expected '\"'\n"); return ""
161
+ '"' -> _get_next(); break
162
+ '\\' ->
163
+ match _next
164
+ '\\' -> result.push('\\'); p._get_next_raw()
165
+ '"' -> result.push('"'); p._get_next_raw()
166
+ '\'' -> result.push('\''); p._get_next_raw()
167
+ '/' -> result.push('/'); p._get_next_raw()
168
+ 'b' -> result.push('\b'); p._get_next_raw()
169
+ 'f' -> result.push('\f'); p._get_next_raw()
170
+ 'n' -> result.push('\n'); p._get_next_raw()
171
+ 'r' -> result.push('\r'); p._get_next_raw()
172
+ 't' -> result.push('\t'); p._get_next_raw()
173
+ 'u' ->
174
+ _get_next_raw()
175
+ ures := p.parseUtf16()
176
+ if ures < 0
177
+ _err("invalid utf escape\n")
178
+ break
179
+ result.push_utf32(ures.u32())
180
+ _ ->
181
+ result.push_utf32(cur.u32())
182
+ result
183
+
184
+ fn (p: JsonParser) parseNum(): int | float =
185
+ result := ""
186
+ is_float := false
187
+
188
+ if cur == '-'
189
+ result.push('-')
190
+ _get_next_raw()
191
+
192
+ if cur == '.'
193
+ result.push('0')
194
+ result.push('.')
195
+ is_float = true
196
+ _get_next_raw()
197
+ else
198
+ while _is_digit(cur)
199
+ result.push(cur.u8())
200
+ _get_next_raw()
201
+ if cur == '.'
202
+ result.push('.')
203
+ _get_next_raw()
204
+
205
+ while _is_digit(cur)
206
+ result.push(cur.u8())
207
+ _get_next_raw()
208
+
209
+ is_exp := when cur
210
+ 'e' ->
211
+ result.push('e'); _get_next_raw()
212
+ true
213
+ 'E' ->
214
+ result.push('E'); _get_next_raw()
215
+ true
216
+ _ -> false
217
+
218
+ if is_exp
219
+ sign := when cur
220
+ '+' ->
221
+ result.push('+'); _get_next_raw()
222
+ true
223
+ '-' ->
224
+ result.push('-'); _get_next_raw()
225
+ true
226
+ _ -> false
227
+ if sign
228
+ while _is_digit(cur)
229
+ result.push(cur.u8())
230
+ _get_next_raw()
231
+
232
+ res := is_float ? result.f64() : result.i64()
233
+ if _is_space(cur)
234
+ _get_next() // skip to the next non-whitespace character
235
+ res
236
+
237
+ fn _get_n(): None? =>
238
+ _get_next_raw()
239
+ if cur == 'u' then
240
+ _get_nu()?
241
+ else
242
+ error
243
+ end
244
+
245
+ fn _get_nu(): None? =>
246
+ _get_next_raw()
247
+ if cur == 'l' then
248
+ _get_nul()?
249
+ else
250
+ error
251
+ end
252
+
253
+ fn _get_nul(): None? =>
254
+ _get_next_raw()
255
+ if cur == 'l' then
256
+ _get_next()
257
+ None
258
+ else
259
+ error
260
+ end
261
+
262
+ fn _get_t(): bool? =
263
+ _get_next_raw()
264
+ if cur == 'r' then
265
+ _get_tr()?
266
+ else
267
+ error
268
+ end
269
+
270
+ fn _get_tr(): bool? =
271
+ _get_next_raw()
272
+ if cur == 'u' then
273
+ _get_tru()?
274
+ else
275
+ error
276
+ end
277
+
278
+ fn _get_tru(): bool? =
279
+ _get_next_raw()
280
+ if cur == 'e' then
281
+ _get_next()
282
+ true
283
+ else
284
+ error
285
+ end
286
+
287
+ fn _get_f(): bool? =
288
+ _get_next_raw()
289
+ if cur == 'a' then
290
+ _get_fa()?
291
+ else
292
+ error
293
+ end
294
+
295
+ fn _get_fa(): bool? =
296
+ _get_next_raw()
297
+ if cur == 'l' then
298
+ _get_fal()?
299
+ else
300
+ error
301
+ end
302
+
303
+ fn _get_fal(): bool? =
304
+ _get_next_raw()
305
+ if cur == 's' then
306
+ _get_fals()?
307
+ else
308
+ error
309
+ end
310
+
311
+ fn _get_fals(): bool? =
312
+ _get_next_raw()
313
+ if cur == 'e' then
314
+ _get_next()
315
+ false
316
+ else
317
+ error
318
+ end
319
+
320
+ test("parse int") |t|
321
+ assert Json.parse("123") == 123
322
+
323
+ test("parse str") |t|
324
+ assert Json.parse(`"hello"`) == "hello"
325
+
326
+ test("parse bool") |t|
327
+ assert Json.parse("true") == true
328
+ assert Json.parse("false") == false
329
+
330
+ test("parse null") |t|
331
+ assert Json.parse("null") == nil
332
+
333
+ test("parse array") |t|
334
+ assert Json.parse(`[]`) == List[Json]()
335
+ assert Json.parse(`[1, 2]`) == List.of[Json](1, 2)
336
+
337
+ test("parse object") |t|
338
+ assert Json.parse(`{}`) == Map[str, Json]()
339
+ assert Json.parse(`{"a": 1, "b": 2}`) == Map.of[str, Json]("a" => 1, "b" => 2)p-
std/list.mi CHANGED
@@ -82,6 +82,15 @@ fn (l: list) contains(v: V): bool =
82
82
  `returns the index of an item in the list if present and comparable otherwise nil
83
83
  pass
84
84
 
85
+ fn (l: list[T]) op_range(yld: fn(v: T): bool): bool =
86
+ `range over func for a list
87
+ current := l.head
88
+ while current != nil
89
+ if !yld(current.value)
90
+ return false
91
+ current = current.next
92
+ true
93
+
85
94
  fn (l: list) op_spread(other: list): list[A] =
86
95
  `combines this list with other list and returns a new list
87
96
  pass
std/map.mi CHANGED
@@ -4,25 +4,34 @@ record Pair[K: Comparable, V](k: K, v: V)
4
4
 
5
5
  `A slice is a data structure describing a contiguous section of an array stored separately from the slice variable itself.
6
6
  `A slice is not an array. A slice describes a piece of an array.
7
- record map[K, V](
7
+ record Map[K, V](
8
8
  items: list[Pair[K, V]]
9
9
  )
10
10
 
11
- fn map.of[K, V](kvs: ...Pair[K, V]): map[K, V] =
11
+ fn Map.of[K, V](kvs: ...Pair[K, V]): map[K, V] =
12
12
  map[K, V]().add(kvs)
13
13
 
14
- fn (m: map) add(kvs: ...Pair[K, V]) =
14
+ fn (m: Map) add(kvs: ...Pair[K, V]) =
15
15
  `adds the specified elements to the start of the list
16
- items.add(pair)
16
+ items.add(kvs)
17
17
 
18
+ fn (m: Map[K, V]) op_range(yld: fn(k: K, v: V): bool): bool =
18
- fn (m: Map) op_range() =
19
+ for item := range items
19
- yield k, v
20
+ if !yld(item.k, item.v)
21
+ false
22
+ true
20
23
 
21
- fn (m: Map) put() =
24
+ fn (m: Map[K, V]) get(k K): V? =
25
+ for k, v := range m
26
+ if k == k
27
+ return v
22
- pass
28
+ nil
23
29
 
30
+ fn (m: Map) put(k K, v V) =
31
+ list.add(Pair(k, v))
32
+
24
- fn (m: Map) put_if() =
33
+ fn (m: Map) put_if(k K, v V) =
25
- pass
34
+ if
26
35
 
27
36
  fn (m: Map) update() =
28
37
  pass
std/math.mi CHANGED
@@ -1,38 +1,64 @@
1
1
  module math
2
2
 
3
3
  `Euler's number, the base of natural logarithms, e
4
+ `https://oeis.org/A001113
4
5
  const E = 2.718f
5
6
 
6
7
  `The natural logarithm of 10
8
+ `https://oeis.org/A002392
7
9
  const LN10 = 2.302f
8
10
 
9
11
  `The natural logarithm of 2
12
+ `https://oeis.org/A002162
10
13
  const LN2 = 0.693f
11
14
 
12
15
  `The base 10 logarithm of e
16
+ `formula: 1 / LN10
13
17
  const LOG10E = 0.434f
14
18
 
15
19
  `The base 2 logarithm of e
20
+ `formula: 1 / LN2
16
21
  const LOG2E = 1.442f
17
22
 
18
23
  `The ratio of the circumference of a circle to its diameter
24
+ `https://oeis.org/A000796
19
25
  const PI = 3.14159f
20
26
 
27
+ `https://oeis.org/A001622
28
+ const PHI = 1.6180f
29
+
21
30
  `The square root of 1/2
22
31
  const SQRT1_2 = 0.707f
23
32
 
24
33
  `The square root of 2
34
+ `https://oeis.org/A002193
25
35
  const SQRT2 = 1.414f
26
36
 
37
+ `https://oeis.org/A019774
38
+ const SQRT_E = 1.64872f
39
+
40
+ `https://oeis.org/A002161
41
+ const SQRT_PI = 1.77245f
42
+
43
+ `https://oeis.org/A139339
44
+ const SQRT_PHI = 1.27201f
45
+
27
46
  `The difference between 1 and the smallest floating point number greater than 1
47
+ `formula: 7/3 - 4/3 - 1
28
48
  const EPSILON = 2.220446049250313e-16f
29
49
 
30
- `Lowest valur of i64
50
+ `Lowest value of int
31
51
  const MIN_INT_VALUE = -0x8000_0000_0000_0000
32
52
 
33
- `Highest valur of i64
53
+ `Highest value of int
34
54
  const MAX_INT_VALUE = 0x7FFF_FFFF_FFFF_FFFF
35
55
 
56
+ `Lowest valur of float
57
+ const MIN_FLOAT_VALUE = 4.9406564584124654417656879286822137236505980e-324
58
+
59
+ `Highest valur of float
60
+ const MAX_FLOAT_VALUE = 1.79769313486231570814527423731704356798070e+308
61
+
36
62
  fn abs(v: float): float =
37
63
  `returns the absolute value of a number v
38
64
  a < 0 ? -a : a
@@ -44,7 +70,25 @@ fn acos(v: float) =
44
70
  asin(-1v)
45
71
 
46
72
 
73
+ `2**28
74
+ const LARGE = 1 << 28
47
- fn acosh(v: float) = 0f
75
+ fn acosh(v: float): float =
76
+ when
77
+ x < 1 | IsNaN(x) -> // first case is special case
78
+ NaN()
79
+ x == 1 ->
80
+ 0
81
+ x >= Large ->
82
+ Log(x) + Ln2 // x > 2**28
83
+ x > 2 ->
84
+ Log(2*x - 1/(x+Sqrt(x*x-1))) // 2**28 > x > 2
85
+ _ ->
86
+ t := x - 1
87
+ // ((2*t+t*t).sqrt() + t).log1p()
88
+ Log1p(t + Sqrt(2*t+t*t)) // 2 >= x > 1
89
+
90
+
91
+
48
92
  fn asin(v: float) = 0f
49
93
  fn asinh(v: float) = 0f
50
94
  fn atan(v: float) = 0f
std/result.mi CHANGED
@@ -2,44 +2,44 @@ module std
2
2
 
3
3
  `result is a type that represents either success ok or failure err.
4
4
  #[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
5
- enum result[T, E]
5
+ enum result[T]
6
6
  | ok(T)
7
- | err(E)
7
+ | err(error)
8
8
 
9
- fn (o result) is_ok(): bool =
9
+ fn (r result) is_ok(): bool =
10
10
  match o
11
11
  ok(v) -> return true
12
12
  err(e) -> return false
13
13
 
14
- fn (o result) is_err(): bool =
14
+ fn (r result) is_err(): bool =
15
15
  !o.is_ok()
16
16
 
17
- fn (o result[T, E]) ok(): option[T] =
17
+ fn (r result[T, E]) ok(): option[T] =
18
18
  match o
19
19
  ok(v) -> some(v)
20
20
  err(e) -> none
21
21
 
22
- fn (o result[T, E]) err(): option[E] =
22
+ fn (r result[T, E]) err(): option[E] =
23
23
  match o
24
24
  ok(v) -> none
25
25
  err(e) -> some(v)
26
26
 
27
- fn (o result) get(): T =
27
+ fn (r result) get(): T =
28
28
  match o
29
29
  ok(v) -> v
30
30
  err(e) -> panic("called `result.get()` on a `none` value")
31
31
 
32
- fn (o result) default(d: T): T =
32
+ fn (r result) default(d: T): T =
33
33
  match o
34
34
  ok(v) -> v
35
35
  err(e) -> d
36
36
 
37
- fn (o result) map(cb: fn(v: T)): result =
37
+ fn (r result) map(cb: fn(v: T)): result =
38
38
  match o
39
39
  ok(v) -> cb(v)
40
40
  err(e) -> unreachable
41
41
 
42
- fn (o result) map_err(cb: fn(e: E)): result =
42
+ fn (r result) map_err(cb: fn(e: E)): result =
43
43
  match o
44
44
  ok(v) -> unreachable
45
45
  err(e) -> cb(v)