Skip to content

Commit c3a7e63

Browse files
committed
Simplify molecule parsers more
1 parent aa1a9cf commit c3a7e63

File tree

1 file changed

+28
-37
lines changed

1 file changed

+28
-37
lines changed

src/language/parsing/molecule.ts

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
as,
32
lazy,
43
literal,
54
map,
@@ -29,18 +28,9 @@ export const moleculeParser: Parser<Molecule> = oneOf([
2928
lazy(() => sugaredFunction),
3029
])
3130

32-
// During parsing molecules and properties are represented as nested arrays (of key/value pairs).
33-
// The following utilities make it easier to work with such a structure.
34-
35-
const omit = (theParser: Parser<unknown>) => as(theParser, [])
36-
3731
const optional = <Output>(
38-
theParser: Parser<readonly Output[]>,
39-
): Parser<readonly Output[]> => oneOf([theParser, omit(nothing)])
40-
41-
const withoutOmittedOutputs = <Output>(
42-
theParser: Parser<readonly (readonly Output[])[]>,
43-
) => map(theParser, output => output.filter(output => output.length > 0))
32+
parser: Parser<NonNullable<Output>>,
33+
): Parser<Output | undefined> => oneOf([parser, nothing])
4434

4535
// Keyless properties are automatically assigned numeric indexes, which uses some mutable state.
4636
type Indexer = () => string
@@ -54,8 +44,6 @@ const makeIncrementingIndexer = (): Indexer => {
5444
}
5545
}
5646

57-
// Language-specific parsers follow.
58-
5947
const propertyDelimiter = oneOf([
6048
sequence([optional(trivia), literal(','), optional(trivia)]),
6149
trivia,
@@ -130,28 +118,31 @@ const property = (index: Indexer) =>
130118
oneOf([namedProperty, numberedProperty(index)]),
131119
)
132120

133-
const moleculeAsEntries = (index: Indexer) =>
134-
withoutOmittedOutputs(
135-
map(
136-
sequence([
137-
literal('{'),
138-
// Allow initial property not preceded by a delimiter (e.g. `{a b}`).
139-
map(optional(property(index)), property => [property]),
140-
zeroOrMore(
141-
map(
142-
sequence([propertyDelimiter, property(index)]),
143-
([_delimiter, property]) => property,
144-
),
121+
const moleculeAsEntries = (
122+
index: Indexer,
123+
): Parser<readonly (readonly [string, string | Molecule])[]> =>
124+
map(
125+
sequence([
126+
literal('{'),
127+
// Allow initial property not preceded by a delimiter (e.g. `{a b}`).
128+
optional(property(index)),
129+
zeroOrMore(
130+
map(
131+
sequence([propertyDelimiter, property(index)]),
132+
([_delimiter, property]) => property,
145133
),
146-
optional(omit(propertyDelimiter)),
147-
literal('}'),
148-
]),
149-
([
150-
_openingBrace,
151-
optionalInitialProperty,
152-
remainingProperties,
153-
_delimiter,
154-
_closingBrace,
155-
]) => [...optionalInitialProperty, ...remainingProperties],
156-
),
134+
),
135+
optional(propertyDelimiter),
136+
literal('}'),
137+
]),
138+
([
139+
_openingBrace,
140+
optionalInitialProperty,
141+
remainingProperties,
142+
_delimiter,
143+
_closingBrace,
144+
]) =>
145+
optionalInitialProperty === undefined
146+
? remainingProperties
147+
: [optionalInitialProperty, ...remainingProperties],
157148
)

0 commit comments

Comments
 (0)