Add associative map constraints and range refinement

This commit is contained in:
2026-08-14 06:26:15 +09:00
parent 8198b615a8
commit cc6ab40807
52 changed files with 8951 additions and 6918 deletions
@@ -182,3 +182,31 @@ Array constraints
left: (identifier)
right: (comparison_constraint
value: (integer))))))))
==================
Map constraint and ascription
==================
{
services = {
api = { port = 8080; };
} as {...{ port = Int; }};
}
---
(source_file
(object
(field_definition
path: (field_path (identifier))
value: (as_expression
narrower: (object
(field_definition
path: (field_path (identifier))
value: (object
(field_definition
path: (field_path (identifier))
value: (literal (integer))))))
wider: (map_constraint
value: (object
(field_definition
path: (field_path (identifier))
value: (identifier))))))))
+18 -2
View File
@@ -2,6 +2,7 @@
// doc/manual/souce/language/grammar.md.
const PREC = {
AS: 0,
DEFAULT: 1,
PATCH: 2,
COMPOSE: 3,
@@ -53,6 +54,7 @@ module.exports = grammar({
$.identifier,
$.regex_literal,
$.comparison_constraint,
$.map_constraint,
$.object,
$.array_constraint,
$.array,
@@ -66,6 +68,7 @@ module.exports = grammar({
$.unary_expression,
$.binary_expression,
$.default_expression,
$.as_expression,
),
literal: $ => choice(
@@ -100,6 +103,13 @@ module.exports = grammar({
'}',
),
map_constraint: $ => seq(
'{',
'...',
field('value', $._expression),
'}',
),
field_definition: $ => seq(
field('path', $.field_path),
'=',
@@ -125,12 +135,12 @@ module.exports = grammar({
']',
),
let_expression: $ => seq(
let_expression: $ => prec.right(seq(
'let',
repeat(seq($.field_definition, ';')),
'in',
field('body', $._expression),
),
)),
function_expression: $ => prec.right(seq(
'(',
@@ -237,5 +247,11 @@ module.exports = grammar({
'default',
field('fallback', $._expression),
)),
as_expression: $ => prec.left(PREC.AS, seq(
field('narrower', $._expression),
'as',
field('wider', $._expression),
)),
},
});
@@ -12,6 +12,7 @@
"match"
"import"
"default"
"as"
] @keyword
[
+100 -34
View File
@@ -91,6 +91,10 @@
"type": "SYMBOL",
"name": "comparison_constraint"
},
{
"type": "SYMBOL",
"name": "map_constraint"
},
{
"type": "SYMBOL",
"name": "object"
@@ -142,6 +146,10 @@
{
"type": "SYMBOL",
"name": "default_expression"
},
{
"type": "SYMBOL",
"name": "as_expression"
}
]
},
@@ -319,6 +327,31 @@
}
]
},
"map_constraint": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "{"
},
{
"type": "STRING",
"value": "..."
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "STRING",
"value": "}"
}
]
},
"field_definition": {
"type": "SEQ",
"members": [
@@ -469,41 +502,45 @@
]
},
"let_expression": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "let"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "field_definition"
},
{
"type": "STRING",
"value": ";"
}
]
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "let"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "field_definition"
},
{
"type": "STRING",
"value": ";"
}
]
}
},
{
"type": "STRING",
"value": "in"
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
},
{
"type": "STRING",
"value": "in"
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
]
}
},
"function_expression": {
"type": "PREC_RIGHT",
@@ -1298,6 +1335,35 @@
}
]
}
},
"as_expression": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "narrower",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "STRING",
"value": "as"
},
{
"type": "FIELD",
"name": "wider",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
}
},
"extras": [
+424 -2
View File
@@ -15,6 +15,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -51,6 +55,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -94,6 +102,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -130,6 +142,180 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
},
{
"type": "object",
"named": true
},
{
"type": "parenthesized_expression",
"named": true
},
{
"type": "path_expression",
"named": true
},
{
"type": "regex_literal",
"named": true
},
{
"type": "unary_expression",
"named": true
}
]
}
}
},
{
"type": "as_expression",
"named": true,
"fields": {
"narrower": {
"multiple": false,
"required": true,
"types": [
{
"type": "array",
"named": true
},
{
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
},
{
"type": "call_expression",
"named": true
},
{
"type": "comparison_constraint",
"named": true
},
{
"type": "default_expression",
"named": true
},
{
"type": "function_expression",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "import_expression",
"named": true
},
{
"type": "let_expression",
"named": true
},
{
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
},
{
"type": "object",
"named": true
},
{
"type": "parenthesized_expression",
"named": true
},
{
"type": "path_expression",
"named": true
},
{
"type": "regex_literal",
"named": true
},
{
"type": "unary_expression",
"named": true
}
]
},
"wider": {
"multiple": false,
"required": true,
"types": [
{
"type": "array",
"named": true
},
{
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
},
{
"type": "call_expression",
"named": true
},
{
"type": "comparison_constraint",
"named": true
},
{
"type": "default_expression",
"named": true
},
{
"type": "function_expression",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "import_expression",
"named": true
},
{
"type": "let_expression",
"named": true
},
{
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -174,6 +360,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -210,6 +400,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -314,6 +508,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -350,6 +548,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -399,6 +601,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -435,6 +641,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -474,6 +684,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -510,6 +724,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -575,6 +793,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -611,6 +833,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -655,6 +881,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -691,6 +921,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -729,6 +963,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -765,6 +1003,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -819,6 +1061,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -855,6 +1101,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -914,6 +1164,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -950,6 +1204,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -1020,6 +1278,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -1056,6 +1318,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -1122,10 +1388,10 @@
}
},
{
"type": "match_arm",
"type": "map_constraint",
"named": true,
"fields": {
"body": {
"value": {
"multiple": false,
"required": true,
"types": [
@@ -1137,6 +1403,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -1173,6 +1443,98 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
},
{
"type": "object",
"named": true
},
{
"type": "parenthesized_expression",
"named": true
},
{
"type": "path_expression",
"named": true
},
{
"type": "regex_literal",
"named": true
},
{
"type": "unary_expression",
"named": true
}
]
}
}
},
{
"type": "match_arm",
"named": true,
"fields": {
"body": {
"multiple": false,
"required": true,
"types": [
{
"type": "array",
"named": true
},
{
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
},
{
"type": "call_expression",
"named": true
},
{
"type": "comparison_constraint",
"named": true
},
{
"type": "default_expression",
"named": true
},
{
"type": "function_expression",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "import_expression",
"named": true
},
{
"type": "let_expression",
"named": true
},
{
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -1215,6 +1577,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -1251,6 +1617,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -1295,6 +1665,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -1331,6 +1705,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -1400,6 +1778,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -1436,6 +1818,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -1490,6 +1876,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -1526,6 +1916,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -1579,6 +1973,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -1615,6 +2013,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -1659,6 +2061,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -1699,6 +2105,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -1742,6 +2152,10 @@
"type": "array_constraint",
"named": true
},
{
"type": "as_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
@@ -1778,6 +2192,10 @@
"type": "literal",
"named": true
},
{
"type": "map_constraint",
"named": true
},
{
"type": "match_expression",
"named": true
@@ -1928,6 +2346,10 @@
"type": "_",
"named": false
},
{
"type": "as",
"named": false
},
{
"type": "comment",
"named": true
+6764 -6735
View File
File diff suppressed because it is too large Load Diff