@ -120,56 +120,30 @@ module.exports = grammar({
_constant _remote _record : ( $ ) => seq ( $ . _name , "." , $ . _constant _record ) ,
/* Special constant types */
_constant _type _annotation : ( $ ) => seq ( ":" , field ( "type" , $ . _constant _type ) ) ,
// Versions of $._type, $._type_annotation, etc, that have constraints
// specific to constants.
_constant _type : ( $ ) =>
choice (
$ . type _hole ,
alias ( $ . constant _tuple _type , $ . tuple _type ) ,
$. _constant _type _name ,
$. _constant _remote _type _name
alias( $ . constant _type , $ . type ) ,
alias( $ . constant _remote _type , $ . remote _type )
) ,
_constant _type _annotation : ( $ ) => seq ( ":" , field ( "type" , $ . _constant _type ) ) ,
constant _tuple _type : ( $ ) =>
seq ( "#" , "(" , optional ( series _of ( $ . _constant _type , "," ) ) , ")" ) ,
_constant _type _name : ( $ ) =>
choice (
alias ( $ . constant _type _constructor , $ . type _constructor ) ,
alias ( $ . constant _type , $ . type )
) ,
_constant _remote _type _name : ( $ ) =>
constant _type : ( $ ) =>
seq (
$ . _name ,
"." ,
choice (
alias ( $ . constant _type _constructor , $ . remote _type _constructor ) ,
alias ( $ . constant _type , $ . remote _type )
)
$ . _upname ,
optional ( seq ( "(" , optional ( series _of ( $ . _constant _type , "," ) ) , ")" ) )
) ,
constant _type _constructor : ( $ ) =>
seq ( $ . _upname , "(" , optional ( series _of ( $ . _constant _type , "," ) ) , ")" ) ,
constant _type : ( $ ) => $ . _upname ,
constant _remote _type : ( $ ) =>
seq ( field ( "module" , $ . _name ) , "." , alias ( $ . constant _type , $ . type ) ) ,
/* External types */
public _external _type : ( $ ) => seq ( "pub" , $ . _external _type ) ,
external _type : ( $ ) => $ . _external _type ,
_external _type : ( $ ) =>
seq (
"external" ,
"type" ,
choice ( $ . type , alias ( $ . external _type _constructor , $ . type _constructor ) )
) ,
// TODO: Is this actually any different from the module type constructors?
external _type _constructor : ( $ ) =>
seq (
$ . _upname ,
seq (
"(" ,
optional (
series _of ( alias ( $ . external _type _argument , $ . type _argument ) , "," )
) ,
")"
)
) ,
external _type _argument : ( $ ) => $ . _name ,
_external _type : ( $ ) => seq ( "external" , "type" , $ . type _name ) ,
/* External functions */
public _external _function : ( $ ) => seq ( "pub" , $ . _external _function ) ,
@ -179,26 +153,25 @@ module.exports = grammar({
"external" ,
"fn" ,
field ( "name" , alias ( $ . _name , $ . function _name ) ) ,
field (
"parameters" ,
alias ( $ . external _function _parameters , $ . function _parameters )
"(" ,
optional (
field (
"parameters" ,
alias ( $ . external _function _parameters , $ . function _parameters )
)
) ,
")" ,
"->" ,
field ( "return_type" , $ . _type ) ,
"=" ,
field ( "body" , $ . external _function _body )
) ,
// TODO: Different from module function parameters?
// Different from module function parameters in that module function
// parameters may be labelled whereas external function parameters cannot.
external _function _parameters : ( $ ) =>
seq (
"(" ,
optional (
series _of (
alias ( $ . external _function _parameter , $ . function _parameter ) ,
","
)
) ,
")"
series _of (
alias ( $ . external _function _parameter , $ . function _parameter ) ,
","
) ,
external _function _parameter : ( $ ) =>
seq (
@ -587,6 +560,8 @@ module.exports = grammar({
$ . field _access ,
$ . function _call
) ,
// Interestingly, the code that parses function arguments also parses
// record arguments, hence the ambiguous name.
arguments : ( $ ) => series _of ( $ . argument , "," ) ,
argument : ( $ ) =>
seq (
@ -694,12 +669,22 @@ module.exports = grammar({
$ . type _hole ,
$ . tuple _type ,
$ . function _type ,
$ . _ type_nam e,
$ . _ remote_typ e_nam e,
$ . type,
$ . remote_typ e,
$ . type _var
) ,
_type _annotation : ( $ ) => seq ( ":" , field ( "type" , $ . _type ) ) ,
// The type parameters are part of the "name." Bit odd, but 🤷
type _name : ( $ ) =>
seq (
$ . _upname ,
optional ( seq ( "(" , optional ( series _of ( $ . type _parameter , "," ) ) , ")" ) )
) ,
type _parameter : ( $ ) => $ . _name ,
type _hole : ( $ ) => $ . _discard _name ,
// If you're wondering why there isn't a `list_type` here, the answer is
// that the "type" form for lists is `List`, which is identical to
// user-defined types etc and thus is not parsed specially.
tuple _type : ( $ ) => seq ( "#" , "(" , optional ( series _of ( $ . _type , "," ) ) , ")" ) ,
function _type : ( $ ) =>
seq (
@ -710,19 +695,14 @@ module.exports = grammar({
) ,
function _parameter _types : ( $ ) =>
seq ( "(" , optional ( series _of ( $ . _type , "," ) ) , ")" ) ,
_type _name : ( $ ) => choice ( $ . type _constructor , $ . type ) ,
_remote _type _name : ( $ ) =>
// "type" is a somewhat ambiguous name, but it refers to a concrete type
// such as `Bool` or `List(Int)` or even `List(#(Int, String))`.
type : ( $ ) =>
seq (
$ . _name ,
"." ,
choice (
alias ( $ . type _constructor , $ . remote _type _constructor ) ,
alias ( $ . type , $ . remote _type )
)
$ . _upname ,
optional ( seq ( "(" , optional ( series _of ( $ . _type , "," ) ) , ")" ) )
) ,
type _constructor : ( $ ) =>
seq ( $ . _upname , seq ( "(" , optional ( series _of ( $ . _type , "," ) ) , ")" ) ) ,
type : ( $ ) => $ . _upname ,
remote _type : ( $ ) => seq ( field ( "module" , $ . _name ) , "." , $ . type ) ,
type _var : ( $ ) => $ . _name ,
/* Common alias becomes a real boy */