~repos /plum

#treesitter#compiler#wasm

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

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


c05610c9 pyrossh

11 months ago
improve lang
test/LibC.plum ADDED
@@ -0,0 +1,11 @@
1
+ module LibC
2
+
3
+ include "include/libs/libc"
4
+
5
+ import std.(C)
6
+ import std.(List, Map, Math)
7
+ import std/encoding.(Base64)
8
+
9
+ extern sqrt(x: C.Double) -> C.Double
10
+ extern pow(x: C.Double, y: C.Double) -> C.Double
11
+ extern sqrt(x: C.Double) -> C.Double
test/aoc_2020_1.plum CHANGED
@@ -1,11 +1,14 @@
1
1
  module aoc2020_1
2
2
 
3
+ import std/fs
4
+ import std/int
5
+
3
6
  main() -> Unit =
4
- input = fs::readFile!("./examples/test/demos/aoc2020/1.txt")
7
+ input = fs.readFile!("./examples/test/demos/aoc2020/1.txt")
5
8
  numbers = parseNumbers(input)
6
- for i in 0..numbers.size
9
+ for i in 0...numbers.size
7
10
  a = numbers.get!<u32>(i)
8
- for j in 0..numbers.size
11
+ for j in 0...numbers.size
9
12
  b = numbers.get!<u32>(j)
10
13
  if a + b == 2020
11
14
  printLn(a * b)
@@ -14,7 +17,7 @@ main() -> Unit =
14
17
  parseNumbers(input: Str) -> List<Int> =
15
18
  numbers = List<Int>()
16
19
  current_number = 0
17
- for i in 0..input.len()
20
+ for i in 0..input.length()
18
21
  c = input.charAt(i)
19
22
  if c >= '0' && c <= '9'
20
23
  current_number *= 10
test/aoc_2020_2.plum CHANGED
@@ -1,10 +1,17 @@
1
- enum Step =
1
+ enum Step(n: Int) =
2
- | READ_MIN_OCCURANCES = 0
2
+ | READ_MIN_OCCURANCES(Step(0))
3
- | READ_MAX_OCCURANCES = 1
3
+ | READ_MAX_OCCURANCES(Step(1))
4
- | READ_CHAR_TO_COUNT = 2
4
+ | READ_CHAR_TO_COUNT(Step(2))
5
- | COUNT_OCCURANCES = 3
5
+ | COUNT_OCCURANCES(Step(3))
6
6
 
7
+ toNumber(Step) =
8
+ match self
9
+ | READ_MIN_OCCURANCES => 0
10
+ | READ_MAX_OCCURANCES => 1
11
+ | READ_CHAR_TO_COUNT => 2
12
+ | COUNT_OCCURANCES => 3
13
+
7
- class PasswordCheckState =
14
+ type PasswordCheckState =
8
15
  step: Step
9
16
  min_occurances: Int
10
17
  max_occurances: Int
@@ -21,7 +28,7 @@ initialCheckState() -> PasswordCheckState =
21
28
  )
22
29
 
23
30
  main() -> Unit =
24
- input = fs::readFile!("./examples/test/demos/aoc2020/2.txt")
31
+ input = fs.readFile!("./examples/test/demos/aoc2020/2.txt")
25
32
  valid_passwords_count = 0
26
33
  state = initialCheckState()
27
34
  for i in 0..input.len()
