plum

#treesitter#compiler#wasm

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

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


6b5d9dbPeter John 2026-08-09T21:01:06+05:30
feat(grammar): remove top-level <Receiver> method annotation syntax
tooling/tree-sitter-plum/grammar.js CHANGED
@@ -176,19 +176,18 @@ module.exports = grammar({
176
176
  seq(
177
177
  "fun",
178
178
  field("name", $.fn_identifier),
179
- field("type", optional(alias($.fn_type, $.type))),
180
- // A method's implicit receiver may be spelled out explicitly as a bare
179
+ // A method's receiver is implicit from nesting the `fn` inside a
181
- // `self` in the first parameter slot (`remove<List>(self, v: a) = ...`),
180
+ // `type`/`enum` body (see `class`/`enum` above) there is no top-level
182
- // matching the `<Receiver>` annotation above. It carries no type of its
181
+ // `<Receiver>` annotation form. `self` may still appear as a bare first
182
+ // parameter to spell out that a nested `fn` is an instance method; it
183
- // own (the receiver type already came from `<Receiver>`), so the parser
183
+ // carries no type of its own, so the parser discards it rather than
184
- // discards it rather than emitting a `param` — see `parse_fn`.
184
+ // emitting a `param` — see `parse_fn`.
185
185
  field("params", seq("(", optional(commaSep1(choice($.self, $.param))), ")")),
186
186
  field("returns", optional(seq("->", $.type))),
187
187
  field("body", seq("=", choice($.expression, $.body))),
188
188
  )
189
189
  ),
190
190
 
191
- fn_type: ($) => seq("<", commaSep1($.type_identifier), ">"),
192
191
  body: ($) => seq($._indent, repeat($._statement), $._dedent),
193
192
 
194
193
  _statement: ($) =>
tooling/tree-sitter-plum/queries/plum/highlights.scm CHANGED
@@ -98,15 +98,4 @@
98
98
 
99
99
  (todo) @keyword.control.exception
100
100
 
101
- "match" @keyword
101
+ "match" @keyword
102
-
103
- ; `name<Receiver>(...)` — the `<Receiver>` method annotation is grammatically a
104
- ; `type` field on `fn` (same shape as an ordinary field/param type), but
105
- ; semantically it's the method's receiver, not a type reference — highlight it
106
- ; like the `self` it implicitly binds rather than like `@type`. This pattern is
107
- ; listed after the generic `(type_identifier) @type` above so it wins: when a
108
- ; node matches more than one pattern, tree-sitter highlighting gives priority
109
- ; to whichever pattern appears last in the query file.
110
- (fn
111
- type: (type
112
- (type_identifier) @keyword))
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/aa.plum CHANGED
@@ -17,23 +17,23 @@ type Cat(IAnimal, IToStr) =
17
17
  name: Str
18
18
  age: Int
19
19
 
20
- fun withName<Cat>(name: Str) -> Cat =
20
+ fun withName(name: Str) -> Cat =
21
- Cat(name: name, age: self.age)
21
+ Cat(name: name, age: self.age)
22
-
22
+
23
- fun withAge<Cat>(age: Int) -> Cat =
23
+ fun withAge(age: Int) -> Cat =
24
- Cat(name: self.name, age: age)
24
+ Cat(name: self.name, age: age)
25
-
25
+
26
- fun speak<Cat>() -> Str =
26
+ fun speak() -> Str =
27
- "meow"
27
+ "meow"
28
-
28
+
29
- fun toStr<Cat>() -> Str =
29
+ fun toStr() -> Str =
30
- for i in 0..10
30
+ for i in 0..10
31
- printLn("delta")
31
+ printLn("delta")
32
- if dog > 1
32
+ if dog > 1
33
- printLn("Hellow")
33
+ printLn("Hellow")
34
- else
34
+ else
35
- printLn("New")
35
+ printLn("New")
36
- "Cat({self.name}, {self.age})"
36
+ "Cat({self.name}, {self.age})"
37
37
 
38
38
  fun main() =
39
39
  printLn("Hello world")
tooling/tree-sitter-plum/test/corpus/enum.txt CHANGED
@@ -6,8 +6,8 @@ enum Bool =
6
6
  | True
7
7
  | False
8
8
 
9
- fun toStr<Bool>() -> Str =
9
+ fun toStr() -> Str =
10
- "Bool"
10
+ "Bool"
11
11
 
12
12
  --------------------------------------------------------------------------------
13
13
 
@@ -17,20 +17,18 @@ fun toStr<Bool>() -> Str =
17
17
  (field
18
18
  (type_identifier))
19
19
  (field
20
- (type_identifier)))
21
- (fn
22
- (fn_identifier)
23
- (type
24
20
  (type_identifier))
21
+ (fn
22
+ (fn_identifier)
25
- (type
23
+ (type
26
- (type_identifier))
24
+ (type_identifier))
27
- (body
25
+ (body
28
- (expression
26
+ (expression
29
- (primary_expression
27
+ (primary_expression
30
- (string
28
+ (string
31
- (string_start)
29
+ (string_start)
32
- (string_content)
30
+ (string_content)
33
- (string_end)))))))
31
+ (string_end))))))))
34
32
 
