plum
git clone https://git.pyrossh.dev/plum
A statically typed, imperative programming language inspired by rust, python
0fe3528
— Peter John
2026-08-09T18:35:27+05:30
feat(libs/std,examples,test): migrate to `fun`-prefixed function syntax
- README.md +13 -13
- examples/basics.plum +1 -1
- examples/closures.plum +3 -3
- examples/control_flow.plum +5 -5
- examples/functions.plum +8 -8
- examples/match.plum +6 -6
- examples/methods.plum +5 -5
- examples/strings.plum +4 -4
- examples/types.plum +2 -2
- libs/std/bool.plum +4 -4
- libs/std/encoding/Base64.plum +7 -7
- libs/std/float.plum +6 -6
- libs/std/http.plum +3 -3
- libs/std/int.plum +13 -13
- libs/std/json.plum +13 -13
- libs/std/list.plum +32 -32
- libs/std/map.plum +6 -6
- libs/std/os.plum +34 -34
- libs/std/result.plum +7 -7
- libs/std/str.plum +40 -40
- test/add.plum +9 -9
- test/aoc_2020_1.plum +2 -2
- test/aoc_2020_2.plum +3 -3
- test/aoc_2020_3.plum +3 -3
- test/aoc_2020_4.plum +1 -1
- test/import_fixtures/helper.plum +1 -1
- test/import_fixtures/main.plum +1 -1
- test/sample.plum +34 -34
- test/simple_add.plum +1 -1
README.md
CHANGED
|
@@ -44,7 +44,7 @@ Blocks are indentation-sensitive (2 spaces), like Python — there's no `{ }` fo
|
|
|
44
44
|
|
|
45
45
|
```plum
|
|
46
46
|
# this is a comment
|
|
47
|
-
main() =
|
|
47
|
+
fun main() =
|
|
48
48
|
x = 1
|
|
49
49
|
if x > 0
|
|
50
50
|
x = x + 1
|
|
@@ -182,16 +182,16 @@ Full example: [`examples/control_flow.plum`](examples/control_flow.plum).
|
|
|
182
182
|
### Functions
|
|
183
183
|
|
|
184
184
|
```plum
|
|
185
|
-
addInts(a: Int, b: Int) -> Int =
|
|
185
|
+
fun addInts(a: Int, b: Int) -> Int =
|
|
186
186
|
a + b
|
|
187
187
|
|
|
188
|
-
greet() = # no return type => Unit
|
|
188
|
+
fun greet() = # no return type => Unit
|
|
189
189
|
todo
|
|
190
190
|
|
|
191
|
-
withDefault(a: Int, step: Int = 1) -> Int =
|
|
191
|
+
fun withDefault(a: Int, step: Int = 1) -> Int =
|
|
192
192
|
a + step
|
|
193
193
|
|
|
194
|
-
sumAll(nums: ...Int) -> Int = # variadic param
|
|
194
|
+
fun sumAll(nums: ...Int) -> Int = # variadic param
|
|
195
195
|
todo
|
|
196
196
|
```
|
|
197
197
|
|
|
@@ -236,7 +236,7 @@ type Box(a) =
|
|
|
236
236
|
trait Comparable(a: Ord) = # bounded generic param
|
|
237
237
|
compareTo(other: a) -> Int
|
|
238
238
|
|
|
239
|
-
wrap(value: a) -> Bool = # generic param type
|
|
239
|
+
fun wrap(value: a) -> Bool = # generic param type
|
|
240
240
|
True
|
|
241
241
|
```
|
|
242
242
|
|
|
@@ -247,16 +247,16 @@ Full example: [`examples/types.plum`](examples/types.plum), [`examples/functions
|
|
|
247
247
|
### Closures
|
|
248
248
|
|
|
249
249
|
```plum
|
|
250
|
-
each(cb: fn(Int) -> Int) -> Int =
|
|
250
|
+
fun each(cb: fn(Int) -> Int) -> Int =
|
|
251
251
|
cb(5)
|
|
252
252
|
|
|
253
|
-
useCapturingClosure() -> Int =
|
|
253
|
+
fun useCapturingClosure() -> Int =
|
|
254
254
|
offset = 100
|
|
255
255
|
cb = |v|
|
|
256
256
|
v + offset
|
|
257
257
|
cb(5)
|
|
258
258
|
|
|
259
|
-
main() -> Int =
|
|
259
|
+
fun main() -> Int =
|
|
260
260
|
each(|v| v * 3) + useCapturingClosure()
|
|
261
261
|
```
|
|
262
262
|
|
|
@@ -279,13 +279,13 @@ type Cat =
|
|
|
279
279
|
name: Str
|
|
280
280
|
age: Int
|
|
281
281
|
|
|
282
|
-
getAge<Cat>() -> Int =
|
|
282
|
+
fun getAge<Cat>() -> Int =
|
|
283
283
|
self.age
|
|
284
284
|
|
|
285
|
-
birthday<Cat>() -> Int =
|
|
285
|
+
fun birthday<Cat>() -> Int =
|
|
286
286
|
self.age + 1
|
|
287
287
|
|
|
288
|
-
main() -> Int =
|
|
288
|
+
fun main() -> Int =
|
|
289
289
|
c = Cat(name: "Whiskers", age: 3)
|
|
290
290
|
a = c.getAge() # method call
|
|
291
291
|
w = Wrapper(inner: c, tag: 1)
|
|
@@ -334,7 +334,7 @@ Full example: [`examples/match.plum`](examples/match.plum).
|
|
|
334
334
|
### String interpolation
|
|
335
335
|
|
|
336
336
|
```plum
|
|
337
|
-
greet(name: Str) -> Str =
|
|
337
|
+
fun greet(name: Str) -> Str =
|
|
338
338
|
"Hello, {name}!"
|
|
339
339
|
```
|
|
340
340
|
|
examples/basics.plum
CHANGED
|
@@ -6,7 +6,7 @@ MAX_RETRIES = 3
|
|
|
6
6
|
PI = 3.14159
|
|
7
7
|
GREETING = "hello"
|
|
8
8
|
|
|
9
|
-
main() =
|
|
9
|
+
fun main() =
|
|
10
10
|
dec = 42
|
|
11
11
|
hex = 0xFF
|
|
12
12
|
bin = 0b1010
|
examples/closures.plum
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
each(cb: fn(Int) -> Int) -> Int =
|
|
1
|
+
fun each(cb: fn(Int) -> Int) -> Int =
|
|
2
2
|
cb(5)
|
|
3
3
|
|
|
4
|
-
useCapturingClosure() -> Int =
|
|
4
|
+
fun useCapturingClosure() -> Int =
|
|
5
5
|
offset = 100
|
|
6
6
|
cb = |v|
|
|
7
7
|
v + offset
|
|
8
8
|
cb(5)
|
|
9
9
|
|
|
10
|
-
main() -> Int =
|
|
10
|
+
fun main() -> Int =
|
|
11
11
|
each(|v| v * 3) + useCapturingClosure()
|
examples/control_flow.plum
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
loopSum(limit: Int) -> Int =
|
|
1
|
+
fun loopSum(limit: Int) -> Int =
|
|
2
2
|
total = 0
|
|
3
3
|
for i in 0..limit
|
|
4
4
|
if i == 3
|
|
@@ -8,7 +8,7 @@ loopSum(limit: Int) -> Int =
|
|
|
8
8
|
total = total + i
|
|
9
9
|
return total
|
|
10
10
|
|
|
11
|
-
classify(n: Int) -> Str =
|
|
11
|
+
fun classify(n: Int) -> Str =
|
|
12
12
|
if n < 0
|
|
13
13
|
return "negative"
|
|
14
14
|
else if n == 0
|
|
@@ -16,14 +16,14 @@ classify(n: Int) -> Str =
|
|
|
16
16
|
else
|
|
17
17
|
return "positive"
|
|
18
18
|
|
|
19
|
-
countdown(start: Int) -> Int =
|
|
19
|
+
fun countdown(start: Int) -> Int =
|
|
20
20
|
i = start
|
|
21
21
|
while i > 0
|
|
22
22
|
i = i - 1
|
|
23
23
|
return i
|
|
24
24
|
|
|
25
|
-
placeholder() =
|
|
25
|
+
fun placeholder() =
|
|
26
26
|
todo
|
|
27
27
|
|
|
28
|
-
checkPositive(n: Int) =
|
|
28
|
+
fun checkPositive(n: Int) =
|
|
29
29
|
assert n > 0
|
examples/functions.plum
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
addInts(a: Int, b: Int) -> Int =
|
|
1
|
+
fun addInts(a: Int, b: Int) -> Int =
|
|
2
2
|
a + b
|
|
3
3
|
|
|
4
|
-
greet() =
|
|
4
|
+
fun greet() =
|
|
5
5
|
todo
|
|
6
6
|
|
|
7
|
-
withDefault(a: Int, step: Int = 1) -> Int =
|
|
7
|
+
fun withDefault(a: Int, step: Int = 1) -> Int =
|
|
8
8
|
a + step
|
|
9
9
|
|
|
10
|
-
sumAll(nums: ...Int) -> Int =
|
|
10
|
+
fun sumAll(nums: ...Int) -> Int =
|
|
11
11
|
total = 0
|
|
12
12
|
for v in nums
|
|
13
13
|
total = total + v
|
|
14
14
|
total
|
|
15
15
|
|
|
16
|
-
wrap(value: T) -> Bool =
|
|
16
|
+
fun wrap(value: T) -> Bool =
|
|
17
17
|
True
|
|
18
18
|
|
|
19
|
-
pair(first: T, second: U) -> Bool =
|
|
19
|
+
fun pair(first: T, second: U) -> Bool =
|
|
20
20
|
True
|
|
21
21
|
|
|
22
|
-
useWrap() -> Bool =
|
|
22
|
+
fun useWrap() -> Bool =
|
|
23
23
|
wrap(5)
|
|
24
24
|
|
|
25
|
-
usePair() -> Bool =
|
|
25
|
+
fun usePair() -> Bool =
|
|
26
26
|
pair(1, "x")
|
examples/match.plum
CHANGED
|
@@ -7,7 +7,7 @@ enum Option =
|
|
|
7
7
|
| Some[Int]
|
|
8
8
|
| None
|
|
9
9
|
|
|
10
|
-
describeNumber(n: Int) -> Str =
|
|
10
|
+
fun describeNumber(n: Int) -> Str =
|
|
11
11
|
match n
|
|
12
12
|
0 =>
|
|
13
13
|
"zero"
|
|
@@ -16,19 +16,19 @@ describeNumber(n: Int) -> Str =
|
|
|
16
16
|
_ =>
|
|
17
17
|
"many"
|
|
18
18
|
|
|
19
|
-
describeBool(b: Bool) -> Int =
|
|
19
|
+
fun describeBool(b: Bool) -> Int =
|
|
20
20
|
match b
|
|
21
21
|
True =>
|
|
22
22
|
1
|
|
23
23
|
False =>
|
|
24
24
|
0
|
|
25
25
|
|
|
26
|
-
bindExample(n: Int) -> Int =
|
|
26
|
+
fun bindExample(n: Int) -> Int =
|
|
27
27
|
match n
|
|
28
28
|
x =>
|
|
29
29
|
x
|
|
30
30
|
|
|
31
|
-
describeColor(c: Color) -> Str =
|
|
31
|
+
fun describeColor(c: Color) -> Str =
|
|
32
32
|
match c
|
|
33
33
|
Red =>
|
|
34
34
|
"red"
|
|
@@ -37,12 +37,12 @@ describeColor(c: Color) -> Str =
|
|
|
37
37
|
Blue =>
|
|
38
38
|
"blue"
|
|
39
39
|
|
|
40
|
-
describeOption(opt: Option) -> Int =
|
|
40
|
+
fun describeOption(opt: Option) -> Int =
|
|
41
41
|
match opt
|
|
42
42
|
Some(v) =>
|
|
43
43
|
v
|
|
44
44
|
None =>
|
|
45
45
|
0
|
|
46
46
|
|
|
47
|
-
main() -> Int =
|
|
47
|
+
fun main() -> Int =
|
|
48
48
|
describeOption(Some(5))
|
examples/methods.plum
CHANGED
|
@@ -2,23 +2,23 @@ type Cat =
|
|
|
2
2
|
name: Str
|
|
3
3
|
age: Int
|
|
4
4
|
|
|
5
|
-
getAge<Cat>(self) -> Int =
|
|
5
|
+
fun getAge<Cat>(self) -> Int =
|
|
6
6
|
self.age
|
|
7
7
|
|
|
8
|
-
birthday<Cat>(self) -> Int =
|
|
8
|
+
fun birthday<Cat>(self) -> Int =
|
|
9
9
|
self.age + 1
|
|
10
10
|
|
|
11
11
|
type Wrapper =
|
|
12
12
|
inner: Cat
|
|
13
13
|
tag: Int
|
|
14
14
|
|
|
15
|
-
innerAge<Wrapper>(self) -> Int =
|
|
15
|
+
fun innerAge<Wrapper>(self) -> Int =
|
|
16
16
|
self.inner.age
|
|
17
17
|
|
|
18
|
-
makeCat() -> Cat =
|
|
18
|
+
fun makeCat() -> Cat =
|
|
19
19
|
Cat(name: "Whiskers", age: 3)
|
|
20
20
|
|
|
21
|
-
main() -> Int =
|
|
21
|
+
fun main() -> Int =
|
|
22
22
|
c = makeCat()
|
|
23
23
|
a = c.getAge()
|
|
24
24
|
b = c.birthday()
|
examples/strings.plum
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
greet(name: Str) -> Str =
|
|
1
|
+
fun greet(name: Str) -> Str =
|
|
2
2
|
"Hello, {name}!"
|
|
3
3
|
|
|
4
|
-
report(count: Int, total: Int) -> Str =
|
|
4
|
+
fun report(count: Int, total: Int) -> Str =
|
|
5
5
|
"{count} of {total} complete"
|
|
6
6
|
|
|
7
|
-
empty() -> Str =
|
|
7
|
+
fun empty() -> Str =
|
|
8
8
|
""
|
|
9
9
|
|
|
10
|
-
escaped() -> Str =
|
|
10
|
+
fun escaped() -> Str =
|
|
11
11
|
"line one\nline two\ttabbed \"quoted\""
|
examples/types.plum
CHANGED
|
@@ -24,8 +24,8 @@ enum Option =
|
|
|
24
24
|
| Some[Int]
|
|
25
25
|
| None
|
|
26
26
|
|
|
27
|
-
makeIntBox() -> Box =
|
|
27
|
+
fun makeIntBox() -> Box =
|
|
28
28
|
Box(value: 5)
|
|
29
29
|
|
|
30
|
-
makeStrBox() -> Box =
|
|
30
|
+
fun makeStrBox() -> Box =
|
|
31
31
|
Box(value: "x")
|
libs/std/bool.plum
CHANGED
|
@@ -4,7 +4,7 @@ enum Bool =
|
|
|
4
4
|
| True
|
|
5
5
|
| False
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
fun parse(v: Str) -> Result[Bool, Str] =
|
|
8
8
|
if v == "true"
|
|
9
9
|
Ok(True)
|
|
10
10
|
else if v == "false"
|
|
@@ -12,21 +12,21 @@ enum Bool =
|
|
|
12
12
|
else
|
|
13
13
|
Err("could not parse bool from '{v}'")
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
fun and(self, o: Bool) -> Bool =
|
|
16
16
|
match self, o
|
|
17
17
|
| True, True => True
|
|
18
18
|
| True, False => False
|
|
19
19
|
| False, True => False
|
|
20
20
|
| False, False => False
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
fun or(self, o: Bool) -> Bool =
|
|
23
23
|
match self, o
|
|
24
24
|
| True, True => True
|
|
25
25
|
| True, False => True
|
|
26
26
|
| False, True => True
|
|
27
27
|
| False, False => False
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
fun toStr(self) -> Str =
|
|
30
30
|
match self
|
|
31
31
|
| True => "True"
|
|
32
32
|
| False => "False"
|
libs/std/encoding/Base64.plum
CHANGED
|
@@ -12,31 +12,31 @@ module std
|
|
|
12
12
|
# language can't yet express.
|
|
13
13
|
|
|
14
14
|
# Encode for PEM (RFC 1421).
|
|
15
|
-
encodePEM(data: Str) -> Str =
|
|
15
|
+
fun encodePEM(data: Str) -> Str =
|
|
16
16
|
todo
|
|
17
17
|
|
|
18
18
|
# Encode for MIME (RFC 2045).
|
|
19
|
-
encodeMIME(data: Str) -> Str =
|
|
19
|
+
fun encodeMIME(data: Str) -> Str =
|
|
20
20
|
todo
|
|
21
21
|
|
|
22
22
|
# Encode for URLs (RFC 4648). Padding characters are stripped by default.
|
|
23
|
-
encodeURL(data: Str, pad: Bool = False) -> Str =
|
|
23
|
+
fun encodeURL(data: Str, pad: Bool = False) -> Str =
|
|
24
24
|
todo
|
|
25
25
|
|
|
26
26
|
# Configurable encoding. The defaults are for RFC 4648.
|
|
27
|
-
encode(data: Str, at62: Str = "+", at63: Str = "/", pad: Str = "=", linelen: Int = 0, linesep: Str = "\r\n") -> Str =
|
|
27
|
+
fun encode(data: Str, at62: Str = "+", at63: Str = "/", pad: Str = "=", linelen: Int = 0, linesep: Str = "\r\n") -> Str =
|
|
28
28
|
todo
|
|
29
29
|
|
|
30
30
|
# Decode for URLs (RFC 4648).
|
|
31
|
-
decodeUrl(data: Str) -> Option =
|
|
31
|
+
fun decodeUrl(data: Str) -> Option =
|
|
32
32
|
todo
|
|
33
33
|
|
|
34
34
|
# Configurable decoding. The defaults are for RFC 4648. Missing padding is
|
|
35
35
|
# not an error. Non-base64 data, other than whitespace (which can appear at
|
|
36
36
|
# any time), is an error.
|
|
37
|
-
decode(data: Str, at62: Str = "+", at63: Str = "/", pad: Str = "=") -> Option =
|
|
37
|
+
fun decode(data: Str, at62: Str = "+", at63: Str = "/", pad: Str = "=") -> Option =
|
|
38
38
|
todo
|
|
39
39
|
|
|
40
40
|
# encode a single byte
|
|
41
|
-
encodeByte(i: Int, at62: Int, at63: Int) -> Int =
|
|
41
|
+
fun encodeByte(i: Int, at62: Int, at63: Int) -> Int =
|
|
42
42
|
todo
|
libs/std/float.plum
CHANGED
|
@@ -17,23 +17,23 @@ MIN_FLOAT_VALUE = 4.9406564584124654417656879286822137236505980e-324 # Lowest va
|
|
|
17
17
|
MAX_FLOAT_VALUE = 1.79769313486231570814527423731704356798070e+308 # Highest value of float
|
|
18
18
|
|
|
19
19
|
# parses a Float from a Str
|
|
20
|
-
fromStr(s: Str) -> Result =
|
|
20
|
+
fun fromStr(s: Str) -> Result =
|
|
21
21
|
todo
|
|
22
22
|
|
|
23
|
-
acosh<Float>(self, v: Float) -> Float =
|
|
23
|
+
fun acosh<Float>(self, v: Float) -> Float =
|
|
24
24
|
todo
|
|
25
25
|
|
|
26
26
|
# Check whether this number is finite, ie not +/-infinity and not NaN.
|
|
27
|
-
isFinite<Float>(self) -> Bool =
|
|
27
|
+
fun isFinite<Float>(self) -> Bool =
|
|
28
28
|
todo
|
|
29
29
|
|
|
30
30
|
# Check whether this number is +/-infinity
|
|
31
|
-
isInfinite<Float>(self) -> Bool =
|
|
31
|
+
fun isInfinite<Float>(self) -> Bool =
|
|
32
32
|
todo
|
|
33
33
|
|
|
34
34
|
# Check whether this number is NaN.
|
|
35
|
-
isNaN<Float>(self) -> Bool =
|
|
35
|
+
fun isNaN<Float>(self) -> Bool =
|
|
36
36
|
todo
|
|
37
37
|
|
|
38
|
-
toStr<Float>(self) -> Str =
|
|
38
|
+
fun toStr<Float>(self) -> Str =
|
|
39
39
|
todo
|
libs/std/http.plum
CHANGED
|
@@ -14,15 +14,15 @@ type Response =
|
|
|
14
14
|
# (`.header(...).contentType(...).body(...).status(...)`), but this language has
|
|
15
15
|
# no "::" static-call syntax and no mutating "with"-style builder methods, so
|
|
16
16
|
# this constructs the Response directly instead.
|
|
17
|
-
createFileResponse(filePath: Str) -> Response =
|
|
17
|
+
fun createFileResponse(filePath: Str) -> Response =
|
|
18
18
|
content = content_type.fromExt(filePath.ext())
|
|
19
19
|
data = os.readFile(filePath)
|
|
20
20
|
Response(headers: Map(), body: data, status: 200)
|
|
21
21
|
|
|
22
|
-
index() -> Response =
|
|
22
|
+
fun index() -> Response =
|
|
23
23
|
createFileResponse("index.html")
|
|
24
24
|
|
|
25
|
-
serveFile(filePath: Str) -> Response =
|
|
25
|
+
fun serveFile(filePath: Str) -> Response =
|
|
26
26
|
content = content_type.fromExt(filePath.ext())
|
|
27
27
|
data = os.readFile(filePath)
|
|
28
28
|
Response(headers: Map(), body: data, status: 200)
|
libs/std/int.plum
CHANGED
|
@@ -7,43 +7,43 @@ LARGE = 1 << 28 # 2**28
|
|
|
7
7
|
type Int
|
|
8
8
|
|
|
9
9
|
# returns a random Int
|
|
10
|
-
random() -> Float =
|
|
10
|
+
fun random() -> Float =
|
|
11
11
|
todo
|
|
12
12
|
|
|
13
13
|
# parses an Int from a Str
|
|
14
|
-
fromStr() -> Result =
|
|
14
|
+
fun fromStr() -> Result =
|
|
15
15
|
todo
|
|
16
16
|
|
|
17
17
|
# returns the absolute value of the Int
|
|
18
|
-
abs<Int>(self) -> Int =
|
|
18
|
+
fun abs<Int>(self) -> Int =
|
|
19
19
|
self < 0 ? -self : self
|
|
20
20
|
|
|
21
|
-
ceil<Int>(self) -> Float =
|
|
21
|
+
fun ceil<Int>(self) -> Float =
|
|
22
22
|
todo
|
|
23
23
|
|
|
24
|
-
floor<Int>(self) -> Float =
|
|
24
|
+
fun floor<Int>(self) -> Float =
|
|
25
25
|
todo
|
|
26
26
|
|
|
27
|
-
round<Int>(self) -> Float =
|
|
27
|
+
fun round<Int>(self) -> Float =
|
|
28
28
|
todo
|
|
29
29
|
|
|
30
|
-
trunc<Int>(self) -> Float =
|
|
30
|
+
fun trunc<Int>(self) -> Float =
|
|
31
31
|
todo
|
|
32
32
|
|
|
33
|
-
log<Int>(self) -> Float =
|
|
33
|
+
fun log<Int>(self) -> Float =
|
|
34
34
|
todo
|
|
35
35
|
|
|
36
|
-
log2<Int>(self) -> Float =
|
|
36
|
+
fun log2<Int>(self) -> Float =
|
|
37
37
|
todo
|
|
38
38
|
|
|
39
|
-
log10<Int>(self) -> Float =
|
|
39
|
+
fun log10<Int>(self) -> Float =
|
|
40
40
|
todo
|
|
41
41
|
|
|
42
|
-
logb<Int>(self) -> Float =
|
|
42
|
+
fun logb<Int>(self) -> Float =
|
|
43
43
|
todo
|
|
44
44
|
|
|
45
|
-
pow<Int>(self, y: Float) -> Float =
|
|
45
|
+
fun pow<Int>(self, y: Float) -> Float =
|
|
46
46
|
todo
|
|
47
47
|
|
|
48
|
-
sqrt<Int>(self) -> Float =
|
|
48
|
+
fun sqrt<Int>(self) -> Float =
|
|
49
49
|
todo
|
libs/std/json.plum
CHANGED
|
@@ -31,41 +31,41 @@ type JsonParser =
|
|
|
31
31
|
next: Int
|
|
32
32
|
src: Readable
|
|
33
33
|
|
|
34
|
-
withSrc(src: Readable) -> JsonParser =
|
|
34
|
+
fun withSrc(src: Readable) -> JsonParser =
|
|
35
35
|
todo
|
|
36
36
|
|
|
37
|
-
parse<JsonParser>(self) -> Result =
|
|
37
|
+
fun parse<JsonParser>(self) -> Result =
|
|
38
38
|
todo
|
|
39
39
|
|
|
40
|
-
createErr<JsonParser>(self) -> JsonParseError =
|
|
40
|
+
fun createErr<JsonParser>(self) -> JsonParseError =
|
|
41
41
|
todo
|
|
42
42
|
|
|
43
|
-
parseNone<JsonParser>(self) -> Result =
|
|
43
|
+
fun parseNone<JsonParser>(self) -> Result =
|
|
44
44
|
todo
|
|
45
45
|
|
|
46
|
-
parseBool<JsonParser>(self) -> Result =
|
|
46
|
+
fun parseBool<JsonParser>(self) -> Result =
|
|
47
47
|
todo
|
|
48
48
|
|
|
49
|
-
parseStr<JsonParser>(self) -> Result =
|
|
49
|
+
fun parseStr<JsonParser>(self) -> Result =
|
|
50
50
|
todo
|
|
51
51
|
|
|
52
|
-
parseFloat<JsonParser>(self) -> Result =
|
|
52
|
+
fun parseFloat<JsonParser>(self) -> Result =
|
|
53
53
|
todo
|
|
54
54
|
|
|
55
|
-
parseInt<JsonParser>(self) -> Result =
|
|
55
|
+
fun parseInt<JsonParser>(self) -> Result =
|
|
56
56
|
todo
|
|
57
57
|
|
|
58
|
-
parseList<JsonParser>(self) -> Result =
|
|
58
|
+
fun parseList<JsonParser>(self) -> Result =
|
|
59
59
|
todo
|
|
60
60
|
|
|
61
|
-
parseMap<JsonParser>(self) -> Result =
|
|
61
|
+
fun parseMap<JsonParser>(self) -> Result =
|
|
62
62
|
todo
|
|
63
63
|
|
|
64
|
-
isSpace(c: Int) -> Bool =
|
|
64
|
+
fun isSpace(c: Int) -> Bool =
|
|
65
65
|
c == 32 || c >= 9 && c <= 13
|
|
66
66
|
|
|
67
|
-
isDelim(c: Int) -> Bool =
|
|
67
|
+
fun isDelim(c: Int) -> Bool =
|
|
68
68
|
c == 44 || c == 125 || c == 58 || c == 93 || isSpace(c) || c == 0
|
|
69
69
|
|
|
70
|
-
isDigit(c: Int) -> Bool =
|
|
70
|
+
fun isDigit(c: Int) -> Bool =
|
|
71
71
|
c >= 48 && c <= 57
|
libs/std/list.plum
CHANGED
|
@@ -15,11 +15,11 @@ type List[T: Stringable](Stringable) =
|
|
|
15
15
|
tail: Option[Node]
|
|
16
16
|
size: Int
|
|
17
17
|
|
|
18
|
-
makeList(values: ...T) -> List =
|
|
18
|
+
fun makeList(values: ...T) -> List =
|
|
19
19
|
List(None, None, 0).add(values)
|
|
20
20
|
|
|
21
21
|
# gets the element at i'th index of the list
|
|
22
|
-
get<List>(self, i: Int) -> Option[T] =
|
|
22
|
+
fun get<List>(self, i: Int) -> Option[T] =
|
|
23
23
|
current = self.head
|
|
24
24
|
index = 0
|
|
25
25
|
while current != None
|
|
@@ -34,47 +34,47 @@ get<List>(self, i: Int) -> Option[T] =
|
|
|
34
34
|
None
|
|
35
35
|
|
|
36
36
|
# sets the element at i'th index of the list
|
|
37
|
-
set<List>(self, i: Int, v: T) -> Option[T] =
|
|
37
|
+
fun set<List>(self, i: Int, v: T) -> Option[T] =
|
|
38
38
|
todo
|
|
39
39
|
|
|
40
40
|
# returns the no of elements in the list
|
|
41
|
-
length<List>(self) -> Int =
|
|
41
|
+
fun length<List>(self) -> Int =
|
|
42
42
|
self.size
|
|
43
43
|
|
|
44
44
|
# adds the specified elements to the start of the list
|
|
45
|
-
add<List>(self, values: ...T) =
|
|
45
|
+
fun add<List>(self, values: ...T) =
|
|
46
46
|
todo
|
|
47
47
|
|
|
48
48
|
# removes the element at i'th index of the list
|
|
49
|
-
removeAt<List>(self, i: Int) =
|
|
49
|
+
fun removeAt<List>(self, i: Int) =
|
|
50
50
|
todo
|
|
51
51
|
|
|
52
52
|
# removes the element v from list
|
|
53
|
-
remove<List>(self, v: T) =
|
|
53
|
+
fun remove<List>(self, v: T) =
|
|
54
54
|
todo
|
|
55
55
|
|
|
56
56
|
# removes all objects from this list
|
|
57
|
-
clear<List>(self) =
|
|
57
|
+
fun clear<List>(self) =
|
|
58
58
|
todo
|
|
59
59
|
|
|
60
60
|
# returns a new list with the elements in reverse order.
|
|
61
|
-
reverse<List>(self, v: fn(T) -> Bool) -> List =
|
|
61
|
+
fun reverse<List>(self, v: fn(T) -> Bool) -> List =
|
|
62
62
|
todo
|
|
63
63
|
|
|
64
64
|
# returns a new list with the elements sorted by sorter
|
|
65
|
-
sort<List>(self, sorter: fn(T) -> Bool) -> List =
|
|
65
|
+
fun sort<List>(self, sorter: fn(T) -> Bool) -> List =
|
|
66
66
|
todo
|
|
67
67
|
|
|
68
68
|
# returns an item and index in the list if the item is is equal to search item
|
|
69
|
-
find<List>(self, search: T) -> Option[T] =
|
|
69
|
+
fun find<List>(self, search: T) -> Option[T] =
|
|
70
70
|
todo
|
|
71
71
|
|
|
72
72
|
# returns the index of an item in the list if present and comparable otherwise None
|
|
73
|
-
contains<List>(self, v: T) -> Bool =
|
|
73
|
+
fun contains<List>(self, v: T) -> Bool =
|
|
74
74
|
todo
|
|
75
75
|
|
|
76
76
|
# calls f for each elem in the list
|
|
77
|
-
each<List>(self, cb: fn(T)) -> Unit =
|
|
77
|
+
fun each<List>(self, cb: fn(T)) -> Unit =
|
|
78
78
|
current = self.head
|
|
79
79
|
while current != None
|
|
80
80
|
match current
|
|
@@ -85,7 +85,7 @@ each<List>(self, cb: fn(T)) -> Unit =
|
|
|
85
85
|
break
|
|
86
86
|
|
|
87
87
|
# returns a list made up of b elements for each elem in the list
|
|
88
|
-
map<List>(self, cb: fn(T) -> U) -> List[U] =
|
|
88
|
+
fun map<List>(self, cb: fn(T) -> U) -> List[U] =
|
|
89
89
|
nl = List()
|
|
90
90
|
current = self.head
|
|
91
91
|
while current != None
|
|
@@ -99,31 +99,31 @@ map<List>(self, cb: fn(T) -> U) -> List[U] =
|
|
|
99
99
|
nl
|
|
100
100
|
|
|
101
101
|
# returns a new list with each element flat-mapped
|
|
102
|
-
flatMap<List>(self) =
|
|
102
|
+
fun flatMap<List>(self) =
|
|
103
103
|
todo
|
|
104
104
|
|
|
105
105
|
# returns a new list with the elements that matched the predicate
|
|
106
|
-
retain<List>(self, predicate: fn(T) -> T) -> List =
|
|
106
|
+
fun retain<List>(self, predicate: fn(T) -> T) -> List =
|
|
107
107
|
todo
|
|
108
108
|
|
|
109
109
|
# returns a new list with the elements that matched the predicate removed
|
|
110
|
-
reject<List>(self, predicate: fn(T) -> T) -> List =
|
|
110
|
+
fun reject<List>(self, predicate: fn(T) -> T) -> List =
|
|
111
111
|
todo
|
|
112
112
|
|
|
113
113
|
# returns true if any element in the list satisfies the predicate
|
|
114
|
-
any<List>(self, predicate: fn(T) -> Bool) -> Bool =
|
|
114
|
+
fun any<List>(self, predicate: fn(T) -> Bool) -> Bool =
|
|
115
115
|
todo
|
|
116
116
|
|
|
117
117
|
# returns true if all of the elements in the list satisfies the predicate
|
|
118
|
-
every<List>(self, predicate: fn(T) -> Bool) -> Bool =
|
|
118
|
+
fun every<List>(self, predicate: fn(T) -> Bool) -> Bool =
|
|
119
119
|
todo
|
|
120
120
|
|
|
121
121
|
# returns the accumulated value of all the elements in the list
|
|
122
|
-
reduce<List>(self, acc: U, cb: fn(T) -> T) -> Option[U] =
|
|
122
|
+
fun reduce<List>(self, acc: U, cb: fn(T) -> T) -> Option[U] =
|
|
123
123
|
todo
|
|
124
124
|
|
|
125
125
|
# returns the first element in the list
|
|
126
|
-
first<List>(self) -> Option[T] =
|
|
126
|
+
fun first<List>(self) -> Option[T] =
|
|
127
127
|
match self.head
|
|
128
128
|
Some(node) =>
|
|
129
129
|
Some(node.value)
|
|
@@ -131,7 +131,7 @@ first<List>(self) -> Option[T] =
|
|
|
131
131
|
None
|
|
132
132
|
|
|
133
133
|
# returns the last element in the list
|
|
134
|
-
last<List>(self) -> Option[T] =
|
|
134
|
+
fun last<List>(self) -> Option[T] =
|
|
135
135
|
match self.tail
|
|
136
136
|
Some(node) =>
|
|
137
137
|
Some(node.value)
|
|
@@ -139,42 +139,42 @@ last<List>(self) -> Option[T] =
|
|
|
139
139
|
None
|
|
140
140
|
|
|
141
141
|
# returns a list containing the first n elements of the given list
|
|
142
|
-
sublist<List>(self, start: Int, end: Int) -> List =
|
|
142
|
+
fun sublist<List>(self, start: Int, end: Int) -> List =
|
|
143
143
|
todo
|
|
144
144
|
|
|
145
145
|
# returns a list containing the first n elements of the given list
|
|
146
|
-
take<List>(self, n: Int) -> List =
|
|
146
|
+
fun take<List>(self, n: Int) -> List =
|
|
147
147
|
todo
|
|
148
148
|
|
|
149
149
|
# returns a list containing the first n elements of the given list
|
|
150
|
-
skip<List>(self, n: Int) -> List =
|
|
150
|
+
fun skip<List>(self, n: Int) -> List =
|
|
151
151
|
todo
|
|
152
152
|
|
|
153
153
|
# returns a list containing the first n elements of the given list
|
|
154
|
-
drop<List>(self, n: Int) -> List =
|
|
154
|
+
fun drop<List>(self, n: Int) -> List =
|
|
155
155
|
todo
|
|
156
156
|
|
|
157
157
|
# returns a new list with some of the elements taken randomly
|
|
158
|
-
sample<List>(self) =
|
|
158
|
+
fun sample<List>(self) =
|
|
159
159
|
todo
|
|
160
160
|
|
|
161
161
|
# returns a new list with all elements shuffled
|
|
162
|
-
shuffle<List>(self) =
|
|
162
|
+
fun shuffle<List>(self) =
|
|
163
163
|
todo
|
|
164
164
|
|
|
165
165
|
# returns a new list with all elements grouped by adjacent pairs
|
|
166
|
-
partition<List>(self) =
|
|
166
|
+
fun partition<List>(self) =
|
|
167
167
|
todo
|
|
168
168
|
|
|
169
169
|
# returns a new list with all elements grouped into chunks
|
|
170
|
-
chunk<List>(self) =
|
|
170
|
+
fun chunk<List>(self) =
|
|
171
171
|
todo
|
|
172
172
|
|
|
173
173
|
# returns a new list with all elements grouped
|
|
174
|
-
groupBy<List>(self) =
|
|
174
|
+
fun groupBy<List>(self) =
|
|
175
175
|
todo
|
|
176
176
|
|
|
177
|
-
join<List>(self, sep: Str = ",") -> Str =
|
|
177
|
+
fun join<List>(self, sep: Str = ",") -> Str =
|
|
178
178
|
res = Buffer()
|
|
179
179
|
self.each(|v|
|
|
180
180
|
res.write(v.toStr())
|
libs/std/map.plum
CHANGED
|
@@ -10,27 +10,27 @@ type Pair[K, V] =
|
|
|
10
10
|
type Map[K, V] =
|
|
11
11
|
items: List[Pair[K, V]]
|
|
12
12
|
|
|
13
|
-
init<Map>(self, kvs: ...Pair) -> Map =
|
|
13
|
+
fun init<Map>(self, kvs: ...Pair) -> Map =
|
|
14
14
|
Map().add(kvs)
|
|
15
15
|
|
|
16
16
|
# adds the specified elements to the start of the list
|
|
17
|
-
add<Map>(self, kvs: ...Pair) =
|
|
17
|
+
fun add<Map>(self, kvs: ...Pair) =
|
|
18
18
|
self.items.add(kvs)
|
|
19
19
|
|
|
20
20
|
# gets a value from the Map using key k
|
|
21
|
-
get<Map>(self, k: K) -> Option[V] =
|
|
21
|
+
fun get<Map>(self, k: K) -> Option[V] =
|
|
22
22
|
for p in self.items
|
|
23
23
|
if p.key == k
|
|
24
24
|
return Some(p.val)
|
|
25
25
|
None
|
|
26
26
|
|
|
27
27
|
# puts a value into the Map
|
|
28
|
-
set<Map>(self, k: K, v: V) =
|
|
28
|
+
fun set<Map>(self, k: K, v: V) =
|
|
29
29
|
self.items.add(Pair(key: k, val: v))
|
|
30
30
|
|
|
31
31
|
# puts a value into the Map if its not already present
|
|
32
|
-
putIfAbsent<Map>(self, k: K, v: V) =
|
|
32
|
+
fun putIfAbsent<Map>(self, k: K, v: V) =
|
|
33
33
|
todo
|
|
34
34
|
|
|
35
|
-
map<Map>(self, cb: fn(Pair[K, V]) -> Pair[X, Y]) -> Map[X, Y] =
|
|
35
|
+
fun map<Map>(self, cb: fn(Pair[K, V]) -> Pair[X, Y]) -> Map[X, Y] =
|
|
36
36
|
self.items.map(cb)
|
libs/std/os.plum
CHANGED
|
@@ -5,106 +5,106 @@ module std
|
|
|
5
5
|
# top-level `let` and `File` is never defined anywhere in the stdlib. Reduced
|
|
6
6
|
# to the underlying path so this at least parses; a real `File` type is
|
|
7
7
|
# still needed here.
|
|
8
|
-
stdin() -> Str =
|
|
8
|
+
fun stdin() -> Str =
|
|
9
9
|
"/dev/stdin"
|
|
10
10
|
|
|
11
|
-
stdout() -> Str =
|
|
11
|
+
fun stdout() -> Str =
|
|
12
12
|
"/dev/stdout"
|
|
13
13
|
|
|
14
|
-
stderr() -> Str =
|
|
14
|
+
fun stderr() -> Str =
|
|
15
15
|
"/dev/stderr"
|
|
16
16
|
|
|
17
17
|
# Writes the specified data, followed by the current line terminator, to the standard output stream.
|
|
18
|
-
printLn(s: Str) =
|
|
18
|
+
fun printLn(s: Str) =
|
|
19
19
|
writeFile(stdout(), s)
|
|
20
20
|
|
|
21
21
|
# Returns a stream to a file from the fs
|
|
22
|
-
readFile(path: Str) -> IO =
|
|
22
|
+
fun readFile(path: Str) -> IO =
|
|
23
23
|
todo
|
|
24
24
|
|
|
25
|
-
writeFile(path: Str, data: Str) =
|
|
25
|
+
fun writeFile(path: Str, data: Str) =
|
|
26
26
|
todo
|
|
27
27
|
|
|
28
|
-
access(path: Str) =
|
|
28
|
+
fun access(path: Str) =
|
|
29
29
|
todo
|
|
30
30
|
|
|
31
|
-
appendFile(path: Str, data: Str) =
|
|
31
|
+
fun appendFile(path: Str, data: Str) =
|
|
32
32
|
todo
|
|
33
33
|
|
|
34
|
-
chmod(path: Str, mode: Int) =
|
|
34
|
+
fun chmod(path: Str, mode: Int) =
|
|
35
35
|
todo
|
|
36
36
|
|
|
37
|
-
chown(path: Str, uid: Int, gid: Int) =
|
|
37
|
+
fun chown(path: Str, uid: Int, gid: Int) =
|
|
38
38
|
todo
|
|
39
39
|
|
|
40
|
-
copyFile(src: Str, dest: Str) =
|
|
40
|
+
fun copyFile(src: Str, dest: Str) =
|
|
41
41
|
todo
|
|
42
42
|
|
|
43
|
-
cp(src: Str, dest: Str) =
|
|
43
|
+
fun cp(src: Str, dest: Str) =
|
|
44
44
|
todo
|
|
45
45
|
|
|
46
|
-
lchmod(path: Str, mode: Int) =
|
|
46
|
+
fun lchmod(path: Str, mode: Int) =
|
|
47
47
|
todo
|
|
48
48
|
|
|
49
|
-
lchown(path: Str, uid: Int, gid: Int) =
|
|
49
|
+
fun lchown(path: Str, uid: Int, gid: Int) =
|
|
50
50
|
todo
|
|
51
51
|
|
|
52
|
-
lutimes(path: Str, atime: Int, mtime: Int) =
|
|
52
|
+
fun lutimes(path: Str, atime: Int, mtime: Int) =
|
|
53
53
|
todo
|
|
54
54
|
|
|
55
|
-
link(existingPath: Str, newPath: Str) =
|
|
55
|
+
fun link(existingPath: Str, newPath: Str) =
|
|
56
56
|
todo
|
|
57
57
|
|
|
58
|
-
lstat(path: Str) =
|
|
58
|
+
fun lstat(path: Str) =
|
|
59
59
|
todo
|
|
60
60
|
|
|
61
|
-
mkdir(path: Str) =
|
|
61
|
+
fun mkdir(path: Str) =
|
|
62
62
|
todo
|
|
63
63
|
|
|
64
|
-
mkdtemp(prefix: Str) =
|
|
64
|
+
fun mkdtemp(prefix: Str) =
|
|
65
65
|
todo
|
|
66
66
|
|
|
67
|
-
open(path: Str, flags: Int) =
|
|
67
|
+
fun open(path: Str, flags: Int) =
|
|
68
68
|
todo
|
|
69
69
|
|
|
70
|
-
opendir(path: Str) =
|
|
70
|
+
fun opendir(path: Str) =
|
|
71
71
|
todo
|
|
72
72
|
|
|
73
|
-
readdir(path: Str) =
|
|
73
|
+
fun readdir(path: Str) =
|
|
74
74
|
todo
|
|
75
75
|
|
|
76
|
-
readlink(path: Str) =
|
|
76
|
+
fun readlink(path: Str) =
|
|
77
77
|
todo
|
|
78
78
|
|
|
79
|
-
realpath(path: Str) =
|
|
79
|
+
fun realpath(path: Str) =
|
|
80
80
|
todo
|
|
81
81
|
|
|
82
|
-
rename(oldPath: Str, newPath: Str) =
|
|
82
|
+
fun rename(oldPath: Str, newPath: Str) =
|
|
83
83
|
todo
|
|
84
84
|
|
|
85
|
-
rmdir(path: Str) =
|
|
85
|
+
fun rmdir(path: Str) =
|
|
86
86
|
todo
|
|
87
87
|
|
|
88
|
-
rm(path: Str) =
|
|
88
|
+
fun rm(path: Str) =
|
|
89
89
|
todo
|
|
90
90
|
|
|
91
|
-
stat(path: Str) =
|
|
91
|
+
fun stat(path: Str) =
|
|
92
92
|
todo
|
|
93
93
|
|
|
94
|
-
statfs(path: Str) =
|
|
94
|
+
fun statfs(path: Str) =
|
|
95
95
|
todo
|
|
96
96
|
|
|
97
|
-
symlink(target: Str, path: Str) =
|
|
97
|
+
fun symlink(target: Str, path: Str) =
|
|
98
98
|
todo
|
|
99
99
|
|
|
100
|
-
truncate(path: Str) =
|
|
100
|
+
fun truncate(path: Str) =
|
|
101
101
|
todo
|
|
102
102
|
|
|
103
|
-
unlink(path: Str) =
|
|
103
|
+
fun unlink(path: Str) =
|
|
104
104
|
todo
|
|
105
105
|
|
|
106
|
-
utimes(path: Str, atime: Int, mtime: Int) =
|
|
106
|
+
fun utimes(path: Str, atime: Int, mtime: Int) =
|
|
107
107
|
todo
|
|
108
108
|
|
|
109
|
-
watch(filename: Str) =
|
|
109
|
+
fun watch(filename: Str) =
|
|
110
110
|
todo
|
libs/std/result.plum
CHANGED
|
@@ -4,10 +4,10 @@ enum Result =
|
|
|
4
4
|
| Ok[T]
|
|
5
5
|
| Err[E]
|
|
6
6
|
|
|
7
|
-
# checks whether the result is an Ok value
|
|
8
|
-
isOk<Result>(self) -> Bool =
|
|
7
|
+
fun isOk<Result>(self) -> Bool =
|
|
8
|
+
'checks whether the result is an Ok value'
|
|
9
|
-
|
|
9
|
+
match self
|
|
10
|
-
|
|
10
|
+
Ok(_) =>
|
|
11
|
-
|
|
11
|
+
True
|
|
12
|
-
|
|
12
|
+
Err(_) =>
|
|
13
|
-
|
|
13
|
+
False
|
libs/std/str.plum
CHANGED
|
@@ -10,123 +10,123 @@ trait Stringable =
|
|
|
10
10
|
type Str(Comparable, Stringable, Readable, Writable) =
|
|
11
11
|
data: Buffer
|
|
12
12
|
|
|
13
|
-
get<Str>(self, i: Int) -> Char =
|
|
13
|
+
fun get<Str>(self, i: Int) -> Char =
|
|
14
14
|
todo
|
|
15
15
|
|
|
16
|
-
contains<Str>(self, search: Str) -> Bool =
|
|
16
|
+
fun contains<Str>(self, search: Str) -> Bool =
|
|
17
17
|
todo
|
|
18
18
|
|
|
19
|
-
indexOf<Str>(self, sub: Str) -> Int =
|
|
19
|
+
fun indexOf<Str>(self, sub: Str) -> Int =
|
|
20
20
|
todo
|
|
21
21
|
|
|
22
|
-
test<Str>(self, pattern: Regex) -> Bool =
|
|
22
|
+
fun test<Str>(self, pattern: Regex) -> Bool =
|
|
23
23
|
todo
|
|
24
24
|
|
|
25
|
-
startsWith<Str>(self, search: Str) -> Bool =
|
|
25
|
+
fun startsWith<Str>(self, search: Str) -> Bool =
|
|
26
26
|
todo
|
|
27
27
|
|
|
28
|
-
concat<Str>(self, other: Str) -> Str =
|
|
28
|
+
fun concat<Str>(self, other: Str) -> Str =
|
|
29
29
|
self + other
|
|
30
30
|
|
|
31
|
-
toStr<Str>(self) -> Str =
|
|
31
|
+
fun toStr<Str>(self) -> Str =
|
|
32
32
|
self
|
|
33
33
|
|
|
34
|
-
matchPattern<Str>(self, pattern: Regex) -> List =
|
|
34
|
+
fun matchPattern<Str>(self, pattern: Regex) -> List =
|
|
35
35
|
todo
|
|
36
36
|
|
|
37
|
-
matchAll<Str>(self, pattern: Regex) -> List =
|
|
37
|
+
fun matchAll<Str>(self, pattern: Regex) -> List =
|
|
38
38
|
todo
|
|
39
39
|
|
|
40
|
-
padStart<Str>(self, sub: Str, count: Int) -> Str =
|
|
40
|
+
fun padStart<Str>(self, sub: Str, count: Int) -> Str =
|
|
41
41
|
todo
|
|
42
42
|
|
|
43
|
-
padEnd<Str>(self, sub: Str, count: Int) -> Str =
|
|
43
|
+
fun padEnd<Str>(self, sub: Str, count: Int) -> Str =
|
|
44
44
|
todo
|
|
45
45
|
|
|
46
|
-
repeat<Str>(self, count: Int) -> Str =
|
|
46
|
+
fun repeat<Str>(self, count: Int) -> Str =
|
|
47
47
|
todo
|
|
48
48
|
|
|
49
|
-
replace<Str>(self, pattern: Regex, sub: Str) -> Str =
|
|
49
|
+
fun replace<Str>(self, pattern: Regex, sub: Str) -> Str =
|
|
50
50
|
todo
|
|
51
51
|
|
|
52
|
-
replaceAll<Str>(self, pattern: Regex, sub: Str) -> Str =
|
|
52
|
+
fun replaceAll<Str>(self, pattern: Regex, sub: Str) -> Str =
|
|
53
53
|
todo
|
|
54
54
|
|
|
55
|
-
search<Str>(self, pattern: Regex) -> Str =
|
|
55
|
+
fun search<Str>(self, pattern: Regex) -> Str =
|
|
56
56
|
todo
|
|
57
57
|
|
|
58
|
-
slice<Str>(self, start: Int, e: Int) -> Str =
|
|
58
|
+
fun slice<Str>(self, start: Int, e: Int) -> Str =
|
|
59
59
|
todo
|
|
60
60
|
|
|
61
|
-
split<Str>(self, separator: Str, limit: Int) -> List =
|
|
61
|
+
fun split<Str>(self, separator: Str, limit: Int) -> List =
|
|
62
62
|
todo
|
|
63
63
|
|
|
64
|
-
sub<Str>(self, start: Int, e: Int) -> Str =
|
|
64
|
+
fun sub<Str>(self, start: Int, e: Int) -> Str =
|
|
65
65
|
todo
|
|
66
66
|
|
|
67
|
-
toLower<Str>(self) -> Str =
|
|
67
|
+
fun toLower<Str>(self) -> Str =
|
|
68
68
|
todo
|
|
69
69
|
|
|
70
70
|
# reverses a Str
|
|
71
|
-
reverse<Str>(self) -> Str =
|
|
71
|
+
fun reverse<Str>(self) -> Str =
|
|
72
72
|
todo
|
|
73
73
|
|
|
74
|
-
camelCase<Str>(self) -> Str =
|
|
74
|
+
fun camelCase<Str>(self) -> Str =
|
|
75
75
|
todo
|
|
76
76
|
|
|
77
|
-
snakeCase<Str>(self) -> Str =
|
|
77
|
+
fun snakeCase<Str>(self) -> Str =
|
|
78
78
|
todo
|
|
79
79
|
|
|
80
|
-
capitalize<Str>(self) -> Str =
|
|
80
|
+
fun capitalize<Str>(self) -> Str =
|
|
81
81
|
todo
|
|
82
82
|
|
|
83
|
-
kebabCase<Str>(self) -> Str =
|
|
83
|
+
fun kebabCase<Str>(self) -> Str =
|
|
84
84
|
todo
|
|
85
85
|
|
|
86
|
-
lowerCase<Str>(self) -> Str =
|
|
86
|
+
fun lowerCase<Str>(self) -> Str =
|
|
87
87
|
todo
|
|
88
88
|
|
|
89
|
-
lowerFirst<Str>(self) -> Str =
|
|
89
|
+
fun lowerFirst<Str>(self) -> Str =
|
|
90
90
|
todo
|
|
91
91
|
|
|
92
|
-
upperCase<Str>(self) -> Str =
|
|
92
|
+
fun upperCase<Str>(self) -> Str =
|
|
93
93
|
todo
|
|
94
94
|
|
|
95
|
-
upperFirst<Str>(self) -> Str =
|
|
95
|
+
fun upperFirst<Str>(self) -> Str =
|
|
96
96
|
todo
|
|
97
97
|
|
|
98
|
-
startCase<Str>(self) -> Str =
|
|
98
|
+
fun startCase<Str>(self) -> Str =
|
|
99
99
|
todo
|
|
100
100
|
|
|
101
|
-
deburr<Str>(self) -> Str =
|
|
101
|
+
fun deburr<Str>(self) -> Str =
|
|
102
102
|
todo
|
|
103
103
|
|
|
104
|
-
escape<Str>(self) -> Str =
|
|
104
|
+
fun escape<Str>(self) -> Str =
|
|
105
105
|
todo
|
|
106
106
|
|
|
107
|
-
escapeRegExp<Str>(self) -> Str =
|
|
107
|
+
fun escapeRegExp<Str>(self) -> Str =
|
|
108
108
|
todo
|
|
109
109
|
|
|
110
|
-
pad<Str>(self) -> Str =
|
|
110
|
+
fun pad<Str>(self) -> Str =
|
|
111
111
|
todo
|
|
112
112
|
|
|
113
|
-
template<Str>(self) -> Str =
|
|
113
|
+
fun template<Str>(self) -> Str =
|
|
114
114
|
todo
|
|
115
115
|
|
|
116
|
-
trim<Str>(self) -> Str =
|
|
116
|
+
fun trim<Str>(self) -> Str =
|
|
117
117
|
todo
|
|
118
118
|
|
|
119
|
-
trimEnd<Str>(self) -> Str =
|
|
119
|
+
fun trimEnd<Str>(self) -> Str =
|
|
120
120
|
todo
|
|
121
121
|
|
|
122
|
-
trimStart<Str>(self) -> Str =
|
|
122
|
+
fun trimStart<Str>(self) -> Str =
|
|
123
123
|
todo
|
|
124
124
|
|
|
125
|
-
truncate<Str>(self) -> Str =
|
|
125
|
+
fun truncate<Str>(self) -> Str =
|
|
126
126
|
todo
|
|
127
127
|
|
|
128
|
-
unescape<Str>(self) -> Str =
|
|
128
|
+
fun unescape<Str>(self) -> Str =
|
|
129
129
|
todo
|
|
130
130
|
|
|
131
|
-
words<Str>(self) -> Str =
|
|
131
|
+
fun words<Str>(self) -> Str =
|
|
132
132
|
todo
|
test/add.plum
CHANGED
|
@@ -2,13 +2,13 @@ module test
|
|
|
2
2
|
|
|
3
3
|
import fs
|
|
4
4
|
|
|
5
|
-
add(a: Int, b: Int) -> Int =
|
|
5
|
+
fun add(a: Int, b: Int) -> Int =
|
|
6
6
|
a + b
|
|
7
7
|
|
|
8
|
-
give42() -> Int =
|
|
8
|
+
fun give42() -> Int =
|
|
9
9
|
42
|
|
10
10
|
|
|
11
|
-
main() -> Int =
|
|
11
|
+
fun main() -> Int =
|
|
12
12
|
x1 = 2 * branch(4)
|
|
13
13
|
x2 = 3 * branch(9)
|
|
14
14
|
x3 = 5 * branch(11)
|
|
@@ -22,7 +22,7 @@ branch(x: Int) -> Int
|
|
|
22
22
|
else
|
|
23
23
|
2
|
|
24
24
|
|
|
25
|
-
main() -> Int =
|
|
25
|
+
fun main() -> Int =
|
|
26
26
|
result = 0
|
|
27
27
|
for i in 0...10
|
|
28
28
|
result += i
|
|
@@ -32,14 +32,14 @@ main() -> Int =
|
|
|
32
32
|
break
|
|
33
33
|
|
|
34
34
|
# Recursive
|
|
35
|
-
factorial(x: Int) -> Int =
|
|
35
|
+
fun factorial(x: Int) -> Int =
|
|
36
36
|
if x < 2 then
|
|
37
37
|
x
|
|
38
38
|
else
|
|
39
39
|
x * factorial(x - 1)
|
|
40
40
|
|
|
41
41
|
# While
|
|
42
|
-
factorial(x: Int) -> Int =
|
|
42
|
+
fun factorial(x: Int) -> Int =
|
|
43
43
|
result = 1
|
|
44
44
|
i = n
|
|
45
45
|
while i == 0
|
|
@@ -55,17 +55,17 @@ factorial(num: Int): Int =
|
|
|
55
55
|
result
|
|
56
56
|
|
|
57
57
|
# Reduce
|
|
58
|
-
factorial(num: Int) -> Int =
|
|
58
|
+
fun factorial(num: Int) -> Int =
|
|
59
59
|
(1..num).reduce(\a, b -> a * b)
|
|
60
60
|
|
|
61
61
|
main() -> Bool
|
|
62
62
|
5.squared() == 25
|
|
63
63
|
|
|
64
64
|
extend Int
|
|
65
|
-
squared() -> Int =
|
|
65
|
+
fun squared() -> Int =
|
|
66
66
|
this * this
|
|
67
67
|
|
|
68
|
-
main() -> Unit =
|
|
68
|
+
fun main() -> Unit =
|
|
69
69
|
input = fs::readFile("./examples/test/demos/aoc2023/1.txt")
|
|
70
70
|
calibration_sum = 0
|
|
71
71
|
first_digit = 0
|
test/aoc_2020_1.plum
CHANGED
|
@@ -3,7 +3,7 @@ module aoc2020_1
|
|
|
3
3
|
import std/fs
|
|
4
4
|
import std/int
|
|
5
5
|
|
|
6
|
-
main() -> Unit =
|
|
6
|
+
fun main() -> Unit =
|
|
7
7
|
input = fs.readFile!("./examples/test/demos/aoc2020/1.txt")
|
|
8
8
|
numbers = parseNumbers(input)
|
|
9
9
|
for i in 0...numbers.size
|
|
@@ -14,7 +14,7 @@ main() -> Unit =
|
|
|
14
14
|
printLn(a * b)
|
|
15
15
|
return
|
|
16
16
|
|
|
17
|
-
parseNumbers(input: Str) -> List<Int> =
|
|
17
|
+
fun parseNumbers(input: Str) -> List<Int> =
|
|
18
18
|
numbers = List<Int>()
|
|
19
19
|
current_number = 0
|
|
20
20
|
for i in 0..input.length()
|
test/aoc_2020_2.plum
CHANGED
|
@@ -4,7 +4,7 @@ enum Step(n: Int) =
|
|
|
4
4
|
| READ_CHAR_TO_COUNT(2)
|
|
5
5
|
| COUNT_OCCURANCES(3)
|
|
6
6
|
|
|
7
|
-
toNumber(self) =
|
|
7
|
+
fun toNumber(self) =
|
|
8
8
|
match self
|
|
9
9
|
| READ_MIN_OCCURANCES => 0
|
|
10
10
|
| READ_MAX_OCCURANCES => 1
|
|
@@ -18,7 +18,7 @@ type PasswordCheckState
|
|
|
18
18
|
current_occurances: Int
|
|
19
19
|
char_to_count: Int
|
|
20
20
|
|
|
21
|
-
create() -> PasswordCheckState =
|
|
21
|
+
fun create() -> PasswordCheckState =
|
|
22
22
|
PasswordCheckState(
|
|
23
23
|
step: READ_MIN_OCCURANCES,
|
|
24
24
|
min_occurances: 0,
|
|
@@ -27,7 +27,7 @@ type PasswordCheckState
|
|
|
27
27
|
char_to_count: '\0',
|
|
28
28
|
)
|
|
29
29
|
|
|
30
|
-
main() -> Unit =
|
|
30
|
+
fun main() -> Unit =
|
|
31
31
|
input = fs.readFile!("./examples/test/demos/aoc2020/2.txt")
|
|
32
32
|
valid_passwords_count = 0
|
|
33
33
|
state = PasswordCheckState.create()
|
test/aoc_2020_3.plum
CHANGED
|
@@ -7,10 +7,10 @@ Tile =
|
|
|
7
7
|
| TREE = True
|
|
8
8
|
| EMPTY = False
|
|
9
9
|
|
|
10
|
-
slopeI() = 1
|
|
10
|
+
fun slopeI() = 1
|
|
11
|
-
slopeJ() = 3
|
|
11
|
+
fun slopeJ() = 3
|
|
12
12
|
|
|
13
|
-
main() -> Unit =
|
|
13
|
+
fun main() -> Unit =
|
|
14
14
|
let input = fs::read_file!("./examples/test/demos/aoc2020/3.txt");
|
|
15
15
|
defer input.free();
|
|
16
16
|
let map = Map::parse(input);
|
test/aoc_2020_4.plum
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module aoc2020_4
|
|
2
2
|
|
|
3
|
-
main() -> Result =
|
|
3
|
+
fun main() -> Result =
|
|
4
4
|
input = fs::readFile!("./examples/test/demos/aoc2020/4.txt")
|
|
5
5
|
valid_passwords = 0
|
|
6
6
|
passwords = StrCutter(input.toStr())
|
test/import_fixtures/helper.plum
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
module fixtures
|
|
2
2
|
|
|
3
|
-
helperValue() -> Int =
|
|
3
|
+
fun helperValue() -> Int =
|
|
4
4
|
42
|
test/import_fixtures/main.plum
CHANGED
|
@@ -2,5 +2,5 @@ module fixtures
|
|
|
2
2
|
|
|
3
3
|
import helper
|
|
4
4
|
|
|
5
|
-
main() -> Int =
|
|
5
|
+
fun main() -> Int =
|
|
6
6
|
helperValue()
|
test/sample.plum
CHANGED
|
@@ -25,19 +25,19 @@ type Cat(ToStr) =
|
|
|
25
25
|
name: Str
|
|
26
26
|
age: Int
|
|
27
27
|
|
|
28
|
-
parseCat<Json>() -> Result(Cat, Err) =
|
|
28
|
+
fun parseCat<Json>() -> Result(Cat, Err) =
|
|
29
29
|
v = try Json.parse(self) as Map(Str, Json)
|
|
30
30
|
Cat::create()
|
|
31
31
|
.name(v.get("name").asStr())
|
|
32
32
|
.age(v.get("age").asInt())
|
|
33
33
|
|
|
34
|
-
withName<Cat>(name: Str) -> Cat =
|
|
34
|
+
fun withName<Cat>(name: Str) -> Cat =
|
|
35
35
|
Cat(name: name, age: self.age)
|
|
36
36
|
|
|
37
|
-
withAge<Cat>(age: Int) -> Cat =
|
|
37
|
+
fun withAge<Cat>(age: Int) -> Cat =
|
|
38
38
|
Cat(name: self.name, age: age)
|
|
39
39
|
|
|
40
|
-
toStr<Cat>() -> Str =
|
|
40
|
+
fun toStr<Cat>() -> Str =
|
|
41
41
|
"Cat({self.name}, {self.age})"
|
|
42
42
|
|
|
43
43
|
|
|
@@ -48,7 +48,7 @@ type User(ToStr) =
|
|
|
48
48
|
age: Int
|
|
49
49
|
todos: List(Todo)
|
|
50
50
|
|
|
51
|
-
parseUser<Json>() -> Result(Self, Err) =
|
|
51
|
+
fun parseUser<Json>() -> Result(Self, Err) =
|
|
52
52
|
v = try Json.parse(self) as Map(Str, Json)
|
|
53
53
|
User.build()
|
|
54
54
|
.name(v.get("name").asStr())
|
|
@@ -57,13 +57,13 @@ parseUser<Json>() -> Result(Self, Err) =
|
|
|
57
57
|
Todo::create().title(t.get("title").asStr()))
|
|
58
58
|
)
|
|
59
59
|
|
|
60
|
-
isAuthorized<User>() -> Bool =
|
|
60
|
+
fun isAuthorized<User>() -> Bool =
|
|
61
61
|
False
|
|
62
62
|
|
|
63
|
-
map<User>(cb: (a: User) -> b) -> b =
|
|
63
|
+
fun map<User>(cb: (a: User) -> b) -> b =
|
|
64
64
|
cb(u)
|
|
65
65
|
|
|
66
|
-
toStr<User>() -> Str =
|
|
66
|
+
fun toStr<User>() -> Str =
|
|
67
67
|
"User({self.name}, {self.age})"
|
|
68
68
|
|
|
69
69
|
u = User.build()
|
|
@@ -83,7 +83,7 @@ u2 = try User.fromJson(`{
|
|
|
83
83
|
]
|
|
84
84
|
}`)
|
|
85
85
|
|
|
86
|
-
stoplightColor(something: Int) -> Color =
|
|
86
|
+
fun stoplightColor(something: Int) -> Color =
|
|
87
87
|
if something > 0
|
|
88
88
|
Red
|
|
89
89
|
else if something == 0
|
|
@@ -91,27 +91,27 @@ stoplightColor(something: Int) -> Color =
|
|
|
91
91
|
else
|
|
92
92
|
Green
|
|
93
93
|
|
|
94
|
-
test("stoplightColor") =
|
|
94
|
+
fun test("stoplightColor") =
|
|
95
95
|
doc: "Get the color of something"
|
|
96
96
|
assert stoplightColor(1) == Red
|
|
97
97
|
assert stoplightColor(0) == Yellow
|
|
98
98
|
assert stoplightColor(-1) == Green
|
|
99
99
|
|
|
100
|
-
toCelsius(f: Float) -> Float =
|
|
100
|
+
fun toCelsius(f: Float) -> Float =
|
|
101
101
|
doc: "Convert fahrenheit temperature reading to celsius"
|
|
102
102
|
return {f - 32} * {5 / 9}
|
|
103
103
|
check:
|
|
104
|
-
toCelsius(0) == 32
|
|
104
|
+
fun toCelsius(0) == 32
|
|
105
|
-
toCelsius(100) == 212
|
|
105
|
+
fun toCelsius(100) == 212
|
|
106
|
-
toCelsius(100) == 392
|
|
106
|
+
fun toCelsius(100) == 392
|
|
107
107
|
|
|
108
|
-
empty() -> Response =
|
|
108
|
+
fun empty() -> Response =
|
|
109
109
|
Response::create()
|
|
110
110
|
.body(Buffer())
|
|
111
111
|
.headers(Map())
|
|
112
112
|
.status(0)
|
|
113
113
|
|
|
114
|
-
createFileResponse(path: Str) -> Result(Response, IOError) =
|
|
114
|
+
fun createFileResponse(path: Str) -> Result(Response, IOError) =
|
|
115
115
|
content_type = try Mime::fromExt(path.ext())
|
|
116
116
|
body = try os.readFile(file)
|
|
117
117
|
Response::create()
|
|
@@ -119,7 +119,7 @@ createFileResponse(path: Str) -> Result(Response, IOError) =
|
|
|
119
119
|
.body(body)
|
|
120
120
|
.status(200)
|
|
121
121
|
|
|
122
|
-
serveFile(file: Str) -> Result(Response, IOError) =
|
|
122
|
+
fun serveFile(file: Str) -> Result(Response, IOError) =
|
|
123
123
|
ext = try Path::fromExt(file)
|
|
124
124
|
content_type = try Mime::fromExt(ext)
|
|
125
125
|
body = os.readFile(file)
|
|
@@ -128,7 +128,7 @@ serveFile(file: Str) -> Result(Response, IOError) =
|
|
|
128
128
|
.body(body)
|
|
129
129
|
.status(200)
|
|
130
130
|
|
|
131
|
-
index() -> Result(Response, IOError) =
|
|
131
|
+
fun index() -> Result(Response, IOError) =
|
|
132
132
|
createFileResponse("index.html")
|
|
133
133
|
|
|
134
134
|
type Response(Reader, Writer) =
|
|
@@ -139,10 +139,10 @@ type Response(Reader, Writer) =
|
|
|
139
139
|
g = Greeter(name: "abc")
|
|
140
140
|
g = Greeter(...g, name: "123")
|
|
141
141
|
|
|
142
|
-
readFile() -> Result(String, Err) =
|
|
142
|
+
fun readFile() -> Result(String, Err) =
|
|
143
143
|
return Err("123")
|
|
144
144
|
|
|
145
|
-
main() -> Unit =
|
|
145
|
+
fun main() -> Unit =
|
|
146
146
|
printLn("123")
|
|
147
147
|
createFileResponse("./src/sample.plum")
|
|
148
148
|
index()
|
|
@@ -158,15 +158,15 @@ main() -> Unit =
|
|
|
158
158
|
| Err(e) =>
|
|
159
159
|
printErr(e)
|
|
160
160
|
|
|
161
|
-
sub(arg1: Int, arg2: Int) -> Int =
|
|
161
|
+
fun sub(arg1: Int, arg2: Int) -> Int =
|
|
162
162
|
local1 = arg1
|
|
163
163
|
local2 = arg2
|
|
164
164
|
local1 - local2
|
|
165
165
|
|
|
166
|
-
addAndStringify(num1: Int, num2: Int) -> Str =
|
|
166
|
+
fun addAndStringify(num1: Int, num2: Int) -> Str =
|
|
167
167
|
return (num1 + num2).toStr()
|
|
168
168
|
|
|
169
|
-
factorial(x: Int) -> Int =
|
|
169
|
+
fun factorial(x: Int) -> Int =
|
|
170
170
|
if x < 2
|
|
171
171
|
x
|
|
172
172
|
else
|
|
@@ -176,7 +176,7 @@ birds = 3
|
|
|
176
176
|
iguanas = 2
|
|
177
177
|
total = addAndStringify(birds, iguanas)
|
|
178
178
|
|
|
179
|
-
pluralize(singular: Str, plural: Str, count: Int) -> Str =
|
|
179
|
+
fun pluralize(singular: Str, plural: Str, count: Int) -> Str =
|
|
180
180
|
countstr = Num.toStr(count)
|
|
181
181
|
if count == 1 then
|
|
182
182
|
"$(countstr) $(singular)"
|
|
@@ -187,7 +187,7 @@ pluralize_test(t: Test) -> Unit =
|
|
|
187
187
|
assert pluralize("cactus", "cacti", 1) == "1 cactus"
|
|
188
188
|
assert pluralize("cactus", "cacti", 2) == "2 cacti"
|
|
189
189
|
|
|
190
|
-
name(d: Option(Str)) -> Str =
|
|
190
|
+
fun name(d: Option(Str)) -> Str =
|
|
191
191
|
if d == Some(v) then
|
|
192
192
|
v.subString(0, 3)
|
|
193
193
|
else if a == b then
|
|
@@ -195,7 +195,7 @@ name(d: Option(Str)) -> Str =
|
|
|
195
195
|
else
|
|
196
196
|
"1231"
|
|
197
197
|
|
|
198
|
-
delta(d: Option(Str)) -> Str =
|
|
198
|
+
fun delta(d: Option(Str)) -> Str =
|
|
199
199
|
if d == Some(v)
|
|
200
200
|
v.subString(0, 3)
|
|
201
201
|
else if a == b
|
|
@@ -210,27 +210,27 @@ MIN_VALUE = -0x8000_0000_0000_0000 # Lowest value of Int
|
|
|
210
210
|
MAX_VALUE = 0x7FFF_FFFF_FFFF_FFFF # Highest value of Int
|
|
211
211
|
LARGE = 268435456 # 2**28
|
|
212
212
|
|
|
213
|
-
random() -> Float = # generate random number
|
|
213
|
+
fun random() -> Float = # generate random number
|
|
214
214
|
panic("TODO")
|
|
215
215
|
|
|
216
|
-
fromStr() -> Result(Int, Err) = # convert Str to Int
|
|
216
|
+
fun fromStr() -> Result(Int, Err) = # convert Str to Int
|
|
217
217
|
Ok(0)
|
|
218
218
|
|
|
219
219
|
type Int(Comparable, Stringable)
|
|
220
220
|
|
|
221
|
-
toFloat<Int>() -> Float = # convert Int to Float
|
|
221
|
+
fun toFloat<Int>() -> Float = # convert Int to Float
|
|
222
222
|
Float(self)
|
|
223
223
|
|
|
224
|
-
add<Int>(other: Int) -> Int =
|
|
224
|
+
fun add<Int>(other: Int) -> Int =
|
|
225
225
|
self + other
|
|
226
226
|
|
|
227
|
-
sub<Int>(other: Int) -> Int =
|
|
227
|
+
fun sub<Int>(other: Int) -> Int =
|
|
228
228
|
self - other
|
|
229
229
|
|
|
230
|
-
abs<Int>() -> Int =
|
|
230
|
+
fun abs<Int>() -> Int =
|
|
231
231
|
self < 0 ? -self : self
|
|
232
232
|
|
|
233
|
-
main() =
|
|
233
|
+
fun main() =
|
|
234
234
|
user = User(name: "John Doe", age: 30)
|
|
235
235
|
if user.isAuthorized()
|
|
236
236
|
println("IsAutho")
|
|
@@ -258,7 +258,7 @@ main() =
|
|
|
258
258
|
.filter({ it == "Sam" })
|
|
259
259
|
.map({ it * 2 })
|
|
260
260
|
|
|
261
|
-
main() =
|
|
261
|
+
fun main() =
|
|
262
262
|
sum = 1 + {{2 * 3} / 4}
|
|
263
263
|
enabled = !False
|
|
264
264
|
open = {count > 10} && {enabled == True} || {debug == False}
|
test/simple_add.plum
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
add(a: Int, b: Int) -> Int =
|
|
1
|
+
fun add(a: Int, b: Int) -> Int =
|
|
2
2
|
a + b
|