-
Notifications
You must be signed in to change notification settings - Fork 5
- Execution - Running generators
- Value Generators - Basic generators that produce a value.
- Basic Combinators - Primitive sequencing combinators.
- Choice Combinators - Randomly selecting a generator to run.
- Iteration Combinators - Running a generator multiple times.
- State Interaction Generators - Generators that interact with state.
Run a generator to completion, combining results into a string.
-
g
- Generator to run. -
ud
- Optional, user data. -
r
- Optional, custom random number generator.
const p = pep.seq('a', pep.choice('b', 'c'));
p.run() === 'ac';
p.run() === 'ac';
p.run() === 'ab';
Left fold over a generator.
-
f
- Accumulation function, passed accumulated value and current value. -
z
- Initial value. -
g
- Generator to run. -
ud
- Optional, user data. -
r
- Optional, custom random number generator.
const p = pep.seq('a', 'b', 'c');
pep.fold((p, c) => p.concat(c), [], p) === ['a', 'b', 'c'];
Begin the execution of a generator. Returns a Javascript iterator.
-
g
- Generator to run. -
ud
- Optional, user data. -
r
- Optional, custom random number generator.
Values are lazily produced. Javascript iterators are stateful, so you can only iterate over the result of begin
once.
const p = pep.seq('a', 'b', 'c');
for (const x of p.begin())
console.log(x);
Yields x
.
pep.lit('abc').run() === 'abc';
pep.lit(5).exec().next().value === 5;
Use lit
to force a generator to yield a non string value.
// Normally, `seq` will attempt to convert `myObj` to a string.
Array.from(pep.seq('a', myObj, 'c')) === ['a', '[Object object]', 'c'];
// But `lit`forces the object to be treated as a literal value.
Array.from(pep.seq('a', pep.lit(myObj), 'c')) === ['a', myObj, 'c'];
Yields x
as a string. x
is converted to a string when str
is first called.
pep.str('abc').run() === 'abc';
pep.str(5).exec().next().value === '5';
pep.str({}).exec().next().value === '[Object object]';
Note that pep.str('')
or pep.str()
is different from pep.empty
. The former yield the value ''
while the latter does not yield any values.
Generator that does not yield any values. This can be used with choice
to add the possibility that nothing will be output.
const p = pep.seq('a', pep.empty, 'b');
Array.from(p.begin()) === ['a', 'b'];
For most cases, empty
is the preferred way to indicate that no value is yielded, rather than pep.str('')
.
Run a sequence of generators from left to right.
const p = pep.seq(pep.str('a'), pep.str('bc'), pep.str('c'));
Array.from(p.begin()) === ['a', 'bc', 'd'];
Any non generator arguments are wrapped in pep.str
:
gen.pep('a', pep.choice(...), 3) === pep.seq(pep.str('a'), pep.choice(...), pep.str(3))
Map function f
over each element produced by p
.
const p = pep.seq('a', 'b', 'c').map(x => x + x);
p.run() === 'aabbcc';
``
Note that `f` is run on every value produced by `g`, not on the entire result of `g`. If you need to run on the entire result of `g`, use `join` or `combine` to merge all the results into a single value first.
```js
const p = pep.join(pep.seq('a', 'b', 'c')).map(x => x + x);
p.run() === 'abcabc';
Array.from(p.begin()) === ['abc', 'abc']
For each element produced by p
, run function f
and then run the generator that f
returns.
-
g
- Generator to run. -
f
- Function that maps values to generators
const p = pep.chain(pep.seq('a', 'b', 'c'), x => pep.seq(x, x));
p.run() === 'aabbcc';
Array.from(p.begin()) === ['a', 'a', 'b', 'b', 'c', 'c']
Note how the yielded values in this case differ from map
.
Like with map
, if you need to run on the entire result of g
, use join
or combine
to merge all the results into a single value first.
Left fold over the results of generators
, combining the results with f
. Yields only a single value.
-
g
- Generator to run. -
f
- Function that maps values to generators
const p = pep.combine(
(p, c) => [p, c],
'x',
pep.seq('a', pep.seq('b', 'c'), 'd'));
Array.from(p.begin()) === [[[[['x', 'a'], 'b'], 'c'], 'd']]
Combining all results of generators into a single string value.
const p = pep.join('a', pep.seq('b', 'c'), 'd');
Array.from(p.begin()) === ['abcd']
Randomly choose from along one or more generators. Each element has the same weight.
const p = pep.choice('a', 'b', c);
p.run() === 'c';
p.run() === 'a';
p.run() === 'c';
p.run() === 'b';
Use empty
to indicate the generator may choose to produce no value.
Randomly choose from along one or more generators, each with its own relative weight.
// Produce 'b' 70% of the time, 'a' 10% and 'c' 20%.
const p = weightedChoice([
[0.1, 'a'],
[0.7, 'b'],
[0.2, 'c']);
p.run() === 'b';
p.run() === 'b';
p.run() === 'c';
p.run() === 'b';
Use empty
to indicate the generator may choose to produce no value.
Mark a value as optional. Produce g
prob * 100% of the time and nothing (1 - prob) * 100% of the time
const p = pep.opt('a');
p.run() === '';
p.run() === 'a';
p.run() === 'a';