Skip to content

Commit

Permalink
rearrange some rules
Browse files Browse the repository at this point in the history
  • Loading branch information
tek committed May 3, 2024
1 parent 75477fb commit a316532
Show file tree
Hide file tree
Showing 14 changed files with 371 additions and 230 deletions.
2 changes: 2 additions & 0 deletions grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ data = require('./grammar/data.js')
decl = require('./grammar/decl.js')
exp = require('./grammar/exp.js')
externals = require('./grammar/externals.js')
general = require('./grammar/general.js')
id = require('./grammar/id.js')
import_ = require('./grammar/import.js')
inline = require('./grammar/inline.js')
Expand All @@ -28,6 +29,7 @@ module.exports = grammar({
optional($._body),
),

...general,
...type,
...context,
...exp,
Expand Down
23 changes: 5 additions & 18 deletions grammar/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,36 +29,23 @@ module.exports = {
* > A => ?a :: A | associates as | A => (?a :: A)
* > ?a :: A -> A | associates as | ?a :: (A -> A)
*/
implicit_parameter: $ => prec.left(seq(
$.implicit_variable,
$._type_annotation,
)),
implicit_parameter: $ => prec.left(seq($.implicit_variable, $._type_annotation)),

constraint: $ => choice(
$._type_name,
alias($._class_infix, $.infix),
alias($._class_apply, $.apply),
$._type_name,
$._type_con,
alias($._ctr_parens, $.parens),
alias($._ctr_tuple, $.tuple),
alias($._type_wildcard, $.wildcard),
$.splice,
$.quasiquote,
$.prefix_tuple,
$.literal,
$._universal,
),

_ctr_forall: $ => prec.right('fun', seq($._forall_body, '.', $.constraints)),

_ctr_context: $ => prec.right('fun', seq(
$._context_inline,
$.constraints,
)),
_ctr_context: $ => prec.right('fun', seq($._context_inline, $.constraints)),

_ctr_signature: $ => prec.right('annotated', seq(
$.constraints,
$._kind_annotation,
)),
_ctr_signature: $ => prec.right('annotated', seq($.constraints, $._kind_annotation)),

constraints: $ => choice(
$.constraint,
Expand Down
3 changes: 3 additions & 0 deletions grammar/decl.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ module.exports = {
$._bind_match,
)),

/**
* This is a supertype.
*/
decl: $ => choice(
$.signature,
$.function,
Expand Down
191 changes: 106 additions & 85 deletions grammar/exp.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
const {parens, brackets, sep1, layout, qualified} = require('./util.js')

module.exports = {

// ------------------------------------------------------------------------
// expression
// names
// ------------------------------------------------------------------------

_exp_name: $ => choice(
Expand All @@ -13,12 +14,15 @@ module.exports = {
$.label,
),

_exp_op: $ => choice(
$._sym,
$._op_ticked,
alias($._prefix_dot, $.operator),
_exp_th_quoted_name: $ => choice(
seq('\'', field('expression', choice($._vars, $._cons))),
prec('prefix', seq('\'\'', field('type', $.type))),
),

// ------------------------------------------------------------------------
// tuples and parens
// ------------------------------------------------------------------------

_exp_parens: $ => parens($, field('expression', $._exp)),

// Having this separate reduces size by ~15kB
Expand Down Expand Up @@ -55,33 +59,12 @@ module.exports = {
*/
_exp_unboxed_sum: $ => unboxed_sum_single($, $._exp),

_exp_section_left: $ => parens(
$,
field('left_operand', $.expression),
$._cond_left_section_op,
field('operator', choice(
$._exp_op,
$._operator_minus,
$._qsym,
)),
),

_exp_section_right: $ => parens(
$,
choice(
seq(alias($._operator_qual_dot_head, $.operator), $.expression),
seq($._ops, $.expression),
)
),
// ------------------------------------------------------------------------
// lists
// ------------------------------------------------------------------------

_exp_list: $ => brackets($, sep1(',', field('element', $._exp)), optional(',')),

_bind_statement: $ => seq(
field('pattern', $._pat),
$._larrow,
field('expression', $._exp),
),

/**
* An expression like `[1,2..20]`.
*/
Expand Down Expand Up @@ -115,14 +98,23 @@ module.exports = {
optional(seq('by', field('key', $._exp))),
),

generator: $ => seq(
field('pattern', $._pat),
$._larrow,
field('expression', $._exp),
),

qualifier: $ => choice(
alias($._bind_statement, $.generator),
$.generator,
$.let,
$.transform,
$.group,
alias($._exp, $.boolean),
),

/**
* This is a supertype.
*/
qualifiers: $ => seq(sep1(',', field('qualifier', $.qualifier))),

_exp_list_comprehension: $ => brackets(
Expand All @@ -131,10 +123,9 @@ module.exports = {
repeat1(seq('|', $.qualifiers)),
),

_exp_th_quoted_name: $ => choice(
seq('\'', field('expression', choice($._vars, $._cons))),
prec('prefix', seq('\'\'', field('type', $.type))),
),
// ------------------------------------------------------------------------
// greedy block args
// ------------------------------------------------------------------------

_exp_lambda: $ => seq(
'\\',
Expand Down Expand Up @@ -163,26 +154,52 @@ module.exports = {
),

/**
* This is a supertype.
* These block arguments don't end in a layout, so they all range over all following block arguments and will
* therefore always be the last argument in an application or infix chain.
* They also pull a trailing type annotation into their body.
*/
guard: $ => choice(
// Cannot be named `pattern` because of name clash.
alias($._bind_statement, $.pattern_guard),
$.let,
alias($._exp, $.boolean),
_exp_greedy: $ => choice(
alias($._exp_lambda, $.lambda),
alias($._exp_let_in, $.let_in),
alias($._exp_conditional, $.conditional),
),

guards: $ => sep1(',', field('guard', $.guard)),
// ------------------------------------------------------------------------
// do
// ------------------------------------------------------------------------

rec: $ => seq(
'rec',
layout($, $.statement),
),

_exp_statement: $ => $._exp,

/**
* Reused by `function`.
* This is a supertype.
*/
_guards: $ => seq(
$._bar,
$._cmd_texp_start,
field('guards', $.guards),
statement: $ => choice(
alias($._exp_statement, $.exp),
alias($.generator, $.bind),
$.let,
$.rec,
),

_do_keyword: _ => choice('mdo', 'do'),

do_module: $ => qualified($, $._do_keyword),

_do: $ => choice(
$.do_module,
$._do_keyword
),

_exp_do: $ => seq($._do, layout_sort($, $._cmd_layout_start_do, field('statement', $.statement))),

// ------------------------------------------------------------------------
// case
// ------------------------------------------------------------------------

match: $ => seq(
field('guards', $._guards),
optional($._phantom_arrow),
Expand Down Expand Up @@ -232,30 +249,9 @@ module.exports = {
optional(alias($._nalts, $.alternatives)),
),

rec: $ => seq(
'rec',
layout($, $.statement),
),

_exp_statement: $ => $._exp,

statement: $ => choice(
alias($._exp_statement, $.exp),
alias($._bind_statement, $.bind),
$.let,
$.rec,
),

_do_keyword: _ => choice('mdo', 'do'),

do_module: $ => qualified($, $._do_keyword),

_do: $ => choice(
$.do_module,
$._do_keyword
),

_exp_do: $ => seq($._do, layout_sort($, $._cmd_layout_start_do, field('statement', $.statement))),
// ------------------------------------------------------------------------
// record
// ------------------------------------------------------------------------

field_update: $ => choice(
alias('..', $.wildcard),
Expand Down Expand Up @@ -288,16 +284,9 @@ module.exports = {
field('field', $.field_name),
),

/**
* These block arguments don't end in a layout, so they all range over all following block arguments and will
* therefore always be the last argument in an application or infix chain.
* They also pull a trailing type annotation into their body.
*/
_exp_greedy: $ => choice(
alias($._exp_lambda, $.lambda),
alias($._exp_let_in, $.let_in),
alias($._exp_conditional, $.conditional),
),
// ------------------------------------------------------------------------
// application
// ------------------------------------------------------------------------

explicit_type: $ => parens($, 'type', field('type', $.type)),

Expand All @@ -310,6 +299,35 @@ module.exports = {
)),
)),

// ------------------------------------------------------------------------
// operators
// ------------------------------------------------------------------------

_exp_op: $ => choice(
$._sym,
$._op_ticked,
alias($._prefix_dot, $.operator),
),

_exp_section_left: $ => parens(
$,
field('left_operand', $.expression),
$._cond_left_section_op,
field('operator', choice(
$._exp_op,
$._operator_minus,
$._qsym,
)),
),

_exp_section_right: $ => parens(
$,
choice(
seq(alias($._operator_qual_dot_head, $.operator), $.expression),
seq($._ops, $.expression),
)
),

_exp_negation: $ => seq('-', prec('negation', field('expression', $.expression))),

/**
Expand All @@ -336,6 +354,13 @@ module.exports = {
field('right_operand', $.expression),
)),

// ------------------------------------------------------------------------
// top level
// ------------------------------------------------------------------------

/**
* This is a supertype.
*/
expression: $ => choice(
alias($._exp_infix, $.infix),
alias($._exp_negation, $.negation),
Expand Down Expand Up @@ -364,11 +389,7 @@ module.exports = {
alias($._exp_case, $.case),
alias($._exp_multi_way_if, $.multi_way_if),
$._exp_name,
$.splice,
$.quasiquote,
$.literal,
$._unit_cons,
$._tuple_cons,
$._universal,
),

_exp_signature: $ => prec.right('annotated', seq(
Expand Down
37 changes: 37 additions & 0 deletions grammar/general.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module.exports = {

// ------------------------------------------------------------------------
// guard
// ------------------------------------------------------------------------

/**
* This is a supertype.
*/
guard: $ => choice(
// Cannot be named `pattern` because of name clash.
alias($.generator, $.pattern_guard),
$.let,
alias($._exp, $.boolean),
),

guards: $ => sep1(',', field('guard', $.guard)),

_guards: $ => seq(
$._bar,
$._cmd_texp_start,
field('guards', $.guards),
),

// ------------------------------------------------------------------------
// rules shared by expression, pattern, type
// ------------------------------------------------------------------------

_universal: $ => choice(
$.splice,
$.quasiquote,
$.literal,
$._unit_cons,
$._tuple_cons,
),

}
Loading

0 comments on commit a316532

Please sign in to comment.