tidal.pegjs
is a parsing expression grammar for the TidalCycles pattern language, written using PEG.js. The goal of the PEG is to easily translate strings of Tidal patterns into annotated JavaScript data structures for use in sequencing.
The easiest way to use this peg is by using Gulp. More details are in the Development section.
'0 2 4 6' ==>
{
'0': {type: 'number', value: 0},
'1/4': {type: 'number', value: 2},
'1/2': {type: 'number', value: 4},
'3/4': {type: 'number', value: 6},
type: 'group'
}
'0 [[2 3] [2 4(3,8,9) 7*2]] 5' =>
{
'0': {type: 'number', value: 0},
'1/3':{
'0':{
'0': {type: 'number', value:2},
'1/2': {type: 'number', value: 3},
type: 'group'
},
'1/2': {
'0': {type: 'number', value: 2},
'1/3': {
value: {type: 'number', value: 4},
soundNum: {type: 'number', value: 3},
steps: {type: 'number', value: 8},
rotateStep: {type: 'number', value: 9},
type: 'euclid'
},
'2/3': {
type: 'repeat',
operator: '*',
repeatValue: {type: 'number', value: 2},
value: {type: 'number', value:7}
}
}
},
'2/3': {type: 'number', value: 5},
type: 'group'
}
The parsed objects can be flattened to generate an output where the keys are fractions corresponding to the section of each sub-pattern in a full cycle
{
'0': {type: 'number', value: 0},
'1/3': {
'0': {
'0': {type: 'number', value: 0},
'1/3': {type: 'number', value: 1},
'2/3': {type: 'number', value: 2},
type: 'group'
},
'1/2': {
'0': {type: 'number', value: 3},
'1/2': {type: 'number', value: 4},
type: 'group'
},
type: 'group'
},
'2/3': {type: 'number', value: 5},
type: 'group'
}
Flattened ==>
{
'0': {type: 'number', value: 0},
'1/3': {type: 'number', value: '0'},
'7/18': {type: 'number', value: '1'},
'4/9': {type: 'number', value: '2'},
'1/2': {type: 'number', value: '3'},
'7/12': {type: 'number', value: '4'},
'2/3': {type: 'number', value: '5'},
}
{
type:'repeat',
operator: '*',
repeatValue:{ type:'number', value:2 },
value: {
'0': { type:'number', value:2 },
'1/2': { type:'number', value:1 },
type: 'group'
}
}
Flattened ==>
{
'0': {type: 'number', value:2},
'1/4': {type: 'number', value: 1},
'1/2': {type: 'number', value: 2},
'3/4': {type: 'number', value: 1},
type: 'group'
}
To install all dependencies run npm install
All files generated by using Gulp will be located in the dist
folder. It is all you will need to use the files as modules to parse and flatten Tidal patterns.
If you want to modify any of the files you can run gulp watch
in the background which will re-compile and run the tests automatically every time there is any modification in any of the files.
-
Compile the parser into a js module:
-
Run
gulp build
-
Pass any Tidal pattern to the parse function as:
const parser = require( './dist/peg-parse.js' ); // Modify path to this file if necessary parser.parse(' 1 2 3 ')
The
peg-parse.js
file can be required as a module in Node.js or in the browser using browserify, etc.For more instructions on compiling parsers, see https://pegjs.org/documentation#generating-a-parser-javascript-api.
-
-
Compile the flattener:
-
Run
gulp flatten
-
Pass any parsed Tidal pattern to the flatten function as:
let flattener = require('./dist/peg-parse-flatten.js'); // Modify path to this file if necessary flattener.flatten({ '0': {type: 'number', value: 0}, '1/3': {type: 'number', value: 1}, '2/3': {type: 'number', value: 2}, type: 'group' });
The
peg-parse-flatten.js
file can be required as a module in Node.js or in the browser using browserify, etc. -
-
Run the mocha tests:
gulp test
-
Watch for changes in any file or tests and run tests automatically whenever this happens:
gulp watch
-
Clean everything that was generated with gulp from the dist folder:
gulp clean
It's recommended to use Gulp since the tasks are clearly defined and the resulting files in the dist
folder are pretty much all you need, but here are instructions to work without it as well.
We haven't done any work making this tidy yet, but will try to do so soon. For now, installing the dependencies can be done with: npm install pegjs -g
For testing you'll also need npm install mocha -g
To compile the parser into a JS module, use pegjs tidal.pegjs
in the top-level directory of this repo. This will create a file named tidal.js
that can be required as a module in Node.js or in the browser using browserify etc.
To compile the parser as a global variable: pegjs --format globals --export-var Tidal tidal.pegjs
.
For more instructions on compiling parsers, see https://pegjs.org/documentation#generating-a-parser-javascript-api.
Tests are done with Mocha, you'll need to have it installed globally. You should also have peg.js installed locally: npm install pegjs
Then run mocha
from the top-level directory to run the parsing tests.
There are still some issues with this project, which can be found in the TODO.md
file. If you see anything else and fix it feel free to create pull requests.
Graham Wakefield and Charlie Roberts ran a workshop on using PEGs to create musical programming languages; check it out for more about how PEGs work and tutorials on creating your own mini-languages.