diff --git a/common/dialects.ts b/common/dialects.ts new file mode 100644 index 00000000..d47d18d3 --- /dev/null +++ b/common/dialects.ts @@ -0,0 +1,4 @@ +export enum Dialect { + DTN, + Tony, +} diff --git a/common/enums.ts b/common/enums.ts deleted file mode 100644 index 1bdf91c2..00000000 --- a/common/enums.ts +++ /dev/null @@ -1,37 +0,0 @@ -export enum Prec { - SubtractionType = -1, - UnionType = 0, - Assignment = 1, - TypeHint = 1, - CurriedType = 1, - NamedInfixApplication = 1, - SectionIdentifier = 1, - Literal = 1, - IntersectionType = 1, - LabeledType = 2, - OperatorInfixApplication = 2, - OptionalType = 3, - Biconditional = 3, - TaggedType = 4, - Implication = 4, - Or = 5, - And = 6, - Equality = 7, - Order = 8, - Mod = 9, - Sum = 10, - Product = 11, - Exponentiation = 12, - Not = 13, - PrefixApplication = 14, - Application = 15, - Term = 16, - Pattern = 16, - Access = 17, - Pipeline = 18, -} - -export enum Dialect { - DTN, - Tony, -} diff --git a/common/imports.ts b/common/imports.ts index b60a10d5..2a422ba8 100644 --- a/common/imports.ts +++ b/common/imports.ts @@ -1,4 +1,5 @@ -import { Dialect, Prec } from './enums' +import { Dialect } from './dialects' +import { Prec } from './precedences' import { commaSep1 } from './util' export const import_ = ($: GrammarSymbols) => @@ -16,7 +17,7 @@ export const _import_body_constructor = (dialect: Dialect) => < switch (dialect) { case Dialect.DTN: return prec.left( - Prec.Pattern, + Prec.PatternOrTerm, seq( '{', commaSep1(field('import', $.import_type)), @@ -27,7 +28,7 @@ export const _import_body_constructor = (dialect: Dialect) => < ) case Dialect.Tony: return prec.left( - Prec.Pattern, + Prec.PatternOrTerm, seq( choice( field('default', alias($.identifier, $.identifier_pattern_name)), diff --git a/common/literals.ts b/common/literals.ts index e9bea2da..d775383c 100644 --- a/common/literals.ts +++ b/common/literals.ts @@ -1,10 +1,9 @@ import { BIN, DIGITS, EXP, HEX, OCT } from './constants' -import { Prec } from './enums' import { buildString } from './util' export const _literal = ( $: GrammarSymbols, -) => prec(Prec.Literal, choice($.boolean, $.number, $.string, $.regex)) +) => choice($.boolean, $.number, $.string, $.regex) export const boolean = () => choice('false', 'true') diff --git a/common/patterns.ts b/common/patterns.ts index abefb772..f8525c72 100644 --- a/common/patterns.ts +++ b/common/patterns.ts @@ -1,9 +1,9 @@ import { buildList, buildMember, buildStruct, buildTuple } from './util' -import { Prec } from './enums' +import { Prec } from './precedences' export const _pattern = ( $: GrammarSymbols, -) => prec(Prec.Pattern, choice($._assignable_pattern, $._literal_pattern)) +) => prec(Prec.PatternOrTerm, choice($._assignable_pattern, $._literal_pattern)) export const _assignable_pattern = ( $: GrammarSymbols, @@ -19,7 +19,7 @@ export const destructuring_pattern = ( $: GrammarSymbols, ) => prec( - Prec.Pattern, + Prec.PatternOrTerm, seq( optional( seq( @@ -38,7 +38,7 @@ export const struct_pattern = ( $: GrammarSymbols, ) => prec( - Prec.Pattern, + Prec.PatternOrTerm, buildStruct( $, choice( @@ -55,17 +55,17 @@ export const member_pattern = ( export const tuple_pattern = ( $: GrammarSymbols, -) => prec(Prec.Pattern, buildTuple($, $._pattern, true)) +) => prec(Prec.PatternOrTerm, buildTuple($, $._pattern, true)) export const list_pattern = ( $: GrammarSymbols, -) => prec(Prec.Pattern, buildList($, $._pattern, true)) +) => prec(Prec.PatternOrTerm, buildList($, $._pattern, true)) export const identifier_pattern = ( $: GrammarSymbols, ) => prec.right( - Prec.Pattern, + Prec.PatternOrTerm, seq( field('name', alias($.identifier, $.identifier_pattern_name)), optional(seq('::', field('type', $._type))), @@ -88,4 +88,4 @@ export const _literal_pattern = ( export const pattern_group = ( $: GrammarSymbols, -) => prec(Prec.Pattern, seq('(', field('pattern', $._pattern), ')')) +) => prec(Prec.PatternOrTerm, seq('(', field('pattern', $._pattern), ')')) diff --git a/common/precedences.ts b/common/precedences.ts new file mode 100644 index 00000000..88a6a4ca --- /dev/null +++ b/common/precedences.ts @@ -0,0 +1,76 @@ +export enum Prec { + SubtractionType = 'SubtractionType', + Type = 'Type', + UnionType = 'UnionType', + CurriedOrIntersectionType = 'CurriedOrIntersectionType', + LabeledType = 'LabeledType', + OptionalType = 'OptionalType', + TaggedType = 'TaggedType', + + NamedInfixApplication = 'NamedInfixApplication', + OperatorInfixApplication = 'OperatorInfixApplication', + Biconditional = 'Biconditional', + Implication = 'Implication', + Or = 'Or', + And = 'And', + Equality = 'Equality', + Order = 'Order', + Mod = 'Mod', + Sum = 'Sum', + Product = 'Product', + Exponentiation = 'Exponentiation', + Not = 'Not', + Pipeline = 'Pipeline', + + Identifier = 'Identifier', + SectionIdentifier = 'SectionIdentifier', + TypeHint = 'TypeHint', + TaggedValue = 'TaggedValue', + Assignment = 'Assignment', + PrefixApplication = 'PrefixApplication', + Application = 'Application', + PatternOrTerm = 'PatternOrTerm', + Access = 'Access', +} + +const typePrecedences = [ + Prec.Access, + Prec.TaggedType, + Prec.OptionalType, + Prec.LabeledType, + Prec.CurriedOrIntersectionType, + Prec.UnionType, + Prec.Type, + Prec.SubtractionType, +] + +const termPrecedences = [ + Prec.Pipeline, + Prec.Access, + Prec.PatternOrTerm, + Prec.Application, + Prec.PrefixApplication, + Prec.Not, + Prec.Exponentiation, + Prec.Product, + Prec.Sum, + Prec.Mod, + Prec.Order, + Prec.Equality, + Prec.And, + Prec.Or, + Prec.Implication, + Prec.Biconditional, + Prec.OperatorInfixApplication, + Prec.NamedInfixApplication, + Prec.Assignment, + Prec.TypeHint, + Prec.TaggedValue, + Prec.SectionIdentifier, + Prec.Identifier, +] + +export const precedences = () => [ + typePrecedences, + termPrecedences, +] diff --git a/common/terms.ts b/common/terms.ts index 58f1f3cc..4849dde5 100644 --- a/common/terms.ts +++ b/common/terms.ts @@ -10,7 +10,7 @@ import { buildTuple, commaSep1, } from './util' -import { Prec } from './enums' +import { Prec } from './precedences' export const _term = ($: GrammarSymbols) => choice(seq($._simple_term, $._newline), $._compound_term) @@ -19,7 +19,7 @@ export const _simple_term = ( $: GrammarSymbols, ) => prec.left( - Prec.Term, + Prec.PatternOrTerm, choice( alias($.simple_abstraction, $.abstraction), $.application, @@ -49,7 +49,7 @@ export const _compound_term = ( $: GrammarSymbols, ) => prec.left( - Prec.Term, + Prec.PatternOrTerm, choice( alias($.compound_abstraction, $.abstraction), alias($.compound_assignment, $.assignment), @@ -175,6 +175,7 @@ export const simple_abstraction = ( $: GrammarSymbols, ) => prec.left( + Prec.PatternOrTerm, commaSep1( field('branch', alias($.simple_abstraction_branch, $.abstraction_branch)), ), @@ -188,6 +189,7 @@ export const compound_abstraction = ( $: GrammarSymbols, ) => prec.left( + Prec.PatternOrTerm, repeat1( field( 'branch', @@ -519,7 +521,7 @@ export const when = ($: GrammarSymbols) => export const struct = ($: GrammarSymbols) => prec( - Prec.Term, + Prec.PatternOrTerm, buildStruct( $, choice($.member, alias($.identifier, $.shorthand_member), $.spread), @@ -530,10 +532,10 @@ export const member = ($: GrammarSymbols) => buildMember($, $._simple_term, $._simple_term) export const tuple = ($: GrammarSymbols) => - prec(Prec.Term, buildTuple($, $._element)) + prec(Prec.PatternOrTerm, buildTuple($, $._element)) export const list = ($: GrammarSymbols) => - prec(Prec.Term, buildList($, $._element)) + prec(Prec.PatternOrTerm, buildList($, $._element)) export const _element = ( $: GrammarSymbols, @@ -545,10 +547,13 @@ export const spread = ($: GrammarSymbols) => export const tagged_value = ( $: GrammarSymbols, ) => - seq( - ':', - field('name', alias($._identifier_without_operators, $.identifier)), - field('value', $._simple_term), + prec.right( + Prec.TaggedValue, + seq( + ':', + field('name', alias($._identifier_without_operators, $.identifier)), + field('value', $._simple_term), + ), ) export const type_alias = ( @@ -577,7 +582,7 @@ export const _operator = () => OPERATOR export const identifier = ( $: GrammarSymbols, -) => choice($._operator, $._identifier_without_operators) +) => prec(Prec.Identifier, choice($._operator, $._identifier_without_operators)) export const group = ($: GrammarSymbols) => seq('(', field('term', $._simple_term), ')') diff --git a/common/types.ts b/common/types.ts index 9c5d88f5..d14d2db8 100644 --- a/common/types.ts +++ b/common/types.ts @@ -1,4 +1,4 @@ -import { Dialect, Prec } from './enums' +import { Dialect } from './dialects' import { buildGenericType, buildStruct, @@ -7,6 +7,7 @@ import { commaSep1, } from './util' import { TYPE } from './constants' +import { Prec } from './precedences' export const type_variable_declaration = ( $: GrammarSymbols, @@ -50,7 +51,7 @@ export const _type_constructor = (dialect: Dialect) => < $.refinement_type_declaration, ) - return choice(...choices) + return prec(Prec.Type, choice(...choices)) } export const _term_type = ( @@ -80,7 +81,7 @@ export const curried_type = ( $: GrammarSymbols, ) => prec.right( - Prec.CurriedType, + Prec.CurriedOrIntersectionType, seq(field('from', $._type), '->', field('to', $._type)), ) @@ -88,7 +89,7 @@ export const intersection_type = ( $: GrammarSymbols, ) => prec.right( - Prec.IntersectionType, + Prec.CurriedOrIntersectionType, seq(field('left', $._type), '&', field('right', $._type)), ) @@ -198,7 +199,7 @@ export const optional_type = ( export const tagged_type = ( $: GrammarSymbols, ) => - prec( + prec.right( Prec.TaggedType, seq( ':', diff --git a/dtn/grammar.ts b/dtn/grammar.ts index 582b33a1..50ca28dc 100644 --- a/dtn/grammar.ts +++ b/dtn/grammar.ts @@ -46,8 +46,9 @@ import { declaration_member, js_identifier, } from '../common/declarations' -import { Dialect } from '../common/enums' +import { Dialect } from '../common/dialects' import { comment } from '../common/miscellaneous' +import { precedences } from '../common/precedences' const dialect = Dialect.DTN @@ -65,7 +66,7 @@ export = grammar({ extras: ($) => [$.comment, /\s+/], word: ($) => $._identifier_without_operators, - precedences: () => [], + precedences, rules: { program: ($) => diff --git a/tony/grammar.ts b/tony/grammar.ts index e167f1ca..9720486b 100644 --- a/tony/grammar.ts +++ b/tony/grammar.ts @@ -113,7 +113,8 @@ import { union_type, } from '../common/types' import { comment, hash_bang_line } from '../common/miscellaneous' -import { Dialect } from '../common/enums' +import { Dialect } from '../common/dialects' +import { precedences } from '../common/precedences' const dialect = Dialect.Tony @@ -132,11 +133,17 @@ export = grammar({ word: ($) => $._identifier_without_operators, conflicts: ($) => [ [$._simple_term, $.identifier_pattern], + [$._simple_term, $._type], [$._simple_term, $.identifier_pattern, $._type], + [$.import_identifier, $.identifier_pattern], + [$.refinement_type_declaration, $.identifier_pattern], [$.string, $.raw_string], + [$._literal, $._literal_pattern], [$.struct, $.struct_pattern], + [$.struct, $.struct_type], [$.struct, $.struct_pattern, $.struct_type], [$.tuple, $.tuple_pattern], + [$.tuple, $.tuple_type], [$.tuple, $.tuple_pattern, $.tuple_type], [$.list, $.list_pattern], [$.application, $.prefix_application, $.infix_application], @@ -147,7 +154,7 @@ export = grammar({ [$.tagged_pattern, $.tagged_type], ], - precedences: () => [], + precedences, rules: { program: ($) =>