plum

#treesitter#compiler#wasm

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

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


ca4e97c — Peter John 2022-11-11T22:32:15+05:30
improve grammar

Generated files not shown: src/parser.c

.github/workflows/ci.yml ADDED
@@ -0,0 +1,22 @@
1
+ name: Build/test
2
+ on:
3
+ pull_request:
4
+ branches:
5
+ - "**"
6
+ push:
7
+ branches:
8
+ - "master"
9
+ jobs:
10
+ test:
11
+ runs-on: ${{ matrix.os }}
12
+ strategy:
13
+ fail-fast: true
14
+ matrix:
15
+ os: [macos-latest, ubuntu-latest, windows-latest]
16
+ steps:
17
+ - uses: actions/checkout@v2
18
+ - uses: actions/setup-node@v2
19
+ with:
20
+ node-version: 16
21
+ - run: npm install
22
+ - run: npm test
examples/Logger.kt ADDED
@@ -0,0 +1,182 @@
1
+ package logger
2
+
3
+ import github/pine/io
4
+ import github/pine/util
5
+ import github/pine/time
6
+
7
+
8
+ val log = Logger()
9
+
10
+ @cache
11
+ fun log() => Logger {
12
+ return Logger()
13
+ }
14
+
15
+ @Handler
16
+ class JULRedirector(
17
+ val downstream: Logger
18
+ )
19
+
20
+ fun JULRedirector.publish(record: LogRecord) => {
21
+ when (record.level) {
22
+ Level.SEVERE -> downstream.error(record.message)
23
+ Level.WARNING -> downstream.warn(record.message)
24
+ Level.INFO -> downstream.info(record.message)
25
+ Level.CONFIG -> downstream.debug(record.message)
26
+ Level.FINE -> downstream.trace(record.message)
27
+ else -> downstream.deepTrace(record.message)
28
+ }
29
+ }
30
+
31
+ fun JULRedirector.flush() => {}
32
+
33
+ fun JULRedirector.close() => {}
34
+
35
+ enum class LogLevel(val value: Int) {
36
+ NONE(100),
37
+ ERROR(2),
38
+ WARN(1),
39
+ INFO(0),
40
+ DEBUG(-1),
41
+ TRACE(-2),
42
+ DEEP_TRACE(-3),
43
+ ALL(-100)
44
+ }
45
+
46
+ class LogMessage(
47
+ val level: LogLevel,
48
+ val message: String
49
+ )
50
+
51
+ fun LogMessage.formatted() => String {
52
+ return "[$level] $message"
53
+ }
54
+
55
+ class Logger(
56
+ var outBackend: ((LogMessage) -> Unit)? = null,
57
+ var errBackend: ((LogMessage) -> Unit)? = null,
58
+ val outQueue: Queue<LogMessage> = ArrayDeque(),
59
+ val errQueue: Queue<LogMessage> = ArrayDeque(),
60
+ val newline: String = System.lineSeparator(),
61
+ val logTime: Bool = false,
62
+ var level: LogLevel = LogLevel.INFO,
63
+ )
64
+
65
+ fun Logger.outputError(msg: LogMessage) => {
66
+ if (errBackend == null) {
67
+ errQueue.offer(msg)
68
+ } else {
69
+ errBackend?.invoke(msg)
70
+ }
71
+ }
72
+
73
+ fun Logger.output(msg: LogMessage) => {
74
+ if (outBackend == null) {
75
+ outQueue.offer(msg)
76
+ } else {
77
+ outBackend?.invoke(msg)
78
+ }
79
+ }
80
+
81
+ fun Logger.log(msgLevel: LogLevel, msg: String, placeholders: Array<out Any?>) => {
82
+ if (level.value <= msgLevel.value) {
83
+ output(LogMessage(msgLevel, format(insertPlaceholders(msg, placeholders))))
84
+ }
85
+ }
86
+
87
+ fun Logger.error(msg: String, vararg placeholders: Any?) => {
88
+ log(LogLevel.ERROR, msg, placeholders)
89
+ }
90
+
91
+ fun Logger.warn(msg: String, vararg placeholders: Any?) => {
92
+ log(LogLevel.WARN, msg, placeholders)
93
+ }
94
+
95
+ fun Logger.info(msg: String, vararg placeholders: Any?) => {
96
+ log(LogLevel.INFO, msg, placeholders)
97
+ }
98
+
99
+ fun Logger.debug(msg: String, vararg placeholders: Any?) => {
100
+ log(LogLevel.DEBUG, msg, placeholders)
101
+ }
102
+
103
+ fun Logger.trace(msg: String, vararg placeholders: Any?) => {
104
+ log(LogLevel.TRACE, msg, placeholders)
105
+ }
106
+
107
+ fun Logger.deepTrace(msg: String, vararg placeholders: Any?) => {
108
+ log(LogLevel.DEEP_TRACE, msg, placeholders)
109
+ }
110
+
111
+ fun Logger.connectJULFrontend() => {
112
+ val rootLogger = java.util.logging.Logger.getLogger("")
113
+ rootLogger.addHandler(JULRedirector(this))
114
+ }
115
+
116
+ fun Logger.connectOutputBackend(outBackend: (LogMessage) -> Unit) => {
117
+ this.outBackend = outBackend
118
+ flushOutQueue()
119
+ }
120
+
121
+ fun Logger.connectErrorBackend(errBackend: (LogMessage) -> Unit) => {
122
+ this.errBackend = errBackend
123
+ flushErrQueue()
124
+ }
125
+
126
+ fun Logger.connectStdioBackend() => {
127
+ connectOutputBackend { println(it.formatted) }
128
+ connectOutputBackend { System.err.println(it.formatted) }
129
+ }
130
+
131
+ fun Logger.insertPlaceholders(msg: String, placeholders: Array<out Any?>) => String {
132
+ val msgLength = msg.length
133
+ val lastIndex = msgLength - 1
134
+ var charIndex = 0
135
+ var placeholderIndex = 0
136
+ var result = StringBuilder()
137
+
138
+ while (charIndex < msgLength) {
139
+ val currentChar = msg.get(charIndex)
140
+ val nextChar = if (charIndex != lastIndex) msg.get(charIndex + 1) else '?'
141
+ if ((currentChar == '{') && (nextChar == '}')) {
142
+ if (placeholderIndex >= placeholders.size) {
143
+ return "ERROR: Tried to log more '{}' placeholders than there are values"
144
+ }
145
+ result.append(placeholders[placeholderIndex] ?: "null")
146
+ placeholderIndex += 1
147
+ charIndex += 2
148
+ } else {
149
+ result.append(currentChar)
150
+ charIndex += 1
151
+ }
152
+ }
153
+
154
+ return result.toString()
155
+ }
156
+
157
+ fun Logger.flushOutQueue() => {
158
+ while (outQueue.isNotEmpty()) {
159
+ outBackend?.invoke(outQueue.poll())
160
+ }
161
+ }
162
+
163
+ fun Logger.flushErrQueue() => {
164
+ while (errQueue.isNotEmpty()) {
165
+ errBackend?.invoke(errQueue.poll())
166
+ }
167
+ }
168
+
169
+ fun Logger.format(msg: String) => String {
170
+ val time = if (logTime) "${Instant.now()} " else ""
171
+ var thread = Thread.currentThread().name
172
+
173
+ return time + shortenOrPad(thread, 10) + msg
174
+ }
175
+
176
+ fun Logger.shortenOrPad(str: String, length: Int) => String {
177
+ if (str.length <= length) {
178
+ return str.padEnd(length, ' ')
179
+ } else {
180
+ return ".." + str.substring(str.length - length + 2)
181
+ }
182
+ }
examples/all.kt ADDED
@@ -0,0 +1,115 @@
1
+ import github.com/std/http
2
+
3
+ enum Color(val rgb: Int) {
4
+ RED(0xFF0000),
5
+ GREEN(0x00FF00),
6
+ BLUE(0x0000FF)
7
+ }
8
+
9
+ fun Color.isReddish() => Bool {
10
+ return this == Color.Red
11
+ }
12
+
13
+ trait List(
14
+ val name: String
15
+ fun area(): Float
16
+ )
17
+
18
+ class Email(value: String)
19
+
20
+ fun Email.init() => {
21
+ if !value.match("/s\@/s") {
22
+ throw error("Email not value ${value}")
23
+ }
24
+ }
25
+
26
+ class Array<T>(
27
+ var items: []T,
28
+ var size: Int
29
+ )
30
+
31
+ fun Array<T>.get(index: Int): T => {
32
+ return items[int]
33
+ }
34
+
35
+ fun Array<T>.set(index: Int, value: T) => {
36
+ items[i] = value
37
+ }
38
+
39
+ fun listOf<T>(elements: ...T): List<T> => {
40
+ return Array(elements)
41
+ }
42
+
43
+ class User(
44
+ val name: String,
45
+ val age: Int,
46
+ val email: Email,
47
+ )
48
+
49
+ fun User.init() => {
50
+ assert(name.size > 5, "name is not valid")
51
+ assert(age > 0 && age < 130, "age is not valid")
52
+ assert(email.test("regex"), "email is not valid")
53
+ }
54
+
55
+ fun User.invoke() => {
56
+ println("Hello")
57
+ listOf(0, 1, 2, 3).map { "Number ${it}" }
58
+ range(0, 10, 1).each { i, v ->
59
+ echo i, v
60
+ }
61
+ }
62
+
63
+ fun User.getFullName() => String {
64
+ return "${name} 123"
65
+ }
66
+
67
+ @Get("/about")
68
+ fun about() => HtmlNode {
69
+ val sir = "John"
70
+ html {
71
+ head {
72
+ title {
73
+ "Tesla"
74
+ }
75
+ }
76
+ body {
77
+ div {
78
+ "Welcome ${sir}"
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ fun main(args: List<String>) => {
85
+ println(hello)
86
+ val items = args?
87
+ .map { it.name }
88
+ .filter { it.isVerified }
89
+ .each { it -> it.name } ?: listOf()
90
+ val john = User("John", 2)
91
+ val jill = User(name = "Jill", age = 3)
92
+ val jack = john.copy(age = 5)
93
+ val (name, age) = jack
94
+ // Pair, Triple
95
+
96
+ val name2 = jill?.let {
97
+ it.name + "123"
98
+ }
99
+
100
+ jill?.run {
101
+ println(it)
102
+ }
103
+
104
+
105
+ names.each { name, i ->
106
+ println(name, i)
107
+ }
108
+
109
+ TODO()
110
+
111
+ when message {
112
+ New -> println("new $id: $quantity")
113
+ Cancel -> println("cancel $id")
114
+ }
115
+ }
grammar.js CHANGED
@@ -2,10 +2,40 @@ const DEC_DIGITS = token(sep1(/[0-9]+/, /_+/));
2
2
  const HEX_DIGITS = token(sep1(/[0-9a-fA-F]+/, /_+/));
3
3
  const BIN_DIGITS = token(sep1(/[01]/, /_+/));
4
4
 
5
+ const PREC = {
6
+ POSTFIX: 16,
7
+ PREFIX: 15,
8
+ TYPE_RHS: 14,
9
+ AS: 13,
10
+ MULTIPLICATIVE: 12,
11
+ ADDITIVE: 11,
12
+ RANGE: 10,
13
+ INFIX: 9,
14
+ ELVIS: 8,
15
+ CHECK: 7,
16
+ COMPARISON: 6,
17
+ EQUALITY: 5,
18
+ CONJUNCTION: 4,
19
+ DISJUNCTION: 3,
20
+ SPREAD: 2,
21
+ SIMPLE_USER_TYPE: 2,
22
+ VAR_DECL: 1,
23
+ ASSIGNMENT: 1,
24
+ BLOCK: 1,
25
+ LAMBDA_LITERAL: 0,
26
+ RETURN_OR_THROW: 0,
27
+ COMMENT: 0
28
+ };
29
+
5
30
  module.exports = grammar({
6
31
  name: 'pine',
7
32
  conflicts: $ => [
8
33
  [$.fun_field],
34
+ [$.decorator_name],
35
+ ],
36
+ extras: $ => [
37
+ $.comment,
38
+ /\s+/ // Whitespace
9
39
  ],
10
40
  rules: {
11
41
  source_file: $ => seq(
@@ -16,6 +46,8 @@ module.exports = grammar({
16
46
 
17
47
  import_statement: $ => seq('import', $.url),
18
48
 
49
+ // Definitions
50
+
19
51
  definitions: $ => choice(
20
52
  $.class_definition,
21
53
  $.trait_definition,
@@ -24,10 +56,11 @@ module.exports = grammar({
24
56
  ),
25
57
 
26
58
  class_definition: $ => seq(
27
- field('traits', optional(repeat($.trait_name))),
59
+ field('decorators', optional(repeat($.decorator_name))),
28
60
  'class',
29
61
  field('name', $.definition_name),
30
62
  field('generics', optional($.generic_list)),
63
+ field('traits', optional($.trait_list)),
31
64
  field('fields', seq('(', commaSep1($.type_field), ')')),
32
65
  ),
33
66
 
@@ -46,20 +79,21 @@ module.exports = grammar({
46
79
  ),
47
80
 
48
81
  fun_definition: $ => seq(
82
+ field('decorators', optional(repeat($.decorator_name))),
49
83
  'fun',
50
84
  field('name', choice($.identifier, $._extension)),
85
+ field('generics', optional($.generic_list)),
51
86
  field('params', seq('(', optional(commaSep1($.param)), ')')),
52
87
  '=>',
53
88
  field('returns', optional(commaSep1($.type))),
54
- '{', '}',
89
+ field('body', $._block)
55
90
  ),
56
91
 
57
- trait_name: $ => seq("@", $.definition_name),
92
+ decorator_name: $ => seq("@", $.identifier, '(', optional(commaSep1($._primary_expression)), ')'),
58
93
 
59
94
  trait_list: $ => seq(
60
- '(',
95
+ ':',
61
- commaSep1($.identifier),
96
+ commaSep1($.definition_name),
62
- ')'
63
97
  ),
64
98
 
65
99
  generic_list: $ => seq(
@@ -98,6 +132,172 @@ module.exports = grammar({
98
132
 
99
133
  enum_field: $ => seq($.enum_field_name, '(', commaSep1($._primary_expression), ')'),
100
134
 
135
+ // Expressions
136
+
137
+ _block: $ => prec(PREC.BLOCK, seq(
138
+ "{",
139
+ // optional($.statements),
140
+ "}"
141
+ )),
142
+
143
+ // statements: $ => seq(
144
+ // $._statement,
145
+ // ),
146
+
147
+ // _statement: $ => choice(
148
+ // choice(
149
+ // $.assignment,
150
+ // $._loop_statement,
151
+ // $._expression
152
+ // )
153
+ // ),
154
+
155
+ // _loop_statement: $ => choice(
156
+ // $.for_statement,
157
+ // $.while_statement,
158
+ // ),
159
+
160
+ // for_statement: $ => prec.right(seq(
161
+ // "for",
162
+ // "(",
163
+ // repeat($.annotation),
164
+ // choice($.variable_declaration, $.multi_variable_declaration),
165
+ // "in",
166
+ // $._expression,
167
+ // ")",
168
+ // optional($.control_structure_body)
169
+ // )),
170
+
171
+ // while_statement: $ => seq(
172
+ // "while",
173
+ // "(",
174
+ // $._expression,
175
+ // ")",
176
+ // choice(";", $.control_structure_body)
177
+ // ),
178
+
179
+ // assignment: $ => choice(
180
+ // prec.left(PREC.ASSIGNMENT, seq($.directly_assignable_expression, $._assignment_and_operator, $._expression)),
181
+ // prec.left(PREC.ASSIGNMENT, seq($.directly_assignable_expression, "=", $._expression)),
182
+ // // TODO
183
+ // ),
184
+
185
+ // // ==========
186
+ // // Expressions
187
+ // // ==========
188
+
189
+ // _expression: $ => choice(
190
+ // $._unary_expression,
191
+ // $._binary_expression,
192
+ // $._primary_expression
193
+ // ),
194
+
195
+ // // Unary expressions
196
+
197
+ // _unary_expression: $ => choice(
198
+ // $.postfix_expression,
199
+ // $.call_expression,
200
+ // $.indexing_expression,
201
+ // $.navigation_expression,
202
+ // $.prefix_expression,
203
+ // $.as_expression,
204
+ // $.spread_expression
205
+ // ),
206
+
207
+ // postfix_expression: $ => prec.left(PREC.POSTFIX, seq($._expression, $._postfix_unary_operator)),
208
+
209
+ // call_expression: $ => prec.left(PREC.POSTFIX, seq($._expression, $.call_suffix)),
210
+
211
+ // indexing_expression: $ => prec.left(PREC.POSTFIX, seq($._expression, $.indexing_suffix)),
212
+
213
+ // navigation_expression: $ => prec.left(PREC.POSTFIX, seq($._expression, $.navigation_suffix)),
214
+
215
+ // prefix_expression: $ => prec.right(seq(choice($.annotation, $.label, $._prefix_unary_operator), $._expression)),
216
+
217
+ // as_expression: $ => prec.left(PREC.AS, seq($._expression, $._as_operator, $._type)),
218
+
219
+ // spread_expression: $ => prec.left(PREC.SPREAD, seq("*", $._expression)),
220
+
221
+ // _binary_expression: $ => choice(
222
+ // $.multiplicative_expression,
223
+ // $.additive_expression,
224
+ // $.range_expression,
225
+ // $.infix_expression,
226
+ // $.elvis_expression,
227
+ // $.check_expression,
228
+ // $.comparison_expression,
229
+ // $.equality_expression,
230
+ // $.comparison_expression,
231
+ // $.equality_expression,
232
+ // $.conjunction_expression,
233
+ // $.disjunction_expression
234
+ // ),
235
+
236
+ // multiplicative_expression: $ => prec.left(PREC.MULTIPLICATIVE, seq($._expression, $._multiplicative_operator, $._expression)),
237
+
238
+ // additive_expression: $ => prec.left(PREC.ADDITIVE, seq($._expression, $._additive_operator, $._expression)),
239
+
240
+ // range_expression: $ => prec.left(PREC.RANGE, seq($._expression, "..", $._expression)),
241
+
242
+ // infix_expression: $ => prec.left(PREC.INFIX, seq($._expression, $.simple_identifier, $._expression)),
243
+
244
+ // elvis_expression: $ => prec.left(PREC.ELVIS, seq($._expression, "?:", $._expression)),
245
+
246
+ // check_expression: $ => prec.left(PREC.CHECK, seq($._expression, choice(
247
+ // seq($._in_operator, $._expression),
248
+ // seq($._is_operator, $._type)))),
249
+
250
+ // comparison_expression: $ => prec.left(PREC.COMPARISON, seq($._expression, $._comparison_operator, $._expression)),
251
+
252
+ // equality_expression: $ => prec.left(PREC.EQUALITY, seq($._expression, $._equality_operator, $._expression)),
253
+
254
+ // conjunction_expression: $ => prec.left(PREC.CONJUNCTION, seq($._expression, "&&", $._expression)),
255
+
256
+ // disjunction_expression: $ => prec.left(PREC.DISJUNCTION, seq($._expression, "||", $._expression)),
257
+
258
+ // // Suffixes
259
+
260
+ // indexing_suffix: $ => seq("[", sep1($._expression, ","), "]"),
261
+
262
+ // navigation_suffix: $ => seq(
263
+ // $._member_access_operator,
264
+ // choice(
265
+ // $.simple_identifier,
266
+ // $.parenthesized_expression,
267
+ // "class"
268
+ // )
269
+ // ),
270
+
271
+ // call_suffix: $ => prec.left(seq(
272
+ // // this introduces ambiguities with 'less than' for comparisons
273
+ // optional($.type_arguments),
274
+ // choice(
275
+ // seq(optional($.value_arguments), $.annotated_lambda),
276
+ // $.value_arguments
277
+ // )
278
+ // )),
279
+
280
+ // variable_declaration: $ => prec.left(PREC.VAR_DECL, seq(
281
+ // // repeat($.annotation), TODO
282
+ // $.simple_identifier,
283
+ // optional(seq(":", $._type))
284
+ // )),
285
+
286
+ // function_type: $ => seq(
287
+ // optional(seq($._simple_user_type, ".")), // TODO: Support "real" types
288
+ // $.function_type_parameters,
289
+ // "->",
290
+ // $._type
291
+ // ),
292
+
293
+ // function_type_parameters: $ => prec.left(1, seq(
294
+ // "(",
295
+ // optional(sep1(choice($.parameter, $._type), ",")),
296
+ // ")"
297
+ // )),
298
+
299
+ // parenthesized_type: $ => seq("(", $._type, ")"),
300
+
101
301
  _primary_expression: $ => choice(
102
302
  $._literal_constant,
103
303
  $._string_literal,
@@ -180,6 +380,10 @@ module.exports = grammar({
180
380
  $.float_literal,
181
381
  "null",
182
382
  ),
383
+
384
+ comment: $ => token(prec(PREC.COMMENT, choice(
385
+ seq("#", /.*/),
386
+ ))),
183
387
  }
184
388
  });
185
389
 
package.json CHANGED
@@ -1,20 +1,24 @@
1
1
  {
2
2
  "name": "tree-sitter-pine",
3
- "version": "1.0.0",
3
+ "version": "0.1.0",
4
4
  "main": "bindings/node",
5
- "description": "Pine grammar for tree-sitter",
5
+ "description": "Tree-Sitter grammar for pine",
6
6
  "scripts": {
7
+ "test": "tree-sitter test",
8
+ "install": "node-gyp rebuild",
7
- "build": "tree-sitter generate && node-gyp build",
9
+ "generate": "tree-sitter generate",
8
- "test": "tree-sitter test && script/parse-examples",
9
10
  "parse": "tree-sitter parse",
10
- "test-windows": "tree-sitter test"
11
+ "build-wasm": "tree-sitter build-wasm",
12
+ "playground": "tree-sitter playground"
11
13
  },
12
14
  "author": "pyrossh",
13
15
  "license": "MIT",
14
16
  "keywords": [
17
+ "tree-sitter",
18
+ "pine",
19
+ "grammar",
15
20
  "parser",
16
- "lexer",
21
+ "lexer"
17
- "pine"
18
22
  ],
19
23
  "dependencies": {
20
24
  "nan": "^2.17.0"
src/grammar.json CHANGED
@@ -72,7 +72,7 @@
72
72
  "members": [
73
73
  {
74
74
  "type": "FIELD",
75
- "name": "traits",
75
+ "name": "decorators",
76
76
  "content": {
77
77
  "type": "CHOICE",
78
78
  "members": [
@@ -80,7 +80,7 @@
80
80
  "type": "REPEAT",
81
81
  "content": {
82
82
  "type": "SYMBOL",
83
- "name": "trait_name"
83
+ "name": "decorator_name"
84
84
  }
85
85
  },
86
86
  {
@@ -117,6 +117,22 @@
117
117
  ]
118
118
  }
119
119
  },
120
+ {
121
+ "type": "FIELD",
122
+ "name": "traits",
123
+ "content": {
124
+ "type": "CHOICE",
125
+ "members": [
126
+ {
127
+ "type": "SYMBOL",
128
+ "name": "trait_list"
129
+ },
130
+ {
131
+ "type": "BLANK"
132
+ }
133
+ ]
134
+ }
135
+ },
120
136
  {
121
137
  "type": "FIELD",
122
138
  "name": "fields",
@@ -340,6 +356,25 @@
340
356
  "fun_definition": {
341
357
  "type": "SEQ",
342
358
  "members": [
359
+ {
360
+ "type": "FIELD",
361
+ "name": "decorators",
362
+ "content": {
363
+ "type": "CHOICE",
364
+ "members": [
365
+ {
366
+ "type": "REPEAT",
367
+ "content": {
368
+ "type": "SYMBOL",
369
+ "name": "decorator_name"
370
+ }
371
+ },
372
+ {
373
+ "type": "BLANK"
374
+ }
375
+ ]
376
+ }
377
+ },
343
378
  {
344
379
  "type": "STRING",
345
380
  "value": "fun"
@@ -361,6 +396,22 @@
361
396
  ]
362
397
  }
363
398
  },
399
+ {
400
+ "type": "FIELD",
401
+ "name": "generics",
402
+ "content": {
403
+ "type": "CHOICE",
404
+ "members": [
405
+ {
406
+ "type": "SYMBOL",
407
+ "name": "generic_list"
408
+ },
409
+ {
410
+ "type": "BLANK"
411
+ }
412
+ ]
413
+ }
414
+ },
364
415
  {
365
416
  "type": "FIELD",
366
417
  "name": "params",
@@ -453,16 +504,16 @@
453
504
  }
454
505
  },
455
506
  {
507
+ "type": "FIELD",
508
+ "name": "body",
509
+ "content": {
456
- "type": "STRING",
510
+ "type": "SYMBOL",
457
- "value": "{"
511
+ "name": "_block"
458
- },
512
+ }
459
- {
460
- "type": "STRING",
461
- "value": "}"
462
513
  }
463
514
  ]
464
515
  },
465
- "trait_name": {
516
+ "decorator_name": {
466
517
  "type": "SEQ",
467
518
  "members": [
468
519
  {
@@ -471,7 +522,48 @@
471
522
  },
472
523
  {
473
524
  "type": "SYMBOL",
474
- "name": "definition_name"
525
+ "name": "identifier"
526
+ },
527
+ {
528
+ "type": "STRING",
529
+ "value": "("
530
+ },
531
+ {
532
+ "type": "CHOICE",
533
+ "members": [
534
+ {
535
+ "type": "SEQ",
536
+ "members": [
537
+ {
538
+ "type": "SYMBOL",
539
+ "name": "_primary_expression"
540
+ },
541
+ {
542
+ "type": "REPEAT",
543
+ "content": {
544
+ "type": "SEQ",
545
+ "members": [
546
+ {
547
+ "type": "STRING",
548
+ "value": ","
549
+ },
550
+ {
551
+ "type": "SYMBOL",
552
+ "name": "_primary_expression"
553
+ }
554
+ ]
555
+ }
556
+ }
557
+ ]
558
+ },
559
+ {
560
+ "type": "BLANK"
561
+ }
562
+ ]
563
+ },
564
+ {
565
+ "type": "STRING",
566
+ "value": ")"
475
567
  }
476
568
  ]
477
569
  },
@@ -480,14 +572,14 @@
480
572
  "members": [
481
573
  {
482
574
  "type": "STRING",
483
- "value": "("
575
+ "value": ":"
484
576
  },
485
577
  {
486
578
  "type": "SEQ",
487
579
  "members": [
488
580
  {
489
581
  "type": "SYMBOL",
490
- "name": "identifier"
582
+ "name": "definition_name"
491
583
  },
492
584
  {
493
585
  "type": "REPEAT",
@@ -500,16 +592,12 @@
500
592
  },
501
593
  {
502
594
  "type": "SYMBOL",
503
- "name": "identifier"
595
+ "name": "definition_name"
504
596
  }
505
597
  ]
506
598
  }
507
599
  }
508
600
  ]
509
- },
510
- {
511
- "type": "STRING",
512
- "value": ")"
513
601
  }
514
602
  ]
515
603
  },
@@ -789,6 +877,23 @@
789
877
  }
790
878
  ]
791
879
  },
880
+ "_block": {
881
+ "type": "PREC",
882
+ "value": 1,
883
+ "content": {
884
+ "type": "SEQ",
885
+ "members": [
886
+ {
887
+ "type": "STRING",
888
+ "value": "{"
889
+ },
890
+ {
891
+ "type": "STRING",
892
+ "value": "}"
893
+ }
894
+ ]
895
+ }
896
+ },
792
897
  "_primary_expression": {
793
898
  "type": "CHOICE",
794
899
  "members": [
@@ -1364,17 +1469,49 @@
1364
1469
  "value": "null"
1365
1470
  }
1366
1471
  ]
1472
+ },
1473
+ "comment": {
1474
+ "type": "TOKEN",
1475
+ "content": {
1476
+ "type": "PREC",
1477
+ "value": 0,
1478
+ "content": {
1479
+ "type": "CHOICE",
1480
+ "members": [
1481
+ {
1482
+ "type": "SEQ",
1483
+ "members": [
1484
+ {
1485
+ "type": "STRING",
1486
+ "value": "#"
1487
+ },
1488
+ {
1489
+ "type": "PATTERN",
1490
+ "value": ".*"
1491
+ }
1492
+ ]
1493
+ }
1494
+ ]
1495
+ }
1496
+ }
1367
1497
  }
1368
1498
  },
1369
1499
  "extras": [
1500
+ {
1501
+ "type": "SYMBOL",
1502
+ "name": "comment"
1503
+ },
1370
1504
  {
1371
1505
  "type": "PATTERN",
1372
- "value": "\\s"
1506
+ "value": "\\s+"
1373
1507
  }
1374
1508
  ],
1375
1509
  "conflicts": [
1376
1510
  [
1377
1511
  "fun_field"
1512
+ ],
1513
+ [
1514
+ "decorator_name"
1378
1515
  ]
1379
1516
  ],
1380
1517
  "precedences": [],
src/node-types.json CHANGED
@@ -28,6 +28,16 @@
28
28
  "type": "class_definition",
29
29
  "named": true,
30
30
  "fields": {
31
+ "decorators": {
32
+ "multiple": true,
33
+ "required": false,
34
+ "types": [
35
+ {
36
+ "type": "decorator_name",
37
+ "named": true
38
+ }
39
+ ]
40
+ },
31
41
  "fields": {
32
42
  "multiple": true,
33
43
  "required": true,
@@ -71,17 +81,64 @@
71
81
  ]
72
82
  },
73
83
  "traits": {
74
- "multiple": true,
84
+ "multiple": false,
75
85
  "required": false,
76
86
  "types": [
77
87
  {
78
- "type": "trait_name",
88
+ "type": "trait_list",
79
89
  "named": true
80
90
  }
81
91
  ]
82
92
  }
83
93
  }
84
94
  },
95
+ {
96
+ "type": "decorator_name",
97
+ "named": true,
98
+ "fields": {},
99
+ "children": {
100
+ "multiple": true,
101
+ "required": true,
102
+ "types": [
103
+ {
104
+ "type": "bin_literal",
105
+ "named": true
106
+ },
107
+ {
108
+ "type": "boolean_literal",
109
+ "named": true
110
+ },
111
+ {
112
+ "type": "character_literal",
113
+ "named": true
114
+ },
115
+ {
116
+ "type": "float_literal",
117
+ "named": true
118
+ },
119
+ {
120
+ "type": "hex_literal",
121
+ "named": true
122
+ },
123
+ {
124
+ "type": "identifier",
125
+ "named": true
126
+ },
127
+ {
128
+ "type": "integer_literal",
129
+ "named": true
130
+ },
131
+ {
132
+ "type": "line_string_literal",
133
+ "named": true
134
+ },
135
+ {
136
+ "type": "multi_line_string_literal",
137
+ "named": true
138
+ }
139
+ ]
140
+ }
141
+ },
85
142
  {
86
143
  "type": "definitions",
87
144
  "named": true,
@@ -220,6 +277,40 @@
220
277
  "type": "fun_definition",
221
278
  "named": true,
222
279
  "fields": {
280
+ "body": {
281
+ "multiple": true,
282
+ "required": true,
283
+ "types": [
284
+ {
285
+ "type": "{",
286
+ "named": false
287
+ },
288
+ {
289
+ "type": "}",
290
+ "named": false
291
+ }
292
+ ]
293
+ },
294
+ "decorators": {
295
+ "multiple": true,
296
+ "required": false,
297
+ "types": [
298
+ {
299
+ "type": "decorator_name",
300
+ "named": true
301
+ }
302
+ ]
303
+ },
304
+ "generics": {
305
+ "multiple": false,
306
+ "required": false,
307
+ "types": [
308
+ {
309
+ "type": "generic_list",
310
+ "named": true
311
+ }
312
+ ]
313
+ },
223
314
  "name": {
224
315
  "multiple": true,
225
316
  "required": true,
@@ -530,11 +621,11 @@
530
621
  }
531
622
  },
532
623
  {
533
- "type": "trait_name",
624
+ "type": "trait_list",
534
625
  "named": true,
535
626
  "fields": {},
536
627
  "children": {
537
- "multiple": false,
628
+ "multiple": true,
538
629
  "required": true,
539
630
  "types": [
540
631
  {
@@ -662,6 +753,10 @@
662
753
  "type": "class",
663
754
  "named": false
664
755
  },
756
+ {
757
+ "type": "comment",
758
+ "named": true
759
+ },
665
760
  {
666
761
  "type": "definition_name",
667
762
  "named": true
test/corpus/class_definitions.txt CHANGED
@@ -68,8 +68,7 @@ Class definitions - Traits
68
68
 
69
69
  package definitions
70
70
 
71
- @B @C
72
- class AnimalSubSpecies (
71
+ class AnimalSubSpecies : B, C (
73
72
  val a: String,
74
73
  val b: Float
75
74
  )
@@ -81,11 +80,10 @@ class AnimalSubSpecies (
81
80
  (identifier))
82
81
  (definitions
83
82
  (class_definition
84
- (trait_name
85
- (definition_name))
86
- (trait_name
87
- (definition_name))
88
83
  (definition_name)
84
+ (trait_list
85
+ (definition_name)
86
+ (definition_name))
89
87
  (type_field
90
88
  (variable_name)
91
89
  (type
@@ -101,8 +99,7 @@ Class definitions - Genrics + Traits
101
99
 
102
100
  package definitions
103
101
 
104
- @B @C
105
- class A<S, T>(
102
+ class A<S, T>: B, C (
106
103
  val a: S,
107
104
  val b: T
108
105
  )
@@ -114,14 +111,13 @@ class A<S, T>(
114
111
  (identifier))
115
112
  (definitions
116
113
  (class_definition
117
- (trait_name
118
- (definition_name))
119
- (trait_name
120
- (definition_name))
121
114
  (definition_name)
122
115
  (generic_list
123
116
  (identifier)
124
117
  (identifier))
118
+ (trait_list
119
+ (definition_name)
120
+ (definition_name))
125
121
  (type_field
126
122
  (variable_name)
127
123
  (type
test/corpus/enum_definitions.txt CHANGED
@@ -4,9 +4,9 @@ Enum definitions - Int
4
4
 
5
5
  package definitions
6
6
 
7
- enum Colors(val rgb: Int) {
7
+ enum Colors(val rgb: Int) { # define colors here
8
8
  RED(0xFF0000),
9
- GREEN(0x00FF00),
9
+ GREEN(0x00FF00), # this needs to sorted
10
10
  BLUE(0x0000FF)
11
11
  }
12
12
 
@@ -22,12 +22,14 @@ enum Colors(val rgb: Int) {
22
22
  (variable_name)
23
23
  (type
24
24
  (definition_name)))
25
+ (comment)
25
26
  (enum_field
26
27
  (enum_field_name)
27
28
  (hex_literal))
28
29
  (enum_field
29
30
  (enum_field_name)
30
31
  (hex_literal))
32
+ (comment)
31
33
  (enum_field
32
34
  (enum_field_name)
33
35
  (hex_literal)))))
test/corpus/functions.txt CHANGED
@@ -22,7 +22,7 @@ Functions - Extension
22
22
 
23
23
  package definitions
24
24
 
25
- fun User.main() => {
25
+ fun User.fullName() => {
26
26
  }
27
27
 
28
28
  --------------------------------------------------------------------------------
@@ -64,6 +64,73 @@ fun add(a: Int, b: Int) => Int {
64
64
  (type
65
65
  (definition_name)))))
66
66
 
67
+ ================================================================================
68
+ Functions - Generics
69
+ ================================================================================
70
+
71
+ package definitions
72
+
73
+ fun add<S, T>(a: S, b: T) => S {
74
+ }
75
+
76
+ --------------------------------------------------------------------------------
77
+
78
+ (source_file
79
+ (package
80
+ (identifier))
81
+ (definitions
82
+ (fun_definition
83
+ (identifier)
84
+ (generic_list
85
+ (identifier)
86
+ (identifier))
87
+ (param
88
+ (variable_name)
89
+ (type
90
+ (definition_name)))
91
+ (param
92
+ (variable_name)
93
+ (type
94
+ (definition_name)))
95
+ (type
96
+ (definition_name)))))
97
+
98
+ ================================================================================
99
+ Functions - Decorators
100
+ ================================================================================
101
+
102
+ package definitions
103
+
104
+ @cache(1000)
105
+ @get()
106
+ fun add(a: Int, b: Int) => Int {
107
+ }
108
+
109
+ --------------------------------------------------------------------------------
110
+
111
+ (source_file
112
+ (package
113
+ (identifier))
114
+ (definitions
115
+ (fun_definition
116
+ (decorator_name
117
+ (identifier)
118
+ (integer_literal))
119
+ (decorator_name
120
+ (identifier))
121
+ (identifier)
122
+ (param
123
+ (variable_name)
124
+ (type
125
+ (definition_name)))
126
+ (param
127
+ (variable_name)
128
+ (type
129
+ (definition_name)))
130
+ (type
131
+ (definition_name)))))
132
+
133
+
67
134
  ================================================================================
68
135
  Functions - High Order 1
69
136
  ================================================================================
test/corpus/import_statements.txt CHANGED
@@ -4,7 +4,7 @@ Import statements
4
4
 
5
5
  package imports
6
6
 
7
- import github/pyros2097/std
7
+ import github/pine/std # importing std library here
8
8
 
9
9
  --------------------------------------------------------------------------------
10
10
 
@@ -12,4 +12,5 @@ import github/pyros2097/std
12
12
  (package
13
13
  (identifier))
14
14
  (import_statement
15
- (url)))
15
+ (url))
16
+ (comment))