Add support for external function statements

pull/204/head
Jonathan Arnett 2021-12-14 01:35:59 +07:00
parent eaa2cc2026
commit 068ae5178f
6 changed files with 4159 additions and 2198 deletions

@ -13,10 +13,10 @@ This is, presently, very much a work-in-progress.
- [x] `import` statements
- [x] `const` statements
- [x] `external type` statements
- [x] `external fn` statements
## TODO
- [ ] external function statements
- [ ] public extenal function statements
- [ ] public external type statements
- [ ] function statements

@ -0,0 +1,45 @@
===================
External functions
===================
external fn read_file(String) -> Result(String, Reason) =
"file" "open"
external fn a(name: String) -> String = "x" "y"
external fn a() -> #(List(Int), fn(Int) -> String) = "x" "y"
---
(source_file
(external_function
name: (function_name)
parameters: (external_function_parameters
(external_function_parameter
type: (type_constructor)))
return_type: (type_constructor
(type_constructor)
(type_constructor))
body: (external_function_body
(string)
(string)))
(external_function
name: (function_name)
parameters: (external_function_parameters
(external_function_parameter
name: (identifier)
type: (type_constructor)))
return_type: (type_constructor)
body: (external_function_body
(string)
(string)))
(external_function
name: (function_name)
return_type: (tuple_type
(type_constructor
(type_constructor))
(function_type
parameter_types: (function_parameter_types
(type_constructor))
return_type: (type_constructor)))
body: (external_function_body
(string)
(string))))

