~repos /plum

#treesitter#compiler#wasm

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

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


d322d056 pyrossh

11 months ago
add better syntax
test/main.go ADDED
@@ -0,0 +1,37 @@
1
+ package main
2
+
3
+ const MIN_VALUE = -0x8000_0000_0000_0000 # Lowest value of Int
4
+ const MAX_VALUE = 0x7FFF_FFFF_FFFF_FFFF # Highest value of Int
5
+ const LARGE = 268435456 # 2**28
6
+
7
+ import (
8
+ "123"
9
+ )
10
+
11
+ type Game struct {
12
+
13
+ }
14
+
15
+ func random() Int {
16
+ panic("TODO")
17
+ }
18
+
19
+ func fromStr() Result(Int, Err) {
20
+ return Ok(0)
21
+ }
22
+
23
+ func (i Int) toFloat() Float {
24
+ return FloatfromInt(i)
25
+ }
26
+
27
+ func (i Int) add(b: Int) Int {
28
+ return i + b
29
+ }
30
+
31
+ func (i Int) sub(b: Int) Int {
32
+ return i - b
33
+ }
34
+
35
+ func (i Int) abs() Int {
36
+ return i < 0 ? -i : i
37
+ }
test/main.java ADDED
@@ -0,0 +1,8 @@
1
+ class Data {
2
+ static Float PI = 3.14;
3
+
4
+ public void printLn() {
5
+ this.name
6
+ return "\(123)";
7
+ }
8
+ }
test/main.js ADDED
@@ -0,0 +1,11 @@
1
+
2
+
3
+ class Data {
4
+ toStr() {
5
+ return `${this.name}`
6
+ }
7
+ }
8
+
9
+ function toStr() {
10
+ return `Hello ${this.name}`
11
+ }
test/main.py ADDED
@@ -0,0 +1,14 @@
1
+ class ToStr:
2
+ pass
3
+
4
+
5
+ class Int(ToStr):
6
+ def __init__():
7
+ pass
8
+ format("%d")
9
+
10
+ def toStr(self):
11
+ return f"Hello {self.name}"
12
+
13
+
14
+ raw_string = r"Python\nis\easy\to\learn"
test/main.rs ADDED
@@ -0,0 +1,19 @@
1
+ mod 123
2
+
3
+ static data = ""
4
+
5
+ use std.asd
6
+
7
+ struct Row {
8
+ id: String
9
+ }
10
+
11
+ impl Row {
12
+ fn add(&self, other: Row) -> Row {
13
+ Row {}
14
+ }
15
+ }
16
+
17
+ fn main() {
18
+
19
+ }
test/sample.plum CHANGED
@@ -1,22 +1,117 @@
1
- module sample
2
-
3
1
  import std.(List, Map, Math)
4
2
  import std/encoding.(Base64)
3
+ import include/libs/libc
5
4
 
6
- Int.random()
7
- Float.random()
5
+ library LibPCRE
8
- Float.PI
6
+ sqrt(x: C.Double) -> C.Double
7
+ pow(x: C.Double, y: C.Double) -> C.Double
8
+ sqrt(x: C.Double) -> C.Double
9
9
 
10
- type Int =
10
+ module Float =
11
- random() -> Int = 20
11
+ PI = 3.14159265359
12
- add(self, other: Int) -> Int = self + other
13
- sub(self, other: Int) -> Int = self - other
14
12
 
13
+ class Float(Comparable, Stringable) =
14
+
15
+ ceil() -> Float =
16
+ todo
17
+
18
+ floor() -> Float =
19
+ todo
20
+
21
+ round() -> Float =
22
+ todo
23
+
24
+ trunc() -> Float =
25
+ todo
26
+
27
+ log() -> Float =
28
+ todo
29
+
30
+ log2() -> Float =
31
+ todo
32
+
33
+ log10() -> Float =
34
+ todo
35
+
36
+ logb() -> Float =
37
+ todo
38
+
39
+ pow(y: Float) -> Float =
40
+ LibM.pow(this, y)
41
+
42
+ pow(y: Int) -> Float =
43
+ pow(y.toFloat())
44
+
45
+ sqrt() -> Float =
46
+ if this < 0.0
47
+ _nan()
48
+ else
49
+ LibM.sqrt(this)
50
+
51
+ asin(v: Float) =
52
+ todo
53
+
54
+ acos(v: Float) =
55
+ if v < 0.1
56
+ asin(v)
57
+ else
58
+ asin(-v)
59
+
15
- type User(ToStr) =
60
+ asinh(v: Float) =
16
- name: Str
17
- age: Int
61
+ todo
62
+
18
- todos: List(Todo)
63
+ atan(v: Float) =
64
+ todo
65
+
66
+ atan2(v: Float) =
67
+ todo
68
+
69
+ atanh(v: Float) =
70
+ todo
19
71
 
