Rudimentary constant support

pull/204/head
Jonathan Arnett 2021-12-13 01:24:34 +07:00
parent f2e9085848
commit 8aecfc0617
5 changed files with 3656 additions and 627 deletions

@ -0,0 +1,79 @@
==========
Constants
==========
const a = "hello"
const a:Int = 1234
const a:Float = -1_234.53__23
const a:#(Int, String) = #(1, "Hello!")
const a:List(Int) = [1, 2]
---
(source_file
(constant
name: (identifier)
value: (string))
(constant
name: (identifier)
type: (type_constructor)
value: (integer))
(constant
name: (identifier)
type: (type_constructor)
value: (float))
(constant
name: (identifier)
type: (tuple_type
(type_constructor)
(type_constructor))
value: (tuple
(integer)
(string)))
(constant
name: (identifier)
type: (type_constructor
(type_constructor))
value: (list
(integer)
(integer))))
=================
Public constants
=================
pub const a = "hello"
pub const a:Int = 1234
pub const a:Float = -1_234.53__23
pub const a:#(Int, String) = #(1, "Hello!")
pub const a:List(Int) = [1, 2]
---
(source_file
(public_constant
name: (identifier)
value: (string))
(public_constant
name: (identifier)
type: (type_constructor)
value: (integer))
(public_constant
name: (identifier)
type: (type_constructor)
value: (float))
(public_constant
name: (identifier)
type: (tuple_type
(type_constructor)
(type_constructor))
value: (tuple
(integer)
(string)))
(public_constant
name: (identifier)
type: (type_constructor
(type_constructor))
value: (list
(integer)
(integer))))

