This commit is contained in:
2025-09-21 22:14:29 +02:00
parent 13d459f594
commit c70e53905a
7 changed files with 23920 additions and 23402 deletions

View File

@@ -1,3 +1,16 @@
# beginner-friendly-lang # Crepuscular
beginner friendly (more than python!) functional programming language beginner friendly (more than python!) functional programming language
## Bugs
Anything that looks like a bug, is probably a bug; PLEASE report it!!
## Repository structure
- [Language specification](./spec.md)
- [Reference tree-sitter parser](./tree-sitter/)
## Language proposals
Just open a Gitea issue

View File

@@ -358,14 +358,18 @@ def add = a -> b -> a + b
- `func(arg1, arg2)`: function application. requires at least one argument. partial function applications are allowed too - `func(arg1, arg2)`: function application. requires at least one argument. partial function applications are allowed too
- `func(_, arg)`: bind some args from function, return funciton taking in the args with `_`, or the non-specified ones - `func(_, arg)`: bind some args from function, return funciton taking in the args with `_`, or the non-specified ones
- `expr :: type`: down-cast type - `expr :: type`: down-cast type
- `recExpr and otherRecExpr`: "sum" fields together of both record expressions. - `recExpr and otherRecExpr`:
if both types are record types, or tagged record types:
- "sum" fields together of both record expressions.
type checking: phi-unify `recExpr` with `otherRecExpr`, and require that both are non-nominal record types type checking: phi-unify `recExpr` with `otherRecExpr`, and require that both are non-nominal record types
- else: identical to `\`a and b\`(a, b)`
- `if cond then a else b` - `if cond then a else b`
- `{field1: val1, field2: val2}` field construction - `{field1: val1, field2: val2}` field construction
- `match expr with <match cases>`: [pattern matching](##pattern-matching) - `match expr with <match cases>`: [pattern matching](##pattern-matching)
- `'Tag expr` - `'Tag expr`
- `a = b` the [equality operator](##equality-operator) - `a = b` the [equality operator](##equality-operator)
- `-a`: identical to `\`-a\`(a)` name: "negate" - `-a`: identical to `\`-a\`(a)` name: "negate"
- `a or b`: identical to `\`a or b\`(a, b)` name: "or"
- `a ^ b`: identical to `\`a^b\`(a, b)` name: "exponent" - `a ^ b`: identical to `\`a^b\`(a, b)` name: "exponent"
- `a + b`: identical to `\`a+b\`(a, b)` name: "sum" - `a + b`: identical to `\`a+b\`(a, b)` name: "sum"
- `a - b`: identical to `\`a-b\`(a, b)` name: "difference" - `a - b`: identical to `\`a-b\`(a, b)` name: "difference"

View File

@@ -35,7 +35,7 @@ module.exports = grammar({
"negate", "negate",
"addition", "addition",
"concat", "concat",
"with", "binary_boolean",
"equal", "equal",
"if", "if",
"let", "let",
@@ -50,7 +50,10 @@ module.exports = grammar({
source_file: $ => repeat($.definition), source_file: $ => repeat($.definition),
_identifier_tok: $ => token(/[a-zA-Z_]+[a-zA-Z0-9_]*/), _identifier_tok: $ => token(/[a-zA-Z_]+[a-zA-Z0-9_]*/),
identifier: $ => reserved('toplevel_kw', $._identifier_tok), identifier: $ => choice(
reserved('toplevel_kw', $._identifier_tok),
token(/`[^\n\`]+`/)
),
path: $ => prec.left(seq($.identifier, repeat(seq('.', $.identifier)))), path: $ => prec.left(seq($.identifier, repeat(seq('.', $.identifier)))),
comment: $ => comment: $ =>
@@ -289,12 +292,6 @@ module.exports = grammar({
field('body', $.expression) field('body', $.expression)
)), )),
and_expr: $ => prec.left("with",
seq(
field('left', $.expression),
'and',
field('right', $.atom))),
if_expr: $ => prec("if", if_expr: $ => prec("if",
seq( seq(
'if', 'if',
@@ -304,27 +301,57 @@ module.exports = grammar({
'else', 'else',
field('else', $.expression))), field('else', $.expression))),
sub_expr: $ => prec.left("addition", _add_expr: $ => prec.left("addition",
seq(field('left', $.expression), '-', field('right', $.expression))), seq(
add_expr: $ => prec.left("addition", field('left', $.expression),
seq(field('left', $.expression), '+', field('right', $.expression))), choice('+', '-'),
field('right', $.expression)
)),
divide_expr: $ => prec.left("multiplication", _multiply_expr: $ => prec.left("multiplication",
seq(field('left', $.expression), '/', field('right', $.expression))), seq(
multiply_expr: $ => prec.left("multiplication", field('left', $.expression),
seq(field('left', $.expression), '*', field('right', $.expression))), choice('*', '/'),
field('right', $.expression)
)),
equal_expr: $ => prec.left("equal", _equal_expr: $ => prec.left("equal",
seq(field('left', $.expression), '=', field('right', $.expression))), seq(
field('left', $.expression),
'=',
field('right', $.expression)
)),
concat_expr: $ => prec.left("concat", _concat_expr: $ => prec.left("concat",
seq(field('left', $.expression), '++', field('right', $.expression))), seq(
field('left', $.expression),
choice('++', '=>'),
field('right', $.expression)
)),
compose_expr: $ => prec.left("concat", _exponent_expr: $ => prec.left("exponent",
seq(field('left', $.expression), '=>', field('right', $.expression))), seq(
field('left', $.expression),
'^',
field('right', $.atom)
)),
exponent_expr: $ => prec.left("exponent", _bin_bool_expr: $ => prec.left("binary_boolean",
seq(field('left', $.expression), '^', field('right', $.atom))), seq(
field('left', $.expression),
choice('and', 'or'),
field('right', $.atom)
)),
binary_expr: $ => choice(
$._exponent_expr,
$._concat_expr,
$._equal_expr,
$._multiply_expr,
$._add_expr,
$._bin_bool_expr,
),
match_arm: $ => prec("match_arm", match_arm: $ => prec("match_arm",
seq( seq(
@@ -336,8 +363,10 @@ module.exports = grammar({
field('arm', $.match_arm), field('arm', $.match_arm),
prec("new_match_arm", repeat(seq('|', field('arm', $.match_arm))))), prec("new_match_arm", repeat(seq('|', field('arm', $.match_arm))))),
negate_expr: $ => prec.right("negate", unary_expr: $ => prec.right("negate",
seq('-', field('expr', $.expression))), seq(
'-',
field('expr', $.expression))),
tag_expr: $ => prec.right("tag", tag_expr: $ => prec.right("tag",
seq( seq(
@@ -354,20 +383,12 @@ module.exports = grammar({
$.await_expr, $.await_expr,
$.type_downcast, $.type_downcast,
$.lambda, $.lambda,
$.and_expr,
$.if_expr, $.if_expr,
$.tag_expr, $.tag_expr,
$.match_expr, $.match_expr,
$.add_expr, $.binary_expr,
$.sub_expr, $.unary_expr,
$.divide_expr,
$.multiply_expr,
$.concat_expr,
$.compose_expr,
$.equal_expr,
$.exponent_expr,
$.negate_expr,
), ),
def: $ => seq( def: $ => seq(

View File

@@ -20,30 +20,40 @@
value: (_) @prepend_indent_start @append_indent_end value: (_) @prepend_indent_start @append_indent_end
body: (_) @prepend_hardline) body: (_) @prepend_hardline)
; TODO: report assertion error ; TODO: (await_binding)
;(await_binding
; body: (_) @prepend_hardline)
(def (def
":" @prepend_space @append_spaced_softline ":" @prepend_space @append_spaced_softline
signature: (_) @prepend_spaced_softline @prepend_indent_start @append_indent_end) signature: (_) @prepend_spaced_softline @prepend_indent_start @append_indent_end)
(def (def
"=" @prepend_space @append_spaced_softline @append_indent_start "=" @prepend_space @append_spaced_softline
value: (_) @append_indent_end) value: (_) @prepend_indent_start @prepend_begin_scope
@append_indent_end @append_end_scope
(#scope_id! "def"))
(def "def" @append_space) (def "def" @append_space)
(if_expr
then: (_) @prepend_begin_scope @append_end_scope
(#scope_id! "if_expr.then"))
(if_expr
else: (_) @prepend_begin_scope @append_end_scope
(#scope_id! "if_expr.else"))
(if_expr (if_expr
"if" @prepend_space @append_space "if" @prepend_space @append_space
"then" @prepend_space @append_spaced_softline "then" @prepend_space @append_spaced_softline
then: (_) @prepend_indent_start @append_indent_end @append_hardline then: (_) @prepend_indent_start
@append_indent_end @append_hardline
"else" @prepend_space @append_spaced_softline "else" @prepend_space @append_spaced_softline
else: (_) @prepend_indent_start @append_indent_end) else: (_) @prepend_indent_start
@append_indent_end)
((match_arm) @append_hardline . (match_arm)) ((match_arm) @append_hardline . (match_arm))
(match_arm (match_arm
"->" @append_spaced_softline @prepend_indent_start @append_indent_end) "->" @append_spaced_softline @prepend_indent_start @append_indent_end)
(match_arm
"|" @prepend_spaced_softline @append_space)
(match_expr (match_expr
"|" @append_space) "|" @append_space)
(match_expr (match_expr
@@ -56,14 +66,11 @@
(list_expression (list_expression
"," @append_spaced_softline) "," @append_spaced_softline)
(list_expression
"[" @append_empty_softline
"]" @prepend_empty_softline)
(list_expression) @prepend_space @append_space
(atom (list_expression
"(" @append_empty_softline "[" @append_begin_scope @append_empty_softline @append_indent_start
")" @prepend_empty_softline) "]" @append_end_scope @prepend_empty_softline @append_indent_end
(#scope_id! "list_expr"))
(extensible_union (extensible_union
"extensible" @append_space "extensible" @append_space
@@ -105,8 +112,36 @@
"{" @append_empty_softline "{" @append_empty_softline
"}" @prepend_empty_softline) "}" @prepend_empty_softline)
; TODO: unify binary exprs (atom
; TODO: scopes "(" @append_begin_scope @append_empty_softline @append_indent_start
; TODO: non-atom exprs ")" @append_end_scope @prepend_empty_softline @append_indent_end
(#scope_id! "paren_expr"))
(await_expr
"await" @append_space)
(type_downcast
"::" @prepend_spaced_softline @append_space)
(lambda
":" @prepend_space @append_space)
(lambda
"->" @prepend_space @append_spaced_softline
body: (_) @prepend_indent_start @append_indent_end)
(type_atom
"(" @append_begin_scope @append_empty_softline @append_indent_start
")" @append_end_scope @prepend_empty_softline @append_indent_end
(#scope_id! "paren_type"))
(tag_expr
tag: (_) @append_space)
(binary_expr
left: (_) @append_spaced_softline
right: (_) @prepend_space)
; TODO: types ; TODO: types
; TODO: disable format regions ; TODO: disable-format-regions
; TODO: folding query

View File

@@ -18,6 +18,9 @@
} }
}, },
"identifier": { "identifier": {
"type": "CHOICE",
"members": [
{
"type": "RESERVED", "type": "RESERVED",
"content": { "content": {
"type": "SYMBOL", "type": "SYMBOL",
@@ -25,6 +28,15 @@
}, },
"context_name": "toplevel_kw" "context_name": "toplevel_kw"
}, },
{
"type": "TOKEN",
"content": {
"type": "PATTERN",
"value": "`[^\\n\\`]+`"
}
}
]
},
"path": { "path": {
"type": "PREC_LEFT", "type": "PREC_LEFT",
"value": 0, "value": 0,
@@ -1410,35 +1422,6 @@
] ]
} }
}, },
"and_expr": {
"type": "PREC_LEFT",
"value": "with",
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "expression"
}
},
{
"type": "STRING",
"value": "and"
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "atom"
}
}
]
}
},
"if_expr": { "if_expr": {
"type": "PREC", "type": "PREC",
"value": "if", "value": "if",
@@ -1484,7 +1467,7 @@
] ]
} }
}, },
"sub_expr": { "_add_expr": {
"type": "PREC_LEFT", "type": "PREC_LEFT",
"value": "addition", "value": "addition",
"content": { "content": {
@@ -1499,66 +1482,17 @@
} }
}, },
{ {
"type": "STRING", "type": "CHOICE",
"value": "-"
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "expression"
}
}
]
}
},
"add_expr": {
"type": "PREC_LEFT",
"value": "addition",
"content": {
"type": "SEQ",
"members": [ "members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "expression"
}
},
{ {
"type": "STRING", "type": "STRING",
"value": "+" "value": "+"
}, },
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "expression"
}
}
]
}
},
"divide_expr": {
"type": "PREC_LEFT",
"value": "multiplication",
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "expression"
}
},
{ {
"type": "STRING", "type": "STRING",
"value": "/" "value": "-"
}
]
}, },
{ {
"type": "FIELD", "type": "FIELD",
@@ -1571,7 +1505,7 @@
] ]
} }
}, },
"multiply_expr": { "_multiply_expr": {
"type": "PREC_LEFT", "type": "PREC_LEFT",
"value": "multiplication", "value": "multiplication",
"content": { "content": {
@@ -1585,10 +1519,19 @@
"name": "expression" "name": "expression"
} }
}, },
{
"type": "CHOICE",
"members": [
{ {
"type": "STRING", "type": "STRING",
"value": "*" "value": "*"
}, },
{
"type": "STRING",
"value": "/"
}
]
},
{ {
"type": "FIELD", "type": "FIELD",
"name": "right", "name": "right",
@@ -1600,7 +1543,7 @@
] ]
} }
}, },
"equal_expr": { "_equal_expr": {
"type": "PREC_LEFT", "type": "PREC_LEFT",
"value": "equal", "value": "equal",
"content": { "content": {
@@ -1629,7 +1572,7 @@
] ]
} }
}, },
"concat_expr": { "_concat_expr": {
"type": "PREC_LEFT", "type": "PREC_LEFT",
"value": "concat", "value": "concat",
"content": { "content": {
@@ -1643,38 +1586,18 @@
"name": "expression" "name": "expression"
} }
}, },
{
"type": "CHOICE",
"members": [
{ {
"type": "STRING", "type": "STRING",
"value": "++" "value": "++"
}, },
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "expression"
}
}
]
}
},
"compose_expr": {
"type": "PREC_LEFT",
"value": "concat",
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "expression"
}
},
{ {
"type": "STRING", "type": "STRING",
"value": "=>" "value": "=>"
}
]
}, },
{ {
"type": "FIELD", "type": "FIELD",
@@ -1687,7 +1610,7 @@
] ]
} }
}, },
"exponent_expr": { "_exponent_expr": {
"type": "PREC_LEFT", "type": "PREC_LEFT",
"value": "exponent", "value": "exponent",
"content": { "content": {
@@ -1716,6 +1639,73 @@
] ]
} }
}, },
"_bin_bool_expr": {
"type": "PREC_LEFT",
"value": "binary_boolean",
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "expression"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "and"
},
{
"type": "STRING",
"value": "or"
}
]
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "atom"
}
}
]
}
},
"binary_expr": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_exponent_expr"
},
{
"type": "SYMBOL",
"name": "_concat_expr"
},
{
"type": "SYMBOL",
"name": "_equal_expr"
},
{
"type": "SYMBOL",
"name": "_multiply_expr"
},
{
"type": "SYMBOL",
"name": "_add_expr"
},
{
"type": "SYMBOL",
"name": "_bin_bool_expr"
}
]
},
"match_arm": { "match_arm": {
"type": "PREC", "type": "PREC",
"value": "match_arm", "value": "match_arm",
@@ -1819,7 +1809,7 @@
} }
] ]
}, },
"negate_expr": { "unary_expr": {
"type": "PREC_RIGHT", "type": "PREC_RIGHT",
"value": "negate", "value": "negate",
"content": { "content": {
@@ -1917,10 +1907,6 @@
"type": "SYMBOL", "type": "SYMBOL",
"name": "lambda" "name": "lambda"
}, },
{
"type": "SYMBOL",
"name": "and_expr"
},
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "if_expr" "name": "if_expr"
@@ -1935,39 +1921,11 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "add_expr" "name": "binary_expr"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "sub_expr" "name": "unary_expr"
},
{
"type": "SYMBOL",
"name": "divide_expr"
},
{
"type": "SYMBOL",
"name": "multiply_expr"
},
{
"type": "SYMBOL",
"name": "concat_expr"
},
{
"type": "SYMBOL",
"name": "compose_expr"
},
{
"type": "SYMBOL",
"name": "equal_expr"
},
{
"type": "SYMBOL",
"name": "exponent_expr"
},
{
"type": "SYMBOL",
"name": "negate_expr"
} }
] ]
}, },
@@ -2113,7 +2071,7 @@
}, },
{ {
"type": "STRING", "type": "STRING",
"value": "with" "value": "binary_boolean"
}, },
{ {
"type": "STRING", "type": "STRING",

View File

@@ -1,56 +1,4 @@
[ [
{
"type": "add_expr",
"named": true,
"fields": {
"left": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
},
"right": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
}
}
},
{
"type": "and_expr",
"named": true,
"fields": {
"left": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
},
"right": {
"multiple": false,
"required": true,
"types": [
{
"type": "atom",
"named": true
}
]
}
}
},
{ {
"type": "atom", "type": "atom",
"named": true, "named": true,
@@ -150,6 +98,36 @@
} }
} }
}, },
{
"type": "binary_expr",
"named": true,
"fields": {
"left": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
},
"right": {
"multiple": false,
"required": true,
"types": [
{
"type": "atom",
"named": true
},
{
"type": "expression",
"named": true
}
]
}
}
},
{ {
"type": "char_literal", "type": "char_literal",
"named": true, "named": true,
@@ -169,58 +147,6 @@
] ]
} }
}, },
{
"type": "compose_expr",
"named": true,
"fields": {
"left": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
},
"right": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
}
}
},
{
"type": "concat_expr",
"named": true,
"fields": {
"left": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
},
"right": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
}
}
},
{ {
"type": "def", "type": "def",
"named": true, "named": true,
@@ -299,32 +225,6 @@
} }
} }
}, },
{
"type": "divide_expr",
"named": true,
"fields": {
"left": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
},
"right": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
}
}
},
{ {
"type": "doc_comment", "type": "doc_comment",
"named": true, "named": true,
@@ -345,58 +245,6 @@
"named": true, "named": true,
"fields": {} "fields": {}
}, },
{
"type": "equal_expr",
"named": true,
"fields": {
"left": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
},
"right": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
}
}
},
{
"type": "exponent_expr",
"named": true,
"fields": {
"left": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
},
"right": {
"multiple": false,
"required": true,
"types": [
{
"type": "atom",
"named": true
}
]
}
}
},
{ {
"type": "expression", "type": "expression",
"named": true, "named": true,
@@ -405,14 +253,6 @@
"multiple": false, "multiple": false,
"required": true, "required": true,
"types": [ "types": [
{
"type": "add_expr",
"named": true
},
{
"type": "and_expr",
"named": true
},
{ {
"type": "atom", "type": "atom",
"named": true "named": true
@@ -426,23 +266,7 @@
"named": true "named": true
}, },
{ {
"type": "compose_expr", "type": "binary_expr",
"named": true
},
{
"type": "concat_expr",
"named": true
},
{
"type": "divide_expr",
"named": true
},
{
"type": "equal_expr",
"named": true
},
{
"type": "exponent_expr",
"named": true "named": true
}, },
{ {
@@ -461,18 +285,6 @@
"type": "match_expr", "type": "match_expr",
"named": true "named": true
}, },
{
"type": "multiply_expr",
"named": true
},
{
"type": "negate_expr",
"named": true
},
{
"type": "sub_expr",
"named": true
},
{ {
"type": "tag_expr", "type": "tag_expr",
"named": true "named": true
@@ -480,6 +292,10 @@
{ {
"type": "type_downcast", "type": "type_downcast",
"named": true "named": true
},
{
"type": "unary_expr",
"named": true
} }
] ]
} }
@@ -893,48 +709,6 @@
} }
} }
}, },
{
"type": "multiply_expr",
"named": true,
"fields": {
"left": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
},
"right": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
}
}
},
{
"type": "negate_expr",
"named": true,
"fields": {
"expr": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
}
}
},
{ {
"type": "num_literal", "type": "num_literal",
"named": true, "named": true,
@@ -1184,32 +958,6 @@
] ]
} }
}, },
{
"type": "sub_expr",
"named": true,
"fields": {
"left": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
},
"right": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
}
}
},
{ {
"type": "tag_expr", "type": "tag_expr",
"named": true, "named": true,
@@ -1398,6 +1146,22 @@
} }
} }
}, },
{
"type": "unary_expr",
"named": true,
"fields": {
"expr": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
}
}
},
{ {
"type": "union_type", "type": "union_type",
"named": true, "named": true,
@@ -1595,6 +1359,10 @@
"type": "match", "type": "match",
"named": false "named": false
}, },
{
"type": "or",
"named": false
},
{ {
"type": "section_comment", "type": "section_comment",
"named": true, "named": true,

46493
tree-sitter/src/parser.c generated

File diff suppressed because it is too large Load Diff