72
+ cbrt(v: Float) =
73
+ todo
74
+
75
+ ceil(v: Float) =
76
+ todo
77
+
78
+ clz32(v: Float) =
79
+ todo
80
+
81
+ func (f: Float) cos(v: Float) =
82
+ todo
83
+
84
+ func (f: Float) cosh(v: Float) =
85
+ todo
86
+
87
+ func (f: Float) exp(v: Float) =
88
+ todo
89
+
90
+ module Int =
91
+ MIN_VALUE = -0x8000_0000_0000_0000 # Lowest value of Int
92
+ MAX_VALUE = 0x7FFF_FFFF_FFFF_FFFF # Highest value of Int
93
+ LARGE = 268435456 # 2**28
94
+
95
+ random() -> Float = # generate random number
96
+ panic("TODO")
97
+
98
+ fromStr() -> Result(Int, Err) = # convert Str to Int
99
+ Ok(0)
100
+
101
+ class Int(Comparable, Stringable) =
102
+ toFloat() -> Float = # convert Int to Float
103
+ Float.fromInt(this)
104
+
105
+ add(other: Int) -> Int =
106
+ this + other
107
+
108
+ sub(other: Int) -> Int =
109
+ this - other
110
+
111
+ abs() -> Int =
112
+ this < 0 ? -this : this
113
+
114
+ module User
20
115
  fromJson(s: Str) -> Result(Self, Err) =
21
116
  v = try Json.parse(s) as Map(Str, Json)
22
117
  User::create()
@@ -26,34 +121,34 @@ type User(ToStr) =
26
121
  Todo::create().title(t.get("title").asStr()))
27
122
  )
28
123
 
29
- queryAll(self, noise: Int) -> Str =
30
- printLn(noise)
31
- ""
32
-
33
- findOne(self) -> Self =
34
- printLn(noise)
35
-
36
- toStr(self) -> Str =
37
- "User({u.name}, {u.age})"
38
-
39
- type Cat(ToStr) =
124
+ class User(ToStr) =
40
125
  name: Str
41
126
  age: Int
127
+ todos: List(Todo)
42
128
 
129
+ toStr() -> Str =
130
+ "User({this.name}, {this.age})"
131
+
132
+
133
+ module Cat
43
134
  fromJson(s: Str) -> Result(Self, Err) =
44
135
  v = try Json.parse(s) as Map(Str, Json)
45
136
  Cat::create()
46
137
  .name(v.get("name").asStr())
47
138
  .age(v.get("age").asInt())
48
139
 
140
+ class Cat(ToStr) =
141
+ name: Str
142
+ age: Int
143
+
49
- withName(self, name: Str) -> Cat =
144
+ withName(name: Str) -> Cat =
50
- Cat(name = name, age = self.age)
145
+ Cat(name = name, age = this.age)
51
146
 
52
- withAge(self, age: Int) -> Cat =
147
+ withAge(age: Int) -> Cat =
53
- Cat(name = self.name, age = age)
148
+ Cat(name = this.name, age = age)
54
149
 
55
- toStr(self) -> Str =
150
+ toStr() -> Str =
56
- "Cat(1, 2)"
151
+ f"Cat({this.name}, {this.age})"
57
152
 
58
153
 
59
154
  2.sqrt().sin().cos()