35
33
  ================================================================================
36
34
  enum - generic variant fields
tooling/tree-sitter-plum/test/corpus/function.txt CHANGED
@@ -98,10 +98,10 @@ fun add(param: T, param2: List[U]) -> List[U] =
98
98
  (todo))))
99
99
 
100
100
  ================================================================================
101
- function - method
101
+ function - bare self param (top-level, not a method receiver annotation)
102
102
  ================================================================================
103
103
 
104
- fun fullname<User>() -> String =
104
+ fun remove(self, v: T) =
105
105
  todo
106
106
 
107
107
  --------------------------------------------------------------------------------
@@ -109,27 +109,6 @@ fun fullname<User>() -> String =
109
109
  (source
110
110
  (fn
111
111
  (fn_identifier)
112
- (type
113
- (type_identifier))
114
- (type
115
- (type_identifier))
116
- (body
117
- (todo))))
118
-
119
- ================================================================================
120
- function - method with explicit self param
121
- ================================================================================
122
-
123
- fun remove<List>(self, v: T) =
124
- todo
125
-
126
- --------------------------------------------------------------------------------
127
-
128
- (source
129
- (fn
130
- (fn_identifier)
131
- (type
132
- (type_identifier))
133
112
  (self)
134
113
  (param
135
114
  (var_identifier)
tooling/tree-sitter-plum/test/corpus/type.txt CHANGED
@@ -10,17 +10,17 @@ type Cat(Stringable) =
10
10
  name: Str
11
11
  age: Int
12
12
 
13
- fun init<Cat>(name: Str) -> Cat =
13
+ fun init(name: Str) -> Cat =
14
- Cat(name: name, age: 0)
14
+ Cat(name: name, age: 0)
15
15
 
16
- fun withName<Cat>(name: Str) -> Cat =
16
+ fun withName(name: Str) -> Cat =
17
- Cat(name: name, age: 0)
17
+ Cat(name: name, age: 0)
18
18
 
19
- fun withAge<Cat>(age: Int) -> Cat =
19
+ fun withAge(age: Int) -> Cat =
20
- Cat(name: "", age: age)
20
+ Cat(name: "", age: age)
21
21
 
22
- fun toStr<Cat>() -> Str =
22
+ fun toStr() -> Str =
23
- "Cat({self.name}, {self.age})"
23
+ "Cat({self.name}, {self.age})"
24
24
 
25
25
  --------------------------------------------------------------------------------
26
26
 
@@ -43,110 +43,102 @@ fun toStr<Cat>() -> Str =
43
43
  (type
44
44
  (type_identifier)))
45
45
  (field
46
- (var_identifier)
47
- (type
48
- (type_identifier))))
49
- (fn
50
- (fn_identifier)
51
- (type
52
- (type_identifier))
53
- (param
54
46
  (var_identifier)
55
47
  (type
56
48
  (type_identifier)))
49
+ (fn
50
+ (fn_identifier)
51
+ (param
52
+ (var_identifier)
57
- (type
53
+ (type
58
- (type_identifier))
54
+ (type_identifier)))
59
- (body
60
- (expression
61
- (primary_expression
62
- (class_call
63
- (type_identifier)
64
- (class_argument_list
65
- (var_identifier)
66
- (expression
67
- (primary_expression
68
- (var_identifier)))
69
- (var_identifier)
70
- (expression
71
- (primary_expression
72
- (integer)))))))))
73
- (fn
74
- (fn_identifier)
75
- (type
76
- (type_identifier))
77
- (param
78
- (var_identifier)
79
55
  (type
56
+ (type_identifier))
57
+ (body
58
+ (expression
59
+ (primary_expression
60
+ (class_call
61
+ (type_identifier)
62
+ (class_argument_list
63
+ (var_identifier)
64
+ (expression
65
+ (primary_expression
66
+ (var_identifier)))
67
+ (var_identifier)
68
+ (expression
69
+ (primary_expression
70
+ (integer)))))))))
71
+ (fn
72
+ (fn_identifier)
73
+ (param
74
+ (var_identifier)
75
+ (type
80
- (type_identifier)))
76
+ (type_identifier)))
81
- (type
82
- (type_identifier))
83
- (body
84
- (expression
85
- (primary_expression
86
- (class_call
87
- (type_identifier)
88
- (class_argument_list
89
- (var_identifier)
90
- (expression
91
- (primary_expression
92
- (var_identifier)))
93
- (var_identifier)
94
- (expression
95
- (primary_expression
96
- (integer)))))))))
97
- (fn
98
- (fn_identifier)
99
- (type
100
- (type_identifier))
101
- (param
102
- (var_identifier)
103
77
  (type
104
- (type_identifier)))
105
- (type
106
- (type_identifier))
78
+ (type_identifier))
107
- (body
79
+ (body
108
- (expression
80
+ (expression
109
- (primary_expression
81
+ (primary_expression
110
- (class_call
82
+ (class_call
111
- (type_identifier)
83
+ (type_identifier)
112
- (class_argument_list
84
+ (class_argument_list
113
- (var_identifier)
85
+ (var_identifier)
114
- (expression
86
+ (expression
115
- (primary_expression
116
- (string
117
- (string_start)
118
- (string_end))))
119
- (var_identifier)
120
- (expression
121
- (primary_expression
122
- (var_identifier)))))))))
123
- (fn
124
- (fn_identifier)
125
- (type
126
- (type_identifier))
127
- (type
128
- (type_identifier))
129
- (body
130
- (expression
131
- (primary_expression
132
- (string
133
- (string_start)
134
- (string_content)
135
- (interpolation
136
- (primary_expression
137
- (attribute
138
87
  (primary_expression
139
- (self))
140
- (fn_identifier))))
88
+ (var_identifier)))
141
- (string_content)
89
+ (var_identifier)
142
- (interpolation
143
- (primary_expression
90
+ (expression
144
- (attribute
145
91
  (primary_expression
92
+ (integer)))))))))
93
+ (fn
94
+ (fn_identifier)
95
+ (param
96
+ (var_identifier)
97
+ (type
98
+ (type_identifier)))
99
+ (type
100
+ (type_identifier))
101
+ (body
102
+ (expression
103
+ (primary_expression
104
+ (class_call
105
+ (type_identifier)
106
+ (class_argument_list
107
+ (var_identifier)
108
+ (expression
109
+ (primary_expression
110
+ (string
111
+ (string_start)
112
+ (string_end))))
113
+ (var_identifier)
114
+ (expression
115
+ (primary_expression
116
+ (var_identifier)))))))))
117
+ (fn
118
+ (fn_identifier)
119
+ (type
120
+ (type_identifier))
121
+ (body
122
+ (expression
123
+ (primary_expression
124
+ (string
125
+ (string_start)
126
+ (string_content)
127
+ (interpolation
128
+ (primary_expression
129
+ (attribute
130
+ (primary_expression
146
- (self))
131
+ (self))
147
- (fn_identifier))))
132
+ (fn_identifier))))
148
- (string_content)
133
+ (string_content)
134
+ (interpolation
135
+ (primary_expression
136
+ (attribute
137
+ (primary_expression
138
+ (self))
139
+ (fn_identifier))))
140
+ (string_content)
149
- (string_end)))))))
141
+ (string_end))))))))
150
142
 
151
143
  ================================================================================
152
144
  type - nested method declaration
tooling/tree-sitter-plum/test/highlight/sample.plum CHANGED
@@ -4,14 +4,14 @@ type Cat(ToStr) =
4
4
  name: Str
5
5
  age: Int
6
6
 
7
- fun withName<Cat>(name: Str) -> Cat =
7
+ fun withName(name: Str) -> Cat =
8
- Cat(name: name, age: self.age)
8
+ Cat(name: name, age: self.age)
9
9
 
10
- fun withAge<Cat>(age: Int) -> Cat =
10
+ fun withAge(age: Int) -> Cat =
11
- Cat(name: self.name, age: age)
11
+ Cat(name: self.name, age: age)
12
12
 
13
- fun toStr<Cat>() -> Str =
13
+ fun toStr() -> Str =
14
- "Cat({self.name}, {self.age})"
14
+ "Cat({self.name}, {self.age})"
15
15
 
16
16
  fun main() =
17
- printLn("Hello world")
17
+ printLn("Hello world")