@ -17,8 +17,8 @@ module.exports = grammar({
$.import,
$.public_constant,
$.constant,
$.external_type
/* $.external_function, */
$.external_type,
$.external_function
/* $._public_extenal_type_or_function, */
/* $.function, */
/* $.public_function, */
@ -74,7 +74,7 @@ module.exports = grammar({
_constant: ($) =>
seq(
"const",
field("name", alias($._name, $.identifier)),
field("name", $.identifier),
optional($._constant_type_annotation),
"=",
field("value", $._constant_value)
@ -169,7 +169,10 @@ module.exports = grammar({
constant_remote_type_constructor: ($) =>
seq($._name, ".", $._constant_type_constructor),
_constant_type_constructor: ($) =>
seq($._upname, optional(seq("(", series_of($._constant_type, ","), ")"))),
seq(
$._upname,
optional(seq("(", optional(series_of($._constant_type, ",")), ")"))
),
/* External types */
external_type: ($) =>
@ -184,6 +187,29 @@ module.exports = grammar({
external_type_arguments: ($) =>
series_of(alias($._name, $.external_type_argument), ","),
/* External functions */
external_function: ($) =>
seq(
"external",
"fn",
field("name", alias($._name, $.function_name)),
"(",
optional(field("parameters", $.external_function_parameters)),
")",
"->",
field("return_type", $._type),
"=",
field("body", $.external_function_body)
),
external_function_parameters: ($) =>
series_of($.external_function_parameter, ","),
external_function_parameter: ($) =>
seq(
optional(seq(field("name", $.identifier), ":")),
field("type", $._type)
),
external_function_body: ($) => seq($.string, $.string),
/* Literals */
_literal: ($) =>
choice(
@ -241,13 +267,42 @@ module.exports = grammar({
),
/* Types */
type_var: ($) => $._name,
_type: ($) =>
choice(
$.type_hole,
$.tuple_type,
$.function_type,
$.type_constructor,
$.remote_type_constructor,
$.type_var
),
type_hole: ($) => $._discard_name,
tuple_type: ($) => seq("#", "(", optional(series_of($._type, ",")), ")"),
function_type: ($) =>
seq(
"fn",
"(",
optional(field("parameter_types", $.function_parameter_types)),
")",
"->",
field("return_type", $._type)
),
function_parameter_types: ($) => series_of($._type, ","),
type_constructor: ($) => $._type_constructor,
remote_type_constructor: ($) => seq($._name, ".", $._type_constructor),
_type_constructor: ($) =>
seq(
$._upname,
optional(seq("(", optional(series_of($._type, ",")), ")"))
),
type_var: ($) => $._name,
/* Reused types from the Gleam lexer */
_discard_name: ($) => /_[_0-9a-z]*/,
_name: ($) => /[_a-z][_0-9a-z]*/,
_upname: ($) => /[A-Z][0-9a-zA-Z]*/,
// Common alias becomes a real boy
identifier: ($) => $._name,
},
});

@ -87,6 +87,10 @@
{
"type": "SYMBOL",
"name": "external_type"
},
{
"type": "SYMBOL",
"name": "external_function"
}
]
},
@ -405,13 +409,8 @@
"type": "FIELD",
"name": "name",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_name"
},
"named": true,
"value": "identifier"
"type": "SYMBOL",
"name": "identifier"
}
},
{
@ -1029,27 +1028,35 @@
"value": "("
},
{
"type": "SEQ",
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_constant_type"
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_constant_type"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_constant_type"
}
]
}
}
]
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_constant_type"
}
]
}
"type": "BLANK"
}
]
},
@ -1164,6 +1171,156 @@
}
]
},
"external_function": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "external"
},
{
"type": "STRING",
"value": "fn"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_name"
},
"named": true,
"value": "function_name"
}
},
{
"type": "STRING",
"value": "("
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "parameters",
"content": {
"type": "SYMBOL",
"name": "external_function_parameters"
}
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": ")"
},
{
"type": "STRING",
"value": "->"
},
{
"type": "FIELD",
"name": "return_type",
"content": {
"type": "SYMBOL",
"name": "_type"
}
},
{
"type": "STRING",
"value": "="
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "external_function_body"
}
}
]
},
"external_function_parameters": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "external_function_parameter"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "external_function_parameter"
}
]
}
}
]
},
"external_function_parameter": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
},
{
"type": "STRING",
"value": ":"
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "FIELD",
"name": "type",
"content": {
"type": "SYMBOL",
"name": "_type"
}
}
]
},
"external_function_body": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "string"
},
{
"type": "SYMBOL",
"name": "string"
}
]
},
"_literal": {
"type": "CHOICE",
"members": [
@ -1618,14 +1775,247 @@
}
]
},
"type_var": {
"type": "SYMBOL",
"name": "_name"
"_type": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "type_hole"
},
{
"type": "SYMBOL",
"name": "tuple_type"
},
{
"type": "SYMBOL",
"name": "function_type"
},
{
"type": "SYMBOL",
"name": "type_constructor"
},
{
"type": "SYMBOL",
"name": "remote_type_constructor"
},
{
"type": "SYMBOL",
"name": "type_var"
}
]
},
"type_hole": {
"type": "SYMBOL",
"name": "_discard_name"
},
"tuple_type": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "#"
},
{
"type": "STRING",
"value": "("
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_type"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_type"
}
]
}
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": ")"
}
]
},
"function_type": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "fn"
},
{
"type": "STRING",
"value": "("
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "parameter_types",
"content": {
"type": "SYMBOL",
"name": "function_parameter_types"
}
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": ")"
},
{
"type": "STRING",
"value": "->"
},
{
"type": "FIELD",
"name": "return_type",
"content": {
"type": "SYMBOL",
"name": "_type"
}
}
]
},
"function_parameter_types": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_type"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_type"
}
]
}
}
]
},
"type_constructor": {
"type": "SYMBOL",
"name": "_type_constructor"
},
"remote_type_constructor": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_name"
},
{
"type": "STRING",
"value": "."
},
{
"type": "SYMBOL",
"name": "_type_constructor"
}
]
},
"_type_constructor": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_upname"
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_type"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_type"
}
]
}
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": ")"
}
]
},
{
"type": "BLANK"
}
]
}
]
},
"type_var": {
"type": "SYMBOL",
"name": "_name"
},
"_discard_name": {
"type": "PATTERN",
"value": "_[_0-9a-z]*"
@ -1637,6 +2027,10 @@
"_upname": {
"type": "PATTERN",
"value": "[A-Z][0-9a-zA-Z]*"
},
"identifier": {
"type": "SYMBOL",
"name": "_name"
}
},
"extras": [

@ -349,6 +349,148 @@
}
}
},
{
"type": "external_function",
"named": true,
"fields": {
"body": {
"multiple": false,
"required": true,
"types": [
{
"type": "external_function_body",
"named": true
}
]
},
"name": {
"multiple": false,
"required": true,
"types": [
{
"type": "function_name",
"named": true
}
]
},
"parameters": {
"multiple": false,
"required": false,
"types": [
{
"type": "external_function_parameters",
"named": true
}
]
},
"return_type": {
"multiple": false,
"required": true,
"types": [
{
"type": "function_type",
"named": true
},
{
"type": "remote_type_constructor",
"named": true
},
{
"type": "tuple_type",
"named": true
},
{
"type": "type_constructor",
"named": true
},
{
"type": "type_hole",
"named": true
},
{
"type": "type_var",
"named": true
}
]
}
}
},
{
"type": "external_function_body",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "string",
"named": true
}
]
}
},
{
"type": "external_function_parameter",
"named": true,
"fields": {
"name": {
"multiple": false,
"required": false,
"types": [
{
"type": "identifier",
"named": true
}
]
},
"type": {
"multiple": false,
"required": true,
"types": [
{
"type": "function_type",
"named": true
},
{
"type": "remote_type_constructor",
"named": true
},
{
"type": "tuple_type",
"named": true
},
{
"type": "type_constructor",
"named": true
},
{
"type": "type_hole",
"named": true
},
{
"type": "type_var",
"named": true
}
]
}
}
},
{
"type": "external_function_parameters",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "external_function_parameter",
"named": true
}
]
}
},
{
"type": "external_type",
"named": true,
@ -398,6 +540,92 @@
]
}
},
{
"type": "function_parameter_types",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "function_type",
"named": true
},
{
"type": "remote_type_constructor",
"named": true
},
{
"type": "tuple_type",
"named": true
},
{
"type": "type_constructor",
"named": true
},
{
"type": "type_hole",
"named": true
},
{
"type": "type_var",
"named": true
}
]
}
},
{
"type": "function_type",
"named": true,
"fields": {
"parameter_types": {
"multiple": false,
"required": false,
"types": [
{
"type": "function_parameter_types",
"named": true
}
]
},
"return_type": {
"multiple": false,
"required": true,
"types": [
{
"type": "function_type",
"named": true
},
{
"type": "remote_type_constructor",
"named": true
},
{
"type": "tuple_type",
"named": true
},
{
"type": "type_constructor",
"named": true
},
{
"type": "type_hole",
"named": true
},
{
"type": "type_var",
"named": true
}
]
}
}
},
{
"type": "identifier",
"named": true,
"fields": {}
},
{
"type": "import",
"named": true,
@ -639,6 +867,10 @@
"multiple": true,
"required": false,
"types": [
{
"type": "function_type",
"named": true
},
{
"type": "remote_type_constructor",
"named": true
@ -654,6 +886,10 @@
{
"type": "type_hole",
"named": true
},
{
"type": "type_var",
"named": true
}
]
}
@ -670,6 +906,10 @@
"type": "constant",
"named": true
},
{
"type": "external_function",
"named": true
},
{
"type": "external_type",
"named": true
@ -717,6 +957,10 @@
"type": "constant",
"named": true
},
{
"type": "external_function",
"named": true
},
{
"type": "external_type",
"named": true
@ -783,6 +1027,10 @@
"multiple": true,
"required": false,
"types": [
{
"type": "function_type",
"named": true
},
{
"type": "remote_type_constructor",
"named": true
@ -798,6 +1046,10 @@
{
"type": "type_hole",
"named": true
},
{
"type": "type_var",
"named": true
}
]
}
@ -810,6 +1062,10 @@
"multiple": true,
"required": false,
"types": [
{
"type": "function_type",
"named": true
},
{
"type": "remote_type_constructor",
"named": true
@ -825,6 +1081,10 @@
{
"type": "type_hole",
"named": true
},
{
"type": "type_var",
"named": true
}
]
}
@ -834,6 +1094,11 @@
"named": true,
"fields": {}
},
{
"type": "type_var",
"named": true,
"fields": {}
},
{
"type": "unqualified_import",
"named": true,
@ -870,6 +1135,10 @@
"type": "-",
"named": false
},
{
"type": "->",
"named": false
},
{
"type": ".",
"named": false
@ -999,7 +1268,11 @@
"named": true
},
{
"type": "identifier",
"type": "fn",
"named": false
},
{
"type": "function_name",
"named": true
},
{

File diff suppressed because it is too large Load Diff