@@ -89,7 +184,7 @@ u2 = try User.fromJson(`{
89
184
 
90
185
 
91
186
 
92
- func stoplightColor(something: Int) -> Color =
187
+ stoplightColor(something: Int) -> Color =
93
188
  if something > 0
94
189
  Red
95
190
  else if something == 0
@@ -97,7 +192,7 @@ func stoplightColor(something: Int) -> Color =
97
192
  else
98
193
  Green
99
194
 
100
- func toCelsius(f: Float) -> Float =
195
+ toCelsius(f: Float) -> Float =
101
196
  doc: "Convert fahrenheit temperature reading to celsius"
102
197
  return {f - 32} * {5 / 9}
103
198
  check:
tooling/tree-sitter-plum/grammar.js CHANGED
@@ -65,7 +65,7 @@ module.exports = grammar({
65
65
  seq(
66
66
  optional(seq("module", $.module)),
67
67
  repeat($.import),
68
- repeat(choice($.record, $.trait, $.enum, $.fn)),
68
+ repeat(choice($.class, $.trait, $.enum, $.fn)),
69
69
  ),
70
70
 
71
71
  module: ($) => $.var_identier,
@@ -86,20 +86,20 @@ module.exports = grammar({
86
86
  ),
87
87
  variadic_type: ($) => seq("...", $.type),
88
88
 
89
- record: ($) =>
89
+ class: ($) =>
90
90
  seq(
91
- "type",
91
+ "class",
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
- field("fields", optional(repeat(alias($.record_field, $.field)))),
97
+ field("fields", optional(repeat(alias($.class_field, $.field)))),
98
98
  field("methods", optional(repeat($.method))),
99
99
  $._dedent,
100
100
  ),
101
101
 
102
- record_field: ($) => seq(field("name", $.identifier), ":", field("type", $.type)),
102
+ class_field: ($) => seq(field("name", $.identifier), ":", field("type", $.type)),
103
103
  method: ($) => seq(
104
104
  field("name", $.identifier),
105
105
  field("params", seq("(", optional(commaSep1($.param)), ")")),
@@ -288,7 +288,7 @@ module.exports = grammar({
288
288
  $.unary_operator,
289
289
  $.attribute,
290
290
  $.fn_call,
291
- $.type_call,
291
+ $.class_call,
292
292
  $.parenthesized_expression,
293
293
  ),
294
294
 
@@ -396,15 +396,6 @@ module.exports = grammar({
396
396
  ),
397
397
  )),
398
398
 
399
- type_call: ($) =>
400
- prec(PREC.call, seq(
401
- field("type", $.type_identifier),
402
- field(
403
- "arguments",
404
- $.argument_list,
405
- ),
406
- )),
407
-
408
399
  argument_list: ($) =>
409
400
  seq(
410
401
  "(",
@@ -421,6 +412,25 @@ module.exports = grammar({
421
412
  pair_argument: ($) =>
422
413
  seq(field("name", $.string), "=>", field("value", $.expression)),
423
414
 
415
+ class_call: ($) =>
416
+ prec(PREC.call, seq(
417
+ field("type", $.type_identifier),
418
+ field(
419
+ "arguments",
420
+ $.class_argument_list,
421
+ ),
422
+ )),
423
+
424
+ class_argument_list: ($) =>
425
+ seq(
426
+ "(",
427
+ optional(
428
+ commaSep1(seq(field("name", $.identifier), ":", field("value", $.expression)),),
429
+ ),
430
+ optional(","),
431
+ ")",
432
+ ),
433
+
424
434
  ternary_expression: ($) =>
425
435
  prec.right(
426
436
  PREC.conditional,
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/{type.txt → class.txt} RENAMED
@@ -1,33 +1,33 @@
1
1
  ================================================================================
2
- type
2
+ class
3
3
  ================================================================================
4
4
 
5
- type Dog =
5
+ class Dog =
6
6
  name: Str
7
7
  age: b
8
8
 
9
- type Int =
9
+ class Int =
10
10
  random() -> Int = 20
11
11
  add(self, other: Int) -> Int = self + other
12
12
  sub(self, other: Int) -> Int = self - other
13
13
 
14
- type Cat(Stringable) =
14
+ class Cat(Stringable) =
15
15
  name: Str
16
16
  age: Int
17
17
 
18
- withName(self, name: Str) -> Cat =
18
+ withName(name: Str) -> Cat =
19
- Cat(name = name, age = 0)
19
+ Cat(name: name, age: 0)
20
20
 
21
- withAge(self, age: Int) -> Cat =
21
+ withAge(age: Int) -> Cat =
22
- Cat(name = "", age = age)
22
+ Cat(name: "", age: age)
23
23
 
24
- toStr(self) -> Str =
24
+ toStr() -> Str =
25
- "Cat(1, 2)"
25
+ "Cat({this.name}, {this.age})"
26
26
 
27
27
  --------------------------------------------------------------------------------
28
28
 
29
29
  (source
30
- (record
30
+ (class
31
31
  (type_identifier)
32
32
  (field
33
33
  (identifier)
@@ -37,7 +37,7 @@ type Cat(Stringable) =
37
37
  (identifier)
38
38
  (type
39
39
  (b))))
40
- (record
40
+ (class
41
41
  (type_identifier)
42
42
  (method
43
43
  (identifier)
@@ -78,7 +78,7 @@ type Cat(Stringable) =
78
78
  (identifier))
79
79
  (primary_expression
80
80
  (identifier)))))))
81
- (record
81
+ (class
82
82
  (type_identifier)
83
83
  (type_identifier)
84
84
  (field
@@ -91,7 +91,6 @@ type Cat(Stringable) =
91
91
  (type_identifier)))
92
92
  (method
93
93
  (identifier)
94
- (param)
95
94
  (param
96
95
  (var_identier)
97
96
  (type
@@ -100,22 +99,19 @@ type Cat(Stringable) =
100
99
  (type_identifier))
101
100
  (body
102
101
  (primary_expression
103
- (type_call
102
+ (class_call
104
103
  (type_identifier)
105
- (argument_list
104
+ (class_argument_list
106
- (keyword_argument
107
- (identifier)
105
+ (identifier)
108
- (expression
106
+ (expression
109
- (primary_expression
107
+ (primary_expression
110
- (identifier))))
108
+ (identifier)))
111
- (keyword_argument
112
- (identifier)
109
+ (identifier)
113
- (expression
110
+ (expression
114
- (primary_expression
111
+ (primary_expression
115
- (integer)))))))))
112
+ (integer))))))))
116
113
  (method
117
114
  (identifier)
118
- (param)
119
115
  (param
120
116
  (var_identier)
121
117
  (type
@@ -124,24 +120,21 @@ type Cat(Stringable) =
124
120
  (type_identifier))
125
121
  (body
126
122
  (primary_expression
127
- (type_call
123
+ (class_call
128
124
  (type_identifier)
129
- (argument_list
125
+ (class_argument_list
130
- (keyword_argument
131
- (identifier)
126
+ (identifier)
132
- (expression
127
+ (expression
133
- (primary_expression
128
+ (primary_expression
134
- (string
129
+ (string
135
- (string_start)
130
+ (string_start)
136
- (string_end)))))
131
+ (string_end))))
137
- (keyword_argument
138
- (identifier)
132
+ (identifier)
139
- (expression
133
+ (expression
140
- (primary_expression
134
+ (primary_expression
141
- (identifier)))))))))
135
+ (identifier))))))))
142
136
  (method
143
137
  (identifier)
144
- (param)
145
138
  (return_type
146
139
  (type_identifier))
147
140
  (body
tooling/vscode-plum/syntaxes/plum.tmLanguage.json CHANGED
@@ -9,169 +9,706 @@
9
9
  "include": "#keywords"
10
10
  },
11
11
  {
12
- "include": "#strings"
12
+ "include": "#constant"
13
13
  },
14
14
  {
15
- "include": "#constant"
15
+ "include": "#string"
16
16
  },
17
17
  {
18
18
  "include": "#entity"
19
19
  },
20
20
  {
21
21
  "include": "#discards"
22
- },
23
- {
24
- "include": "#raw_string_literals"
25
22
  }
26
23
  ],
27
24
  "repository": {
25
+ "comments": {
26
+ "patterns": [
27
+ {
28
+ "name": "comment.line.plum",
29
+ "match": "#.*"
30
+ }
31
+ ]
32
+ },
28
33
  "keywords": {
29
34
  "patterns": [
35
+ {
36
+ "match": "\\b(library|module|class|enum|trait|this)\\b",
37
+ "name": "keyword.const.plum"
38
+ },
30
39
  {
31
40
  "name": "keyword.control.plum",
32
- "match": "\\b(self|this|fn|impl|where|extern|func|try|var|val|module|import|trait|type|enum|in|return|continue|break|match|if|else|while|for|as|is|assert|panic)\\b"
41
+ "match": "\\b(try|import|in|return|continue|break|match|if|else|while|for|as|is|assert|panic)\\b"
33
42
  },
34
43
  {
35
- "name": "keyword.operator.arrow.plum",
44
+ "name": "keyword.operator.splat.plum",
36
- "match": "(<\\-|\\->)"
45
+ "match": "\\.\\.\\."
37
46
  },
38
47
  {
39
- "name": "keyword.operator.pipe.plum",
48
+ "name": "keyword.operator.comparison.plum",
40
- "match": "\\|>"
49
+ "match": "(==|!=|<=|>=|<|>)"
41
50
  },
42
51
  {
43
- "name": "keyword.operator.splat.plum",
52
+ "name": "keyword.operator.logical.plum",
44
- "match": "\\.\\."
53
+ "match": "(&&|\\|\\|)"
45
54
  },
46
55
  {
47
- "name": "keyword.operator.comparison.plum",
56
+ "name": "keyword.operator.arithmetic.plum",
48
- "match": "(==|!=)"
57
+ "match": "(\\+|\\-|/|\\*|%)"
49
58
  },
50
59
  {
51
- "name": "keyword.operator.comparison.float.plum",
60
+ "name": "keyword.operator.assignment.plum",
61
+ "match": "="
62
+ }
63
+ ]
64
+ },
65
+ "constant": {
66
+ "patterns": [
67
+ {
68
+ "name": "entity.name.type.plum",
52
- "match": "(<=\\.|>=\\.|<\\.|>\\.)"
69
+ "match": "[[:upper:]][[:alnum:]]*"
53
70
  },
54
71
  {
72
+ "comment": "ALL CAPS constants",
55
- "name": "keyword.operator.comparison.int.plum",
73
+ "name": "constant.other.caps.plum",
56
- "match": "(<=|>=|<|>)"
74
+ "match": "\\b[A-Z]{2}[A-Z0-9_]*\\b"
57
75
  },
58
76
  {
77
+ "comment": "constant declarations",
78
+ "match": "\\b\\s+([A-Z_]*)\\b",
79
+ "captures": {
80
+ "1": {
81
+ "name": "storage.type.plum"
82
+ },
83
+ "2": {
84
+ "name": "constant.other.caps.plum"
85
+ }
86
+ }
87
+ }
88
+ ]
89
+ },
90
+ "string": {
59
- "name": "keyword.operator.logical.plum",
91
+ "name": "meta.fstring.plum",
92
+ "begin": "([fF])(([\"]))",
60
- "match": "(&&|\\|\\|)"
93
+ "end": "(\\3)|((?<!\\\\)\\n)",
94
+ "beginCaptures": {
95
+ "1": {
96
+ "name": "string.interpolated.plum string.quoted.single.plum storage.type.string.plum"
61
97
  },
98
+ "2": {
99
+ "name": "punctuation.definition.string.begin.plum string.quoted.single.plum"
100
+ }
101
+ },
102
+ "endCaptures": {
103
+ "1": {
104
+ "name": "punctuation.definition.string.end.plum string.interpolated.plum string.quoted.single.plum"
105
+ },
106
+ "2": {
107
+ "name": "invalid.illegal.newline.plum"
108
+ }
109
+ },
110
+ "patterns": [
62
111
  {
63
- "name": "keyword.operator.arithmetic.float.plum",
112
+ "include": "#fstring-guts"
64
- "match": "(\\+\\.|\\-\\.|/\\.|\\*\\.)"
65
113
  },
66
114
  {
67
- "name": "keyword.operator.arithmetic.int.plum",
115
+ "include": "#fstring-illegal-single-brace"
68
- "match": "(\\+|\\-|/|\\*|%)"
69
116
  },
70
117
  {
71
- "name": "keyword.operator.assignment.plum",
118
+ "include": "#fstring-single-brace"
72
- "match": "="
73
119
  },
74
120
  {
75
- "name": "keyword.operator.comparison.plum",
76
- "match": "(<|>)"
121
+ "include": "#fstring-single-core"
77
122
  }
78
123
  ]
79
124
  },
80
- "strings": {
125
+ "fstring-guts": {
126
+ "patterns": [
127
+ {
128
+ "include": "#escape-sequence-unicode"
129
+ },
130
+ {
131
+ "include": "#escape-sequence"
132
+ },
133
+ {
81
- "name": "string.quoted.double.plum",
134
+ "include": "#string-line-continuation"
82
- "begin": "\"",
135
+ },
136
+ {
83
- "end": "\"",
137
+ "include": "#fstring-formatting"
138
+ }
139
+ ]
140
+ },
141
+ "escape-sequence-unicode": {
84
142
  "patterns": [
85
143
  {
86
144
  "name": "constant.character.escape.plum",
87
- "match": "\\\\."
145
+ "match": "(?x)\n \\\\ (\n u[0-9A-Fa-f]{4}\n | U[0-9A-Fa-f]{8}\n | N\\{[\\w\\s]+?\\}\n )\n"
88
146
  }
89
147
  ]
90
148
  },
91
- "comments": {
149
+ "escape-sequence": {
150
+ "name": "constant.character.escape.plum",
151
+ "match": "(?x)\n \\\\ (\n x[0-9A-Fa-f]{2}\n | [0-7]{1,3}\n | [\\\\\"'abfnrtv]\n )\n"
152
+ },
153
+ "string-line-continuation": {
154
+ "name": "constant.language.plum",
155
+ "match": "\\\\$"
156
+ },
157
+ "fstring-formatting": {
92
158
  "patterns": [
93
159
  {
94
- "name": "comment.line.plum",
160
+ "include": "#fstring-formatting-braces"
161
+ },
162
+ {
95
- "match": "#.*"
163
+ "include": "#fstring-formatting-singe-brace"
96
164
  }
97
165
  ]
98
166
  },
99
- "constant": {
167
+ "fstring-formatting-braces": {
100
168
  "patterns": [
101
169
  {
170
+ "comment": "empty braces are illegal",
102
- "include": "#binary_number"
171
+ "match": "({)(\\s*?)(})",
172
+ "captures": {
173
+ "1": {
174
+ "name": "constant.character.format.placeholder.other.plum"
175
+ },
176
+ "2": {
177
+ "name": "invalid.illegal.brace.plum"
178
+ },
179
+ "3": {
180
+ "name": "constant.character.format.placeholder.other.plum"
181
+ }
182
+ }
103
183
  },
104
184
  {
185
+ "name": "constant.character.escape.plum",
186
+ "match": "({{|}})"
187
+ }
188
+ ]
189
+ },
190
+ "fstring-formatting-singe-brace": {
191
+ "name": "invalid.illegal.brace.plum",
192
+ "match": "(}(?!}))"
193
+ },
194
+ "fstring-illegal-single-brace": {
195
+ "comment": "it is illegal to have a multiline brace inside a single-line string",
196
+ "begin": "(\\{)(?=[^\\n}]*$\\n?)",
197
+ "end": "(\\})|(?=\\n)",
198
+ "beginCaptures": {
199
+ "1": {
200
+ "name": "constant.character.format.placeholder.other.plum"
201
+ }
202
+ },
203
+ "endCaptures": {
204
+ "1": {
205
+ "name": "constant.character.format.placeholder.other.plum"
206
+ }
207
+ },
208
+ "patterns": [
209
+ {
105
- "include": "#octal_number"
210
+ "include": "#fstring-terminator-single"
106
211
  },
107
212
  {
108
- "include": "#hexadecimal_number"
213
+ "include": "#f-expression"
214
+ }
215
+ ]
216
+ },
217
+ "fstring-terminator-single": {
218
+ "patterns": [
219
+ {
220
+ "name": "storage.type.format.plum",
221
+ "match": "(=(![rsa])?)(?=})"
109
222
  },
110
223
  {
224
+ "name": "storage.type.format.plum",
111
- "include": "#decimal_number"
225
+ "match": "(=?![rsa])(?=})"
112
226
  },
113
227
  {
228
+ "match": "(?x)\n ( (?: =?) (?: ![rsa])? )\n ( : \\w? [<>=^]? [-+ ]? \\#?\n \\d* ,? (\\.\\d+)? [bcdeEfFgGnosxX%]? )(?=})\n",
229
+ "captures": {
230
+ "1": {
114
- "include": "#boolean"
231
+ "name": "storage.type.format.plum"
232
+ },
233
+ "2": {
234
+ "name": "storage.type.format.plum"
235
+ }
236
+ }
115
237
  },
116
238
  {
117
- "name": "entity.name.type.plum",
118
- "match": "[[:upper:]][[:alnum:]]*"
239
+ "include": "#fstring-terminator-single-tail"
240
+ }
241
+ ]
242
+ },
243
+ "fstring-terminator-single-tail": {
244
+ "begin": "((?:=?)(?:![rsa])?)(:)(?=.*?{)",
245
+ "end": "(?=})|(?=\\n)",
246
+ "beginCaptures": {
247
+ "1": {
248
+ "name": "storage.type.format.plum"
249
+ },
250
+ "2": {
251
+ "name": "storage.type.format.plum"
252
+ }
253
+ },
254
+ "patterns": [
255
+ {
256
+ "include": "#fstring-illegal-single-brace"
257
+ },
258
+ {
259
+ "include": "#fstring-single-brace"
260
+ },
261
+ {
262
+ "name": "storage.type.format.plum",
263
+ "match": "([bcdeEfFgGnosxX%])(?=})"
264
+ },
265
+ {
266
+ "name": "storage.type.format.plum",
267
+ "match": "(\\.\\d+)"
268
+ },
269
+ {
270
+ "name": "storage.type.format.plum",
271
+ "match": "(,)"
272
+ },
273
+ {
274
+ "name": "storage.type.format.plum",
275
+ "match": "(\\d+)"
276
+ },
277
+ {
278
+ "name": "storage.type.format.plum",
279
+ "match": "(\\#)"
280
+ },
281
+ {
282
+ "name": "storage.type.format.plum",
283
+ "match": "([-+ ])"
284
+ },
285
+ {
286
+ "name": "storage.type.format.plum",
287
+ "match": "([<>=^])"
288
+ },
289
+ {
290
+ "name": "storage.type.format.plum",
291
+ "match": "(\\w)"
292
+ }
293
+ ]
294
+ },
295
+ "fstring-single-brace": {
296
+ "comment": "value interpolation using { ... }",
297
+ "begin": "(\\{)",
298
+ "end": "(?x)\n (\\})|(?=\\n)\n",
299
+ "beginCaptures": {
300
+ "1": {
301
+ "name": "constant.character.format.placeholder.other.plum"
302
+ }
303
+ },
304
+ "endCaptures": {
305
+ "1": {
306
+ "name": "constant.character.format.placeholder.other.plum"
307
+ }
308
+ },
309
+ "patterns": [
310
+ {
311
+ "include": "#fstring-terminator-single"
312
+ },
313
+ {
314
+ "include": "#f-expression"
315
+ }
316
+ ]
317
+ },
318
+ "fstring-single-core": {
319
+ "name": "string.interpolated.plum string.quoted.single.plum",
320
+ "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"
321
+ },
322
+ "f-expression": {
323
+ "comment": "All valid Python expressions, except comments and line continuation",
324
+ "patterns": [
325
+ {
326
+ "include": "#expression-bare"
327
+ },
328
+ {
329
+ "include": "#member-access"
330
+ },
331
+ {
332
+ "comment": "Tokenize identifiers to help linters",
333
+ "match": "(?x) \\b ([[:alpha:]_]\\w*) \\b"
334
+ }
335
+ ]
336
+ },
337
+ "expression": {
338
+ "comment": "All valid Python expressions",
339
+ "patterns": [
340
+ {
341
+ "include": "#expression-base"
342
+ },
343
+ {
344
+ "include": "#member-access"
345
+ },
346
+ {
347
+ "comment": "Tokenize identifiers to help linters",
348
+ "match": "(?x) \\b ([[:alpha:]_]\\w*) \\b"
349
+ }
350
+ ]
351
+ },
352
+ "expression-base": {
353
+ "comment": "valid Python expressions with comments and line continuation",
354
+ "patterns": [
355
+ {
356
+ "include": "#comments"
357
+ },
358
+ {
359
+ "include": "#expression-bare"
360
+ },
361
+ {
362
+ "include": "#line-continuation"
363
+ }
364
+ ]
365
+ },
366
+ "expression-bare": {
367
+ "comment": "valid Python expressions w/o comments and line continuation",
368
+ "patterns": [
369
+ {
370
+ "include": "#number"
371
+ },
372
+ {
373
+ "include": "#string"
374
+ },
375
+ {
376
+ "include": "#operator"
377
+ },
378
+ {
379
+ "include": "#curly-braces"
380
+ },
381
+ {
382
+ "include": "#item-access"
383
+ },
384
+ {
385
+ "include": "#round-braces"
386
+ },
387
+ {
388
+ "include": "#function-call"
389
+ },
390
+ {
391
+ "include": "#special-names"
392
+ },
393
+ {
394
+ "include": "#special-variables"
395
+ },
396
+ {
397
+ "include": "#ellipsis"
398
+ }
399
+ ]
400
+ },
401
+ "round-braces": {
402
+ "begin": "\\(",
403
+ "end": "\\)",
404
+ "beginCaptures": {
405
+ "0": {
406
+ "name": "punctuation.parenthesis.begin.plum"
407
+ }
408
+ },
409
+ "endCaptures": {
410
+ "0": {
411
+ "name": "punctuation.parenthesis.end.plum"
412
+ }
413
+ },
414
+ "patterns": [
415
+ {
416
+ "include": "#expression"
417
+ }
418
+ ]
419
+ },
420
+ "ellipsis": {
421
+ "name": "constant.other.ellipsis.plum",
422
+ "match": "\\.\\.\\."
423
+ },
424
+ "number": {
425
+ "name": "constant.numeric.plum",
426
+ "patterns": [
427
+ {
428
+ "include": "#number-float"
429
+ },
430
+ {
431
+ "include": "#number-dec"
432
+ },
433
+ {
434
+ "include": "#number-hex"
435
+ },
436
+ {
437
+ "include": "#number-oct"
438
+ },
439
+ {
440
+ "include": "#number-bin"
441
+ },
442
+ {
443
+ "include": "#number-long"
444
+ },
445
+ {
446
+ "name": "invalid.illegal.name.plum",
447
+ "match": "\\b[0-9]+\\w+"
119
448
  }
120
449
  ]
121
450
  },
122
- "binary_number": {
123
- "name": "constant.numeric.binary.plum",
124
- "match": "\\b0[bB]0*1[01_]*\\b",
125
- "patterns": []
451
+ "number-float": {
452
+ "name": "constant.numeric.float.plum",
453
+ "match": "(?x)\n (?<! \\w)(?:\n (?:\n \\.[0-9](?: _?[0-9] )*\n |\n [0-9](?: _?[0-9] )* \\. [0-9](?: _?[0-9] )*\n |\n [0-9](?: _?[0-9] )* \\.\n ) (?: [eE][+-]?[0-9](?: _?[0-9] )* )?\n |\n [0-9](?: _?[0-9] )* (?: [eE][+-]?[0-9](?: _?[0-9] )* )\n )([jJ])?\\b\n",
454
+ "captures": {
455
+ "1": {
456
+ "name": "storage.type.imaginary.number.plum"
457
+ }
458
+ }
126
459
  },
127
- "octal_number": {
460
+ "number-dec": {
128
- "name": "constant.numeric.octal.plum",
461
+ "name": "constant.numeric.dec.plum",
129
- "match": "\\b0[oO]0*[1-7][0-7]*\\b",
462
+ "match": "(?x)\n (?<![\\w\\.])(?:\n [1-9](?: _?[0-9] )*\n |\n 0+\n |\n [0-9](?: _?[0-9] )* ([jJ])\n |\n 0 ([0-9]+)(?![eE\\.])\n )\\b\n",
130
- "patterns": []
463
+ "captures": {
464
+ "1": {
465
+ "name": "storage.type.imaginary.number.plum"
466
+ },
467
+ "2": {
468
+ "name": "invalid.illegal.dec.plum"
469
+ }
470
+ }
131
471
  },
132
- "decimal_number": {
472
+ "function-call": {
133
- "name": "constant.numeric.decimal.plum",
473
+ "name": "meta.function-call.plum",
474
+ "comment": "Regular function call of the type \"name(args)\"",
134
- "match": "\\b(0*[1-9][0-9_]*|0)(\\.(0*[1-9][0-9_]*|0)?(e-?0*[1-9][0-9]*)?)?\\b",
475
+ "begin": "(?x)\n \\b(?=\n ([[:alpha:]_]\\w*) \\s* (\\()\n )\n",
476
+ "end": "(\\))",
477
+ "endCaptures": {
478
+ "1": {
479
+ "name": "punctuation.definition.arguments.end.plum"
480
+ }
481
+ },
135
- "patterns": []
482
+ "patterns": [
483
+ {
484
+ "include": "#special-variables"
485
+ },
486
+ {
487
+ "include": "#function-name"
488
+ },
489
+ {
490
+ "include": "#function-arguments"
491
+ }
492
+ ]
136
493
  },
137
- "hexadecimal_number": {
494
+ "number-hex": {
138
- "name": "constant.numeric.hexadecimal.plum",
495
+ "name": "constant.numeric.hex.plum",
139
- "match": "\\b0[xX]0*[1-9a-zA-Z][0-9a-zA-Z]*\\b",
496
+ "match": "(?x)\n (?<![\\w\\.])\n (0[xX]) (_?[0-9a-fA-F])+\n \\b\n",
140
- "patterns": []
497
+ "captures": {
498
+ "1": {
499
+ "name": "storage.type.number.plum"
500
+ }
501
+ }
502
+ },
503
+ "number-oct": {
504
+ "name": "constant.numeric.oct.plum",
505
+ "match": "(?x)\n (?<![\\w\\.])\n (0[oO]) (_?[0-7])+\n \\b\n",
506
+ "captures": {
507
+ "1": {
508
+ "name": "storage.type.number.plum"
509
+ }
510
+ }
511
+ },
512
+ "number-bin": {
513
+ "name": "constant.numeric.bin.plum",
514
+ "match": "(?x)\n (?<![\\w\\.])\n (0[bB]) (_?[01])+\n \\b\n",
515
+ "captures": {
516
+ "1": {
517
+ "name": "storage.type.number.plum"
518
+ }
519
+ }
141
520
  },
142
- "string_placeholder": {
521
+ "number-long": {
522
+ "name": "constant.numeric.bin.plum",
523
+ "comment": "this is to support python2 syntax for long ints",
524
+ "match": "(?x)\n (?<![\\w\\.])\n ([1-9][0-9]* | 0) ([lL])\n \\b\n",
525
+ "captures": {
526
+ "2": {
527
+ "name": "storage.type.number.plum"
528
+ }
529
+ }
530
+ },
531
+ "function-name": {
143
532
  "patterns": [
144
533
  {
145
- "match": "%(\\[\\d+\\])?([\\+#\\-0\\x20]{,2}((\\d+|\\*)?(\\.?(\\d+|\\*|(\\[\\d+\\])\\*?)?(\\[\\d+\\])?)?))?[vT%tbcdoqxXUbeEfFgGspw]",
534
+ "comment": "Some color schemas support meta.function-call.generic scope",
146
- "name": "constant.other.placeholder.go"
535
+ "name": "meta.function-call.generic.plum",
536
+ "match": "(?x)\n \\b ([[:alpha:]_]\\w*) \\b\n"
147
537
  }
148
538
  ]
149
539
  },
150
- "raw_string_literals": {
151
- "comment": "Raw string literals",
152
- "begin": "`",
540
+ "function-arguments": {
541
+ "begin": "(\\()",
542
+ "end": "(?=\\))(?!\\)\\s*\\()",
543
+ "beginCaptures": {
544
+ "1": {
545
+ "name": "punctuation.definition.arguments.begin.plum"
546
+ }
547
+ },
548
+ "contentName": "meta.function-call.arguments.plum",
549
+ "patterns": [
550
+ {
551
+ "name": "punctuation.separator.arguments.plum",
552
+ "match": "(,)"
553
+ },
554
+ {
555
+ "match": "(?x)\n (?:(?<=[,(])|^) \\s* (\\*{1,2})\n",
556
+ "captures": {
557
+ "1": {
558
+ "name": "keyword.operator.unpacking.arguments.plum"
559
+ }
560
+ }
561
+ },
562
+ {
563
+ "include": "#lambda-incomplete"
564
+ },
565
+ {
566
+ "include": "#illegal-names"
567
+ },
568
+ {
569
+ "match": "\\b([[:alpha:]_]\\w*)\\s*(=)(?!=)",
570
+ "captures": {
571
+ "1": {
572
+ "name": "variable.parameter.function-call.plum"
573
+ },
574
+ "2": {
575
+ "name": "keyword.operator.assignment.plum"
576
+ }
577
+ }
578
+ },
579
+ {
580
+ "name": "keyword.operator.assignment.plum",
581
+ "match": "=(?!=)"
582
+ },
583
+ {
584
+ "include": "#expression"
585
+ },
586
+ {
587
+ "match": "\\s*(\\))\\s*(\\()",
588
+ "captures": {
589
+ "1": {
590
+ "name": "punctuation.definition.arguments.end.plum"
591
+ },
592
+ "2": {
593
+ "name": "punctuation.definition.arguments.begin.plum"
594
+ }
595
+ }
596
+ }
597
+ ]
598
+ },
599
+ "member-access": {
600
+ "name": "meta.member.access.plum",
601
+ "begin": "(\\.)\\s*(?!\\.)",
602
+ "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",
603
+ "beginCaptures": {
604
+ "1": {
605
+ "name": "punctuation.separator.period.plum"
606
+ }
607
+ },
608
+ "patterns": [
609
+ {
610
+ "include": "#function-call"
611
+ },
612
+ {
613
+ "include": "#member-access-base"
614
+ },
615
+ {
616
+ "include": "#member-access-attribute"
617
+ }
618
+ ]
619
+ },
620
+ "member-access-base": {
621
+ "patterns": [
622
+ {
623
+ "include": "#special-names"
624
+ },
625
+ {
626
+ "include": "#line-continuation"
627
+ },
628
+ {
629
+ "include": "#item-access"
630
+ }
631
+ ]
632
+ },
633
+ "member-access-attribute": {
634
+ "comment": "Highlight attribute access in otherwise non-specialized cases.",
635
+ "name": "meta.attribute.plum",
636
+ "match": "(?x)\n \\b ([[:alpha:]_]\\w*) \\b\n"
637
+ },
638
+ "special-names": {
639
+ "name": "constant.other.caps.plum",
640
+ "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"
641
+ },
642
+ "curly-braces": {
643
+ "begin": "\\{",
644
+ "end": "\\}",
153
645
  "beginCaptures": {
154
646
  "0": {
155
- "name": "punctuation.definition.string.begin.go"
647
+ "name": "punctuation.definition.dict.begin.plum"
156
648
  }
157
649
  },
158
- "end": "`",
159
650
  "endCaptures": {
160
651
  "0": {
161
- "name": "punctuation.definition.string.end.go"
652
+ "name": "punctuation.definition.dict.end.plum"
162
653
  }
163
654
  },
164
- "name": "string.quoted.raw.go",
165
655
  "patterns": [
166
656
  {
657
+ "include": "#expression"
658
+ }
659
+ ]
660
+ },
661
+ "item-access": {
662
+ "patterns": [
663
+ {
664
+ "name": "meta.item-access.plum",
665
+ "begin": "(?x)\n \\b(?=\n [[:alpha:]_]\\w* \\s* \\[\n )\n",
666
+ "end": "(\\])",
667
+ "endCaptures": {
668
+ "1": {
669
+ "name": "punctuation.definition.arguments.end.plum"
670
+ }
671
+ },
672
+ "patterns": [
673
+ {
674
+ "include": "#item-name"
675
+ },
676
+ {
677
+ "include": "#expression"
678
+ }
679
+ ]
680
+ }
681
+ ]
682
+ },
683
+ "item-name": {
684
+ "patterns": [
685
+ {
167
- "include": "#string_placeholder"
686
+ "include": "#special-variables"
687
+ },
688
+ {
689
+ "include": "#special-names"
690
+ },
691
+ {
692
+ "name": "meta.indexed-name.plum",
693
+ "match": "(?x)\n \\b ([[:alpha:]_]\\w*) \\b\n"
168
694
  }
169
695
  ]
170
696
  },
697
+ "special-variables": {
698
+ "match": "(?x)\n \\b (?<!\\.) (?:\n (this) | (cls)\n )\\b\n",
699
+ "captures": {
700
+ "1": {
701
+ "name": "variable.language.special.self.plum"
702
+ },
703
+ "2": {
704
+ "name": "variable.language.special.cls.plum"
705
+ }
706
+ }
707
+ },
171
708
  "entity": {
172
709
  "patterns": [
173
710
  {
174
- "begin": "\\b([[:lower:]][[:word:]]*)\\b[[:space:]]*\\(",
711
+ "begin": "\\b([[:lower:]][[:word:]]*)\\b\\(",
175
712
  "end": "\\)",
176
713
  "patterns": [
177
714
  {
@@ -191,10 +728,6 @@
191
728
  {
192
729
  "name": "entity.name.namespace.plum",
193
730
  "match": "\\b([[:lower:]][[:word:]]*):"
194
- },
195
- {
196
- "name": "entity.name.namespace.plum",
197
- "match": "\\b(doc|check|expect|where)\\b"
198
731
  }
199
732
  ]
200
733
  },