@ -4,7 +4,6 @@ module.exports = grammar({
name : "gleam" ,
name : "gleam" ,
extras : ( $ ) => [ ";" , NEWLINE , /\s/ ] ,
extras : ( $ ) => [ ";" , NEWLINE , /\s/ ] ,
conflicts : ( $ ) => [
conflicts : ( $ ) => [
[ $ . record , $ . record _name ] ,
[ $ . var , $ . identifier ] ,
[ $ . var , $ . identifier ] ,
[ $ . _maybe _record _expression , $ . _maybe _tuple _expression ] ,
[ $ . _maybe _record _expression , $ . _maybe _tuple _expression ] ,
] ,
] ,
@ -65,8 +64,8 @@ module.exports = grammar({
optional ( seq ( "as" , field ( "alias" , $ . identifier ) ) )
optional ( seq ( "as" , field ( "alias" , $ . identifier ) ) )
) ,
) ,
seq (
seq (
field ( "name" , $ . record_name ) ,
field ( "name" , $ . type_identifier ) ,
optional ( seq ( "as" , field ( "alias" , $ . record_name ) ) )
optional ( seq ( "as" , field ( "alias" , $ . type_identifier ) ) )
)
)
) ,
) ,
@ -86,41 +85,34 @@ module.exports = grammar({
$ . string ,
$ . string ,
$ . float ,
$ . float ,
$ . integer ,
$ . integer ,
alias ( $ . _ constant_tuple , $ . tuple ) ,
alias ( $ . constant_tuple , $ . tuple ) ,
alias ( $ . _ constant_list , $ . list ) ,
alias ( $ . constant_list , $ . list ) ,
alias ( $ . _constant _bit _string , $ . bit _string ) ,
alias ( $ . _constant _bit _string , $ . bit _string ) ,
alias ( $ . _constant _record , $ . record ) ,
alias ( $ . constant _record , $ . record )
alias ( $ . _constant _remote _record , $ . remote _record )
) ,
) ,
_ constant_tuple : ( $ ) =>
constant_tuple : ( $ ) =>
seq ( "#" , "(" , optional ( series _of ( $ . _constant _value , "," ) ) , ")" ) ,
seq ( "#" , "(" , optional ( series _of ( $ . _constant _value , "," ) ) , ")" ) ,
_ constant_list : ( $ ) =>
constant_list : ( $ ) =>
seq ( "[" , optional ( series _of ( $ . _constant _value , "," ) ) , "]" ) ,
seq ( "[" , optional ( series _of ( $ . _constant _value , "," ) ) , "]" ) ,
... bit _string _rules ( "constant" , "_constant_value" , "integer" ) ,
... bit _string _rules ( "constant" , "_constant_value" , "integer" ) ,
_ constant_record : ( $ ) =>
constant_record : ( $ ) =>
seq (
seq (
$ . record _name ,
field ( "name" , choice ( $ . type _identifier , $ . remote _type _identifier ) ) ,
optional ( alias ( $ . _constant _record _arguments , $ . arguments ) )
optional (
field ( "arguments" , alias ( $ . constant _record _arguments , $ . arguments ) )
)
) ,
) ,
_constant _record _arguments : ( $ ) =>
constant_record _arguments : ( $ ) =>
seq (
seq (
"(" ,
"(" ,
optional (
optional ( series _of ( alias ( $ . constant _record _argument , $ . argument ) , "," ) ) ,
series _of ( alias ( $ . _constant _record _argument , $ . argument ) , "," )
) ,
")"
")"
) ,
) ,
_ constant_record _argument : ( $ ) =>
constant_record _argument : ( $ ) =>
seq (
seq (
optional ( seq ( field ( "label" , $ . identifier ) , ":" ) ) ,
optional ( seq ( field ( "label" , $ . identifier ) , ":" ) ) ,
field ( "value" , $ . _constant _value )
field ( "value" , $ . _constant _value )
) ,
) ,
_constant _remote _record : ( $ ) =>
seq (
field ( "module" , alias ( $ . _name , $ . identifier ) ) ,
"." ,
$ . _constant _record
) ,
/* Special constant types */
/* Special constant types */
// Versions of $._type, $._type_annotation, etc, that have constraints
// Versions of $._type, $._type_annotation, etc, that have constraints
@ -129,16 +121,17 @@ module.exports = grammar({
choice (
choice (
$ . type _hole ,
$ . type _hole ,
alias ( $ . constant _tuple _type , $ . tuple _type ) ,
alias ( $ . constant _tuple _type , $ . tuple _type ) ,
alias ( $ . constant _type , $ . type ) ,
alias ( $ . constant _type , $ . type )
alias ( $ . constant _remote _type , $ . remote _type )
) ,
) ,
_constant _type _annotation : ( $ ) => seq ( ":" , field ( "type" , $ . _constant _type ) ) ,
_constant _type _annotation : ( $ ) => seq ( ":" , field ( "type" , $ . _constant _type ) ) ,
constant _tuple _type : ( $ ) =>
constant _tuple _type : ( $ ) =>
seq ( "#" , "(" , optional ( series _of ( $ . _constant _type , "," ) ) , ")" ) ,
seq ( "#" , "(" , optional ( series _of ( $ . _constant _type , "," ) ) , ")" ) ,
constant _type : ( $ ) =>
constant _type : ( $ ) =>
seq (
seq (
$ . _upname ,
field ( "name" , choice ( $ . type _identifier , $ . remote _type _identifier ) ) ,
optional ( alias ( $ . constant _type _arguments , $ . type _arguments ) )
optional (
field ( "arguments" , alias ( $ . constant _type _arguments , $ . type _arguments ) )
)
) ,
) ,
constant _type _arguments : ( $ ) =>
constant _type _arguments : ( $ ) =>
seq (
seq (
@ -150,9 +143,6 @@ module.exports = grammar({
) ,
) ,
constant _type _argument : ( $ ) => $ . _constant _type ,
constant _type _argument : ( $ ) => $ . _constant _type ,
constant _remote _type : ( $ ) =>
seq ( field ( "module" , $ . identifier ) , "." , alias ( $ . constant _type , $ . type ) ) ,
/* External types */
/* External types */
public _external _type : ( $ ) => seq ( "pub" , $ . _external _type ) ,
public _external _type : ( $ ) => seq ( "pub" , $ . _external _type ) ,
external _type : ( $ ) => $ . _external _type ,
external _type : ( $ ) => $ . _external _type ,
@ -165,7 +155,7 @@ module.exports = grammar({
seq (
seq (
"external" ,
"external" ,
"fn" ,
"fn" ,
field ( "name" , alias( $ . _name , $ . function _name ) ) ,
field ( "name" , $. identifier ) ,
"(" ,
"(" ,
optional (
optional (
field (
field (
@ -296,7 +286,6 @@ module.exports = grammar({
// If we decide that record constructors (value constructors) are
// If we decide that record constructors (value constructors) are
// actually functions, this will require a refactor.
// actually functions, this will require a refactor.
$ . record ,
$ . record ,
$ . remote _record ,
$ . var ,
$ . var ,
$ . todo ,
$ . todo ,
$ . tuple ,
$ . tuple ,
@ -312,8 +301,11 @@ module.exports = grammar({
$ . field _access ,
$ . field _access ,
$ . function _call
$ . function _call
) ,
) ,
record : ( $ ) => seq ( alias ( $ . _upname , $ . record _name ) , optional ( $ . arguments ) ) ,
record : ( $ ) =>
remote _record : ( $ ) => seq ( field ( "module" , $ . identifier ) , "." , $ . record ) ,
seq (
field ( "name" , choice ( $ . type _identifier , $ . remote _type _identifier ) ) ,
field ( "arguments" , optional ( $ . arguments ) )
) ,
todo : ( $ ) =>
todo : ( $ ) =>
seq ( "todo" , optional ( seq ( "(" , field ( "message" , $ . string ) , ")" ) ) ) ,
seq ( "todo" , optional ( seq ( "(" , field ( "message" , $ . string ) , ")" ) ) ) ,
tuple : ( $ ) => seq ( "#" , "(" , optional ( series _of ( $ . _expression , "," ) ) , ")" ) ,
tuple : ( $ ) => seq ( "#" , "(" , optional ( series _of ( $ . _expression , "," ) ) , ")" ) ,
@ -471,14 +463,8 @@ module.exports = grammar({
seq ( "{" , $ . _case _clause _guard _expression , "}" ) ,
seq ( "{" , $ . _case _clause _guard _expression , "}" ) ,
$ . _constant _value
$ . _constant _value
) ,
) ,
// Somehow writing alias($._name, $.var) vs just $.var solves a precedence
// issue with tree-sitter
_case _clause _tuple _access : ( $ ) =>
_case _clause _tuple _access : ( $ ) =>
seq (
seq ( field ( "tuple" , $ . var ) , "." , field ( "index" , $ . integer ) ) ,
field ( "tuple" , alias ( $ . _name , $ . var ) ) ,
"." ,
field ( "index" , $ . integer )
) ,
let : ( $ ) => seq ( "let" , $ . _assignment ) ,
let : ( $ ) => seq ( "let" , $ . _assignment ) ,
assert : ( $ ) => seq ( "assert" , $ . _assignment ) ,
assert : ( $ ) => seq ( "assert" , $ . _assignment ) ,
_assignment : ( $ ) =>
_assignment : ( $ ) =>
@ -490,7 +476,10 @@ module.exports = grammar({
) ,
) ,
record _update : ( $ ) =>
record _update : ( $ ) =>
seq (
seq (
field ( "constructor" , choice ( $ . record _name , $ . remote _record _name ) ) ,
field (
"constructor" ,
choice ( $ . type _identifier , $ . remote _type _identifier )
) ,
"(" ,
"(" ,
".." ,
".." ,
field ( "spread" , $ . _expression ) ,
field ( "spread" , $ . _expression ) ,
@ -530,7 +519,6 @@ module.exports = grammar({
_maybe _record _expression : ( $ ) =>
_maybe _record _expression : ( $ ) =>
choice (
choice (
$ . record ,
$ . record ,
$ . remote _record ,
$ . var ,
$ . var ,
$ . function _call ,
$ . function _call ,
$ . expression _group ,
$ . expression _group ,
@ -577,7 +565,6 @@ module.exports = grammar({
choice (
choice (
$ . var ,
$ . var ,
$ . discard _var ,
$ . discard _var ,
$ . remote _constructor _pattern ,
$ . constructor _pattern ,
$ . constructor _pattern ,
$ . string ,
$ . string ,
$ . integer ,
$ . integer ,
@ -586,28 +573,29 @@ module.exports = grammar({
alias ( $ . _pattern _bit _string , $ . bit _string _pattern ) ,
alias ( $ . _pattern _bit _string , $ . bit _string _pattern ) ,
$ . list _pattern
$ . list _pattern
) ,
) ,
optional ( field ( "assign" , seq ( "as" , alias( $ . _name , $. pattern _assign ) ) ) )
optional ( field ( "assign" , seq ( "as" , $. pattern _assign ) ) )
) ,
) ,
pattern _assign : ( $ ) => $ . _name ,
var : ( $ ) => $ . _name ,
var : ( $ ) => $ . _name ,
discard _var : ( $ ) => $ . _discard _name ,
discard _var : ( $ ) => $ . _discard _name ,
remote_ constructor_pattern : ( $ ) =>
constructor_pattern : ( $ ) =>
seq ( $ . _name , "." , $ . _constructor _pattern ) ,
seq (
constructor _pattern : ( $ ) => $ . _constructor _pattern ,
field ( "name" , choice ( $ . type _identifier , $ . remote _type _identifier ) ) ,
_constructor _pattern : ( $ ) =>
optional ( field ( "arguments" , $ . pattern _constructor _arguments ) )
seq ( $ . _upname , optional ( $ . pattern _constructor _args ) ) ,
) ,
pattern _constructor _arg s: ( $ ) =>
pattern _constructor _arg ument s: ( $ ) =>
seq (
seq (
"(" ,
"(" ,
optional ( series _of ( $ . _pattern _constructor _arg , "," ) ) ,
optional ( series _of ( $ . _pattern _constructor _arg ument , "," ) ) ,
optional ( $ . pattern _spread ) ,
optional ( $ . pattern _spread ) ,
")"
")"
) ,
) ,
_pattern _constructor _arg : ( $ ) =>
_pattern _constructor _arg ument : ( $ ) =>
choice (
choice (
$ . pattern _constructor _named _arg ,
$ . pattern _constructor _named _arg ument ,
alias ( $ . constructor _pattern , $ . pattern _constructor _unnamed _arg )
alias ( $ . constructor _pattern , $ . pattern _constructor _unnamed _arg ument )
) ,
) ,
pattern _constructor _named _arg : ( $ ) =>
pattern _constructor _named _arg ument : ( $ ) =>
seq ( $ . _name , ":" , $ . constructor _pattern ) ,
seq ( $ . _name , ":" , $ . constructor _pattern ) ,
pattern _spread : ( $ ) => seq ( ".." , optional ( "," ) ) ,
pattern _spread : ( $ ) => seq ( ".." , optional ( "," ) ) ,
tuple _pattern : ( $ ) =>
tuple _pattern : ( $ ) =>
@ -618,9 +606,9 @@ module.exports = grammar({
... bit _string _rules (
... bit _string _rules (
"pattern" ,
"pattern" ,
"_pattern" ,
"_pattern" ,
"_pattern_bit_string_segment_arg "
"_pattern_bit_string_segment_arg ument "
) ,
) ,
_pattern _bit _string _segment _arg : ( $ ) => choice ( $ . var , $ . integer ) ,
_pattern _bit _string _segment _arg ument : ( $ ) => choice ( $ . var , $ . integer ) ,
list _pattern : ( $ ) =>
list _pattern : ( $ ) =>
seq (
seq (
"[" ,
"[" ,
@ -644,11 +632,11 @@ module.exports = grammar({
type _constructors : ( $ ) => repeat1 ( $ . type _constructor ) ,
type _constructors : ( $ ) => repeat1 ( $ . type _constructor ) ,
type _constructor : ( $ ) =>
type _constructor : ( $ ) =>
seq (
seq (
$. _upname ,
field( "name" , $ . type _identifier ) ,
optional ( seq( "(" , optional ( $ . type _constructor _arguments ) , ")" ) )
optional ( field( "arguments" , $ . type _constructor _arguments ) )
) ,
) ,
type _constructor _arguments : ( $ ) =>
type _constructor _arguments : ( $ ) =>
se ries_of ( $ . type _constructor _argument , ", ") ,
se q( "(" , optional ( se ries_of ( $ . type _constructor _argument , ", ") ) , ") ") ,
type _constructor _argument : ( $ ) =>
type _constructor _argument : ( $ ) =>
seq (
seq (
optional ( seq ( field ( "label" , $ . identifier ) , ":" ) ) ,
optional ( seq ( field ( "label" , $ . identifier ) , ":" ) ) ,
@ -696,14 +684,7 @@ module.exports = grammar({
/* Types */
/* Types */
_type : ( $ ) =>
_type : ( $ ) =>
choice (
choice ( $ . type _hole , $ . tuple _type , $ . function _type , $ . type , $ . type _var ) ,
$ . type _hole ,
$ . tuple _type ,
$ . function _type ,
$ . type ,
$ . remote _type ,
$ . type _var
) ,
_type _annotation : ( $ ) => seq ( ":" , field ( "type" , $ . _type ) ) ,
_type _annotation : ( $ ) => seq ( ":" , field ( "type" , $ . _type ) ) ,
type _hole : ( $ ) => $ . _discard _name ,
type _hole : ( $ ) => $ . _discard _name ,
// If you're wondering why there isn't a `list_type` here, the answer is
// If you're wondering why there isn't a `list_type` here, the answer is
@ -720,29 +701,34 @@ module.exports = grammar({
function _parameter _types : ( $ ) =>
function _parameter _types : ( $ ) =>
seq ( "(" , optional ( series _of ( $ . _type , "," ) ) , ")" ) ,
seq ( "(" , optional ( series _of ( $ . _type , "," ) ) , ")" ) ,
// "type" is a somewhat ambiguous name, but it refers to a concrete type
// "type" is a somewhat ambiguous name, but it refers to a concrete type
// such as `Bool` or `List(Int)` or even `List(#(Int, String))`.
// such as `Bool` or `List(Int)` or even `result.Result(#(Int, Int), Nil)`.
type : ( $ ) => seq ( $ . _upname , field ( "arguments" , optional ( $ . type _arguments ) ) ) ,
type : ( $ ) =>
seq (
field ( "name" , choice ( $ . type _identifier , $ . remote _type _identifier ) ) ,
field ( "arguments" , optional ( $ . type _arguments ) )
) ,
type _arguments : ( $ ) =>
type _arguments : ( $ ) =>
seq ( "(" , optional ( series _of ( $ . type _argument , "," ) ) , ")" ) ,
seq ( "(" , optional ( series _of ( $ . type _argument , "," ) ) , ")" ) ,
type _argument : ( $ ) => $ . _type ,
type _argument : ( $ ) => $ . _type ,
remote _type : ( $ ) => seq ( field ( "module" , $ . identifier ) , "." , $ . type ) ,
type _var : ( $ ) => $ . _name ,
type _var : ( $ ) => $ . _name ,
// "type_name" referes essentially to the declaration of a type. The type
// "type_name" essentially refers to the declaration of a type. The type
// parameters are part of the "name." Bit odd, but 🤷
// parameters are part of the "name." Bit odd, but 🤷
// e.g. MyType(a, b)
// e.g. MyType(a, b)
type _name : ( $ ) => seq ( $ . _upname , optional ( $ . type _parameters ) ) ,
type _name : ( $ ) =>
seq (
field ( "name" , choice ( $ . type _identifier , $ . remote _type _identifier ) ) ,
optional ( field ( "parameters" , $ . type _parameters ) )
) ,
type _parameters : ( $ ) =>
type _parameters : ( $ ) =>
seq ( "(" , optional ( series _of ( $ . type _parameter , "," ) ) , ")" ) ,
seq ( "(" , optional ( series _of ( $ . type _parameter , "," ) ) , ")" ) ,
type _parameter : ( $ ) => $ . _name ,
type _parameter : ( $ ) => $ . _name ,
remote _type _name : ( $ ) =>
seq ( field ( "module" , $ . identifier ) , "." , $ . type _name ) ,
/* Shared AST nodes */
/* Shared AST nodes */
identifier : ( $ ) => $ . _name ,
identifier : ( $ ) => $ . _name ,
record_name : ( $ ) => $ . _upname ,
type_identifier : ( $ ) => $ . _upname ,
remote _ record_name : ( $ ) =>
remote _ type_identifier : ( $ ) =>
seq ( field ( "module" , $ . identifier ) , "." , $. record _name ) ,
seq ( field ( "module" , $ . identifier ) , "." , field( "name" , $ . type _identifier ) ) ,
/* Reused types from the Gleam lexer */
/* Reused types from the Gleam lexer */
_discard _name : ( $ ) => / _ [ _0 - 9 a - z ] * / ,
_discard _name : ( $ ) => / _ [ _0 - 9 a - z ] * / ,