~repos /plum

#treesitter#compiler#wasm

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

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


419a88fe pyrossh

11 months ago
improce code
.gitignore CHANGED
@@ -9,4 +9,5 @@ static/bundle/
9
9
  static/monaco-editor-workers/
10
10
  static/worker/
11
11
  node_modules
12
- *.vsix
12
+ *.vsix
13
+ codegen
test/main.go CHANGED
@@ -1,7 +1,7 @@
1
1
  package main
2
2
 
3
- const MIN_VALUE = -0x8000_0000_0000_0000 # Lowest value of Int
3
+ const MIN_VALUE = -0x8000_0000_0000_0000 // Lowest value of Int
4
- const MAX_VALUE = 0x7FFF_FFFF_FFFF_FFFF # Highest value of Int
4
+ const MAX_VALUE = 0x7FFF_FFFF_FFFF_FFFF // Highest value of Int
5
5
  const LARGE = 268435456 # 2**28
6
6
 
7
7
  import (
test/main.java CHANGED
@@ -3,6 +3,7 @@ class Data {
3
3
 
4
4
  public void printLn() {
5
5
  this.name
6
+ final 123 =
6
7
  return "\(123)";
7
8
  }
8
9
  }
test/main.kt ADDED
@@ -0,0 +1,8 @@
1
+ class Data {
2
+ val Float PI = 3.14;
3
+
4
+ fun printLn() {
5
+ val name = "123"
6
+ return "${123}";
7
+ }
8
+ }
test/main.rs CHANGED
@@ -5,7 +5,7 @@ static data = ""
5
5
  use std.asd
6
6
 
7
7
  struct Row {
8
- id: String
8
+ pub id: String
9
9
  }
10
10
 
11
11
  impl Row {
test/sample.plum CHANGED
@@ -6,171 +6,153 @@ library LibC("include/libs/libc")
6
6
  pow(x: C.Double, y: C.Double) -> C.Double
7
7
  sqrt(x: C.Double) -> C.Double
8
8
 
9
- module Float =
10
- PI = 3.14159265359
11
-
12
9
  class Float(Comparable, Stringable) =
10
+ static val PI = 3.14159265359
13
11
 
14
- ceil() -> Float =
12
+ fun ceil() -> Float =
15
- todo
13
+ panic("TODO")
16
14
 
17
- floor() -> Float =
15
+ fun floor() -> Float =
18
- todo
16
+ panic("TODO")
19
17
 
20
- round() -> Float =
18
+ fun round() -> Float =
21
- todo
19
+ panic("TODO")
22
20
 
23
- trunc() -> Float =
21
+ fun trunc() -> Float =
24
- todo
22
+ panic("TODO")
25
23
 
26
- log() -> Float =
24
+ fun log() -> Float =
27
- todo
25
+ panic("TODO")
28
26
 
29
- log2() -> Float =
27
+ fun log2() -> Float =
30
- todo
28
+ panic("TODO")
31
29
 
32
- log10() -> Float =
30
+ fun log10() -> Float =
33
- todo
31
+ panic("TODO")
34
32
 
35
- logb() -> Float =
33
+ fun logb() -> Float =
36
- todo
34
+ panic("TODO")
37
35
 
38
- pow(y: Float) -> Float =
36
+ fun pow(y: Float) -> Float =
39
37
  LibM.pow(this, y)
40
38
 
41
- pow(y: Int) -> Float =
39
+ fun pow(y: Int) -> Float =
42
40
  pow(y.toFloat())
43
41
 
44
- sqrt() -> Float =
42
+ fun sqrt() -> Float =
45
43
  if this < 0.0
46
44
  _nan()
47
45
  else
48
46
  LibM.sqrt(this)
49
47
 
50
- asin(v: Float) =
48
+ fun asin(v: Float) =
51
49
  todo
52
50
 
53
- acos(v: Float) =
51
+ fun acos(v: Float) =
54
52
  if v < 0.1
55
53
  asin(v)
56
54
  else
57
55
  asin(-v)
58
56
 
59
- asinh(v: Float) =
57
+ fun asinh(v: Float) =
60
58
  todo
61
59
 
62
- atan(v: Float) =
60
+ fun atan(v: Float) =
63
61
  todo
64
62
 
65
- atan2(v: Float) =
63
+ fun atan2(v: Float) =
66
64
  todo
67
65
 
68
- atanh(v: Float) =
66
+ fun atanh(v: Float) =
69
67
  todo
70
68
 
71
- cbrt(v: Float) =
69
+ fun cbrt(v: Float) =
72
70
  todo
73
71
 
74
- ceil(v: Float) =
72
+ fun ceil(v: Float) =
75
73
  todo
76
74
 
77
- clz32(v: Float) =
75
+ fun clz32(v: Float) =
78
76
  todo
79
77
 
80
- func (f: Float) cos(v: Float) =
78
+ fun cos(v: Float) =
81
79
  todo
82
80
 
83
- func (f: Float) cosh(v: Float) =
81
+ fun cosh(v: Float) =
84
82
  todo
85
83
 
86
- func (f: Float) exp(v: Float) =
84
+ fun exp(v: Float) =
87
85
  todo
88
86
 
89
- module Int =
87
+ class Int(Comparable, Stringable) =
90
- MIN_VALUE = -0x8000_0000_0000_0000 # Lowest value of Int
88
+ static val MIN_VALUE = -0x8000_0000_0000_0000 # Lowest value of Int
91
- MAX_VALUE = 0x7FFF_FFFF_FFFF_FFFF # Highest value of Int
89
+ static val MAX_VALUE = 0x7FFF_FFFF_FFFF_FFFF # Highest value of Int
92
- LARGE = 268435456 # 2**28
90
+ static val LARGE = 268435456 # 2**28
93
91
 
94
- random() -> Float = # generate random number
92
+ static fun random() -> Float = # generate random number
95
93
  panic("TODO")
96
94
 
97
- fromStr() -> Result(Int, Err) = # convert Str to Int
95
+ static fun fromStr() -> Result(Int, Err) = # convert Str to Int
98
- Ok(0)
96
+ Ok(0)
99
97
 
100
- class Int(Comparable, Stringable) =
101
- toFloat() -> Float = # convert Int to Float
98
+ fun toFloat() -> Float = # convert Int to Float
102
99
  Float.fromInt(this)
103
100
 
104
- add(other: Int) -> Int =
101
+ fun add(other: Int) -> Int =
105
102
  this + other
106
103
 
107
- sub(other: Int) -> Int =
104
+ fun sub(other: Int) -> Int =
108
105
  this - other
109
106
 
110
- abs() -> Int =
107
+ fun abs() -> Int =
111
108
  this < 0 ? -this : this
112
109
 
113
- module User
114
- fromJson(s: Str) -> Result(Self, Err) =
115
- v = try Json.parse(s) as Map(Str, Json)
116
- User::create()
117
- .name(v.get("name").asStr())
118
- .email(v.get("email").asStr())
119
- .todos(v.get("todos").asList().map(\t ->
120
- Todo::create().title(t.get("title").asStr()))
121
- )
122
-
123
- class User(ToStr) =
110
+ type Cat(ToStr) =
124
111
  name: Str
125
112
  age: Int
126
- todos: List(Todo)
127
-
128
- toStr() -> Str =
129
- "User({this.name}, {this.age})"
130
113
 
114
+ toCat(self: Str) -> Cat =
115
+ v = try Json.parse(s) as Map(Str, Json)
116
+ Cat::create()
117
+ .name(v.get("name").asStr())
118
+ .age(v.get("age").asInt())
131
119
 
132
- module Cat
133
- fromJson(s: Str) -> Result(Self, Err) =
134
- v = try Json.parse(s) as Map(Str, Json)
135
- Cat::create()
136
- .name(v.get("name").asStr())
137
- .age(v.get("age").asInt())
138
-
139
- class Cat(ToStr) =
140
- name: Str
141
- age: Int
142
-
143
- withName(name: Str) -> Cat =
120
+ withName(self: Cat, name: Str) -> Cat =
144
- Cat(name = name, age = this.age)
121
+ Cat(name: name, age: self.age)
145
122
 
146
- withAge(age: Int) -> Cat =
123
+ withAge(self: Cat, age: Int) -> Cat =
147
- Cat(name = this.name, age = age)
124
+ Cat(name: self.name, age: age)
148
125
 
149
- toStr() -> Str =
126
+ toStr(self: Cat) -> Str =
150
- f"Cat({this.name}, {this.age})"
127
+ "Cat({self.name}, {self.age})"
151
128
 
152
129
 
153
130
  2.sqrt().sin().cos()
154
131
 
132
+ type User(ToStr) =
133
+ name: Str
134
+ age: Int
155
- # Less indentation
135
+ todos: List(Todo)
156
136
 
137
+ toJson(self: Str) -> Result(Self, Err) =
138
+ v = try Json.parse(self) as Map(Str, Json)
139
+ User::create()
140
+ .name(v.get("name").asStr())
141
+ .email(v.get("email").asStr())
142
+ .todos(v.get("todos").asList().map(|t|
143
+ Todo::create().title(t.get("title").asStr()))
144
+ )
145
+
146
+ toStr(self: User) -> Str =
147
+ "User({self.name}, {self.age})"
148
+
157
- u = User::create()
149
+ u = User.create()
158
150
  .name("John Doe")
159
151
  .email("john@example.com")
160
152
  .todos(Todo::create().title("Make pizza"))
161
153
  .todos(Todo::create().title("Finish Toasty"))
162
154
  .todos(Todo::create().title("Sleep"))
163
155
 
164
- # User(
165
- # name: "John Doe",
166
- # email: "john@example.com",
167
- # todos: List(
168
- # Todo(title: "Make pizza"),
169
- # Todo(title: "Finish Toasty"),
170
- # Todo(title: "Sleep"),
171
- # )
172
- # )
173
-
174
156
  u2 = try User.fromJson(`{
175
157
  "name": "John Doe",
176
158
  "email": "john@example.com",
@@ -181,8 +163,6 @@ u2 = try User.fromJson(`{
181
163
  ]
182
164
  }`)
183
165
 
184
-
185
-
186
166
  stoplightColor(something: Int) -> Color =
187
167
  if something > 0
188
168
  Red
@@ -199,44 +179,44 @@ toCelsius(f: Float) -> Float =
199
179
  toCelsius(100) == 212
200
180
  toCelsius(100) == 392
201
181
 
182
+ empty() -> Response =
183
+ Response::create()
184
+ .body(Buffer())
185
+ .headers(Map())
186
+ .status(0)
187
+
188
+ createFileResponse(path: Str) -> Result(Response, IOError) =
189
+ content_type = try Mime::fromExt(path.ext())
190
+ body = try os.readFile(file)
191
+ Response::create()
192
+ .header("Content-Type", content_type)
193
+ .body(body)
194
+ .status(200)
195
+
196
+ serveFile(file: Str) -> Result(Response, IOError) =
197
+ ext = try Path::fromExt(file)
198
+ content_type = try Mime::fromExt(ext)
199
+ body = os.readFile(file)
200
+ Response::create()
201
+ .header("Content-Type", content_type)
202
+ .body(body)
203
+ .status(200)
204
+
205
+ index() -> Result(Response, IOError) =
206
+ createFileResponse("index.html")
207
+
202
208
  type Response(Reader, Writer) =
203
- val body: Buffer = Buffer()
209
+ body: Buffer = Buffer()
204
- val headers: Map(Str, Str) = Map()
210
+ headers: Map(Str, Str) = Map()
205
- val status: Int = 0
211
+ status: Int = 0
206
-
207
- static fn empty() -> Self =
208
- Response::create()
209
- .body(Buffer())
210
- .headers(Map())
211
- .status(0)
212
-
213
- fn createFileResponse(path: Str) -> Result(Response, IOError) =
214
- content_type = try Mime::fromExt(path.ext())
215
- body = try os.readFile(file)
216
- Response::create()
217
- .header("Content-Type", content_type)
218
- .body(body)
219
- .status(200)
220
-
221
- fn serveFile(file: Str) -> Result(Response, IOError) =
222
- ext = try Path::fromExt(file)
223
- content_type = try Mime::fromExt(ext)
224
- body = os.readFile(file)
225
- Response::create()
226
- .header("Content-Type", content_type)
227
- .body(body)
228
- .status(200)
229
-
230
- fn index() -> Result(Response, IOError) =
231
- createFileResponse("index.html")
232
212
 
233
213
  g = Greeter(name: "abc")
234
214
  g = Greeter(...g, name: "123")
235
215
 
236
- func readFile() -> Result(String, Err) =
216
+ readFile() -> Result(String, Err) =
237
217
  return Err("123")
238
218
 
239
- func main() -> Unit =
219
+ main() -> Unit =
240
220
  printLn("123")
241
221
  createFileResponse("./src/sample.plum")
242
222
  index()
@@ -252,59 +232,47 @@ func main() -> Unit =
252
232
  Err(e) =>
253
233
  printErr(e)
254
234
 
255
- func sub(arg1: Int, arg2: Int) -> Int =
235
+ sub(arg1: Int, arg2: Int) -> Int =
256
236
  local1 = arg1
257
237
  local2 = arg2
258
238
  local1 - local2
259
239
 
260
- func addAndStringify(num1: Int, num2: Int) -> Str =
240
+ addAndStringify(num1: Int, num2: Int) -> Str =
261
241
  return (num1 + num2).toStr()
262
242
 
263
- func factorial(x: Int) -> Int =
243
+ factorial(x: Int) -> Int =
264
244
  if x < 2
265
245
  x
266
246
  else
267
247
  x * factorial(x - 1)
268
248
 
269
- var birds = 3
249
+ birds = 3
270
- var iguanas = 2
250
+ iguanas = 2
271
- var total = addAndStringify(birds, iguanas)
251
+ total = addAndStringify(birds, iguanas)
272
252
 
273
- func pluralize(singular: Str, plural: Str, count: Int) -> Str =
253
+ pluralize(singular: Str, plural: Str, count: Int) -> Str =
274
254
  countstr = Num.toStr(count)
275
255
  if count == 1 then
276
256
  "$(countstr) $(singular)"
277
257
  else
278
258
  "$(countstr) $(plural)"
279
259
 
280
- func pluralize_test(t: Test) -> Unit =
260
+ pluralize_test(t: Test) -> Unit =
281
261
  assert pluralize("cactus", "cacti", 1) == "1 cactus"
282
262
  assert pluralize("cactus", "cacti", 2) == "2 cacti"
283
263
 
264
+
284
- type User =
265
+ class User =
285
266
  name: String
286
- age: String
267
+ age: Int
287
268
 
288
- isAuthorized() -> Bool =
269
+ isAuthorized(self: User) -> Bool =
289
270
  False
290
271
 
291
- map(cb: (a: User) -> b) -> b =
272
+ map(self: User, cb: (a: User) -> b) -> b =
292
273
  cb(u)
293
274
 
294
-
295
- type Teacher(
296
- name: String,
297
- subject: String
298
- )
299
-
300
- user = User(
301
- name: "John Doe",
302
- age: 30
303
- )
304
- params = Map("one" => 1, "two" => 2, "three" => 3)
305
- arr = List(1, 2, 3, 4)
306
-
307
- func name(d: Option(Str)) -> Str =
275
+ name(d: Option(Str)) -> Str =
308
276
  if d == Some(v) then
309
277
  v.subString(0, 3)
310
278
  else if a == b then
@@ -319,25 +287,61 @@ delta(d: Option(Str)) -> Str =
319
287
  "123"
320
288
  else
321
289
  if a < 100
322
- printLn("Data")
290
+ "Data"
323
291
  else
292
+ "No Data"
293
+
294
+ MIN_VALUE = -0x8000_0000_0000_0000 # Lowest value of Int
295
+ MAX_VALUE = 0x7FFF_FFFF_FFFF_FFFF # Highest value of Int
296
+ LARGE = 268435456 # 2**28
297
+
298
+ random() -> Float = # generate random number
299
+ panic("TODO")
300
+
301
+ fromStr() -> Result(Int, Err) = # convert Str to Int
302
+ Ok(0)
303
+
304
+ type Int(Comparable, Stringable)
305
+
306
+ toFloat(self: Int) -> Float = # convert Int to Float
307
+ float::fromInt(self)
308
+
309
+ add(self: Int, other: Int) -> Int =
310
+ self + other
311
+
312
+ sub(self: Int, other: Int) -> Int =
313
+ self - other
314
+
315
+ abs(self: Int) -> Int =
316
+ self < 0 ? -self : self
317
+
318
+ main() =
319
+ user = User(name: "John Doe", age: 30)
320
+ if user.isAuthorized()
324
- println("No Data")
321
+ println("IsAutho")
322
+
323
+ user.map({ it.name })
324
+
325
+ params = Map("one" => 1, "two" => 2, "three" => 3)
326
+ arr = List(1, 2, 3, 4)
325
327
 
326
- d.price?.takeIf(\a -> a != "")
328
+ d.price?.takeIf(\a -> a != "")
327
- (1 + 2).mod(3).pow(2).sqrt()
329
+ (1 + 2).mod(3).pow(2).sqrt()
328
330
 
329
- if v == None
331
+ if v == None
330
- error.Error
332
+ error.Error
331
- else if Some(c) = v
333
+ else if Some(c) = v
332
- c * 20
334
+ c * 20
333
335
 
334
- match v
336
+ match v
335
- None -> error.Error
337
+ None -> error.Error
336
- Some(c) -> c * 20
338
+ Some(c) -> c * 20
337
339
 
338
- names = List("Sam", "Lee", "Ari")
340
+ names = List("Sam", "Lee", "Ari")
339
- names.append("Jess")
341
+ names.append("Jess")
342
+ names
343
+ .filter({ it == "Sam" })
340
- names.map(\num -> num * 2)
344
+ .map({ it * 2 })
341
345
 
342
346
  module std/http
343
347
 
tooling/tree-sitter-plum/.gitignore CHANGED
@@ -4,4 +4,4 @@ node_modules
4
4
  build
5
5
  *.log
6
6
  /examples/*/
7
- /target/
7
+ /target/
tooling/tree-sitter-plum/grammar.js CHANGED
@@ -88,24 +88,17 @@ module.exports = grammar({
88
88
 
89
89
  class: ($) =>
90
90
  seq(
91
- "class",
91
+ "type",
92
92
  field("name", $.type_identifier),
93
93
  field("implements", optional(seq("(", commaSep1($.type_identifier), ")"))),
94
94
  field("generics", optional($.generics)),
95
95
  "=",
96
96
  $._indent,
97
97
  field("fields", optional(repeat(alias($.class_field, $.field)))),
98
- field("methods", optional(repeat($.method))),
99
98
  $._dedent,
100
99
  ),
101
-
102
100
  class_field: ($) => seq(field("name", $.identifier), ":", field("type", $.type)),
103
- method: ($) => seq(
101
+
104
- field("name", $.identifier),
105
- field("params", seq("(", optional(commaSep1($.param)), ")")),
106
- field("returns", optional(seq("->", $.return_type))),
107
- field("body", seq("=", choice($.expression, $.body))),
108
- ),
109
102
  trait: ($) =>
110
103
  seq(
111
104
  "trait",
@@ -124,14 +117,11 @@ module.exports = grammar({
124
117
  ),
125
118
 
126
119
  param: ($) =>
127
- choice(
128
- seq("self"),
129
- seq(
120
+ seq(
130
- field("name", $.var_identier),
121
+ field("name", $.var_identier),
131
- ":",
122
+ ":",
132
- field("type", choice($.type, $.variadic_type)),
123
+ field("type", choice($.type, $.variadic_type)),
133
- optional(seq("=", field("value", $.expression))),
124
+ optional(seq("=", field("value", $.expression))),
134
- ),
135
125
  ),
136
126
 
137
127
  return_type: ($) =>
@@ -144,7 +134,6 @@ module.exports = grammar({
144
134
  "=",
145
135
  $._indent,
146
136
  optional(repeat(alias($.enum_field, $.field))),
147
- optional(repeat($.method)),
148
137
  $._dedent,
149
138
  ),
150
139
 
@@ -157,7 +146,7 @@ module.exports = grammar({
157
146
 
158
147
  fn: ($) =>
159
148
  seq(
160
- field("name", choice($.identifier, $.static_identifier)),
149
+ field("name", $.identifier),
161
150
  field("params", seq("(", optional(commaSep1($.param)), ")")),
162
151
  field("returns", optional(seq("->", $.return_type))),
163
152
  field("body", seq("=", choice($.expression, $.body))),
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/class.txt DELETED
@@ -1,145 +0,0 @@
1
- ================================================================================
2
- class
3
- ================================================================================
4
-
5
- class Dog =
6
- name: Str
7
- age: b
8
-
9
- class Int =
10
- random() -> Int = 20
11
- add(self, other: Int) -> Int = self + other
12
- sub(self, other: Int) -> Int = self - other
13
-
14
- class Cat(Stringable) =
15
- name: Str
16
- age: Int
17
-
18
- withName(name: Str) -> Cat =
19
- Cat(name: name, age: 0)
20
-
21
- withAge(age: Int) -> Cat =
22
- Cat(name: "", age: age)
23
-
24
- toStr() -> Str =
25
- "Cat({this.name}, {this.age})"
26
-
27
- --------------------------------------------------------------------------------
28
-
29
- (source
30
- (class
31
- (type_identifier)
32
- (field
33
- (identifier)
34
- (type
35
- (type_identifier)))
36
- (field
37
- (identifier)
38
- (type
39
- (b))))
40
- (class
41
- (type_identifier)
42
- (method
43
- (identifier)
44
- (return_type
45
- (type_identifier))
46
- (expression
47
- (primary_expression
48
- (integer))))
49
- (method
50
- (identifier)
51
- (param)
52
- (param
53
- (var_identier)
54
- (type
55
- (type_identifier)))
56
- (return_type
57
- (type_identifier))
58
- (expression
59
- (primary_expression
60
- (binary_operator
61
- (primary_expression
62
- (identifier))
63
- (primary_expression
64
- (identifier))))))
65
- (method
66
- (identifier)
67
- (param)
68
- (param
69
- (var_identier)
70
- (type
71
- (type_identifier)))
72
- (return_type
73
- (type_identifier))
74
- (expression
75
- (primary_expression
76
- (binary_operator
77
- (primary_expression
78
- (identifier))
79
- (primary_expression
80
- (identifier)))))))
81
- (class
82
- (type_identifier)
83
- (type_identifier)
84
- (field
85
- (identifier)
86
- (type
87
- (type_identifier)))
88
- (field
89
- (identifier)
90
- (type
91
- (type_identifier)))
92
- (method
93
- (identifier)
94
- (param
95
- (var_identier)
96
- (type
97
- (type_identifier)))
98
- (return_type
99
- (type_identifier))
100
- (body
101
- (primary_expression
102
- (class_call
103
- (type_identifier)
104
- (class_argument_list
105
- (identifier)
106
- (expression
107
- (primary_expression
108
- (identifier)))
109
- (identifier)
110
- (expression
111
- (primary_expression
112
- (integer))))))))
113
- (method
114
- (identifier)
115
- (param
116
- (var_identier)
117
- (type
118
- (type_identifier)))
119
- (return_type
120
- (type_identifier))
121
- (body
122
- (primary_expression
123
- (class_call
124
- (type_identifier)
125
- (class_argument_list
126
- (identifier)
127
- (expression
128
- (primary_expression
129
- (string
130
- (string_start)
131
- (string_end))))
132
- (identifier)
133
- (expression
134
- (primary_expression
135
- (identifier))))))))
136
- (method
137
- (identifier)
138
- (return_type
139
- (type_identifier))
140
- (body
141
- (primary_expression
142
- (string
143
- (string_start)
144
- (string_content)
145
- (string_end)))))))
tooling/tree-sitter-plum/test/corpus/enum.txt CHANGED
@@ -6,8 +6,8 @@ enum Bool =
6
6
  | True
7
7
  | False
8
8
 
9
- toStr(self) -> Str =
9
+ toStr(self: Bool) -> Str =
10
- "Bool"
10
+ "Bool"
11
11
 
12
12
  --------------------------------------------------------------------------------
13
13
 
@@ -17,15 +17,18 @@ enum Bool =
17
17
  (field
18
18
  (type_identifier))
19
19
  (field
20
+ (type_identifier)))
21
+ (fn
22
+ (identifier)
23
+ (param
24
+ (var_identier)
25
+ (type
26
+ (type_identifier)))
27
+ (return_type
20
28
  (type_identifier))
21
- (method
22
- (identifier)
23
- (param)
24
- (return_type
25
- (type_identifier))
26
- (body
29
+ (body
27
- (primary_expression
30
+ (primary_expression
28
- (string
31
+ (string
29
- (string_start)
32
+ (string_start)
30
- (string_content)
33
+ (string_content)
31
- (string_end)))))))
34
+ (string_end))))))
tooling/tree-sitter-plum/test/corpus/type.txt ADDED
@@ -0,0 +1,111 @@
1
+ ================================================================================
2
+ type
3
+ ================================================================================
4
+
5
+ type Dog =
6
+ name: Str
7
+ age: b
8
+
9
+ type Cat(Stringable) =
10
+ name: Str
11
+ age: Int
12
+
13
+ withName(self: Cat, name: Str) -> Cat =
14
+ Cat(name: name, age: 0)
15
+
16
+ withAge(self: Cat, age: Int) -> Cat =
17
+ Cat(name: "", age: age)
18
+
19
+ toStr(self: Cat) -> Str =
20
+ "Cat({this.name}, {this.age})"
21
+
22
+ --------------------------------------------------------------------------------
23
+
24
+ (source
25
+ (class
26
+ (type_identifier)
27
+ (field
28
+ (identifier)
29
+ (type
30
+ (type_identifier)))
31
+ (field
32
+ (identifier)
33
+ (type
34
+ (b))))
35
+ (class
36
+ (type_identifier)
37
+ (type_identifier)
38
+ (field
39
+ (identifier)
40
+ (type
41
+ (type_identifier)))
42
+ (field
43
+ (identifier)
44
+ (type
45
+ (type_identifier))))
46
+ (fn
47
+ (identifier)
48
+ (param
49
+ (var_identier)
50
+ (type
51
+ (type_identifier)))
52
+ (param
53
+ (var_identier)
54
+ (type
55
+ (type_identifier)))
56
+ (return_type
57
+ (type_identifier))
58
+ (body
59
+ (primary_expression
60
+ (class_call
61
+ (type_identifier)
62
+ (class_argument_list
63
+ (identifier)
64
+ (expression
65
+ (primary_expression
66
+ (identifier)))
67
+ (identifier)
68
+ (expression
69
+ (primary_expression
70
+ (integer))))))))
71
+ (fn
72
+ (identifier)
73
+ (param
74
+ (var_identier)
75
+ (type
76
+ (type_identifier)))
77
+ (param
78
+ (var_identier)
79
+ (type
80
+ (type_identifier)))
81
+ (return_type
82
+ (type_identifier))
83
+ (body
84
+ (primary_expression
85
+ (class_call
86
+ (type_identifier)
87
+ (class_argument_list
88
+ (identifier)
89
+ (expression
90
+ (primary_expression
91
+ (string
92
+ (string_start)
93
+ (string_end))))
94
+ (identifier)
95
+ (expression
96
+ (primary_expression
97
+ (identifier))))))))
98
+ (fn
99
+ (identifier)
100
+ (param
101
+ (var_identier)
102
+ (type
103
+ (type_identifier)))
104
+ (return_type
105
+ (type_identifier))
106
+ (body
107
+ (primary_expression
108
+ (string
109
+ (string_start)
110
+ (string_content)
111
+ (string_end))))))
tooling/vscode-plum/syntaxes/plum.tmLanguage.json CHANGED
@@ -36,12 +36,12 @@
36
36
  "keywords": {
37
37
  "patterns": [
38
38
  {
39
- "match": "\\b(library|module|class|enum|trait|this)\\b",
39
+ "match": "\\b(module|type|enum|trait|self)\\b",
40
40
  "name": "keyword.const.plum"
41
41
  },
42
42
  {
43
43
  "name": "keyword.control.plum",
44
- "match": "\\b(try|import|in|return|continue|break|match|if|else|while|for|as|is|assert|panic)\\b"
44
+ "match": "\\b(try|import|in|return|continue|break|match|if|else|while|for|as|is|assert|panic|pass)\\b"
45
45
  },
46
46
  {
47
47
  "name": "keyword.operator.splat.plum",
@@ -106,318 +106,59 @@
106
106
  },
107
107
  "patterns": [
108
108
  {
109
- "include": "#fstring-guts"
109
+ "include": "#interpolated-plum"
110
- },
111
- {
112
- "include": "#fstring-illegal-single-brace"
113
- },
114
- {
115
- "include": "#fstring-single-brace"
116
- },
117
- {
118
- "include": "#fstring-single-core"
119
- }
120
- ]
121
- },
122
- "fstring-guts": {
123
- "patterns": [
124
- {
125
- "include": "#escape-sequence-unicode"
126
- },
127
- {
128
- "include": "#escape-sequence"
129
- },
130
- {
131
- "include": "#string-line-continuation"
132
- },
133
- {
134
- "include": "#fstring-formatting"
135
- }
136
- ]
137
- },
138
- "escape-sequence-unicode": {
139
- "patterns": [
140
- {
141
- "name": "constant.character.escape.plum",
142
- "match": "(?x)\n \\\\ (\n u[0-9A-Fa-f]{4}\n | U[0-9A-Fa-f]{8}\n | N\\{[\\w\\s]+?\\}\n )\n"
143
110
  }
144
111
  ]
145
112
  },
146
- "escape-sequence": {
113
+ "interpolated-plum": {
147
- "name": "constant.character.escape.plum",
148
- "match": "(?x)\n \\\\ (\n x[0-9A-Fa-f]{2}\n | [0-7]{1,3}\n | [\\\\\"'abfnrtv]\n )\n"
149
- },
150
- "string-line-continuation": {
151
- "name": "constant.language.plum",
152
- "match": "\\\\$"
153
- },
154
- "fstring-formatting": {
155
114
  "patterns": [
156
115
  {
157
- "include": "#fstring-formatting-braces"
116
+ "name": "meta.embedded.line.plum",
117
+ "contentName": "source.plum",
118
+ "begin": "{",
119
+ "beginCaptures": {
120
+ "0": {
121
+ "name": "punctuation.section.embedded.begin.plum"
122
+ }
158
- },
123
+ },
124
+ "end": "}",
125
+ "endCaptures": {
126
+ "0": {
127
+ "name": "punctuation.section.embedded.end.plum"
128
+ }
129
+ },
130
+ "patterns": [
159
- {
131
+ {
160
- "include": "#fstring-formatting-singe-brace"
132
+ "include": "#nest_curly_and_self"
161
- }
162
- ]
163
- },
164
- "fstring-formatting-braces": {
165
- "patterns": [
166
- {
167
- "comment": "empty braces are illegal",
168
- "match": "({)(\\s*?)(})",
169
- "captures": {
170
- "1": {
171
- "name": "constant.character.format.placeholder.other.plum"
172
- },
173
- "2": {
174
- "name": "invalid.illegal.brace.plum"
175
133
  },
176
- "3": {
134
+ {
177
- "name": "constant.character.format.placeholder.other.plum"
135
+ "include": "$self"
178
136
  }
179
- }
180
- },
181
- {
182
- "name": "constant.character.escape.plum",
183
- "match": "({{|}})"
184
- }
185
- ]
137
+ ]
186
- },
187
- "fstring-formatting-singe-brace": {
188
- "name": "invalid.illegal.brace.plum",
189
- "match": "(}(?!}))"
190
- },
191
- "fstring-illegal-single-brace": {
192
- "comment": "it is illegal to have a multiline brace inside a single-line string",
193
- "begin": "(\\{)(?=[^\\n}]*$\\n?)",
194
- "end": "(\\})|(?=\\n)",
195
- "beginCaptures": {
196
- "1": {
197
- "name": "constant.character.format.placeholder.other.plum"
198
- }
199
- },
200
- "endCaptures": {
201
- "1": {
202
- "name": "constant.character.format.placeholder.other.plum"
203
- }
204
- },
205
- "patterns": [
206
- {
207
- "include": "#fstring-terminator-single"
208
- },
209
- {
210
- "include": "#f-expression"
211
138
  }
212
139
  ]
213
140
  },
214
- "fstring-terminator-single": {
141
+ "nest_curly_and_self": {
215
142
  "patterns": [
216
143
  {
217
- "name": "storage.type.format.plum",
218
- "match": "(=(![rsa])?)(?=})"
219
- },
220
- {
221
- "name": "storage.type.format.plum",
222
- "match": "(=?![rsa])(?=})"
144
+ "begin": "{",
223
- },
224
- {
225
- "match": "(?x)\n ( (?: =?) (?: ![rsa])? )\n ( : \\w? [<>=^]? [-+ ]? \\#?\n \\d* ,? (\\.\\d+)? [bcdeEfFgGnosxX%]? )(?=})\n",
226
145
  "captures": {
227
- "1": {
146
+ "0": {
228
- "name": "storage.type.format.plum"
147
+ "name": "punctuation.section.scope.plum"
229
- },
230
- "2": {
231
- "name": "storage.type.format.plum"
232
148
  }
233
- }
234
- },
235
- {
236
- "include": "#fstring-terminator-single-tail"
237
- }
238
- ]
239
- },
240
- "fstring-terminator-single-tail": {
241
- "begin": "((?:=?)(?:![rsa])?)(:)(?=.*?{)",
242
- "end": "(?=})|(?=\\n)",
243
- "beginCaptures": {
244
- "1": {
245
- "name": "storage.type.format.plum"
246
- },
247
- "2": {
248
- "name": "storage.type.format.plum"
249
- }
250
- },
251
- "patterns": [
252
- {
253
- "include": "#fstring-illegal-single-brace"
254
- },
255
- {
256
- "include": "#fstring-single-brace"
257
- },
258
- {
259
- "name": "storage.type.format.plum",
260
- "match": "([bcdeEfFgGnosxX%])(?=})"
261
- },
262
- {
263
- "name": "storage.type.format.plum",
264
- "match": "(\\.\\d+)"
265
- },
266
- {
267
- "name": "storage.type.format.plum",
268
- "match": "(,)"
269
- },
270
- {
271
- "name": "storage.type.format.plum",
272
- "match": "(\\d+)"
273
- },
274
- {
275
- "name": "storage.type.format.plum",
276
- "match": "(\\#)"
277
- },
278
- {
279
- "name": "storage.type.format.plum",
280
- "match": "([-+ ])"
281
- },
282
- {
283
- "name": "storage.type.format.plum",
284
- "match": "([<>=^])"
285
- },
286
- {
287
- "name": "storage.type.format.plum",
288
- "match": "(\\w)"
289
- }
290
- ]
291
- },
292
- "fstring-single-brace": {
293
- "comment": "value interpolation using { ... }",
294
- "begin": "(\\{)",
295
- "end": "(?x)\n (\\})|(?=\\n)\n",
296
- "beginCaptures": {
297
- "1": {
298
- "name": "constant.character.format.placeholder.other.plum"
299
- }
300
- },
301
- "endCaptures": {
302
- "1": {
303
- "name": "constant.character.format.placeholder.other.plum"
304
- }
305
- },
306
- "patterns": [
307
- {
308
- "include": "#fstring-terminator-single"
309
- },
310
- {
311
- "include": "#f-expression"
312
- }
313
- ]
314
- },
315
- "fstring-single-core": {
316
- "name": "string.interpolated.plum string.quoted.single.plum",
317
- "match": "(?x)\n (.+?)\n (\n (?# .* and .*? in multi-line match need special handling of\n newlines otherwise SublimeText and Atom will match slightly\n differently.\n\n The guard for newlines has to be separate from the\n lookahead because of special $ matching rule.)\n ($\\n?)\n |\n (?=[\\\\\\}\\{]|(['\"])|((?<!\\\\)\\n))\n )\n (?# due to how multiline regexps are matched we need a special case\n for matching a newline character)\n | \\n\n"
318
- },
319
- "f-expression": {
320
- "comment": "All valid Python expressions, except comments and line continuation",
321
- "patterns": [
322
- {
323
- "include": "#expression-bare"
324
- },
325
- {
326
- "include": "#member-access"
327
- },
328
- {
329
- "comment": "Tokenize identifiers to help linters",
330
- "match": "(?x) \\b ([[:alpha:]_]\\w*) \\b"
331
- }
332
- ]
333
- },
334
- "expression": {
335
- "comment": "All valid Python expressions",
336
- "patterns": [
337
- {
338
- "include": "#expression-base"
339
- },
340
- {
341
- "include": "#member-access"
342
- },
343
- {
344
- "comment": "Tokenize identifiers to help linters",
345
- "match": "(?x) \\b ([[:alpha:]_]\\w*) \\b"
346
- }
347
- ]
348
- },
349
- "expression-base": {
350
- "comment": "valid Python expressions with comments and line continuation",
351
- "patterns": [
352
- {
353
- "include": "#comments"
354
- },
355
- {
356
- "include": "#expression-bare"
357
- },
358
- {
359
- "include": "#line-continuation"
360
- }
361
- ]
362
- },
363
- "expression-bare": {
364
- "comment": "valid Python expressions w/o comments and line continuation",
365
- "patterns": [
366
- {
367
- "include": "#number"
368
- },
369
- {
370
- "include": "#string"
371
- },
372
- {
373
- "include": "#operator"
374
- },
375
- {
376
- "include": "#curly-braces"
377
- },
378
- {
379
- "include": "#item-access"
380
- },
381
- {
382
- "include": "#round-braces"
383
- },
384
- {
385
- "include": "#function-call"
386
- },
387
- {
388
- "include": "#special-names"
389
- },
390
- {
391
- "include": "#special-variables"
149
+ },
150
+ "end": "}",
151
+ "patterns": [
152
+ {
153
+ "include": "#nest_curly_and_self"
154
+ }
155
+ ]
392
156
  },
393
157
  {
394
- "include": "#ellipsis"
158
+ "include": "$self"
395
159
  }
396
160
  ]
397
161
  },
398
- "round-braces": {
399
- "begin": "\\(",
400
- "end": "\\)",
401
- "beginCaptures": {
402
- "0": {
403
- "name": "punctuation.parenthesis.begin.plum"
404
- }
405
- },
406
- "endCaptures": {
407
- "0": {
408
- "name": "punctuation.parenthesis.end.plum"
409
- }
410
- },
411
- "patterns": [
412
- {
413
- "include": "#expression"
414
- }
415
- ]
416
- },
417
- "ellipsis": {
418
- "name": "constant.other.ellipsis.plum",
419
- "match": "\\.\\.\\."
420
- },
421
162
  "number": {
422
163
  "name": "constant.numeric.plum",
423
164
  "patterns": [
@@ -430,15 +171,9 @@
430
171
  {
431
172
  "include": "#number-hex"
432
173
  },
433
- {
434
- "include": "#number-oct"
435
- },
436
174
  {
437
175
  "include": "#number-bin"
438
176
  },
439
- {
440
- "include": "#number-long"
441
- },
442
177
  {
443
178
  "name": "invalid.illegal.name.plum",
444
179
  "match": "\\b[0-9]+\\w+"
@@ -466,28 +201,6 @@
466
201
  }
467
202
  }
468
203
  },
469
- "function-call": {
470
- "name": "meta.function-call.plum",
471
- "comment": "Regular function call of the type \"name(args)\"",
472
- "begin": "(?x)\n \\b(?=\n ([[:alpha:]_]\\w*) \\s* (\\()\n )\n",
473
- "end": "(\\))",
474
- "endCaptures": {
475
- "1": {
476
- "name": "punctuation.definition.arguments.end.plum"
477
- }
478
- },
479
- "patterns": [
480
- {
481
- "include": "#special-variables"
482
- },
483
- {
484
- "include": "#function-name"
485
- },
486
- {
487
- "include": "#function-arguments"
488
- }
489
- ]
490
- },
491
204
  "number-hex": {
492
205
  "name": "constant.numeric.hex.plum",
493
206
  "match": "(?x)\n (?<![\\w\\.])\n (0[xX]) (_?[0-9a-fA-F])+\n \\b\n",
@@ -497,15 +210,6 @@
497
210
  }
498
211
  }
499
212
  },
500
- "number-oct": {
501
- "name": "constant.numeric.oct.plum",
502
- "match": "(?x)\n (?<![\\w\\.])\n (0[oO]) (_?[0-7])+\n \\b\n",
503
- "captures": {
504
- "1": {
505
- "name": "storage.type.number.plum"
506
- }
507
- }
508
- },
509
213
  "number-bin": {
510
214
  "name": "constant.numeric.bin.plum",
511
215
  "match": "(?x)\n (?<![\\w\\.])\n (0[bB]) (_?[01])+\n \\b\n",
@@ -515,193 +219,6 @@
515
219
  }
516
220
  }
517
221
  },
518
- "number-long": {
519
- "name": "constant.numeric.bin.plum",
520
- "comment": "this is to support python2 syntax for long ints",
521
- "match": "(?x)\n (?<![\\w\\.])\n ([1-9][0-9]* | 0) ([lL])\n \\b\n",
522
- "captures": {
523
- "2": {
524
- "name": "storage.type.number.plum"
525
- }
526
- }
527
- },
528
- "function-name": {
529
- "patterns": [
530
- {
531
- "comment": "Some color schemas support meta.function-call.generic scope",
532
- "name": "meta.function-call.generic.plum",
533
- "match": "(?x)\n \\b ([[:alpha:]_]\\w*) \\b\n"
534
- }
535
- ]
536
- },
537
- "function-arguments": {
538
- "begin": "(\\()",
539
- "end": "(?=\\))(?!\\)\\s*\\()",
540
- "beginCaptures": {
541
- "1": {
542
- "name": "punctuation.definition.arguments.begin.plum"
543
- }
544
- },
545
- "contentName": "meta.function-call.arguments.plum",
546
- "patterns": [
547
- {
548
- "name": "punctuation.separator.arguments.plum",
549
- "match": "(,)"
550
- },
551
- {
552
- "match": "(?x)\n (?:(?<=[,(])|^) \\s* (\\*{1,2})\n",
553
- "captures": {
554
- "1": {
555
- "name": "keyword.operator.unpacking.arguments.plum"
556
- }
557
- }
558
- },
559
- {
560
- "include": "#lambda-incomplete"
561
- },
562
- {
563
- "include": "#illegal-names"
564
- },
565
- {
566
- "match": "\\b([[:alpha:]_]\\w*)\\s*(=)(?!=)",
567
- "captures": {
568
- "1": {
569
- "name": "variable.parameter.function-call.plum"
570
- },
571
- "2": {
572
- "name": "keyword.operator.assignment.plum"
573
- }
574
- }
575
- },
576
- {
577
- "name": "keyword.operator.assignment.plum",
578
- "match": "=(?!=)"
579
- },
580
- {
581
- "include": "#expression"
582
- },
583
- {
584
- "match": "\\s*(\\))\\s*(\\()",
585
- "captures": {
586
- "1": {
587
- "name": "punctuation.definition.arguments.end.plum"
588
- },
589
- "2": {
590
- "name": "punctuation.definition.arguments.begin.plum"
591
- }
592
- }
593
- }
594
- ]
595
- },
596
- "member-access": {
597
- "name": "meta.member.access.plum",
598
- "begin": "(\\.)\\s*(?!\\.)",
599
- "end": "(?x)\n # stop when you've just read non-whitespace followed by non-word\n # i.e. when finished reading an identifier or function call\n (?<=\\S)(?=\\W) |\n # stop when seeing the start of something that's not a word,\n # i.e. when seeing a non-identifier\n (^|(?<=\\s))(?=[^\\\\\\w\\s]) |\n $\n",
600
- "beginCaptures": {
601
- "1": {
602
- "name": "punctuation.separator.period.plum"
603
- }
604
- },
605
- "patterns": [
606
- {
607
- "include": "#function-call"
608
- },
609
- {
610
- "include": "#member-access-base"
611
- },
612
- {
613
- "include": "#member-access-attribute"
614
- }
615
- ]
616
- },
617
- "member-access-base": {
618
- "patterns": [
619
- {
620
- "include": "#special-names"
621
- },
622
- {
623
- "include": "#line-continuation"
624
- },
625
- {
626
- "include": "#item-access"
627
- }
628
- ]
629
- },
630
- "member-access-attribute": {
631
- "comment": "Highlight attribute access in otherwise non-specialized cases.",
632
- "name": "meta.attribute.plum",
633
- "match": "(?x)\n \\b ([[:alpha:]_]\\w*) \\b\n"
634
- },
635
- "special-names": {
636
- "name": "constant.other.caps.plum",
637
- "match": "(?x)\n \\b\n # we want to see \"enough\", meaning 2 or more upper-case\n # letters in the beginning of the constant\n #\n # for more details refer to:\n # https://github.com/MagicStack/MagicPython/issues/42\n (\n _* [[:upper:]] [_\\d]* [[:upper:]]\n )\n [[:upper:]\\d]* (_\\w*)?\n \\b\n"
638
- },
639
- "curly-braces": {
640
- "begin": "\\{",
641
- "end": "\\}",
642
- "beginCaptures": {
643
- "0": {
644
- "name": "punctuation.definition.dict.begin.plum"
645
- }
646
- },
647
- "endCaptures": {
648
- "0": {
649
- "name": "punctuation.definition.dict.end.plum"
650
- }
651
- },
652
- "patterns": [
653
- {
654
- "include": "#expression"
655
- }
656
- ]
657
- },
658
- "item-access": {
659
- "patterns": [
660
- {
661
- "name": "meta.item-access.plum",
662
- "begin": "(?x)\n \\b(?=\n [[:alpha:]_]\\w* \\s* \\[\n )\n",
663
- "end": "(\\])",
664
- "endCaptures": {
665
- "1": {
666
- "name": "punctuation.definition.arguments.end.plum"
667
- }
668
- },
669
- "patterns": [
670
- {
671
- "include": "#item-name"
672
- },
673
- {
674
- "include": "#expression"
675
- }
676
- ]
677
- }
678
- ]
679
- },
680
- "item-name": {
681
- "patterns": [
682
- {
683
- "include": "#special-variables"
684
- },
685
- {
686
- "include": "#special-names"
687
- },
688
- {
689
- "name": "meta.indexed-name.plum",
690
- "match": "(?x)\n \\b ([[:alpha:]_]\\w*) \\b\n"
691
- }
692
- ]
693
- },
694
- "special-variables": {
695
- "match": "(?x)\n \\b (?<!\\.) (?:\n (this) | (cls)\n )\\b\n",
696
- "captures": {
697
- "1": {
698
- "name": "variable.language.special.self.plum"
699
- },
700
- "2": {
701
- "name": "variable.language.special.cls.plum"
702
- }
703
- }
704
- },
705
222
  "entity": {
706
223
  "patterns": [
707
224
  {