1
0

Add array and set comprehensions

This commit is contained in:
Jip J. Dekker 2021-01-10 23:07:13 +11:00
parent d65b8593a3
commit d096c1f831
5 changed files with 5384 additions and 3974 deletions

View File

@ -1,3 +1,71 @@
===================
Array Comprehension
===================
simple = [ i | i in X ];
where = [ i | i in X where i == 2 ];
multiple = [ i | i in X, j in Y where i == j];
---
(source_file
(assignment (identifier) (array_comprehension (identifier) (generator (identifier) (identifier))))
(assignment (identifier) (array_comprehension (identifier) (generator (identifier) (identifier) (infix_operator (identifier) (integer_literal)))))
(assignment (identifier) (array_comprehension (identifier) (generator (identifier) (identifier)) (generator (identifier) (identifier) (infix_operator (identifier) (identifier))))))
====
Call
====
no_args = my_fn();
single_arg = my_fn(1);
mult_args = my_fn(2, "test");
---
(source_file
(assignment (identifier) (call (identifier)))
(assignment (identifier) (call (identifier) (integer_literal)))
(assignment (identifier) (call (identifier) (integer_literal) (string_literal))))
============
If-Then-Else
============
if_only = if b then i < j endif;
value_select = if b then i else j endif;
elseif = if b then i elseif c then j else k endif;
elseif_no_else = if b then i < j elseif c then j > i endif;
---
(source_file
(assignment (identifier) (if_then_else (identifier) (infix_operator (identifier) (identifier))))
(assignment (identifier) (if_then_else (identifier) (identifier) (identifier)))
(assignment (identifier) (if_then_else (identifier) (identifier) (identifier) (identifier) (identifier)))
(assignment (identifier) (if_then_else (identifier) (infix_operator (identifier) (identifier)) (identifier) (infix_operator (identifier) (identifier)))))
============
Index Access
============
named_colection = my_collection[1];
named_accessor = my_collection[i];
literal_collection = [1,2,3][i];
multiple_accessor = my_collection[i,2];
expression_accessor = my_collection[-i + 2];
slice = my_collection[1..2];
---
(source_file
(assignment (identifier) (indexed_access (identifier) (integer_literal)))
(assignment (identifier) (indexed_access (identifier) (identifier)))
(assignment (identifier) (indexed_access (array_literal (integer_literal) (integer_literal) (integer_literal)) (identifier)))
(assignment (identifier) (indexed_access (identifier) (identifier) (integer_literal)))
(assignment (identifier) (indexed_access (identifier) (infix_operator (prefix_operator (identifier)) (integer_literal))))
(assignment (identifier) (indexed_access (identifier) (infix_operator (integer_literal) (integer_literal)))))
==============
Infix Operator
==============
@ -55,59 +123,6 @@ or = x \/ y;
(assignment (identifier) (infix_operator (identifier) (identifier)))
(assignment (identifier) (infix_operator (identifier) (identifier))))
====
Call
====
no_args = my_fn();
single_arg = my_fn(1);
mult_args = my_fn(2, "test");
---
(source_file
(assignment (identifier) (call (identifier)))
(assignment (identifier) (call (identifier) (integer_literal)))
(assignment (identifier) (call (identifier) (integer_literal) (string_literal))))
================
If-Then-Else
================
if_only = if b then i < j endif;
value_select = if b then i else j endif;
elseif = if b then i elseif c then j else k endif;
elseif_no_else = if b then i < j elseif c then j > i endif;
---
(source_file
(assignment (identifier) (if_then_else (identifier) (infix_operator (identifier) (identifier))))
(assignment (identifier) (if_then_else (identifier) (identifier) (identifier)))
(assignment (identifier) (if_then_else (identifier) (identifier) (identifier) (identifier) (identifier)))
(assignment (identifier) (if_then_else (identifier) (infix_operator (identifier) (identifier)) (identifier) (infix_operator (identifier) (identifier)))))
============
Index Access
============
named_colection = my_collection[1];
named_accessor = my_collection[i];
literal_collection = [1,2,3][i];
multiple_accessor = my_collection[i,2];
expression_accessor = my_collection[-i + 2];
slice = my_collection[1..2];
---
(source_file
(assignment (identifier) (indexed_access (identifier) (integer_literal)))
(assignment (identifier) (indexed_access (identifier) (identifier)))
(assignment (identifier) (indexed_access (array_literal (integer_literal) (integer_literal) (integer_literal)) (identifier)))
(assignment (identifier) (indexed_access (identifier) (identifier) (integer_literal)))
(assignment (identifier) (indexed_access (identifier) (infix_operator (prefix_operator (identifier)) (integer_literal))))
(assignment (identifier) (indexed_access (identifier) (infix_operator (integer_literal) (integer_literal)))))
===========
Precedences
===========
@ -142,3 +157,18 @@ unicode_negation = ¬ b;
(assignment (identifier) (prefix_operator (identifier)))
(assignment (identifier) (prefix_operator (boolean_literal)))
(assignment (identifier) (prefix_operator (identifier))))
=================
Set Comprehension
=================
simple = { i | i in X };
where = { i | i in X where i == 2 };
multiple = { i | i in X, j in Y where i == j};
---
(source_file
(assignment (identifier) (set_comprehension (identifier) (generator (identifier) (identifier))))
(assignment (identifier) (set_comprehension (identifier) (generator (identifier) (identifier) (infix_operator (identifier) (integer_literal)))))
(assignment (identifier) (set_comprehension (identifier) (generator (identifier) (identifier)) (generator (identifier) (identifier) (infix_operator (identifier) (identifier))))))

