diff --git a/grammar.js b/grammar.js index 778fbdb5..81c7ffc0 100644 --- a/grammar.js +++ b/grammar.js @@ -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') @@ -28,6 +29,7 @@ module.exports = grammar({ optional($._body), ), + ...general, ...type, ...context, ...exp, diff --git a/grammar/context.js b/grammar/context.js index 2f955ad0..303ead3b 100644 --- a/grammar/context.js +++ b/grammar/context.js @@ -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, diff --git a/grammar/decl.js b/grammar/decl.js index aacf8e65..1bf6fba4 100644 --- a/grammar/decl.js +++ b/grammar/decl.js @@ -108,6 +108,9 @@ module.exports = { $._bind_match, )), + /** + * This is a supertype. + */ decl: $ => choice( $.signature, $.function, diff --git a/grammar/exp.js b/grammar/exp.js index 223fb15a..1b6a07cb 100644 --- a/grammar/exp.js +++ b/grammar/exp.js @@ -1,8 +1,9 @@ const {parens, brackets, sep1, layout, qualified} = require('./util.js') module.exports = { + // ------------------------------------------------------------------------ - // expression + // names // ------------------------------------------------------------------------ _exp_name: $ => choice( @@ -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 @@ -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]`. */ @@ -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( @@ -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( '\\', @@ -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), @@ -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), @@ -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)), @@ -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))), /** @@ -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), @@ -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( diff --git a/grammar/general.js b/grammar/general.js new file mode 100644 index 00000000..477b0e92 --- /dev/null +++ b/grammar/general.js @@ -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, + ), + +} diff --git a/grammar/inline.js b/grammar/inline.js index 78efee6b..cc4f4578 100644 --- a/grammar/inline.js +++ b/grammar/inline.js @@ -1,15 +1,20 @@ module.exports = { inline: $ => [ - $._number, - $._stringly, + + // ------------------------------------------------ + // variable + // ------------------------------------------------ $._var, $._vars, $._varids, $._varids_ticked, $._varop, - $._qvarsym, + + // ------------------------------------------------ + // constructor + // ------------------------------------------------ $._constructor, $._con, @@ -18,57 +23,69 @@ module.exports = { $._conids, $._conids_ticked, $._conop, - $._qconsym, - $._op_ticked, - $._modid, - $._tyconid, - $._tyconids, - $._tycon, - $._qtycon, - $._tycons, - $._tyconops, - $._tyops, + // ------------------------------------------------ + // operator + // ------------------------------------------------ + $._qvarsym, + $._qconsym, $._sym, $._qsym, $._pqsym, + $._any_prefix_dot, + $._any_tight_dot, + $._unboxed_bar, - $._type_annotation, - $._kind_annotation, - - $._parameter_type, - $._field_type, - - $._pat_apply_arg, - $._type_apply_arg, + // ------------------------------------------------ + // expression + // ------------------------------------------------ $._exp_name, $._exp_greedy, $._let, + // ------------------------------------------------ + // pattern + // ------------------------------------------------ + + $._pat_apply_arg, $._pat_name, $._pat_texp, - $._type_name, - $._forall, - - $._unboxed_bar, + // ------------------------------------------------ + // type + // ------------------------------------------------ - $._unit_cons, - $._tuple_cons, + $._tyconid, + $._tyconids, + $._tycon, + $._qtycon, + $._tycons, + $._tyconops, + $._tyops, + $._type_name, + $._forall, + $._type_apply_arg, + $._parameter_type, + $._field_type, $._type_head, $._type_instance_head, + $._type_annotation, + $._kind_annotation, // ------------------------------------------------ - // dot + // literal // ------------------------------------------------ - $._any_prefix_dot, - $._any_tight_dot, + $._number, + $._stringly, + $._unit_cons, + $._tuple_cons, + $._universal, // ------------------------------------------------ // function vs bind diff --git a/grammar/literal.js b/grammar/literal.js index 0a4f6136..c565dd5e 100644 --- a/grammar/literal.js +++ b/grammar/literal.js @@ -7,6 +7,7 @@ hex_exponent = /[pP][+-]?[0-9a-fA-F_]+/ magic_hash = rule => token(seq(rule, optional(token.immediate(/##?/)))) module.exports = { + // ------------------------------------------------------------------------ // literals // ------------------------------------------------------------------------ diff --git a/grammar/module.js b/grammar/module.js index 894bb359..6430994a 100644 --- a/grammar/module.js +++ b/grammar/module.js @@ -71,6 +71,9 @@ module.exports = { alias($._cond_layout_end_explicit, '}'), ), + /** + * This is a supertype. + */ declaration: $ => choice( $.decl, $.type_synomym, diff --git a/grammar/operator.js b/grammar/operator.js index 09f702c6..8855d5ed 100644 --- a/grammar/operator.js +++ b/grammar/operator.js @@ -1,6 +1,7 @@ const {parens} = require('./util.js') module.exports = { + // ------------------------------------------------------------------------ // var // ------------------------------------------------------------------------ diff --git a/grammar/pat.js b/grammar/pat.js index 674f574b..880b0ea3 100644 --- a/grammar/pat.js +++ b/grammar/pat.js @@ -2,8 +2,42 @@ const {parens, brackets, braces} = require('./util.js') module.exports = { + // ------------------------------------------------------------------------ + // tuples and parens + // ------------------------------------------------------------------------ + + _pat_parens: $ => parens($, field('pattern', $._pat_texp)), + + _pat_tuple_elems: $ => sep2(',', field('element', $._pat_texp)), + + _pat_tuple: $ => parens($, $._pat_tuple_elems), + + _pat_unboxed_tuple: $ => unboxed_tuple_full($, $._pat_texp), + + _pat_unboxed_sum: $ => unboxed_sum_single($, $._pat_texp), + + _pat_list: $ => brackets($, sep1(',', field('element', $._pat_texp)), optional(',')), + + // ------------------------------------------------------------------------ + // record + // ------------------------------------------------------------------------ + + field_pattern: $ => choice( + alias('..', $.wildcard), + seq(field('field', $._field_names), optional(seq('=', field('pattern', $._pat_texp)))), + ), + + _pat_record: $ => prec('record', seq( + field('constructor', $.pattern), + braces($, sep(',', field('field', $.field_pattern))), + )), + + // ------------------------------------------------------------------------ + // misc + // ------------------------------------------------------------------------ + /** - * This dynamic precedence penalty ensures is relevant for the conflict between `function` and `bind`. + * This dynamic precedence penalty is relevant for the conflict between `function` and `bind`. * Consider: * * > f (A a) = exp @@ -24,71 +58,50 @@ module.exports = { $._cons, ), - field_pattern: $ => choice( - alias('..', $.wildcard), - seq(field('field', $._field_names), optional(seq('=', field('pattern', $._pat_texp)))), - ), - _pat_as: $ => prec('prefix', seq(field('bind', $.variable), $._tight_at, field('pattern', $.pattern))), - _pat_record: $ => prec('record', seq( - field('constructor', $.pattern), - braces($, sep(',', field('field', $.field_pattern))), - )), - _pat_wildcard: _ => '_', - _pat_parens: $ => parens($, field('pattern', $._pat_texp)), - - _pat_tuple_elems: $ => sep2(',', field('element', $._pat_texp)), - - _pat_tuple: $ => parens($, $._pat_tuple_elems), - - _pat_unboxed_tuple: $ => unboxed_tuple_full($, $._pat_texp), - - _pat_unboxed_sum: $ => unboxed_sum_single($, $._pat_texp), - - _pat_list: $ => brackets($, sep1(',', field('element', $._pat_texp)), optional(',')), - _pat_strict: $ => prec('prefix', seq($._any_prefix_bang, field('pattern', $.pattern))), _pat_irrefutable: $ => prec('prefix', seq($._any_prefix_tilde, field('pattern', $.pattern))), + // ------------------------------------------------------------------------ + // application + // ------------------------------------------------------------------------ + _pat_apply_arg: $ => choice( $.pattern, alias($._at_type, $.type_binder), $.explicit_type, ), - _pat_op: $ => choice( - $.constructor_operator, - $._conids_ticked, - ), - - // ------------------------------------------------------------------------------------------------------------------- - // non-atomic - // ------------------------------------------------------------------------------------------------------------------- - _pat_apply: $ => prec.left('apply', seq( field('function', $.pattern), field('argument', $._pat_apply_arg), )), + // ------------------------------------------------------------------------ + // operators + // ------------------------------------------------------------------------ + _pat_negation: $ => seq('-', field('number', $._number)), _pat_infix: $ => prec.right('infix', seq( field('left_operand', $.pattern), optional($._cond_no_section_op), - choice( - field('operator', $._pat_op), - seq( - $._cond_qualified_op, - field('operator', $._qconsym), - ), - ), + field('operator', choice( + $.constructor_operator, + $._conids_ticked, + seq($._cond_qualified_op, $._qconsym), + )), field('right_operand', $.pattern), )), + // ------------------------------------------------------------------------ + // top level + // ------------------------------------------------------------------------ + pattern: $ => choice( alias($._pat_infix, $.infix), alias($._pat_negation, $.negation), @@ -105,13 +118,11 @@ module.exports = { alias($._plist, $.list), alias($._pat_strict, $.strict), alias($._pat_irrefutable, $.irrefutable), - $.splice, - $.quasiquote, - $.literal, - $._unit_cons, - $._tuple_cons, + $._universal, ), + patterns: $ => repeat1(prec('patterns', $._pat_apply_arg)), + _pat_signature: $ => prec.right('annotated', seq( field('pattern', $.pattern), $._type_annotation, @@ -122,13 +133,8 @@ module.exports = { prec.right($.pattern), ), - patterns: $ => repeat1(prec('patterns', $._pat_apply_arg)), - view_pattern: $ => seq(field('expression', $._exp), $._arrow, field('pattern', $._pat_texp)), - _pat_texp: $ => choice( - $.view_pattern, - $._pat, - ) + _pat_texp: $ => choice($.view_pattern, $._pat), } diff --git a/grammar/type.js b/grammar/type.js index 52640d4c..6731aa5c 100644 --- a/grammar/type.js +++ b/grammar/type.js @@ -16,6 +16,9 @@ module.exports = { _type_param_invisible: $ => prefix_at($, field('bind', $.type_param)), + /** + * This is a supertype. + */ type_param: $ => choice( alias($._type_param_wildcard, $.wildcard), alias($._type_param_invisible, $.invisible), @@ -33,35 +36,11 @@ module.exports = { quantified_variables: $ => repeat1(choice($.type_param, alias($._inferred_tyvar, $.inferred))), // ------------------------------------------------------------------------ - // type + // tuples and parens // ------------------------------------------------------------------------ - _forall_keyword: _ => choice('forall', '∀'), - - _forall_body: $ => seq( - field('quantifier', $._forall_keyword), - optional(field('variables', $.quantified_variables)), - ), - - forall: $ => prec('qtype-single', seq( - $._forall_body, - '.', - )), - - forall_required: $ => prec('qtype-single', seq( - $._forall_body, - $._arrow, - )), - - _forall: $ => choice( - $.forall, - $.forall_required, - ), - _type_parens: $ => parens($, field('type', $._ktype)), - _type_list: $ => brackets($, sep1(',', field('element', $._ktype))), - _type_tuple_elems: $ => sep2(',', field('element', $._ktype)), /** @@ -70,13 +49,23 @@ module.exports = { */ _type_tuple: $ => parens($, $._type_tuple_elems), + _type_unboxed_tuple: $ => unboxed_tuple_full($, $._ktype), + + _type_unboxed_sum: $ => unboxed_sum_full($, $._ktype), + + _type_list: $ => brackets($, sep1(',', field('element', $._ktype))), + + // ------------------------------------------------------------------------ + // names etc + // ------------------------------------------------------------------------ + _type_promoted: $ => seq( '\'', choice( alias($._plist, $.empty_list), - $.prefix_tuple, alias($._type_tuple, $.tuple), alias($._type_list, $.list), + $.prefix_tuple, $.unit, ), ), @@ -84,22 +73,17 @@ module.exports = { _type_name: $ => choice( $.variable, $._promoted_tycons, + prec('type-name', $._tycons), ), - _type_con: $ => prec('type-name', choice( - $._tycons, - $.unit, - alias($._plist, $.type_prefix_list) - )), - _type_star: _ => choice('*', '★'), - _type_unboxed_tuple: $ => unboxed_tuple_full($, $._ktype), - - _type_unboxed_sum: $ => unboxed_sum_full($, $._ktype), - _type_wildcard: _ => '_', + // ------------------------------------------------------------------------ + // application + // ------------------------------------------------------------------------ + _at_type: $ => prefix_at($, field('type', $.type)), _type_apply_arg: $ => choice($.type, alias($._at_type, $.kind_application)), @@ -112,41 +96,80 @@ module.exports = { field('argument', $._type_apply_arg), )), + // ------------------------------------------------------------------------ + // infix + // ------------------------------------------------------------------------ + _type_infix: $ => prec.right('infix', seq( field('left_operand', $.type), field('operator', $._tyops), field('right_operand', $.type), )), + // ------------------------------------------------------------------------ + // unquantified type + // ------------------------------------------------------------------------ + + /** + * This is a supertype. + */ type: $ => choice( $._type_name, - $._type_con, alias($._type_star, $.star), alias($._type_wildcard, $.wildcard), alias($._type_parens, $.parens), alias($._type_promoted, $.promoted), alias($._type_list, $.list), + alias($._plist, $.prefix_list), alias($._type_unboxed_tuple, $.unboxed_tuple), alias($._type_unboxed_sum, $.unboxed_sum), alias($._type_tuple, $.tuple), - $.splice, - $.quasiquote, - $.literal, - $.unboxed_unit, - $._tuple_cons, alias($._type_infix, $.infix), alias($._type_apply, $.apply), + $._universal, + ), + + // ------------------------------------------------------------------------ + // forall + // ------------------------------------------------------------------------ + + _forall_keyword: _ => choice('forall', '∀'), + + _forall_body: $ => seq( + field('quantifier', $._forall_keyword), + optional(field('variables', $.quantified_variables)), + ), + + forall: $ => prec('qtype-single', seq( + $._forall_body, + '.', + )), + + forall_required: $ => prec('qtype-single', seq( + $._forall_body, + $._arrow, + )), + + _forall: $ => choice( + $.forall, + $.forall_required, ), _qtype_forall: $ => prec.right('qtype-curried', seq($._forall_body, '.', $.quantified_type)), _qtype_forall_required: $ => prec.right('qtype-curried', seq($._forall_body, $._arrow, $.quantified_type)), + // ------------------------------------------------------------------------ + // function + // ------------------------------------------------------------------------ + _fun_arrow: $ => seq( optional($._phantom_arrow), $._arrow, ), + modifier: $ => prec('prefix', seq($._prefix_percent, $.type)), + _linear_fun_arrow: $ => choice( seq( field('multiplicity', $.modifier), @@ -184,11 +207,22 @@ module.exports = { field('result', $.quantified_type), )), + // ------------------------------------------------------------------------ + // context + // ------------------------------------------------------------------------ + _qtype_context: $ => prec.right('qtype-curried', seq( $._context_inline, field('type', $.quantified_type), )), + // ------------------------------------------------------------------------ + // top level + // ------------------------------------------------------------------------ + + /** + * This is a supertype. + */ quantified_type: $ => choice( alias($._qtype_function, $.function), alias($._qtype_linear_function, $.linear_function), @@ -219,8 +253,6 @@ module.exports = { $.quantified_type, ), - modifier: $ => prec('prefix', seq($._prefix_percent, $.type)), - // ------------------------------------------------------------------------ // type head // ------------------------------------------------------------------------ @@ -228,7 +260,7 @@ module.exports = { _type_head_name: $ => field('name', choice( $._tycon, $.unit, - alias($._plist, $.type_prefix_list), + alias($._plist, $.prefix_list), )), _type_head_parens: $ => parens( diff --git a/test/corpus/context.txt b/test/corpus/context.txt index 4894c689..b7047384 100644 --- a/test/corpus/context.txt +++ b/test/corpus/context.txt @@ -1100,3 +1100,19 @@ a :: (a + a => a) => a (variable)) (variable))) (variable))))) + +================================================================================ +context: empty +================================================================================ + +a :: () => a + +-------------------------------------------------------------------------------- + +(haskell + (declarations + (signature + (variable) + (context + (unit) + (variable))))) diff --git a/test/corpus/data.txt b/test/corpus/data.txt index 3c24df0f..b7068066 100644 --- a/test/corpus/data.txt +++ b/test/corpus/data.txt @@ -503,6 +503,21 @@ data A deriving (∀ a . A a :: Type -> Constraint) (name) (name)))))))) +================================================================================ +data: deriving empty +================================================================================ + +data A deriving () + +-------------------------------------------------------------------------------- + +(haskell + (declarations + (data_type + (name) + (deriving + (unit))))) + ================================================================================ data: datatype context trivial ================================================================================ @@ -874,7 +889,7 @@ data [] a = MkNil (special (unit))))) (data_type - (type_prefix_list) + (prefix_list) (type_params (variable)) (data_constructors diff --git a/test/corpus/type.txt b/test/corpus/type.txt index 8a7a438f..bd3448d5 100644 --- a/test/corpus/type.txt +++ b/test/corpus/type.txt @@ -98,7 +98,7 @@ type A = [A a] (declarations (type_synomym (name) - (type_prefix_list)) + (prefix_list)) (type_synomym (name) (list