~repos /plum
git clone https://pyrossh.dev/repos/plum.git
A statically typed, imperative programming language inspired by rust, python
fd085d94
—
pyrossh 1 year ago
new rules
- libs/std/bool.plum +61 -21
- libs/std/float.plum +49 -77
- libs/std/int.plum +63 -67
- libs/std/json.plum +2 -2
- libs/std/list.plum +170 -172
- libs/std/map.plum +9 -0
- libs/std/str.plum +107 -130
- tooling/tree-sitter-plum/grammar.js +19 -25
- tooling/tree-sitter-plum/src/grammar.json +0 -0
- tooling/tree-sitter-plum/src/node-types.json +0 -0
- tooling/tree-sitter-plum/src/parser.c +0 -0
- tooling/tree-sitter-plum/test/corpus/assign.txt +5 -3
- tooling/tree-sitter-plum/test/corpus/enum.txt +15 -2
- tooling/tree-sitter-plum/test/corpus/type.txt +111 -107
- tooling/vscode-plum/syntaxes/plum.tmLanguage.json +2 -17
libs/std/bool.plum
CHANGED
|
@@ -1,26 +1,66 @@
|
|
|
1
1
|
module std
|
|
2
2
|
|
|
3
|
+
type Int =
|
|
4
|
+
add(b: Int) -> Int = this + b
|
|
5
|
+
sub(b: Int) -> Int = this - b
|
|
6
|
+
|
|
7
|
+
|
|
3
|
-
Bool =
|
|
8
|
+
enum Bool =
|
|
4
9
|
| True
|
|
5
10
|
| False
|
|
6
11
|
|
|
12
|
+
and(other: Bool) -> Bool =
|
|
7
|
-
|
|
13
|
+
match this, other
|
|
14
|
+
True, True => True
|
|
15
|
+
True, False => False
|
|
16
|
+
False, True => False
|
|
17
|
+
False, False => False
|
|
18
|
+
|
|
19
|
+
or(other: Bool) -> Bool =
|
|
20
|
+
match this, other
|
|
21
|
+
True, True => True
|
|
22
|
+
True, False => True
|
|
23
|
+
False, True => True
|
|
24
|
+
False, False => False
|
|
25
|
+
|
|
8
|
-
|
|
26
|
+
toStr() -> Str =
|
|
27
|
+
match this
|
|
9
|
-
|
|
28
|
+
True => "True"
|
|
29
|
+
False => "False"
|
|
30
|
+
|
|
31
|
+
fromStr(s: Str) -> Result(Bool, Err) =
|
|
10
|
-
"
|
|
32
|
+
if s == "true"
|
|
33
|
+
True
|
|
34
|
+
else if s == "false"
|
|
35
|
+
False
|
|
11
|
-
|
|
36
|
+
else
|
|
37
|
+
Err("could not parse bool from '{s}'")
|
|
38
|
+
|
|
12
|
-
|
|
39
|
+
type Result =
|
|
13
|
-
|
|
40
|
+
| Ok(a)
|
|
41
|
+
| Err(b)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
type Option =
|
|
45
|
+
| Some(a)
|
|
46
|
+
| None
|
|
47
|
+
|
|
14
|
-
|
|
48
|
+
readFile() -> Result(String, Err) =
|
|
49
|
+
return Err
|
|
50
|
+
|
|
51
|
+
data = try readFile()
|
|
52
|
+
|
|
53
|
+
if Ok(d) = readFile()
|
|
54
|
+
println(d)
|
|
55
|
+
|
|
15
|
-
|
|
56
|
+
match readFile()
|
|
57
|
+
Ok(d) =>
|
|
58
|
+
printLn(d)
|
|
16
|
-
|
|
59
|
+
Err(e) =>
|
|
17
|
-
|
|
60
|
+
printErr(e)
|
|
18
|
-
|
|
61
|
+
|
|
19
|
-
False, False => False
|
|
20
|
-
|
|
21
|
-
Bool\or(other: Bool) -> Bool =
|
|
22
|
-
|
|
62
|
+
type List =
|
|
63
|
+
| Empty
|
|
23
|
-
|
|
64
|
+
| Node(a)
|
|
24
|
-
|
|
65
|
+
|
|
25
|
-
|
|
66
|
+
add() =
|
|
26
|
-
False, False => False
|
libs/std/float.plum
CHANGED
|
@@ -1,80 +1,52 @@
|
|
|
1
1
|
module std/float
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
E = 2.718f
|
|
5
|
-
|
|
6
|
-
# The natural logarithm of
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# The
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
# The
|
|
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
|
-
EPSILON = 2.220446049250313e-16f
|
|
41
|
-
|
|
42
|
-
# Lowest value of float
|
|
43
|
-
MIN_FLOAT_VALUE = 4.9406564584124654417656879286822137236505980e-324
|
|
44
|
-
|
|
45
|
-
# Highest value of float
|
|
46
|
-
MAX_FLOAT_VALUE = 1.79769313486231570814527423731704356798070e+308
|
|
47
|
-
|
|
48
|
-
Float::PI=3.14
|
|
49
|
-
|
|
50
|
-
fn acosh(v: float): float =
|
|
51
|
-
when
|
|
52
|
-
x < 1 | IsNaN(x) -> // first case is special case
|
|
53
|
-
NaN()
|
|
54
|
-
x == 1 ->
|
|
55
|
-
0
|
|
56
|
-
x >= Large ->
|
|
57
|
-
Log(x) + Ln2 // x > 2**28
|
|
58
|
-
x > 2 ->
|
|
59
|
-
Log(2*x - 1/(x+Sqrt(x*x-1))) // 2**28 > x > 2
|
|
60
|
-
_ ->
|
|
61
|
-
t := x - 1
|
|
62
|
-
// ((2*t+t*t).sqrt() + t).log1p()
|
|
63
|
-
Log1p(t + Sqrt(2*t+t*t)) // 2 >= x > 1
|
|
64
|
-
|
|
65
|
-
fn is_finite(): bool = true
|
|
66
|
-
` Check whether this number is finite, ie not +/-infinity and not NaN.
|
|
67
|
-
` True if exponent is not all 1s
|
|
68
|
-
(bits() and 0x7FF0_0000_0000_0000) != 0x7FF0_0000_0000_0000
|
|
69
|
-
|
|
70
|
-
# Check whether this number is +/-infinity
|
|
71
|
-
is_infinite: Bool =>
|
|
3
|
+
type Float =
|
|
4
|
+
E = 2.718f # Euler's number, the base of natural logarithms, e, https://oeis.org/A001113
|
|
5
|
+
LN10 = 2.302f # The natural logarithm of 10, https://oeis.org/A002392
|
|
6
|
+
LN2 = 0.693f # The natural logarithm of 2 https://oeis.org/A002162
|
|
7
|
+
LOG10E = 0.434f # The base 10 logarithm of e # formula: 1 / LN10
|
|
8
|
+
LOG2E = 1.442f # The base 2 logarithm of e # formula: 1 / LN2
|
|
9
|
+
PI = 3.14159f # The ratio of the circumference of a circle to its diameter https://oeis.org/A000796
|
|
10
|
+
PHI = 1.6180f # https://oeis.org/A001622
|
|
11
|
+
SQRT1_2 = 0.707f # The square root of 1/2
|
|
12
|
+
SQRT2 = 1.414f # The square root of 2 https://oeis.org/A002193
|
|
13
|
+
SQRT_E = 1.64872f # https://oeis.org/A019774
|
|
14
|
+
SQRT_PI = 1.77245f # https://oeis.org/A002161
|
|
15
|
+
SQRT_PHI = 1.27201f # https://oeis.org/A139339
|
|
16
|
+
EPSILON = 2.220446049250313e-16f # The difference between 1 and the smallest floating point number greater than 1 formula: 7/3 - 4/3 - 1
|
|
17
|
+
MIN_FLOAT_VALUE = 4.9406564584124654417656879286822137236505980e-324 # Lowest value of float
|
|
18
|
+
MAX_FLOAT_VALUE = 1.79769313486231570814527423731704356798070e+308 # Highest value of float
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
::fromStr(s: Str) -> Result(Float, Err) =
|
|
22
|
+
todo
|
|
23
|
+
|
|
24
|
+
acosh(v: Float) -> Float =
|
|
25
|
+
match
|
|
26
|
+
x < 1 | IsNaN(x) => NaN() # first case is special case
|
|
27
|
+
x == 1 => 0
|
|
28
|
+
x >= Large => x.log() + LN2 # x > 2**28
|
|
29
|
+
x > 2 => Log(2*x - 1/(x+Sqrt(x*x-1))) # 2**28 > x > 2
|
|
30
|
+
_ =>
|
|
31
|
+
t =
|
|
32
|
+
((2*t+t*t).sqrt() + t).log1p() 2 >= x > 1
|
|
33
|
+
|
|
34
|
+
# Check whether this number is finite, ie not +/-infinity and not NaN.
|
|
35
|
+
# True if exponent is not all 1s
|
|
36
|
+
isFinite() -> Bool =
|
|
37
|
+
(bits() && 0x7FF0_0000_0000_0000) != 0x7FF0_0000_0000_0000
|
|
38
|
+
|
|
39
|
+
# Check whether this number is +/-infinity
|
|
72
40
|
# True if exponent is all 1s and mantissa is 0
|
|
41
|
+
isInfinite() -> Bool =
|
|
73
|
-
|
|
42
|
+
((bits() && 0x7FF0_0000_0000_0000) == 0x7FF0_0000_0000_0000) && # exp
|
|
74
|
-
|
|
43
|
+
((bits() && 0x000F_FFFF_FFFF_FFFF) == 0) # mantissa
|
|
75
|
-
|
|
44
|
+
|
|
76
|
-
|
|
45
|
+
# Check whether this number is NaN.
|
|
77
|
-
fn is_nan(): Bool =>
|
|
78
|
-
|
|
46
|
+
# True if exponent is all 1s and mantissa is non-0
|
|
47
|
+
isNaN() -> Bool =
|
|
79
|
-
|
|
48
|
+
((bits() && 0x7FF0_0000_0000_0000) == 0x7FF0_0000_0000_0000) && # exp
|
|
80
|
-
|
|
49
|
+
((bits() && 0x000F_FFFF_FFFF_FFFF) != 0) # mantissa
|
|
50
|
+
|
|
51
|
+
toStr() -> Str =
|
|
52
|
+
todo
|
libs/std/int.plum
CHANGED
|
@@ -1,95 +1,91 @@
|
|
|
1
1
|
module std/int
|
|
2
2
|
|
|
3
|
-
Int: Comparable, ToStr =
|
|
3
|
+
type Int : Comparable, ToStr =
|
|
4
|
+
MIN_VALUE = -0x8000_0000_0000_0000 # Lowest value of Int
|
|
5
|
+
MAX_VALUE = 0x7FFF_FFFF_FFFF_FFFF # Highest value of Int
|
|
6
|
+
LARGE = 1 << 28 # 2**28
|
|
4
7
|
|
|
5
|
-
# Lowest value of Int
|
|
6
|
-
|
|
8
|
+
::random() -> Float = # Return random number
|
|
9
|
+
todo
|
|
7
10
|
|
|
8
|
-
# Highest value of Int
|
|
9
|
-
|
|
11
|
+
::parseInt() -> Result(Int, Err) =
|
|
12
|
+
0
|
|
10
13
|
|
|
14
|
+
# returns the absolute value of the Int
|
|
11
|
-
|
|
15
|
+
abs() -> Int =
|
|
12
|
-
|
|
16
|
+
this < 0 ? -this : this
|
|
13
17
|
|
|
14
|
-
|
|
18
|
+
ceil() -> Float =
|
|
15
|
-
|
|
19
|
+
todo
|
|
16
20
|
|
|
17
|
-
# returns the absolute value of the Int
|
|
18
|
-
|
|
21
|
+
floor() -> Float =
|
|
19
|
-
|
|
22
|
+
todo
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
round() -> Float =
|
|
22
|
-
|
|
25
|
+
todo
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
trunc() -> Float =
|
|
25
|
-
|
|
28
|
+
todo
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
log() -> Float =
|
|
28
|
-
|
|
31
|
+
todo
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
log2() -> Float =
|
|
31
|
-
|
|
34
|
+
todo
|
|
32
35
|
|
|
33
|
-
|
|
36
|
+
log10() -> Float =
|
|
34
|
-
|
|
37
|
+
todo
|
|
35
38
|
|
|
36
|
-
|
|
39
|
+
logb() -> Float =
|
|
37
|
-
|
|
40
|
+
todo
|
|
38
41
|
|
|
39
|
-
|
|
42
|
+
pow(y: Float) -> Float =
|
|
40
|
-
|
|
43
|
+
LibM.pow(this, y)
|
|
41
44
|
|
|
42
|
-
|
|
45
|
+
pow(y: Int) -> Float =
|
|
43
|
-
|
|
46
|
+
pow(y.toFloat())
|
|
44
47
|
|
|
45
|
-
Int\pow(y: Float) -> Float =
|
|
46
|
-
LibM.pow(this, y)
|
|
47
|
-
|
|
48
|
-
Int\pow(y: Int) -> Float =
|
|
49
|
-
pow(y.toFloat())
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
sqrt() -> Float =
|
|
52
|
-
|
|
49
|
+
if this < 0.0 then
|
|
53
|
-
|
|
50
|
+
_nan()
|
|
54
|
-
|
|
51
|
+
else
|
|
55
|
-
|
|
52
|
+
LibM.sqrt(this)
|
|
56
|
-
end
|
|
57
53
|
|
|
58
|
-
|
|
54
|
+
asin(v: Float) =
|
|
59
|
-
|
|
55
|
+
todo
|
|
60
56
|
|
|
61
|
-
|
|
57
|
+
acos(v: Float) =
|
|
62
|
-
|
|
58
|
+
if v < 0.1
|
|
63
|
-
|
|
59
|
+
asin(v)
|
|
64
|
-
|
|
60
|
+
else
|
|
65
|
-
|
|
61
|
+
asin(-v)
|
|
66
62
|
|
|
67
|
-
|
|
63
|
+
asinh(v: Float) =
|
|
68
|
-
|
|
64
|
+
todo
|
|
69
65
|
|
|
70
|
-
|
|
66
|
+
atan(v: Float) =
|
|
71
|
-
|
|
67
|
+
todo
|
|
72
68
|
|
|
73
|
-
|
|
69
|
+
atan2(v: Float) =
|
|
74
|
-
|
|
70
|
+
todo
|
|
75
71
|
|
|
76
|
-
|
|
72
|
+
atanh(v: Float) =
|
|
77
|
-
|
|
73
|
+
todo
|
|
78
74
|
|
|
79
|
-
|
|
75
|
+
cbrt(v: Float) =
|
|
80
|
-
|
|
76
|
+
todo
|
|
81
77
|
|
|
82
|
-
|
|
78
|
+
ceil(v: Float) =
|
|
83
|
-
|
|
79
|
+
todo
|
|
84
80
|
|
|
85
|
-
|
|
81
|
+
clz32(v: Float) =
|
|
86
|
-
|
|
82
|
+
todo
|
|
87
83
|
|
|
88
|
-
|
|
84
|
+
cos(v: Float) =
|
|
89
|
-
|
|
85
|
+
todo
|
|
90
86
|
|
|
91
|
-
|
|
87
|
+
cosh(v: Float) =
|
|
92
|
-
|
|
88
|
+
todo
|
|
93
89
|
|
|
94
|
-
|
|
90
|
+
exp(v: Float) =
|
|
95
|
-
|
|
91
|
+
todo
|
libs/std/json.plum
CHANGED
|
@@ -15,7 +15,7 @@ JsonParseError = {
|
|
|
15
15
|
token: Char
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
Json
|
|
18
|
+
Json::parse(src: Str | Buffer | IO) -> Json | JsonParseError =
|
|
19
19
|
JsonParser.withSrc(src).parse()
|
|
20
20
|
|
|
21
21
|
Json\parseNone() -> None | JsonParseError =
|
|
@@ -50,7 +50,7 @@ JsonParser::withSrc(src: Str | Buffer | IO) -> JsonParser =
|
|
|
50
50
|
fn isSpace(c: U32): Bool => (c == ' ') or ((c >= '\t') and (c <= '\r'))
|
|
51
51
|
|
|
52
52
|
fn isDelim(c: U32): Bool =>
|
|
53
|
-
(c == ',')
|
|
53
|
+
(c == ',') || (c == '}') || (c == ':') || (c == ']') || (_is_space(c)) || (c == 0)
|
|
54
54
|
|
|
55
55
|
fn isDigit(c: U32) -> Bool {
|
|
56
56
|
return (c >= '0') && (c <= '9')
|
libs/std/list.plum
CHANGED
|
@@ -1,176 +1,174 @@
|
|
|
1
1
|
module std
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`A node stores the data in a list and contains pointers to the previous and next sibling nodes
|
|
4
|
-
Node =
|
|
4
|
+
type Node =
|
|
5
|
-
value:
|
|
5
|
+
value: a
|
|
6
|
-
prev: Node
|
|
6
|
+
prev: Option[Node]
|
|
7
|
-
next: Node
|
|
7
|
+
next: Option[Node]
|
|
8
|
-
|
|
8
|
+
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
`A list is a data structure describing a contiguous section of an array stored separately from the slice variable itself.
|
|
11
|
-
|
|
10
|
+
`It contains the pointers to the start and end nodes (head, tail) and maintains the size as well
|
|
12
|
-
|
|
11
|
+
class List
|
|
13
|
-
head: Node
|
|
12
|
+
head: Option[Node]
|
|
14
|
-
tail: Node
|
|
13
|
+
tail: Option[Node]
|
|
15
14
|
size: Int
|
|
16
|
-
|
|
15
|
+
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
init(values: ...a) -> List =
|
|
19
|
-
|
|
17
|
+
List().add(values...)
|
|
20
|
-
|
|
18
|
+
|
|
21
|
-
|
|
19
|
+
`gets the element at i'th index of the list
|
|
22
|
-
|
|
20
|
+
get(i: Int) -> a =
|
|
23
|
-
|
|
21
|
+
current = this.head
|
|
24
|
-
|
|
22
|
+
index = 0
|
|
25
|
-
|
|
23
|
+
while current != Nil
|
|
26
|
-
|
|
24
|
+
if index == i
|
|
27
|
-
|
|
25
|
+
current.value
|
|
28
|
-
|
|
26
|
+
else
|
|
27
|
+
current = current.next
|
|
28
|
+
index += 1
|
|
29
|
+
|
|
30
|
+
`sets the element at i'th index of the list
|
|
31
|
+
set(i: Int, v: a) -> a =
|
|
32
|
+
todo
|
|
33
|
+
|
|
34
|
+
`returns the no of elements in the list
|
|
35
|
+
length() -> Int =
|
|
36
|
+
this.size
|
|
37
|
+
|
|
38
|
+
add(values: ...a) =
|
|
39
|
+
`adds the specified elements to the start of the list
|
|
40
|
+
for v in values
|
|
41
|
+
this.head = Node(value: v, prev: Nil, next: this.head)
|
|
42
|
+
this.head.next.prev = this.head
|
|
43
|
+
this.size += 1
|
|
44
|
+
|
|
45
|
+
`removes the element at i'th index of the list
|
|
46
|
+
removeAt(i: Int) =
|
|
47
|
+
this.tail?.prev?.next = Nil
|
|
48
|
+
`old tail node gets deallocated due to zero reference count
|
|
49
|
+
this.tail = list.tail?.prev
|
|
50
|
+
this.size -= 1
|
|
51
|
+
|
|
52
|
+
`removes the element v from list
|
|
53
|
+
remove(v: a) =
|
|
54
|
+
this.tail?.prev?.next = Nil
|
|
55
|
+
`old tail node gets deallocated due to zero reference count
|
|
56
|
+
this.tail = list.tail?.prev
|
|
57
|
+
this.size -= 1
|
|
58
|
+
|
|
59
|
+
`removes all objects from this list
|
|
60
|
+
clear() =
|
|
61
|
+
this.tail?.prev?.next = Nil
|
|
62
|
+
`old tail node gets deallocated due to zero reference count
|
|
63
|
+
this.tail = list.tail?.prev
|
|
64
|
+
this.size -= 1
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
`returns a new list with the elements in reverse order.
|
|
68
|
+
reverse(v: fn(v: a) -> Bool) -> List =
|
|
69
|
+
todo
|
|
70
|
+
|
|
71
|
+
`returns a new list with the elements sorted by sorter
|
|
72
|
+
sort(sorter: fn(v: a) -> Bool) -> List =
|
|
73
|
+
todo
|
|
74
|
+
|
|
75
|
+
`returns an item and index in the list if the item is is equal to search item
|
|
76
|
+
find(search: a): Option[a] =
|
|
77
|
+
todo
|
|
78
|
+
|
|
79
|
+
`returns the index of an item in the list if present and comparable otherwise Nil
|
|
80
|
+
contains(v: a) -> Bool =
|
|
81
|
+
todo
|
|
82
|
+
|
|
83
|
+
`calls f for each elem in the list
|
|
84
|
+
each(cb: fn(v: a)) -> Unit =
|
|
85
|
+
current := this.head
|
|
86
|
+
while current != Nil
|
|
87
|
+
cb(current.value)
|
|
29
88
|
current = current.next
|
|
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
|
-
# returns true if all of the elements in the list satisfies the predicate
|
|
118
|
-
List\every(predicate: fn(v: a) -> Bool) -> Bool =
|
|
119
|
-
todo
|
|
120
|
-
|
|
121
|
-
# returns the accumulated value of all the elements in the list
|
|
122
|
-
List\reduce[B](acc: B, cb: fn(v: a) -> A): B =
|
|
123
|
-
todo
|
|
124
|
-
|
|
125
|
-
# returns the first element in the list
|
|
126
|
-
List\first() -> a | Nil =
|
|
127
|
-
l.head?.value
|
|
128
|
-
|
|
129
|
-
# returns the last element in the list
|
|
130
|
-
List\last() -> a | Nil =
|
|
131
|
-
l.tail?.value
|
|
132
|
-
|
|
133
|
-
# returns a list containing the first n elements of the given list
|
|
134
|
-
List\sublist(start: int, end: int) -> List(A) =
|
|
135
|
-
todo
|
|
136
|
-
|
|
137
|
-
# returns a list containing the first n elements of the given list
|
|
138
|
-
List\take(n: int) -> List(A) =
|
|
139
|
-
todo
|
|
140
|
-
|
|
141
|
-
# returns a list containing the first n elements of the given list
|
|
142
|
-
List\skip(n: int) -> List(A) =
|
|
143
|
-
todo
|
|
144
|
-
|
|
145
|
-
`Returns a list containing the first n elements of the given list
|
|
146
|
-
List\drop(n: int) -> List(A) =
|
|
147
|
-
todo
|
|
148
|
-
|
|
149
|
-
# returns a new list with some of the elements taken randomly`
|
|
150
|
-
List\sample() =
|
|
151
|
-
todo
|
|
152
|
-
|
|
153
|
-
# returns a new list with all elements shuffled`
|
|
154
|
-
List\shuffle() =
|
|
155
|
-
todo
|
|
156
|
-
|
|
157
|
-
# returns a new list with all elements shuffled`
|
|
158
|
-
List\partition() =
|
|
159
|
-
todo
|
|
160
|
-
|
|
161
|
-
# returns a new list with all elements shuffled`
|
|
162
|
-
List\chunk() =
|
|
163
|
-
todo
|
|
164
|
-
|
|
165
|
-
# returns a new list with all elements grouped`
|
|
166
|
-
List\groupBy() =
|
|
167
|
-
todo
|
|
168
|
-
|
|
169
|
-
List\join(sep: Str = ",") -> Str =
|
|
170
|
-
res := Buffer()
|
|
171
|
-
l.each() |v|
|
|
172
|
-
if @HasTrait(V, ToStr)
|
|
173
|
-
res.write(v.to_str(), sep)
|
|
174
|
-
else
|
|
175
|
-
res.write(@TypeToString(v), sep)
|
|
176
|
-
res.to_str()
|
|
89
|
+
|
|
90
|
+
`returns a list made up of B elements for each elem in the list
|
|
91
|
+
map(cb: fn(v: a) -> b) -> List(b) =
|
|
92
|
+
nl := []
|
|
93
|
+
current := this.head
|
|
94
|
+
while current != Nil
|
|
95
|
+
item := cb(current.value)
|
|
96
|
+
nl.push(item)
|
|
97
|
+
nl
|
|
98
|
+
|
|
99
|
+
`returns a new list with all elements shuffled`
|
|
100
|
+
flatMap() =
|
|
101
|
+
todo
|
|
102
|
+
|
|
103
|
+
`returns a new list with the elements that matched the predicate
|
|
104
|
+
retain(predicate: fn(v: a) -> a) -> List =
|
|
105
|
+
todo
|
|
106
|
+
|
|
107
|
+
`returns a new list with the elements that matched the predicate removed
|
|
108
|
+
reject(predicate: fn(v: a) -> a) -> List =
|
|
109
|
+
todo
|
|
110
|
+
|
|
111
|
+
`returns true if any element in the list satisfies the predicate
|
|
112
|
+
any(predicate: fn(v: a) -> Bool) -> Bool =
|
|
113
|
+
todo
|
|
114
|
+
|
|
115
|
+
`returns true if all of the elements in the list satisfies the predicate
|
|
116
|
+
every(predicate: fn(v: a) -> Bool) -> Bool =
|
|
117
|
+
todo
|
|
118
|
+
|
|
119
|
+
`returns the accumulated value of all the elements in the list
|
|
120
|
+
reduce[B](acc: B, cb: fn(v: a) -> a): B =
|
|
121
|
+
todo
|
|
122
|
+
|
|
123
|
+
`returns the first element in the list
|
|
124
|
+
first() -> Option[a] =
|
|
125
|
+
this.head?.value
|
|
126
|
+
|
|
127
|
+
`returns the last element in the list
|
|
128
|
+
last() -> Option[a] =
|
|
129
|
+
this.tail?.value
|
|
130
|
+
|
|
131
|
+
`returns a list containing the first n elements of the given list
|
|
132
|
+
sublist(start: int, end: int) -> List =
|
|
133
|
+
todo
|
|
134
|
+
|
|
135
|
+
`returns a list containing the first n elements of the given list
|
|
136
|
+
take(n: int) -> List =
|
|
137
|
+
todo
|
|
138
|
+
|
|
139
|
+
`returns a list containing the first n elements of the given list
|
|
140
|
+
skip(n: int) -> List =
|
|
141
|
+
todo
|
|
142
|
+
|
|
143
|
+
`returns a list containing the first n elements of the given list
|
|
144
|
+
drop(n: int) -> List =
|
|
145
|
+
todo
|
|
146
|
+
|
|
147
|
+
`returns a new list with some of the elements taken randomly`
|
|
148
|
+
sample() =
|
|
149
|
+
todo
|
|
150
|
+
|
|
151
|
+
`returns a new list with all elements shuffled`
|
|
152
|
+
shuffle() =
|
|
153
|
+
todo
|
|
154
|
+
|
|
155
|
+
`returns a new list with all elements shuffled`
|
|
156
|
+
partition() =
|
|
157
|
+
todo
|
|
158
|
+
|
|
159
|
+
`returns a new list with all elements shuffled`
|
|
160
|
+
chunk() =
|
|
161
|
+
todo
|
|
162
|
+
|
|
163
|
+
`returns a new list with all elements grouped`
|
|
164
|
+
groupBy() =
|
|
165
|
+
todo
|
|
166
|
+
|
|
167
|
+
join(sep: Str = ",") -> Str =
|
|
168
|
+
res := Buffer()
|
|
169
|
+
this.each() |v|
|
|
170
|
+
if @HasTrait(V, ToStr)
|
|
171
|
+
res.write(v.to_str(), sep)
|
|
172
|
+
else
|
|
173
|
+
res.write(@TypeToString(v), sep)
|
|
174
|
+
res.to_str()
|
libs/std/map.plum
CHANGED
|
@@ -27,6 +27,15 @@ Map\get(k: a) -> b | Nil =
|
|
|
27
27
|
return v
|
|
28
28
|
Nil
|
|
29
29
|
|
|
30
|
+
# Get a value from the Map using key k
|
|
31
|
+
Map\get(k: a) -> b | Nil =
|
|
32
|
+
found : Option(b) = None
|
|
33
|
+
for k, v in items do
|
|
34
|
+
if k == k
|
|
35
|
+
found = v
|
|
36
|
+
break
|
|
37
|
+
found
|
|
38
|
+
|
|
30
39
|
# Put a value into the Map
|
|
31
40
|
Map\set(k: a, v: b) =
|
|
32
41
|
items.add(pair(k, v))
|
libs/std/str.plum
CHANGED
|
@@ -1,177 +1,154 @@
|
|
|
1
1
|
module std/str
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`ToStr defines any data that can be converted to a str
|
|
4
|
-
|
|
4
|
+
trait Stringable =
|
|
5
5
|
toStr() -> Str
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
```
|
|
9
|
-
A Str is an array of contiguous data stored in memory with a null termination using hex 0x00 or ASCII 0x00.
|
|
10
|
-
It is immutable and cannot be modified. It is copied for any changes and saved to a new memory location.
|
|
11
|
-
The previous str is freed if its reference count is 0 within the block.
|
|
12
|
-
```
|
|
13
|
-
Str : Comparable + ToStr = {
|
|
14
|
-
data: Buffer
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
Str\get(i: Int) -> Char =
|
|
18
|
-
data.get(i)
|
|
19
|
-
|
|
20
|
-
Str\contains(search: Str) -> Bool =
|
|
21
|
-
todo
|
|
22
6
|
|
|
7
|
+
`A Str is an array of contiguous data stored in memory with a null termination using hex 0x00 or ASCII 0x00.
|
|
8
|
+
`It is immutable and cannot be modified. It is copied for any changes and saved to a new memory location.
|
|
23
|
-
|
|
9
|
+
`The previous str is freed if its reference count is 0 within the block.
|
|
24
|
-
todo
|
|
25
|
-
|
|
26
|
-
Str
|
|
10
|
+
type Str is Comparable, Stringable, Readable, Writable =
|
|
27
|
-
|
|
11
|
+
data: Buffer
|
|
28
12
|
|
|
29
|
-
Str\search(key: Str) -> (Int, Bool) =
|
|
30
|
-
low, mid, high = 0, 0, n.numItems
|
|
31
|
-
|
|
13
|
+
get(i: Int) -> Char =
|
|
32
|
-
mid = (low + high) / 2
|
|
33
|
-
cmp = key > n.items[mid].key
|
|
34
|
-
low = cmp > 0 ? mid + 1 : low
|
|
35
|
-
high = cmp < 0 ? mid : high
|
|
36
|
-
if cmp == 0 then
|
|
37
|
-
return (mid, True)
|
|
38
|
-
|
|
14
|
+
data.get(i)
|
|
39
15
|
|
|
40
|
-
|
|
16
|
+
contains(self, search: Str) -> Bool =
|
|
41
|
-
|
|
17
|
+
todo
|
|
42
18
|
|
|
43
|
-
|
|
19
|
+
indexOf(self, sub: Str) -> Int =
|
|
44
|
-
|
|
20
|
+
todo
|
|
45
21
|
|
|
46
|
-
|
|
22
|
+
test(self, pattern: Regex) -> Bool =
|
|
47
|
-
|
|
23
|
+
todo
|
|
48
24
|
|
|
49
|
-
|
|
25
|
+
search(key: Str) -> (Int, Bool) =
|
|
26
|
+
low, mid, high = 0, 0, n.numItems
|
|
27
|
+
while low < high
|
|
28
|
+
mid = (low + high) / 2
|
|
29
|
+
cmp = key > n.items[mid].key
|
|
30
|
+
low = cmp > 0 ? mid + 1 : low
|
|
31
|
+
high = cmp < 0 ? mid : high
|
|
32
|
+
if cmp == 0 then
|
|
33
|
+
return (mid, True)
|
|
50
|
-
|
|
34
|
+
(low, False)
|
|
51
35
|
|
|
52
|
-
|
|
36
|
+
startsWith(search: str) -> Bool =
|
|
53
|
-
|
|
37
|
+
todo
|
|
54
38
|
|
|
55
|
-
|
|
39
|
+
concat(other: Str) -> Str =
|
|
56
|
-
|
|
40
|
+
s + other
|
|
57
41
|
|
|
58
|
-
|
|
42
|
+
toStr(self) -> Str =
|
|
59
|
-
|
|
43
|
+
self
|
|
60
44
|
|
|
61
|
-
|
|
45
|
+
matchPattern(self, pattern: Regex) -> List<Str> =
|
|
62
|
-
|
|
46
|
+
todo
|
|
63
47
|
|
|
64
|
-
|
|
48
|
+
matchAll(self, pattern: Regex) -> List<Str> =
|
|
65
|
-
|
|
49
|
+
todo
|
|
66
50
|
|
|
67
|
-
|
|
51
|
+
padStart(self, sub: Str, count: Int) -> Str =
|
|
68
|
-
|
|
52
|
+
todo
|
|
69
53
|
|
|
70
|
-
|
|
54
|
+
padEnd(self, sub: Str, count: Int) -> Str =
|
|
71
|
-
|
|
55
|
+
todo
|
|
72
56
|
|
|
73
|
-
|
|
57
|
+
repeat(self, count: Int) -> Str =
|
|
74
|
-
|
|
58
|
+
todo
|
|
75
59
|
|
|
76
|
-
|
|
60
|
+
replace(pattern: Regex, sub: Str) -> Str =
|
|
77
|
-
|
|
61
|
+
todo
|
|
78
62
|
|
|
79
|
-
|
|
63
|
+
replaceAll(pattern: Regex, sub: Str) -> Str =
|
|
80
|
-
|
|
64
|
+
todo
|
|
81
65
|
|
|
82
|
-
|
|
66
|
+
search(pattern: Regex) -> Str =
|
|
83
|
-
|
|
67
|
+
todo
|
|
84
68
|
|
|
85
|
-
`reverses a Str
|
|
86
|
-
|
|
69
|
+
slice(start: Int, e: Int) -> Str =
|
|
87
|
-
start := 0
|
|
88
|
-
end := length - 1
|
|
89
|
-
result := []
|
|
90
|
-
while start < end
|
|
91
|
-
const temp = data[start]
|
|
92
|
-
result[start] = data[end]
|
|
93
|
-
result[end] = temp
|
|
94
|
-
end = end - 1
|
|
95
|
-
start = start + 1
|
|
96
|
-
|
|
70
|
+
todo
|
|
97
71
|
|
|
98
|
-
|
|
72
|
+
split(separator: Str, limit: Int) -> []Str =
|
|
99
|
-
|
|
73
|
+
todo
|
|
100
74
|
|
|
101
|
-
|
|
75
|
+
sub(start: Int, e: Int) -> Str =
|
|
102
|
-
|
|
76
|
+
todo
|
|
103
77
|
|
|
104
|
-
|
|
78
|
+
toLower() -> Str =
|
|
105
|
-
match self.to_lower()
|
|
106
|
-
"true" -> True
|
|
107
|
-
"false" -> False
|
|
108
|
-
_ -> error("could not parse bool '${this}'")
|
|
109
|
-
if self.lower() == "true"
|
|
110
|
-
|
|
79
|
+
todo
|
|
111
|
-
else if self.lower() == "false"
|
|
112
|
-
False
|
|
113
|
-
else
|
|
114
|
-
error("could not parse bool '${this}'")
|
|
115
80
|
|
|
81
|
+
# reverses a Str
|
|
82
|
+
reverse() -> Str =
|
|
83
|
+
start := 0
|
|
84
|
+
end := length - 1
|
|
85
|
+
result := []
|
|
86
|
+
while start < end
|
|
87
|
+
const temp = data[start]
|
|
88
|
+
result[start] = data[end]
|
|
89
|
+
result[end] = temp
|
|
90
|
+
end = end - 1
|
|
91
|
+
start = start + 1
|
|
92
|
+
result
|
|
116
93
|
|
|
117
|
-
|
|
94
|
+
camelCase() -> Str =
|
|
118
|
-
|
|
95
|
+
todo
|
|
119
96
|
|
|
120
|
-
|
|
97
|
+
snakeCase() -> Str =
|
|
121
|
-
|
|
98
|
+
todo
|
|
122
99
|
|
|
123
|
-
|
|
100
|
+
capitalize() -> Str =
|
|
124
|
-
|
|
101
|
+
todo
|
|
125
102
|
|
|
126
|
-
|
|
103
|
+
kebabCase() -> Str =
|
|
127
|
-
|
|
104
|
+
todo
|
|
128
105
|
|
|
129
|
-
|
|
106
|
+
lowerCase() -> Str =
|
|
130
|
-
|
|
107
|
+
todo
|
|
131
108
|
|
|
132
|
-
|
|
109
|
+
lowerFirst() -> Str =
|
|
133
|
-
|
|
110
|
+
todo
|
|
134
111
|
|
|
135
|
-
|
|
112
|
+
upperCase() -> Str =
|
|
136
|
-
|
|
113
|
+
todo
|
|
137
114
|
|
|
138
|
-
|
|
115
|
+
upperFirst() -> Str =
|
|
139
|
-
|
|
116
|
+
todo
|
|
140
117
|
|
|
141
118
|
|
|
142
|
-
|
|
119
|
+
startCase() -> Str =
|
|
143
|
-
|
|
120
|
+
todo
|
|
144
121
|
|
|
145
|
-
|
|
122
|
+
deburr() -> Str =
|
|
146
|
-
|
|
123
|
+
todo
|
|
147
124
|
|
|
148
|
-
|
|
125
|
+
escape() -> Str =
|
|
149
|
-
|
|
126
|
+
todo
|
|
150
127
|
|
|
151
|
-
|
|
128
|
+
escapeRegExp() -> Str =
|
|
152
|
-
|
|
129
|
+
todo
|
|
153
130
|
|
|
154
|
-
|
|
131
|
+
pad() -> Str =
|
|
155
|
-
|
|
132
|
+
todo
|
|
156
133
|
|
|
157
|
-
|
|
134
|
+
template() -> Str =
|
|
158
|
-
|
|
135
|
+
todo
|
|
159
136
|
|
|
160
|
-
|
|
137
|
+
trim() -> Str =
|
|
161
|
-
|
|
138
|
+
todo
|
|
162
139
|
|
|
163
|
-
|
|
140
|
+
trimEnd() -> Str =
|
|
164
|
-
|
|
141
|
+
todo
|
|
165
142
|
|
|
166
|
-
|
|
143
|
+
trimStart() -> Str =
|
|
167
|
-
|
|
144
|
+
todo
|
|
168
145
|
|
|
169
|
-
|
|
146
|
+
truncate() -> Str =
|
|
170
|
-
|
|
147
|
+
todo
|
|
171
148
|
|
|
172
|
-
|
|
149
|
+
unescape() -> Str =
|
|
173
|
-
|
|
150
|
+
todo
|
|
174
151
|
|
|
175
|
-
|
|
152
|
+
words() -> Str =
|
|
176
|
-
|
|
153
|
+
todo
|
|
177
154
|
|
tooling/tree-sitter-plum/grammar.js
CHANGED
|
@@ -65,13 +65,13 @@ module.exports = grammar({
|
|
|
65
65
|
seq(
|
|
66
66
|
optional(seq("module", $.module)),
|
|
67
67
|
repeat($.import),
|
|
68
|
-
repeat(choice($.record, $.
|
|
68
|
+
repeat(choice($.record, $.trait, $.enum, $.fn)),
|
|
69
69
|
),
|
|
70
70
|
|
|
71
|
-
module: ($) => $.
|
|
71
|
+
module: ($) => $.var_identier,
|
|
72
72
|
|
|
73
73
|
import: ($) => seq("import", $.url),
|
|
74
|
-
url: (
|
|
74
|
+
url: () => sep1(/[a-zA-Z_][a-zA-Z_0-9]*/, "/"),
|
|
75
75
|
|
|
76
76
|
generics: ($) => seq("(", commaSep1($.generic_type), ")"),
|
|
77
77
|
generic_type: ($) =>
|
|
@@ -80,7 +80,7 @@ module.exports = grammar({
|
|
|
80
80
|
choice(
|
|
81
81
|
seq(
|
|
82
82
|
$.type_identifier,
|
|
83
|
-
field("generics", optional(seq("
|
|
83
|
+
field("generics", optional(seq("[", commaSep1($.type), "]"))),
|
|
84
84
|
),
|
|
85
85
|
$.generic,
|
|
86
86
|
),
|
|
@@ -88,24 +88,19 @@ module.exports = grammar({
|
|
|
88
88
|
|
|
89
89
|
record: ($) =>
|
|
90
90
|
seq(
|
|
91
|
+
"type",
|
|
91
92
|
field("name", $.type_identifier),
|
|
92
93
|
field("implements", optional(seq(":", sep1($.type_identifier, "+")))),
|
|
93
94
|
field("generics", optional($.generics)),
|
|
94
95
|
"=",
|
|
95
|
-
field("fields", seq("{", $._newline, sep1($.record_field, $._newline), $._newline, "}")),
|
|
96
|
-
),
|
|
97
|
-
|
|
98
|
-
record_field: ($) =>
|
|
99
|
-
seq(field("name", $.identifier), ":", field("type", $.type)),
|
|
100
|
-
|
|
101
|
-
object: ($) =>
|
|
102
|
-
seq(
|
|
103
|
-
|
|
96
|
+
$._indent,
|
|
104
|
-
|
|
97
|
+
optional(repeat($.record_field)),
|
|
105
|
-
field("implements", optional(seq(":", commaSep1($.type_identifier)))),
|
|
106
|
-
|
|
98
|
+
optional(repeat($.method)),
|
|
99
|
+
$._dedent,
|
|
107
100
|
),
|
|
108
101
|
|
|
102
|
+
record_field: ($) => seq(field("name", $.identifier), ":", field("type", $.type)),
|
|
103
|
+
method: ($) => alias($.fn, "method"),
|
|
109
104
|
trait: ($) =>
|
|
110
105
|
seq(
|
|
111
106
|
"trait",
|
|
@@ -125,7 +120,7 @@ module.exports = grammar({
|
|
|
125
120
|
|
|
126
121
|
param: ($) =>
|
|
127
122
|
seq(
|
|
128
|
-
field("name", $.
|
|
123
|
+
field("name", $.var_identier),
|
|
129
124
|
":",
|
|
130
125
|
field("type", choice($.type, $.variadic_type)),
|
|
131
126
|
optional(seq("=", field("value", $.expression))),
|
|
@@ -136,10 +131,12 @@ module.exports = grammar({
|
|
|
136
131
|
|
|
137
132
|
enum: ($) =>
|
|
138
133
|
seq(
|
|
134
|
+
"enum",
|
|
139
135
|
field("name", $.type_identifier),
|
|
140
136
|
"=",
|
|
141
137
|
$._indent,
|
|
142
|
-
|
|
138
|
+
optional(repeat($.enum_field)),
|
|
139
|
+
optional(repeat($.method)),
|
|
143
140
|
$._dedent,
|
|
144
141
|
),
|
|
145
142
|
|
|
@@ -152,10 +149,10 @@ module.exports = grammar({
|
|
|
152
149
|
|
|
153
150
|
fn: ($) =>
|
|
154
151
|
seq(
|
|
155
|
-
field("name", choice($.
|
|
152
|
+
field("name", choice($.identifier, $.static_identifier)),
|
|
156
153
|
field("params", seq("(", optional(commaSep1($.param)), ")")),
|
|
157
154
|
field("returns", optional(seq("->", $.return_type))),
|
|
158
|
-
field("body", seq("=", $.body)),
|
|
155
|
+
field("body", seq("=", choice($.expression, $.body))),
|
|
159
156
|
),
|
|
160
157
|
|
|
161
158
|
body: ($) => seq($._indent, repeat($._statement), $._dedent),
|
|
@@ -178,7 +175,7 @@ module.exports = grammar({
|
|
|
178
175
|
assign: ($) =>
|
|
179
176
|
prec.right(
|
|
180
177
|
seq(
|
|
181
|
-
field("left", commaSep1($.
|
|
178
|
+
field("left", commaSep1($.var_identier)),
|
|
182
179
|
"=",
|
|
183
180
|
field("right", $.expression),
|
|
184
181
|
),
|
|
@@ -207,12 +204,9 @@ module.exports = grammar({
|
|
|
207
204
|
reference: ($) =>
|
|
208
205
|
prec(
|
|
209
206
|
PREC.call,
|
|
210
|
-
seq(choice($.
|
|
207
|
+
seq(choice($.var_identier, $.type_identifier), optional(seq(".", $.identifier))),
|
|
211
208
|
),
|
|
212
209
|
|
|
213
|
-
method_identifier: ($) =>
|
|
214
|
-
seq($.type_identifier, "\\", $.fn_identifier),
|
|
215
|
-
|
|
216
210
|
static_identifier: ($) =>
|
|
217
211
|
seq($.type_identifier, "::", $.fn_identifier),
|
|
218
212
|
|
tooling/tree-sitter-plum/src/grammar.json
CHANGED
|
Binary file
|
tooling/tree-sitter-plum/src/node-types.json
CHANGED
|
Binary file
|
tooling/tree-sitter-plum/src/parser.c
CHANGED
|
Binary file
|
tooling/tree-sitter-plum/test/corpus/assign.txt
CHANGED
|
@@ -99,6 +99,8 @@ countriesList = listOf("US", "INDIA", "CANADA")
|
|
|
99
99
|
a = list.of(1, 2, 3)
|
|
100
100
|
b = list.of(list.of(1), list.of(2), list.of(3))
|
|
101
101
|
c = list.of(1, 2, 3 * 4, 8, n)
|
|
102
|
+
d = "{name} {age}"
|
|
103
|
+
e = "Cat<{fullname()}, {age}>"
|
|
102
104
|
|
|
103
105
|
--------------------------------------------------------------------------------
|
|
104
106
|
|
|
@@ -219,13 +221,13 @@ c = list.of(1, 2, 3 * 4, 8, n)
|
|
|
219
221
|
assign - Call map
|
|
220
222
|
================================================================================
|
|
221
223
|
|
|
222
|
-
countryCode =
|
|
224
|
+
countryCode = Map(
|
|
223
225
|
"in" => "INDIA",
|
|
224
226
|
"us" => "United States",
|
|
225
227
|
"ca" => "Canada"
|
|
226
228
|
)
|
|
227
|
-
a =
|
|
229
|
+
a = Map("a" => 1, "b" => 2)
|
|
228
|
-
b =
|
|
230
|
+
b = Map("a" => 1, "b" => Map("c" => 3, "d" => 4))
|
|
229
231
|
|
|
230
232
|
--------------------------------------------------------------------------------
|
|
231
233
|
|
tooling/tree-sitter-plum/test/corpus/enum.txt
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
enum
|
|
3
3
|
================================================================================
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
enum Bool
|
|
6
6
|
| True
|
|
7
7
|
| False
|
|
8
8
|
|
|
9
|
+
toStr() -> Str =
|
|
10
|
+
"Bool"
|
|
11
|
+
|
|
9
12
|
--------------------------------------------------------------------------------
|
|
10
13
|
|
|
11
14
|
(source
|
|
@@ -14,4 +17,14 @@ Bool =
|
|
|
14
17
|
(enum_field
|
|
15
18
|
(type_identifier))
|
|
16
19
|
(enum_field
|
|
17
|
-
(type_identifier))
|
|
20
|
+
(type_identifier))
|
|
21
|
+
(method
|
|
22
|
+
(identifier)
|
|
23
|
+
(return_type
|
|
24
|
+
(type_identifier))
|
|
25
|
+
(body
|
|
26
|
+
(primary_expression
|
|
27
|
+
(string
|
|
28
|
+
(string_start)
|
|
29
|
+
(string_content)
|
|
30
|
+
(string_end)))))))
|
tooling/tree-sitter-plum/test/corpus/type.txt
CHANGED
|
@@ -2,20 +2,35 @@
|
|
|
2
2
|
type - definition
|
|
3
3
|
================================================================================
|
|
4
4
|
|
|
5
|
-
Cat
|
|
5
|
+
type Cat is Stringable =
|
|
6
6
|
name: Str
|
|
7
7
|
age: Int
|
|
8
|
-
}
|
|
9
8
|
|
|
10
|
-
Dog =
|
|
9
|
+
type Dog =
|
|
11
10
|
name: a
|
|
12
11
|
age: b
|
|
13
|
-
}
|
|
14
12
|
|
|
15
|
-
Dog(a: Compare +
|
|
13
|
+
type Dog(a: Compare + Stringable, b) is Stringable =
|
|
16
14
|
name: a
|
|
17
15
|
age: b
|
|
16
|
+
|
|
17
|
+
type Int =
|
|
18
|
+
add(other: Int) -> Int = this + other
|
|
19
|
+
sub(other: Int) -> Int = this - other
|
|
20
|
+
|
|
21
|
+
type Cat is Stringable =
|
|
22
|
+
name: Str
|
|
18
|
-
|
|
23
|
+
age: Int
|
|
24
|
+
|
|
25
|
+
withName(name: Str) -> Cat =
|
|
26
|
+
Cat(name = name, age = 0)
|
|
27
|
+
|
|
28
|
+
withAge(age: Int) -> Cat =
|
|
29
|
+
Cat(name = "", age = age)
|
|
30
|
+
|
|
31
|
+
Stringable() -> Str =
|
|
32
|
+
"Cat"
|
|
33
|
+
|
|
19
34
|
--------------------------------------------------------------------------------
|
|
20
35
|
|
|
21
36
|
(source
|
|
@@ -54,32 +69,39 @@ Dog(a: Compare + String, b) = {
|
|
|
54
69
|
(record_field
|
|
55
70
|
(identifier)
|
|
56
71
|
(type
|
|
57
|
-
(b))))
|
|
72
|
+
(b))))
|
|
58
|
-
|
|
73
|
+
(record
|
|
59
|
-
|
|
74
|
+
(type_identifier)
|
|
60
|
-
|
|
75
|
+
(method
|
|
61
|
-
================================================================================
|
|
62
|
-
|
|
63
|
-
Cat : ToStr = {
|
|
64
|
-
|
|
76
|
+
(identifier)
|
|
65
|
-
age: Int
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
Cat\withName(name: Str) -> Cat =
|
|
69
|
-
Cat(name = name, age = 0)
|
|
70
|
-
|
|
71
|
-
Cat\withAge(age: Int) -> Cat =
|
|
72
|
-
Cat(name = "", age = age)
|
|
73
|
-
|
|
74
|
-
Cat\fullname() -> Str =
|
|
75
|
-
"${name} ${age}"
|
|
76
|
-
|
|
77
|
-
Cat\toStr() -> Str =
|
|
78
|
-
"Cat<{fullname()}, {age}>"
|
|
79
|
-
|
|
80
|
-
--------------------------------------------------------------------------------
|
|
81
|
-
|
|
82
|
-
(
|
|
77
|
+
(param
|
|
78
|
+
(var_identier)
|
|
79
|
+
(type
|
|
80
|
+
(type_identifier)))
|
|
81
|
+
(return_type
|
|
82
|
+
(type_identifier))
|
|
83
|
+
(expression
|
|
84
|
+
(primary_expression
|
|
85
|
+
(binary_operator
|
|
86
|
+
(primary_expression
|
|
87
|
+
(this))
|
|
88
|
+
(primary_expression
|
|
89
|
+
(identifier))))))
|
|
90
|
+
(method
|
|
91
|
+
(identifier)
|
|
92
|
+
(param
|
|
93
|
+
(var_identier)
|
|
94
|
+
(type
|
|
95
|
+
(type_identifier)))
|
|
96
|
+
(return_type
|
|
97
|
+
(type_identifier))
|
|
98
|
+
(expression
|
|
99
|
+
(primary_expression
|
|
100
|
+
(binary_operator
|
|
101
|
+
(primary_expression
|
|
102
|
+
(this))
|
|
103
|
+
(primary_expression
|
|
104
|
+
(identifier)))))))
|
|
83
105
|
(record
|
|
84
106
|
(type_identifier)
|
|
85
107
|
(type_identifier)
|
|
@@ -88,82 +110,64 @@ Cat\toStr() -> Str =
|
|
|
88
110
|
(type
|
|
89
111
|
(type_identifier)))
|
|
90
112
|
(record_field
|
|
91
|
-
(identifier)
|
|
92
|
-
(type
|
|
93
|
-
(type_identifier))))
|
|
94
|
-
(fn
|
|
95
|
-
(method_identifier
|
|
96
|
-
(type_identifier)
|
|
97
|
-
(fn_identifier))
|
|
98
|
-
(param
|
|
99
113
|
(identifier)
|
|
100
114
|
(type
|
|
101
115
|
(type_identifier)))
|
|
102
|
-
(return_type
|
|
103
|
-
(type_identifier))
|
|
104
|
-
(
|
|
116
|
+
(method
|
|
105
|
-
(primary_expression
|
|
106
|
-
(type_call
|
|
107
|
-
(type_identifier)
|
|
108
|
-
(argument_list
|
|
109
|
-
(keyword_argument
|
|
110
|
-
(identifier)
|
|
111
|
-
(expression
|
|
112
|
-
(primary_expression
|
|
113
|
-
(identifier))))
|
|
114
|
-
(keyword_argument
|
|
115
|
-
(identifier)
|
|
116
|
-
(expression
|
|
117
|
-
(primary_expression
|
|
118
|
-
(integer)))))))))
|
|
119
|
-
(fn
|
|
120
|
-
(method_identifier
|
|
121
|
-
(type_identifier)
|
|
122
|
-
(fn_identifier))
|
|
123
|
-
(param
|
|
124
117
|
(identifier)
|
|
125
|
-
(
|
|
126
|
-
(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
(
|
|
134
|
-
(
|
|
135
|
-
|
|
136
|
-
(
|
|
137
|
-
(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
(
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
118
|
+
(param
|
|
119
|
+
(var_identier)
|
|
120
|
+
(type
|
|
121
|
+
(type_identifier)))
|
|
122
|
+
(return_type
|
|
123
|
+
(type_identifier))
|
|
124
|
+
(body
|
|
125
|
+
(primary_expression
|
|
126
|
+
(type_call
|
|
127
|
+
(type_identifier)
|
|
128
|
+
(argument_list
|
|
129
|
+
(keyword_argument
|
|
130
|
+
(identifier)
|
|
131
|
+
(expression
|
|
132
|
+
(primary_expression
|
|
133
|
+
(identifier))))
|
|
134
|
+
(keyword_argument
|
|
135
|
+
(identifier)
|
|
136
|
+
(expression
|
|
137
|
+
(primary_expression
|
|
138
|
+
(integer)))))))))
|
|
139
|
+
(method
|
|
140
|
+
(identifier)
|
|
141
|
+
(param
|
|
142
|
+
(var_identier)
|
|
143
|
+
(type
|
|
144
|
+
(type_identifier)))
|
|
145
|
+
(return_type
|
|
146
|
+
(type_identifier))
|
|
147
|
+
(body
|
|
148
|
+
(primary_expression
|
|
149
|
+
(type_call
|
|
150
|
+
(type_identifier)
|
|
151
|
+
(argument_list
|
|
152
|
+
(keyword_argument
|
|
153
|
+
(identifier)
|
|
154
|
+
(expression
|
|
155
|
+
(primary_expression
|
|
156
|
+
(string
|
|
157
|
+
(string_start)
|
|
158
|
+
(string_end)))))
|
|
159
|
+
(keyword_argument
|
|
160
|
+
(identifier)
|
|
161
|
+
(expression
|
|
162
|
+
(primary_expression
|
|
163
|
+
(identifier)))))))))
|
|
164
|
+
(method
|
|
165
|
+
(identifier)
|
|
166
|
+
(return_type
|
|
167
|
+
(type_identifier))
|
|
168
|
+
(body
|
|
169
|
+
(primary_expression
|
|
170
|
+
(string
|
|
171
|
+
(string_start)
|
|
172
|
+
(string_content)
|
|
173
|
+
(string_end)))))))
|
tooling/vscode-plum/syntaxes/plum.tmLanguage.json
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"patterns": [
|
|
27
27
|
{
|
|
28
28
|
"name": "keyword.control.plum",
|
|
29
|
-
"match": "\\b(
|
|
29
|
+
"match": "\\b(module|import|trait|type|enum|fn|in|this|return|continue|break|match|if|else|while|for|as|is|assert|crash|todo)\\b"
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
"name": "keyword.operator.arrow.plum",
|
|
@@ -85,22 +85,7 @@
|
|
|
85
85
|
"patterns": [
|
|
86
86
|
{
|
|
87
87
|
"name": "comment.line.plum",
|
|
88
|
-
"match": "
|
|
88
|
+
"match": "`.*"
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
"begin": "```",
|
|
92
|
-
"beginCaptures": {
|
|
93
|
-
"0": {
|
|
94
|
-
"name": "punctuation.definition.comment.begin.plum"
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
"end": "```",
|
|
98
|
-
"endCaptures": {
|
|
99
|
-
"0": {
|
|
100
|
-
"name": "punctuation.definition.comment.end.plum"
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
"name": "comment.block.plum"
|
|
104
89
|
}
|
|
105
90
|
]
|
|
106
91
|
},
|