View File

@ -43,15 +43,48 @@ module.exports = grammar({
$.identifier,
$._literal,
$.array_comprehension,
$.call,
$.if_then_else,
$.indexed_access,
$.infix_operator,
$.prefix_operator,
$.set_comprehension,
// TODO: Other expression types
seq('(', $._expression, ')'),
),
array_comprehension: $ => seq(
'[', $._expression, '|', sepBy1(',', $.generator), ']',
),
call: $ => prec(PREC.call, seq(
field('name', $.identifier),
'(',
field('arguments', sepBy(',', $._expression)),
')',
)),
generator: $ => seq(
$.identifier, 'in', $._expression,
optional(seq('where', $._expression))
),
if_then_else: $ => seq(
"if", $._expression,
"then", $._expression,
repeat(seq("elseif", $._expression, "then", $._expression)),
optional(seq("else", $._expression)),
"endif",
),
indexed_access: $ => prec(PREC.call, seq(
field('collection', $._expression),
'[',
field('indices', seq($._expression, repeat(seq(',', $._expression)))),
']',
)),
infix_operator: $ => {
const table = [
[prec.left, PREC.equivalence, '<->'],
@ -80,33 +113,15 @@ module.exports = grammar({
))));
},
call: $ => prec(PREC.call, seq(
field('name', $.identifier),
'(',
field('arguments', sepBy(',', $._expression)),
')',
)),
if_then_else: $ => seq(
"if", $._expression,
"then", $._expression,
repeat(seq("elseif", $._expression, "then", $._expression)),
optional(seq("else", $._expression)),
"endif",
),
indexed_access: $ => prec(PREC.call, seq(
field('collection', $._expression),
'[',
field('indices', seq($._expression, repeat(seq(',', $._expression)))),
']',
)),
prefix_operator: $ => prec(PREC.unary, seq(
field('operator', choice('-', 'not', '¬')),
$._expression
)),
set_comprehension: $ => seq(
'{', $._expression, '|', sepBy1(',', $.generator), '}',
),
_literal: $ => choice(
$.absent,
$.array_literal,
@ -163,3 +178,7 @@ module.exports = grammar({
function sepBy(sep, rule) {
return seq(repeat(seq(rule, sep)), optional(rule))
}
function sepBy1(sep, rule) {
return seq(rule, repeat(seq(sep, rule)), optional(sep))
}

534
src/grammar.json vendored
View File

@ -85,6 +85,10 @@
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "SYMBOL",
"name": "array_comprehension"
},
{
"type": "SYMBOL",
"name": "call"
@ -105,6 +109,10 @@
"type": "SYMBOL",
"name": "prefix_operator"
},
{
"type": "SYMBOL",
"name": "set_comprehension"
},
{
"type": "SEQ",
"members": [
@ -124,6 +132,288 @@
}
]
},
"array_comprehension": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "["
},
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "STRING",
"value": "|"
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "generator"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "generator"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
},
{
"type": "STRING",
"value": "]"
}
]
},
"call": {
"type": "PREC",
"value": 15,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
},
{
"type": "STRING",
"value": "("
},
{
"type": "FIELD",
"name": "arguments",
"content": {
"type": "SEQ",
"members": [
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "STRING",
"value": ","
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "BLANK"
}
]
}
]
}
},
{
"type": "STRING",
"value": ")"
}
]
}
},
"generator": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "STRING",
"value": "in"
},
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "where"
},
{
"type": "SYMBOL",
"name": "_expression"
}
]
},
{
"type": "BLANK"
}
]
}
]
},
"if_then_else": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "if"
},
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "STRING",
"value": "then"
},
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "elseif"
},
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "STRING",
"value": "then"
},
{
"type": "SYMBOL",
"name": "_expression"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "else"
},
{
"type": "SYMBOL",
"name": "_expression"
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "endif"
}
]
},
"indexed_access": {
"type": "PREC",
"value": 15,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "collection",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "STRING",
"value": "["
},
{
"type": "FIELD",
"name": "indices",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_expression"
}
]
}
}
]
}
},
{
"type": "STRING",
"value": "]"
}
]
}
},
"infix_operator": {
"type": "CHOICE",
"members": [
@ -704,192 +994,6 @@
}
]
},
"call": {
"type": "PREC",
"value": 15,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
},
{
"type": "STRING",
"value": "("
},
{
"type": "FIELD",
"name": "arguments",
"content": {
"type": "SEQ",
"members": [
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "STRING",
"value": ","
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "BLANK"
}
]
}
]
}
},
{
"type": "STRING",
"value": ")"
}
]
}
},
"if_then_else": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "if"
},
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "STRING",
"value": "then"
},
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "elseif"
},
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "STRING",
"value": "then"
},
{
"type": "SYMBOL",
"name": "_expression"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "else"
},
{
"type": "SYMBOL",
"name": "_expression"
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "endif"
}
]
},
"indexed_access": {
"type": "PREC",
"value": 15,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "collection",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "STRING",
"value": "["
},
{
"type": "FIELD",
"name": "indices",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_expression"
}
]
}
}
]
}
},
{
"type": "STRING",
"value": "]"
}
]
}
},
"prefix_operator": {
"type": "PREC",
"value": 13,
@ -924,6 +1028,64 @@
]
}
},
"set_comprehension": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "{"
},
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "STRING",
"value": "|"
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "generator"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "generator"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
},
{
"type": "STRING",
"value": "}"
}
]
},
"_literal": {
"type": "CHOICE",
"members": [

311
src/node-types.json vendored
View File

@ -1,4 +1,79 @@
[
{
"type": "array_comprehension",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "absent",
"named": true
},
{
"type": "array_comprehension",
"named": true
},
{
"type": "array_literal",
"named": true
},
{
"type": "boolean_literal",
"named": true
},
{
"type": "call",
"named": true
},
{
"type": "float_literal",
"named": true
},
{
"type": "generator",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "if_then_else",
"named": true
},
{
"type": "indexed_access",
"named": true
},
{
"type": "infix_operator",
"named": true
},
{
"type": "integer_literal",
"named": true
},
{
"type": "prefix_operator",
"named": true
},
{
"type": "set_comprehension",
"named": true
},
{
"type": "set_literal",
"named": true
},
{
"type": "string_literal",
"named": true
}
]
}
},
{
"type": "array_literal",
"named": true,
@ -11,6 +86,10 @@
"type": "absent",
"named": true
},
{
"type": "array_comprehension",
"named": true
},
{
"type": "array_literal",
"named": true
@ -51,6 +130,10 @@
"type": "prefix_operator",
"named": true
},
{
"type": "set_comprehension",
"named": true
},
{
"type": "set_literal",
"named": true
@ -82,6 +165,10 @@
"type": "absent",
"named": true
},
{
"type": "array_comprehension",
"named": true
},
{
"type": "array_literal",
"named": true
@ -122,6 +209,10 @@
"type": "prefix_operator",
"named": true
},
{
"type": "set_comprehension",
"named": true
},
{
"type": "set_literal",
"named": true
@ -173,6 +264,10 @@
"type": "absent",
"named": true
},
{
"type": "array_comprehension",
"named": true
},
{
"type": "array_literal",
"named": true
@ -213,6 +308,10 @@
"type": "prefix_operator",
"named": true
},
{
"type": "set_comprehension",
"named": true
},
{
"type": "set_literal",
"named": true
@ -236,7 +335,7 @@
}
},
{
"type": "if_then_else",
"type": "generator",
"named": true,
"fields": {},
"children": {
@ -247,6 +346,10 @@
"type": "absent",
"named": true
},
{
"type": "array_comprehension",
"named": true
},
{
"type": "array_literal",
"named": true
@ -287,6 +390,81 @@
"type": "prefix_operator",
"named": true
},
{
"type": "set_comprehension",
"named": true
},
{
"type": "set_literal",
"named": true
},
{
"type": "string_literal",
"named": true
}
]
}
},
{
"type": "if_then_else",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "absent",
"named": true
},
{
"type": "array_comprehension",
"named": true
},
{
"type": "array_literal",
"named": true
},
{
"type": "boolean_literal",
"named": true
},
{
"type": "call",
"named": true
},
{
"type": "float_literal",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "if_then_else",
"named": true
},
{
"type": "indexed_access",
"named": true
},
{
"type": "infix_operator",
"named": true
},
{
"type": "integer_literal",
"named": true
},
{
"type": "prefix_operator",
"named": true
},
{
"type": "set_comprehension",
"named": true
},
{
"type": "set_literal",
"named": true
@ -318,6 +496,10 @@
"type": "absent",
"named": true
},
{
"type": "array_comprehension",
"named": true
},
{
"type": "array_literal",
"named": true
@ -358,6 +540,10 @@
"type": "prefix_operator",
"named": true
},
{
"type": "set_comprehension",
"named": true
},
{
"type": "set_literal",
"named": true
@ -388,6 +574,10 @@
"type": "absent",
"named": true
},
{
"type": "array_comprehension",
"named": true
},
{
"type": "array_literal",
"named": true
@ -428,6 +618,10 @@
"type": "prefix_operator",
"named": true
},
{
"type": "set_comprehension",
"named": true
},
{
"type": "set_literal",
"named": true
@ -460,6 +654,10 @@
"type": "absent",
"named": true
},
{
"type": "array_comprehension",
"named": true
},
{
"type": "array_literal",
"named": true
@ -500,6 +698,10 @@
"type": "prefix_operator",
"named": true
},
{
"type": "set_comprehension",
"named": true
},
{
"type": "set_literal",
"named": true
@ -652,6 +854,10 @@
"type": "absent",
"named": true
},
{
"type": "array_comprehension",
"named": true
},
{
"type": "array_literal",
"named": true
@ -692,6 +898,10 @@
"type": "prefix_operator",
"named": true
},
{
"type": "set_comprehension",
"named": true
},
{
"type": "set_literal",
"named": true
@ -735,6 +945,10 @@
"type": "absent",
"named": true
},
{
"type": "array_comprehension",
"named": true
},
{
"type": "array_literal",
"named": true
@ -775,6 +989,85 @@
"type": "prefix_operator",
"named": true
},
{
"type": "set_comprehension",
"named": true
},
{
"type": "set_literal",
"named": true
},
{
"type": "string_literal",
"named": true
}
]
}
},
{
"type": "set_comprehension",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "absent",
"named": true
},
{
"type": "array_comprehension",
"named": true
},
{
"type": "array_literal",
"named": true
},
{
"type": "boolean_literal",
"named": true
},
{
"type": "call",
"named": true
},
{
"type": "float_literal",
"named": true
},
{
"type": "generator",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "if_then_else",
"named": true
},
{
"type": "indexed_access",
"named": true
},
{
"type": "infix_operator",
"named": true
},
{
"type": "integer_literal",
"named": true
},
{
"type": "prefix_operator",
"named": true
},
{
"type": "set_comprehension",
"named": true
},
{
"type": "set_literal",
"named": true
@ -798,6 +1091,10 @@
"type": "absent",
"named": true
},
{
"type": "array_comprehension",
"named": true
},
{
"type": "array_literal",
"named": true
@ -838,6 +1135,10 @@
"type": "prefix_operator",
"named": true
},
{
"type": "set_comprehension",
"named": true
},
{
"type": "set_literal",
"named": true
@ -1075,6 +1376,10 @@
"type": "union",
"named": false
},
{
"type": "where",
"named": false
},
{
"type": "xor",
"named": false
@ -1083,6 +1388,10 @@
"type": "{",
"named": false
},
{
"type": "|",
"named": false
},
{
"type": "}",
"named": false

8314
src/parser.c vendored

File diff suppressed because it is too large Load Diff