Skip to content

Commit a076c52

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

File tree

1 file changed

+28
-35
lines changed

1 file changed

+28
-35
lines changed

src/language/parsing/molecule.ts

Lines changed: 28 additions & 35 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
@@ -130,28 +120,31 @@ const property = (index: Indexer) =>
130120
oneOf([namedProperty, numberedProperty(index)]),
131121
)
132122

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

0 commit comments

Comments
 (0)