test/main.java CHANGED
@@ -1,4 +1,4 @@
1
- class Data {
1
+ class Data<T> {
2
2
  static Float PI = 3.14;
3
3
 
4
4
  public void printLn() {
test/main.kt CHANGED
@@ -2,7 +2,7 @@ class Data {
2
2
  val Float PI = 3.14;
3
3
 
4
4
  fun printLn() {
5
- val name = "123"
5
+ val name = "${name}123"
6
- return "${123}";
6
+ return "${name}";
7
7
  }
8
- }
8
+ }
test/main.rs CHANGED
@@ -15,5 +15,5 @@ impl Row {
15
15
  }
16
16
 
17
17
  fn main() {
18
-
18
+ row.add(|v: int|)
19
19
  }
test/sample.plum CHANGED
@@ -1,129 +1,43 @@
1
- import std.(List, Map, Math)
2
- import std/encoding.(Base64)
1
+ module std/http
3
-
4
- library LibC("include/libs/libc")
5
- sqrt(x: C.Double) -> C.Double
6
- pow(x: C.Double, y: C.Double) -> C.Double
7
- sqrt(x: C.Double) -> C.Double
8
-
9
- class Float(Comparable, Stringable) =
10
- static val PI = 3.14159265359
11
-
12
- fun ceil() -> Float =
13
- panic("TODO")
14
-
15
- fun floor() -> Float =
16
- panic("TODO")
17
-
18
- fun round() -> Float =
19
- panic("TODO")
20
-
21
- fun trunc() -> Float =
22
- panic("TODO")
23
-
24
- fun log() -> Float =
25
- panic("TODO")
26
-
27
- fun log2() -> Float =
28
- panic("TODO")
29
-
30
- fun log10() -> Float =
31
- panic("TODO")
32
-
33
- fun logb() -> Float =
34
- panic("TODO")
35
-
36
- fun pow(y: Float) -> Float =
37
- LibM.pow(this, y)
38
-
39
- fun pow(y: Int) -> Float =
40
- pow(y.toFloat())
41
-
42
- fun sqrt() -> Float =
43
- if this < 0.0
44
- _nan()
45
- else
46
- LibM.sqrt(this)
47
-
48
- fun asin(v: Float) =
49
- todo
50
-
51
- fun acos(v: Float) =
52
- if v < 0.1
53
- asin(v)
54
- else
55
- asin(-v)
56
-
57
- fun asinh(v: Float) =
58
- todo
59
-
60
- fun atan(v: Float) =
61
- todo
62
-
63
- fun atan2(v: Float) =
64
- todo
65
-
66
- fun atanh(v: Float) =
67
- todo
68
-
69
- fun cbrt(v: Float) =
70
- todo
71
-
72
- fun ceil(v: Float) =
73
- todo
74
-
75
- fun clz32(v: Float) =
76
- todo
77
-
78
- fun cos(v: Float) =
79
- todo
80
-
81
- fun cosh(v: Float) =
82
- todo
83
-
84
- fun exp(v: Float) =
85
- todo
86
2
 
3
+ import std/path
4
+ import std/os
87
- class Int(Comparable, Stringable) =
5
+ import std/http/content_type
88
- static val MIN_VALUE = -0x8000_0000_0000_0000 # Lowest value of Int
89
- static val MAX_VALUE = 0x7FFF_FFFF_FFFF_FFFF # Highest value of Int
90
- static val LARGE = 268435456 # 2**28
6
+ import std/libc
91
7
 
92
- static fun random() -> Float = # generate random number
93
- panic("TODO")
8
+ trait Writer =
94
-
95
- static fun fromStr() -> Result(Int, Err) = # convert Str to Int
9
+ write(p: Str | Buffer) -> Result(Int, WriteError)
96
- Ok(0)
97
10
 
98
- fun toFloat() -> Float = # convert Int to Float
99
- Float.fromInt(this)
11
+ enum ReadError =
12
+ | Eof
13
+ | Closed
100
14
 
101
- fun add(other: Int) -> Int =
15
+ enum WriteError =
16
+ | Eof
102
- this + other
17
+ | Closed
103
18
 
104
- fun sub(other: Int) -> Int =
105
- this - other
19
+ trait Reader =
20
+ read(p: Str | Buffer) -> Result(Int, ReadError)
106
21
 
107
- fun abs() -> Int =
108
- this < 0 ? -this : this
22
+ trait IO(Reader, Writer)
109
23
 
110
24
  type Cat(ToStr) =
111
25
  name: Str
112
26
  age: Int
113
27
 
114
- toCat(self: Str) -> Cat =
28
+ parseCat<Json>() -> Result(Cat, Err) =
115
- v = try Json.parse(s) as Map(Str, Json)
29
+ v = try Json.parse(self) as Map(Str, Json)
116
30
  Cat::create()
117
31
  .name(v.get("name").asStr())
118
32
  .age(v.get("age").asInt())
119
33
 
120
- withName(self: Cat, name: Str) -> Cat =
34
+ withName<Cat>(name: Str) -> Cat =
121
35
  Cat(name: name, age: self.age)
122
36
 
123
- withAge(self: Cat, age: Int) -> Cat =
37
+ withAge<Cat>(age: Int) -> Cat =
124
38
  Cat(name: self.name, age: age)
125
39
 
126
- toStr(self: Cat) -> Str =
40
+ toStr<Cat>() -> Str =
127
41
  "Cat({self.name}, {self.age})"
128
42
 
129
43
 
@@ -134,24 +48,30 @@ type User(ToStr) =
134
48
  age: Int
135
49
  todos: List(Todo)
136
50
 
137
- toJson(self: Str) -> Result(Self, Err) =
51
+ parseUser<Json>() -> Result(Self, Err) =
138
52
  v = try Json.parse(self) as Map(Str, Json)
139
- User::create()
53
+ User.build()
140
54
  .name(v.get("name").asStr())
141
55
  .email(v.get("email").asStr())
142
56
  .todos(v.get("todos").asList().map(|t|
143
57
  Todo::create().title(t.get("title").asStr()))
144
58
  )
59
+
60
+ isAuthorized<User>() -> Bool =
61
+ False
62
+
63
+ map<User>(cb: (a: User) -> b) -> b =
64
+ cb(u)
145
65
 
146
- toStr(self: User) -> Str =
66
+ toStr<User>() -> Str =
147
67
  "User({self.name}, {self.age})"
148
68
 
149
- u = User.create()
69
+ u = User.build()
150
70
  .name("John Doe")
151
71
  .email("john@example.com")
152
- .todos(Todo::create().title("Make pizza"))
72
+ .todos(Todo.create().title("Make pizza"))
153
- .todos(Todo::create().title("Finish Toasty"))
73
+ .todos(Todo.create().title("Finish Toasty"))
154
- .todos(Todo::create().title("Sleep"))
74
+ .todos(Todo.create().title("Sleep"))
155
75
 
156
76
  u2 = try User.fromJson(`{
157
77
  "name": "John Doe",
@@ -171,6 +91,12 @@ stoplightColor(something: Int) -> Color =
171
91
  else
172
92
  Green
173
93
 
94
+ test("stoplightColor") =
95
+ doc: "Get the color of something"
96
+ assert stoplightColor(1) == Red
97
+ assert stoplightColor(0) == Yellow
98
+ assert stoplightColor(-1) == Green
99
+
174
100
  toCelsius(f: Float) -> Float =
175
101
  doc: "Convert fahrenheit temperature reading to celsius"
176
102
  return {f - 32} * {5 / 9}
@@ -261,17 +187,6 @@ pluralize_test(t: Test) -> Unit =
261
187
  assert pluralize("cactus", "cacti", 1) == "1 cactus"
262
188
  assert pluralize("cactus", "cacti", 2) == "2 cacti"
263
189
 
264
-
265
- class User =
266
- name: String
267
- age: Int
268
-
269
- isAuthorized(self: User) -> Bool =
270
- False
271
-
272
- map(self: User, cb: (a: User) -> b) -> b =
273
- cb(u)
274
-
275
190
  name(d: Option(Str)) -> Str =
276
191
  if d == Some(v) then
277
192
  v.subString(0, 3)
@@ -303,16 +218,16 @@ fromStr() -> Result(Int, Err) = # convert Str to Int
303
218
 
304
219
  type Int(Comparable, Stringable)
305
220
 
306
- toFloat(self: Int) -> Float = # convert Int to Float
221
+ toFloat<Int>() -> Float = # convert Int to Float
307
- float::fromInt(self)
222
+ Float(self)
308
223
 
309
- add(self: Int, other: Int) -> Int =
224
+ add<Int>(other: Int) -> Int =
310
225
  self + other
311
226
 
312
- sub(self: Int, other: Int) -> Int =
227
+ sub<Int>(other: Int) -> Int =
313
228
  self - other
314
229
 
315
- abs(self: Int) -> Int =
230
+ abs<Int>() -> Int =
316
231
  self < 0 ? -self : self
317
232
 
318
233
  main() =
@@ -341,32 +256,4 @@ main() =
341
256
  names.append("Jess")
342
257
  names
343
258
  .filter({ it == "Sam" })
344
- .map({ it * 2 })
259
+ .map({ it * 2 })
345
-
346
- module std/http
347
-
348
- import std/path
349
- import std/os
350
- import std/http/content_type
351
- import std/libc
352
-
353
- extern sqrt(x: libc.Double) -> libc.Double
354
- extern pow(x: libc.Double, y: libc.Double) -> libc.Double
355
-
356
-
357
- trait Writer =
358
- write(p: Str | Buffer) -> Result[Int, WriteError]
359
-
360
- enum ReadError =
361
- | EOF
362
- | Closed
363
-
364
- enum WriteError =
365
- | EOF
366
- | Closed
367
-
368
- trait Reader =
369
- read(p: Str | Buffer) -> Result[Int, ReadError]
370
-
371
- trait IO(Reader, Writer) =
372
- pass
tooling/tree-sitter-plum/_queries/highlights.scm DELETED
@@ -1,132 +0,0 @@
1
- ; Identifier naming conventions
2
-
3
- ((identifier) @constructor
4
- (#match? @constructor "^[A-Z]"))
5
-
6
- ((identifier) @constant
7
- (#match? @constant "^[A-Z][A-Z_]*$"))
8
-
9
- ; Builtin functions
10
-
11
- ((call
12
- function: (identifier) @function.builtin)
13
- (#match?
14
- @function.builtin
15
- "^(abs|all|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|vars|zip|__import__)$"))
16
-
17
- ; Function calls
18
-
19
- (decorator) @function
20
-
21
- (call
22
- function: (attribute attribute: (identifier) @function.method))
23
- (call
24
- function: (identifier) @function)
25
-
26
- ; Function definitions
27
-
28
- (function_definition
29
- name: (identifier) @function)
30
-
31
- (identifier) @variable
32
- (attribute attribute: (identifier) @property)
33
- (type (identifier) @type)
34
-
35
- ; Literals
36
-
37
- [
38
- (none)
39
- (true)
40
- (false)
41
- ] @constant.builtin
42
-
43
- [
44
- (integer)
45
- (float)
46
- ] @number
47
-
48
- (comment) @comment
49
- (string) @string
50
- (escape_sequence) @escape
51
-
52
- (interpolation
53
- "{" @punctuation.special
54
- "}" @punctuation.special) @embedded
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
- "and"
94
- "in"
95
- "is"
96
- "not"
97
- "or"
98
- ] @operator
99
-
100
- [
101
- "as"
102
- "assert"
103
- "async"
104
- "await"
105
- "break"
106
- "class"
107
- "continue"
108
- "def"
109
- "del"
110
- "elif"
111
- "else"
112
- "except"
113
- "exec"
114
- "finally"
115
- "for"
116
- "from"
117
- "global"
118
- "if"
119
- "import"
120
- "lambda"
121
- "nonlocal"
122
- "pass"
123
- "print"
124
- "raise"
125
- "return"
126
- "try"
127
- "while"
128
- "with"
129
- "yield"
130
- "match"
131
- "case"
132
- ] @keyword
tooling/tree-sitter-plum/_queries/tags.scm DELETED
@@ -1,14 +0,0 @@
1
- (module (expression_statement (assignment left: (identifier) @name) @definition.constant))
2
-
3
- (class_definition
4
- name: (identifier) @name) @definition.class
5
-
6
- (function_definition
7
- name: (identifier) @name) @definition.function
8
-
9
- (call
10
- function: [
11
- (identifier) @name
12
- (attribute
13
- attribute: (identifier) @name)
14
- ]) @reference.call
tooling/tree-sitter-plum/bindings/rust/lib.rs CHANGED
@@ -37,10 +37,10 @@ pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");
37
37
 
38
38
  // Uncomment these to include any queries that this grammar contains
39
39
 
40
- // pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm");
40
+ pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm");
41
41
  // pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm");
42
42
  // pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm");
43
- // pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm");
43
+ pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm");
44
44
 
45
45
  #[cfg(test)]
46
46
  mod tests {
tooling/tree-sitter-plum/grammar.js CHANGED
@@ -147,11 +147,13 @@ module.exports = grammar({
147
147
  fn: ($) =>
148
148
  seq(
149
149
  field("name", $.identifier),
150
+ field("type", optional(alias($.fn_type, $.type))),
150
151
  field("params", seq("(", optional(commaSep1($.param)), ")")),
151
152
  field("returns", optional(seq("->", $.return_type))),
152
153
  field("body", seq("=", choice($.expression, $.body))),
153
154
  ),
154
155
 
156
+ fn_type: ($) => seq("<", commaSep1($.type_identifier), ">"),
155
157
  body: ($) => seq($._indent, repeat($._statement), $._dedent),
156
158
 
157
159
  _statement: ($) =>
@@ -268,7 +270,7 @@ module.exports = grammar({
268
270
  primary_expression: ($) =>
269
271
  choice(
270
272
  $.binary_operator,
271
- $.this,
273
+ $.self,
272
274
  $.identifier,
273
275
  $.type_identifier,
274
276
  $.string,
@@ -497,7 +499,7 @@ module.exports = grammar({
497
499
  token(seq("0", /[bB]/, BIN_DIGITS)),
498
500
  ),
499
501
 
500
- this: (_) => /this/,
502
+ self: (_) => /self/,
501
503
  identifier: (_) => /[_a-z][_a-zA-Z0-9]*/,
502
504
  generic: ($) => choice($.a, $.b, $.c, $.d), // single letter
503
505
  a: (_) => token("a"),
tooling/tree-sitter-plum/package.json CHANGED
@@ -49,21 +49,6 @@
49
49
  "test": "tree-sitter test"
50
50
  },
51
51
  "repository": "https://github.com/pyrossh/plum",
52
- "tree-sitter": [
53
- {
54
- "scope": "source.plum",
55
- "file-types": [
56
- "plum"
57
- ],
58
- "injection-regex": "plum",
59
- "highlights": [
60
- "queries/highlights.scm"
61
- ],
62
- "tags": [
63
- "queries/tags.scm"
64
- ]
65
- }
66
- ],
67
52
  "eslintConfig": {
68
53
  "env": {
69
54
  "commonjs": true,
@@ -106,5 +91,11 @@
106
91
  }
107
92
  ]
108
93
  }
94
+ },
95
+ "tree-sitter": [
96
+ {
97
+ "scope": "source.plum",
98
+ "injection-regex": "^plum$"
109
- }
99
+ }
100
+ ]
110
- }
101
+ }
tooling/tree-sitter-plum/queries/highlights.scm ADDED
@@ -0,0 +1,79 @@
1
+ ; Identifier conventions
2
+
3
+ ; Assume all-caps names are constants
4
+ ((identifier) @constant
5
+ (#match? @constant "^[A-Z][A-Z_]*$"))
6
+
7
+ [
8
+ (identifier)
9
+ ] @variable
10
+
11
+ (class
12
+ name: (type_identifier) @type)
13
+
14
+ (trait
15
+ name: (type_identifier) @type)
16
+
17
+ (enum
18
+ name: (type_identifier) @type)
19
+
20
+ (fn
21
+ name: (identifier) @function)
22
+
23
+ [
24
+ (integer)
25
+ (float)
26
+ ] @number
27
+
28
+ (comment) @comment
29
+ (string) @string
30
+ (escape_sequence) @escape
31
+ (self) @variable.builtin
32
+
33
+ [
34
+ "("
35
+ ")"
36
+ "["
37
+ "]"
38
+ "{"
39
+ "}"
40
+ (module)
41
+ ] @punctuation.bracket
42
+
43
+ [
44
+ "."
45
+ ","
46
+ ] @punctuation.delimiter
47
+
48
+
49
+ (interpolation
50
+ "{" @punctuation.special
51
+ "}" @punctuation.special) @embedded
52
+
53
+ [
54
+ "="
55
+ "!="
56
+ "=="
57
+ "*"
58
+ "/"
59
+ "%"
60
+ "^"
61
+ "-"
62
+ "+"
63
+ ">"
64
+ ">="
65
+ "<"
66
+ "<="
67
+ "<>"
68
+ "||"
69
+ "&&"
70
+ "in"
71
+ "is"
72
+ ] @operator
73
+
74
+ [
75
+ "module"
76
+ "type"
77
+ "enum"
78
+ "trait"
79
+ ] @keyword
tooling/tree-sitter-plum/queries/tags.scm ADDED
@@ -0,0 +1,11 @@
1
+ (class
2
+ name: (type_identifier) @name) @definition.class
3
+
4
+ (enum
5
+ name: (type_identifier) @name) @definition.class
6
+
7
+ (trait
8
+ name: (type_identifier) @name) @definition.interface
9
+
10
+ (fn
11
+ name: (identifier) @name) @definition.function
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/enum.txt CHANGED
@@ -6,7 +6,7 @@ enum Bool =
6
6
  | True
7
7
  | False
8
8
 
9
- toStr(self: Bool) -> Str =
9
+ toStr<Bool>() -> Str =
10
10
  "Bool"
11
11
 
12
12
  --------------------------------------------------------------------------------
@@ -20,10 +20,8 @@ toStr(self: Bool) -> Str =
20
20
  (type_identifier)))
21
21
  (fn
22
22
  (identifier)
23
- (param
24
- (var_identier)
25
- (type
23
+ (type
26
- (type_identifier)))
24
+ (type_identifier))
27
25
  (return_type
28
26
  (type_identifier))
29
27
  (body
tooling/tree-sitter-plum/test/corpus/function.txt CHANGED
@@ -101,7 +101,7 @@ add(param: a, param2: List(b)) -> List(b) =
101
101
  function - method
102
102
  ================================================================================
103
103
 
104
- User\fullname() -> String =
104
+ fullname<User>() -> String =
105
105
  todo
106
106
 
107
107
  --------------------------------------------------------------------------------
tooling/tree-sitter-plum/test/corpus/type.txt CHANGED
@@ -10,13 +10,13 @@ type Cat(Stringable) =
10
10
  name: Str
11
11
  age: Int
12
12
 
13
- withName(self: Cat, name: Str) -> Cat =
13
+ withName<Cat>(name: Str) -> Cat =
14
14
  Cat(name: name, age: 0)
15
15
 
16
- withAge(self: Cat, age: Int) -> Cat =
16
+ withAge<Cat>(age: Int) -> Cat =
17
17
  Cat(name: "", age: age)
18
18
 
19
- toStr(self: Cat) -> Str =
19
+ toStr<Cat>() -> Str =
20
20
  "Cat({this.name}, {this.age})"
21
21
 
22
22
  --------------------------------------------------------------------------------
@@ -45,10 +45,8 @@ toStr(self: Cat) -> Str =
45
45
  (type_identifier))))
46
46
  (fn
47
47
  (identifier)
48
- (param
49
- (var_identier)
50
- (type
48
+ (type
51
- (type_identifier)))
49
+ (type_identifier))
52
50
  (param
53
51
  (var_identier)
54
52
  (type
@@ -70,10 +68,8 @@ toStr(self: Cat) -> Str =
70
68
  (integer))))))))
71
69
  (fn
72
70
  (identifier)
73
- (param
74
- (var_identier)
75
- (type
71
+ (type
76
- (type_identifier)))
72
+ (type_identifier))
77
73
  (param
78
74
  (var_identier)
79
75
  (type
@@ -97,10 +93,8 @@ toStr(self: Cat) -> Str =
97
93
  (identifier))))))))
98
94
  (fn
99
95
  (identifier)
100
- (param
101
- (var_identier)
102
- (type
96
+ (type
103
- (type_identifier)))
97
+ (type_identifier))
104
98
  (return_type
105
99
  (type_identifier))
106
100
  (body
tooling/tree-sitter-plum/tree-sitter-plum.pc ADDED
@@ -0,0 +1,11 @@
1
+ prefix=/usr/local
2
+ libdir=${prefix}/lib
3
+ includedir=${prefix}/include
4
+
5
+ Name: tree-sitter-plum
6
+ Description: Plum grammar for tree-sitter
7
+ URL: https://git.sr.ht/~pyrossh/plum
8
+ Version: 0.0.1
9
+ Requires:
10
+ Libs: -L${libdir} -ltree-sitter-plum
11
+ Cflags: -I${includedir}
tooling/tree-sitter-plum/tree-sitter.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "grammars": [
3
+ {
4
+ "name": "plum",
5
+ "camelcase": "Plum",
6
+ "scope": "source.plum",
7
+ "path": ".",
8
+ "file-types": [
9
+ "plum"
10
+ ],
11
+ "highlights": [
12
+ "queries/highlights.scm"
13
+ ],
14
+ "tags": [
15
+ "queries/tags.scm"
16
+ ],
17
+ "injection-regex": "plum"
18
+ }
19
+ ],
20
+ "metadata": {
21
+ "version": "0.0.1",
22
+ "license": "MIT",
23
+ "description": "plum grammar for tree-sitter",
24
+ "authors": [
25
+ {
26
+ "name": "pyrossh"
27
+ }
28
+ ],
29
+ "links": {
30
+ "repository": "https://github.com/pyrossh/plum"
31
+ }
32
+ },
33
+ "bindings": {
34
+ "c": true,
35
+ "go": true,
36
+ "node": true,
37
+ "python": true,
38
+ "rust": true,
39
+ "swift": true
40
+ }
41
+ }
tooling/vscode-plum/syntaxes/plum.tmLanguage.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
- "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
3
2
  "name": "plum",
3
+ "scopeName": "source.plum",
4
4
  "patterns": [
5
5
  {
6
6
  "include": "#comments"
@@ -14,6 +14,9 @@
14
14
  {
15
15
  "include": "#string"
16
16
  },
17
+ {
18
+ "include": "raw_quoted_string"
19
+ },
17
20
  {
18
21
  "include": "#number"
19
22
  },
@@ -36,12 +39,16 @@
36
39
  "keywords": {
37
40
  "patterns": [
38
41
  {
39
- "match": "\\b(module|type|enum|trait|self)\\b",
42
+ "match": "\\b(module|type|enum|trait|extern|include|self)\\b",
40
43
  "name": "keyword.const.plum"
41
44
  },
42
45
  {
43
46
  "name": "keyword.control.plum",
44
- "match": "\\b(try|import|in|return|continue|break|match|if|else|while|for|as|is|assert|panic|pass)\\b"
47
+ "match": "\\b(try|import|in|return|continue|break|match|if|else|while|for|as|is|assert|panic)\\b"
48
+ },
49
+ {
50
+ "name": "keyword.operator.range.plum",
51
+ "match": "\\.\\."
45
52
  },
46
53
  {
47
54
  "name": "keyword.operator.splat.plum",
@@ -67,10 +74,6 @@
67
74
  },
68
75
  "constant": {
69
76
  "patterns": [
70
- {
71
- "name": "entity.name.type.plum",
72
- "match": "[[:upper:]][[:alnum:]]*"
73
- },
74
77
  {
75
78
  "comment": "ALL CAPS constants",
76
79
  "name": "constant.other.caps.plum",
@@ -90,75 +93,6 @@
90
93
  }
91
94
  ]
92
95
  },
93
- "string": {
94
- "name": "string.quoted.double.plum",
95
- "begin": "\"",
96
- "beginCaptures": {
97
- "0": {
98
- "name": "punctuation.definition.string.begin.plum"
99
- }
100
- },
101
- "end": "\"",
102
- "endCaptures": {
103
- "0": {
104
- "name": "punctuation.definition.string.end.plum"
105
- }
106
- },
107
- "patterns": [
108
- {
109
- "include": "#interpolated-plum"
110
- }
111
- ]
112
- },
113
- "interpolated-plum": {
114
- "patterns": [
115
- {
116
- "name": "meta.embedded.line.plum",
117
- "contentName": "source.plum",
118
- "begin": "{",
119
- "beginCaptures": {
120
- "0": {
121
- "name": "punctuation.section.embedded.begin.plum"
122
- }
123
- },
124
- "end": "}",
125
- "endCaptures": {
126
- "0": {
127
- "name": "punctuation.section.embedded.end.plum"
128
- }
129
- },
130
- "patterns": [
131
- {
132
- "include": "#nest_curly_and_self"
133
- },
134
- {
135
- "include": "$self"
136
- }
137
- ]
138
- }
139
- ]
140
- },
141
- "nest_curly_and_self": {
142
- "patterns": [
143
- {
144
- "begin": "{",
145
- "captures": {
146
- "0": {
147
- "name": "punctuation.section.scope.plum"
148
- }
149
- },
150
- "end": "}",
151
- "patterns": [
152
- {
153
- "include": "#nest_curly_and_self"
154
- }
155
- ]
156
- },
157
- {
158
- "include": "$self"
159
- }
160
- ]
161
- },
162
96
  "number": {
163
97
  "name": "constant.numeric.plum",
164
98
  "patterns": [
@@ -221,6 +155,10 @@
221
155
  },
222
156
  "entity": {
223
157
  "patterns": [
158
+ {
159
+ "name": "entity.name.type.plum",
160
+ "match": "[[:upper:]][[:alnum:]]*"
161
+ },
224
162
  {
225
163
  "begin": "\\b([[:lower:]][[:word:]]*)\\b\\(",
226
164
  "end": "\\)",
@@ -235,6 +173,23 @@
235
173
  }
236
174
  }
237
175
  },
176
+ {
177
+ "begin": "([[:lower:]][[:word:]]*)<([[:upper:]][[:alnum:]]*)>()",
178
+ "end": "\\)",
179
+ "patterns": [
180
+ {
181
+ "include": "$self"
182
+ }
183
+ ],
184
+ "captures": {
185
+ "1": {
186
+ "name": "entity.name.function.plum"
187
+ },
188
+ "2": {
189
+ "name": "keyword.control.plum"
190
+ }
191
+ }
192
+ },
238
193
  {
239
194
  "name": "variable.parameter.plum",
240
195
  "match": "\\b([[:lower:]][[:word:]]*):\\s"
@@ -245,10 +200,134 @@
245
200
  }
246
201
  ]
247
202
  },
203
+ "string": {
204
+ "patterns": [
205
+ {
206
+ "name": "string.quoted.double.plum",
207
+ "begin": "\"",
208
+ "beginCaptures": {
209
+ "0": {
210
+ "name": "punctuation.definition.string.begin.plum"
211
+ }
212
+ },
213
+ "end": "\"",
214
+ "endCaptures": {
215
+ "0": {
216
+ "name": "punctuation.definition.string.end.plum"
217
+ }
218
+ },
219
+ "patterns": [
220
+ {
221
+ "include": "#template-substitution-element"
222
+ },
223
+ {
224
+ "include": "#string-character-escape"
225
+ }
226
+ ]
227
+ }
228
+ ]
229
+ },
230
+ "string-character-escape": {
231
+ "name": "constant.character.escape.plum",
232
+ "match": "\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|u\\{[0-9A-Fa-f]+\\}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$)"
233
+ },
234
+ "template-substitution-element": {
235
+ "name": "meta.template.expression.plum",
236
+ "begin": "\\{",
237
+ "beginCaptures": {
238
+ "0": {
239
+ "name": "punctuation.definition.template-expression.begin.plum"
240
+ }
241
+ },
242
+ "end": "\\}",
243
+ "endCaptures": {
244
+ "0": {
245
+ "name": "punctuation.definition.template-expression.end.plum"
246
+ }
247
+ },
248
+ "patterns": [
249
+ {
250
+ "include": "#expression"
251
+ }
252
+ ],
253
+ "contentName": "meta.embedded.line.plum"
254
+ },
255
+ "expression": {
256
+ "patterns": [
257
+ {
258
+ "match": "\\b(self)\\b",
259
+ "name": "keyword.const.plum"
260
+ },
261
+ {
262
+ "match": "(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*(\\#?[[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])",
263
+ "captures": {
264
+ "1": {
265
+ "name": "punctuation.accessor.plum"
266
+ },
267
+ "2": {
268
+ "name": "punctuation.accessor.optional.plum"
269
+ },
270
+ "3": {
271
+ "name": "variable.other.constant.property.plum"
272
+ }
273
+ }
274
+ },
275
+ {
276
+ "match": "(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*)",
277
+ "captures": {
278
+ "1": {
279
+ "name": "punctuation.accessor.plum"
280
+ },
281
+ "2": {
282
+ "name": "punctuation.accessor.optional.plum"
283
+ },
284
+ "3": {
285
+ "name": "variable.other.property.plum"
286
+ }
287
+ }
288
+ },
289
+ {
290
+ "name": "variable.other.constant.plum",
291
+ "match": "([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])"
292
+ },
293
+ {
294
+ "name": "variable.other.readwrite.plum",
295
+ "match": "[_$[:alpha:]][_$[:alnum:]]*"
296
+ }
297
+ ]
298
+ },
299
+ "raw_quoted_string": {
300
+ "comment": "Raw string literals",
301
+ "begin": "`",
302
+ "beginCaptures": {
303
+ "0": {
304
+ "name": "punctuation.definition.string.begin.go.mod"
305
+ }
306
+ },
307
+ "end": "`",
308
+ "endCaptures": {
309
+ "0": {
310
+ "name": "punctuation.definition.string.end.go.mod"
311
+ }
312
+ },
313
+ "name": "string.quoted.raw",
314
+ "patterns": [
315
+ {
316
+ "include": "#string_placeholder"
317
+ }
318
+ ]
319
+ },
320
+ "string_placeholder": {
321
+ "patterns": [
322
+ {
323
+ "match": "%(\\[\\d+\\])?([\\+#\\-0\\x20]{,2}((\\d+|\\*)?(\\.?(\\d+|\\*|(\\[\\d+\\])\\*?)?(\\[\\d+\\])?)?))?[vT%tbcdoqxXUbeEfFgGsp]",
324
+ "name": "constant.other.placeholder.go.mod"
325
+ }
326
+ ]
327
+ },
248
328
  "discards": {
249
329
  "name": "comment.unused.plum",
250
330
  "match": "\\b_(?:[[:word:]]+)?\\b"
251
331
  }
252
- },
332
+ }
253
- "scopeName": "source.plum"
254
333
  }