@ -2,26 +2,37 @@ const NEWLINE = /\r?\n/;
module.exports = grammar({
name: "gleam",
extras: ($) => [";", "\n", "\r\n", /\s/],
extras: ($) => [";", NEWLINE, /\s/],
rules: {
/* General rules */
source_file: ($) =>
repeat(seq(choice($.target_group, $._statement), NEWLINE)),
optional(
seq(
series_of(choice($.target_group, $._statement), NEWLINE),
optional(NEWLINE)
)
),
_statement: ($) =>
choice(
$.import,
$.public_constant,
$.constant
/* $.type, */
/* $.function */
),
/* Target groups */
target_group: ($) =>
seq(
"if",
field("target", $.target),
"{",
field("body", repeat(seq($._statement, NEWLINE))),
optional(seq(series_of($._statement, NEWLINE), optional(NEWLINE))),
"}"
),
_statement: ($) =>
choice(
$.import
/* $.constant, */
/* $.type, */
/* $.function */
),
target: ($) => choice("erlang", "javascript"),
/* Import statements */
import: ($) =>
seq(
"import",
@ -50,7 +61,74 @@ module.exports = grammar({
)
),
alias: ($) => $._name,
/* Constant statements */
public_constant: ($) => seq("pub", $._constant),
constant: ($) => $._constant,
_constant: ($) =>
seq(
"const",
field("name", alias($._name, $.identifier)),
optional($._type_annotation),
"=",
field("value", $._literal)
),
/* Literals */
_literal: ($) =>
choice(
$.string,
$.float,
$.integer,
$.tuple,
$.list
// $.bitstring,
// $.record,
// $.remote_record
),
string: ($) => /\"(?:\\[efnrt\"\\]|[^\"])*\"/,
float: ($) => /-?[0-9_]+\.[0-9_]+/,
integer: ($) => /-?[0-9_]+/,
tuple: ($) => seq("#", "(", series_of($._literal, ","), ")"),
list: ($) => seq("[", series_of($._literal, ","), "]"),
/* Types */
_type_annotation: ($) => seq(":", field("type", $._type)),
_type: ($) =>
choice(
alias($._discard_name, $.type_hole),
$.tuple_type,
$.fn_type,
$.type_constructor,
$.remote_type_constructor,
$.type_var
),
tuple_type: ($) => seq("#", "(", optional(series_of($._type, ",")), ")"),
fn_type: ($) =>
seq(
"fn",
"(",
series_of(alias($._type, $.argument_type), ","),
")",
"->",
alias($._type, $.return_type)
),
type_constructor: ($) => $._type_constructor,
remote_type_constructor: ($) => seq($._name, ".", $._type_constructor),
_type_constructor: ($) =>
seq($._upname, optional(seq("(", 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]*/,
},
});
// Shamelessly stolen "sep1" from tree-sitter-elixir, renamed to match a similar
// function in the Gleam parser.
// https://github.com/elixir-lang/tree-sitter-elixir/blob/de3ec57591aebf451e710fc9c984cf601258baf5/grammar.js#L817-L819
function series_of(rule, separator) {
return seq(rule, repeat(seq(separator, rule)));
}

@ -2,29 +2,89 @@
"name": "gleam",
"rules": {
"source_file": {
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "target_group"
},
{
"type": "SYMBOL",
"name": "_statement"
}
]
},
{
"type": "PATTERN",
"value": "\\r?\\n"
}
]
}
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "target_group"
},
{
"type": "SYMBOL",
"name": "_statement"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "PATTERN",
"value": "\\r?\\n"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "target_group"
},
{
"type": "SYMBOL",
"name": "_statement"
}
]
}
]
}
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "PATTERN",
"value": "\\r?\\n"
},
{
"type": "BLANK"
}
]
}
]
},
{
"type": "BLANK"
}
]
},
"_statement": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "import"
},
{
"type": "SYMBOL",
"name": "public_constant"
},
{
"type": "SYMBOL",
"name": "constant"
}
]
},
"target_group": {
"type": "SEQ",
@ -46,15 +106,54 @@
"value": "{"
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "_statement"
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_statement"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "PATTERN",
"value": "\\r?\\n"
},
{
"type": "SYMBOL",
"name": "_statement"
}
]
}
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "PATTERN",
"value": "\\r?\\n"
},
{
"type": "BLANK"
}
]
}
]
},
{
"type": "BLANK"
}
}
]
},
{
"type": "STRING",
@ -62,15 +161,6 @@
}
]
},
"_statement": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "import"
}
]
},
"target": {
"type": "CHOICE",
"members": [
@ -283,6 +373,436 @@
"type": "SYMBOL",
"name": "_name"
},
"public_constant": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "pub"
},
{
"type": "SYMBOL",
"name": "_constant"
}
]
},
"constant": {
"type": "SYMBOL",
"name": "_constant"
},
"_constant": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "const"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_name"
},
"named": true,
"value": "identifier"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_type_annotation"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "="
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_literal"
}
}
]
},
"_literal": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "string"
},
{
"type": "SYMBOL",
"name": "float"
},
{
"type": "SYMBOL",
"name": "integer"
},
{
"type": "SYMBOL",
"name": "tuple"
},
{
"type": "SYMBOL",
"name": "list"
}
]
},
"string": {
"type": "PATTERN",
"value": "\\\"(?:\\\\[efnrt\\\"\\\\]|[^\\\"])*\\\""
},
"float": {
"type": "PATTERN",
"value": "-?[0-9_]+\\.[0-9_]+"
},
"integer": {
"type": "PATTERN",
"value": "-?[0-9_]+"
},
"tuple": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "#"
},
{
"type": "STRING",
"value": "("
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_literal"
}
]
}
}
]
},
{
"type": "STRING",
"value": ")"
}
]
},
"list": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "["
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_literal"
}
]
}
}
]
},
{
"type": "STRING",
"value": "]"
}
]
},
"_type_annotation": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ":"
},
{
"type": "FIELD",
"name": "type",
"content": {
"type": "SYMBOL",
"name": "_type"
}
}
]
},
"_type": {
"type": "CHOICE",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_discard_name"
},
"named": true,
"value": "type_hole"
},
{
"type": "SYMBOL",
"name": "tuple_type"
},
{
"type": "SYMBOL",
"name": "fn_type"
},
{
"type": "SYMBOL",
"name": "type_constructor"
},
{
"type": "SYMBOL",
"name": "remote_type_constructor"
},
{
"type": "SYMBOL",
"name": "type_var"
}
]
},
"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": ")"
}
]
},
"fn_type": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "fn"
},
{
"type": "STRING",
"value": "("
},
{
"type": "SEQ",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_type"
},
"named": true,
"value": "argument_type"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_type"
},
"named": true,
"value": "argument_type"
}
]
}
}
]
},
{
"type": "STRING",
"value": ")"
},
{
"type": "STRING",
"value": "->"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_type"
},
"named": true,
"value": "return_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": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_type"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_type"
}
]
}
}
]
},
{
"type": "STRING",
"value": ")"
}
]
},
{
"type": "BLANK"
}
]
}
]
},
"type_var": {
"type": "SYMBOL",
"name": "_name"
},
"_discard_name": {
"type": "PATTERN",
"value": "_[_0-9a-z]*"
},
"_name": {
"type": "PATTERN",
"value": "[_a-z][_0-9a-z]*"
@ -298,12 +818,8 @@
"value": ";"
},
{
"type": "STRING",
"value": "\n"
},
{
"type": "STRING",
"value": "\r\n"
"type": "PATTERN",
"value": "\\r?\\n"
},
{
"type": "PATTERN",

@ -4,6 +4,132 @@
"named": true,
"fields": {}
},
{
"type": "argument_type",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "fn_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": "constant",
"named": true,
"fields": {
"name": {
"multiple": false,
"required": true,
"types": [
{
"type": "identifier",
"named": true
}
]
},
"type": {
"multiple": false,
"required": false,
"types": [
{
"type": "fn_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
}
]
},
"value": {
"multiple": false,
"required": true,
"types": [
{
"type": "float",
"named": true
},
{
"type": "integer",
"named": true
},
{
"type": "list",
"named": true
},
{
"type": "string",
"named": true
},
{
"type": "tuple",
"named": true
}
]
}
}
},
{
"type": "fn_type",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "argument_type",
"named": true
},
{
"type": "return_type",
"named": true
}
]
}
},
{
"type": "import",
"named": true,
@ -40,11 +166,184 @@
]
}
},
{
"type": "list",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "float",
"named": true
},
{
"type": "integer",
"named": true
},
{
"type": "list",
"named": true
},
{
"type": "string",
"named": true
},
{
"type": "tuple",
"named": true
}
]
}
},
{
"type": "module",
"named": true,
"fields": {}
},
{
"type": "public_constant",
"named": true,
"fields": {
"name": {
"multiple": false,
"required": true,
"types": [
{
"type": "identifier",
"named": true
}
]
},
"type": {
"multiple": false,
"required": false,
"types": [
{
"type": "fn_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
}
]
},
"value": {
"multiple": false,
"required": true,
"types": [
{
"type": "float",
"named": true
},
{
"type": "integer",
"named": true
},
{
"type": "list",
"named": true
},
{
"type": "string",
"named": true
},
{
"type": "tuple",
"named": true
}
]
}
}
},
{
"type": "remote_type_constructor",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "fn_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": "return_type",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "fn_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": "source_file",
"named": true,
@ -53,10 +352,18 @@
"multiple": true,
"required": false,
"types": [
{
"type": "constant",
"named": true
},
{
"type": "import",
"named": true
},
{
"type": "public_constant",
"named": true
},
{
"type": "target_group",
"named": true
@ -73,16 +380,6 @@
"type": "target_group",
"named": true,
"fields": {
"body": {
"multiple": true,
"required": false,
"types": [
{
"type": "import",
"named": true
}
]
},
"target": {
"multiple": false,
"required": true,
@ -93,8 +390,132 @@
}
]
}
},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "constant",
"named": true
},
{
"type": "import",
"named": true
},
{
"type": "public_constant",
"named": true
}
]
}
},
{
"type": "tuple",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "float",
"named": true
},
{
"type": "integer",
"named": true
},
{
"type": "list",
"named": true
},
{
"type": "string",
"named": true
},
{
"type": "tuple",
"named": true
}
]
}
},
{
"type": "tuple_type",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "fn_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": "type_constructor",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "fn_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": "type_var",
"named": true,
"fields": {}
},
{
"type": "unqualified_import",
"named": true,
@ -111,10 +532,26 @@
}
}
},
{
"type": "#",
"named": false
},
{
"type": "(",
"named": false
},
{
"type": ")",
"named": false
},
{
"type": ",",
"named": false
},
{
"type": "->",
"named": false
},
{
"type": ".",
"named": false
@ -123,14 +560,46 @@
"type": "/",
"named": false
},
{
"type": ":",
"named": false
},
{
"type": "=",
"named": false
},
{
"type": "[",
"named": false
},
{
"type": "]",
"named": false
},
{
"type": "as",
"named": false
},
{
"type": "const",
"named": false
},
{
"type": "erlang",
"named": false
},
{
"type": "float",
"named": true
},
{
"type": "fn",
"named": false
},
{
"type": "identifier",
"named": true
},
{
"type": "if",
"named": false
@ -139,10 +608,26 @@
"type": "import",
"named": false
},
{
"type": "integer",
"named": true
},
{
"type": "javascript",
"named": false
},
{
"type": "pub",
"named": false
},
{
"type": "string",
"named": true
},
{
"type": "type_hole",
"named": true
},
{
"type": "{",
"named": false

File diff suppressed because it is too large Load Diff