This commit is contained in:
Felix Roos 2022-02-21 01:00:12 +01:00
parent 3b248ae94c
commit 966de74d5b
10 changed files with 301 additions and 39 deletions

View file

@ -1936,6 +1936,7 @@ function peg$parse(input, options) {
this.type_ = "element"; this.type_ = "element";
this.source_ = source; this.source_ = source;
this.options_ = options; this.options_ = options;
this.location_ = location();
} }
var CommandStub = function(name, options) var CommandStub = function(name, options)

View file

@ -604,6 +604,30 @@ Pattern.prototype.bootstrap = () => {
})); }));
return bootstrapped; return bootstrapped;
}; };
function withLocationOffset(pat, offset) {
let startLine;
return pat.fmap((value) => {
value = typeof value === "object" && !Array.isArray(value) ? value : {value};
let locations = value.locations || [];
startLine = startLine || locations[0].start.line;
locations = locations.map(({start, end}) => {
const colOffset = startLine === end.line ? offset.start.column : 0;
return {
start: {
...start,
line: start.line - 1 + (offset.start.line - 1) + 1,
column: start.column - 1 + colOffset
},
end: {
...end,
line: end.line - 1 + (offset.start.line - 1) + 1,
column: end.column - 1 + colOffset
}
};
});
return {...value, locations};
});
}
export { export {
Fraction, Fraction,
TimeSpan, TimeSpan,
@ -641,5 +665,6 @@ export {
struct, struct,
mask, mask,
invert, invert,
inv inv,
withLocationOffset
}; };

12
docs/dist/parse.js vendored
View file

@ -1,6 +1,7 @@
import * as krill from "../_snowpack/link/repl/krill-parser.js"; import * as krill from "../_snowpack/link/repl/krill-parser.js";
import * as strudel from "../_snowpack/link/strudel.js"; import * as strudel from "../_snowpack/link/strudel.js";
import {Scale, Note, Interval} from "../_snowpack/pkg/@tonaljs/tonal.js"; import {Scale, Note, Interval} from "../_snowpack/pkg/@tonaljs/tonal.js";
import {addMiniLocations} from "./shapeshifter.js";
const {pure, Pattern, Fraction, stack, slowcat, sequence, timeCat, silence} = strudel; const {pure, Pattern, Fraction, stack, slowcat, sequence, timeCat, silence} = strudel;
const applyOptions = (parent) => (pat, i) => { const applyOptions = (parent) => (pat, i) => {
const ast = parent.source_[i]; const ast = parent.source_[i];
@ -39,6 +40,7 @@ function resolveReplications(ast) {
{ {
type_: "element", type_: "element",
source_: child.source_, source_: child.source_,
location_: child.location_,
options_: { options_: {
operator: { operator: {
type_: "stretch", type_: "stretch",
@ -80,7 +82,15 @@ export function patternifyAST(ast) {
return silence; return silence;
} }
if (typeof ast.source_ !== "object") { if (typeof ast.source_ !== "object") {
return ast.source_; if (!addMiniLocations) {
return ast.source_;
}
if (!ast.location_) {
console.warn("no location for", ast);
return ast.source_;
}
const {start, end} = ast.location_;
return pure(ast.source_).withLocation({start, end});
} }
return patternifyAST(ast.source_); return patternifyAST(ast.source_);
case "stretch": case "stretch":

View file

@ -10,6 +10,7 @@ const { Pattern } = strudel;
const isNote = (name) => /^[a-gC-G][bs]?[0-9]$/.test(name); const isNote = (name) => /^[a-gC-G][bs]?[0-9]$/.test(name);
const addLocations = true; const addLocations = true;
export const addMiniLocations = true;
export default (code) => { export default (code) => {
const ast = parseScriptWithLocation(code); const ast = parseScriptWithLocation(code);
@ -23,16 +24,39 @@ export default (code) => {
return node; return node;
} }
const grandparent = parents[parents.length - 2]; const grandparent = parents[parents.length - 2];
const isPatternArg = (parent) => const isTimeCat = parent?.type === 'ArrayExpression' && isPatternFactory(grandparent);
parent?.type === 'CallExpression' && Object.keys(Pattern.prototype.factories).includes(parent.callee.name); const isMarkable = isPatternFactory(parent) || isTimeCat;
const isTimeCat = parent?.type === 'ArrayExpression' && isPatternArg(grandparent); // operator overloading => still not done
const isMarkable = isPatternArg(parent) || isTimeCat; const operators = {
'*': 'fast',
'/': 'slow',
'&': 'stack',
'&&': 'append',
};
if (
node.type === 'BinaryExpression' &&
operators[node.operator] &&
['LiteralNumericExpression', 'LiteralStringExpression', 'IdentifierExpression'].includes(node.right?.type) &&
canBeOverloaded(node.left)
) {
let arg = node.left;
if (node.left.type === 'IdentifierExpression') {
arg = wrapReify(node.left);
}
return new CallExpression({
callee: new StaticMemberExpression({
property: operators[node.operator],
object: wrapReify(arg),
}),
arguments: [node.right],
});
}
// replace pseudo note variables // replace pseudo note variables
if (node.type === 'IdentifierExpression') { if (node.type === 'IdentifierExpression') {
if (isNote(node.name)) { if (isNote(node.name)) {
const value = node.name[1] === 's' ? node.name.replace('s', '#') : node.name; const value = node.name[1] === 's' ? node.name.replace('s', '#') : node.name;
if (addLocations && isMarkable) { if (addLocations && isMarkable) {
return addPureWithLocation(value, node, ast.locations, nodesWithLocation); return reifyWithLocation(value, node, ast.locations, nodesWithLocation);
} }
return new LiteralStringExpression({ value }); return new LiteralStringExpression({ value });
} }
@ -42,7 +66,26 @@ export default (code) => {
} }
if (addLocations && node.type === 'LiteralStringExpression' && isMarkable) { if (addLocations && node.type === 'LiteralStringExpression' && isMarkable) {
// console.log('add', node); // console.log('add', node);
return addPureWithLocation(node.value, node, ast.locations, nodesWithLocation); return reifyWithLocation(node.value, node, ast.locations, nodesWithLocation);
}
if (!addMiniLocations) {
return node;
}
// mini notation location handling
const miniFunctions = ['mini', 'm'];
const isAlreadyWrapped = parent?.type === 'CallExpression' && parent.callee.name === 'withLocationOffset';
if (node.type === 'CallExpression' && miniFunctions.includes(node.callee.name) && !isAlreadyWrapped) {
// mini('c3')
if (node.arguments.length > 1) {
// TODO: transform mini(...args) to cat(...args.map(mini)) ?
console.warn('multi arg mini locations not supported yet...');
return node;
}
return wrapLocationOffset(node, node.arguments, ast.locations, nodesWithLocation);
}
if (node.type === 'StaticMemberExpression' && miniFunctions.includes(node.property) && !isAlreadyWrapped) {
// 'c3'.mini or 'c3'.m
return wrapLocationOffset(node, node.object, ast.locations, nodesWithLocation);
} }
return node; return node;
}, },
@ -53,15 +96,49 @@ export default (code) => {
return codegen(shifted); return codegen(shifted);
}; };
// turns node in pure(value).withLocation(location), where location is the node's location in the source code function wrapReify(node) {
// with this, the pure pattern can pass its location to the event, to know where to highlight when it's active return new CallExpression({
function addPureWithLocation(value, node, locations, nodesWithLocation) { callee: new IdentifierExpression({
// console.log('addPure', value, node); name: 'reify',
}),
arguments: [node],
});
}
function isPatternFactory(node) {
return node?.type === 'CallExpression' && Object.keys(Pattern.prototype.factories).includes(node.callee.name);
}
function canBeOverloaded(node) {
return (node.type === 'IdentifierExpression' && isNote(node.name)) || isPatternFactory(node);
// TODO: support sequence(c3).transpose(3).x.y.z
}
// turn node into withLocationOffset(node, location)
function wrapLocationOffset(node, stringNode, locations, nodesWithLocation) {
// console.log('wrapppp', stringNode);
const expression = {
type: 'CallExpression',
callee: {
type: 'IdentifierExpression',
name: 'withLocationOffset',
},
arguments: [node, getLocationObject(stringNode, locations)],
};
nodesWithLocation.push(expression);
// console.log('wrapped', codegen(expression));
return expression;
}
// turns node in reify(value).withLocation(location), where location is the node's location in the source code
// with this, the reified pattern can pass its location to the event, to know where to highlight when it's active
function reifyWithLocation(value, node, locations, nodesWithLocation) {
// console.log('reifyWithLocation', value, node);
const withLocation = new CallExpression({ const withLocation = new CallExpression({
callee: new StaticMemberExpression({ callee: new StaticMemberExpression({
object: new CallExpression({ object: new CallExpression({
callee: new IdentifierExpression({ callee: new IdentifierExpression({
name: 'pure', name: 'reify',
}), }),
arguments: [new LiteralStringExpression({ value })], arguments: [new LiteralStringExpression({ value })],
}), }),
@ -82,7 +159,7 @@ function getLocationObject(node, locations) {
console.log("locationAST", locationAST);*/ console.log("locationAST", locationAST);*/
/*const callAST = parseScript( /*const callAST = parseScript(
`pure(${node.name}).withLocation(${JSON.stringify( `reify(${node.name}).withLocation(${JSON.stringify(
ast.locations.get(node) ast.locations.get(node)
)})` )})`
).statements[0].expression;*/ ).statements[0].expression;*/

11
docs/dist/tonal.js vendored
View file

@ -2,7 +2,7 @@ import {Note, Interval, Scale} from "../_snowpack/pkg/@tonaljs/tonal.js";
import {Pattern as _Pattern} from "../_snowpack/link/strudel.js"; import {Pattern as _Pattern} from "../_snowpack/link/strudel.js";
const Pattern = _Pattern; const Pattern = _Pattern;
function toNoteEvent(event) { function toNoteEvent(event) {
if (typeof event === "string") { if (typeof event === "string" || typeof event === "number") {
return {value: event}; return {value: event};
} }
if (event.value) { if (event.value) {
@ -53,13 +53,20 @@ Pattern.prototype._mapNotes = function(func) {
Pattern.prototype._transpose = function(intervalOrSemitones) { Pattern.prototype._transpose = function(intervalOrSemitones) {
return this._mapNotes(({value, scale}) => { return this._mapNotes(({value, scale}) => {
const interval = !isNaN(Number(intervalOrSemitones)) ? Interval.fromSemitones(intervalOrSemitones) : String(intervalOrSemitones); const interval = !isNaN(Number(intervalOrSemitones)) ? Interval.fromSemitones(intervalOrSemitones) : String(intervalOrSemitones);
if (typeof value === "number") {
const semitones = typeof interval === "string" ? Interval.semitones(interval) || 0 : interval;
return {value: value + semitones};
}
return {value: Note.transpose(value, interval), scale}; return {value: Note.transpose(value, interval), scale};
}); });
}; };
Pattern.prototype._scaleTranspose = function(offset) { Pattern.prototype._scaleTranspose = function(offset) {
return this._mapNotes(({value, scale}) => { return this._mapNotes(({value, scale}) => {
if (!scale) { if (!scale) {
throw new Error("can only use scaleOffset after .scale"); throw new Error("can only use scaleTranspose after .scale");
}
if (typeof value !== "string") {
throw new Error("can only use scaleTranspose with notes");
} }
return {value: scaleTranspose(scale, Number(offset), value), scale}; return {value: scaleTranspose(scale, Number(offset), value), scale};
}); });

View file

@ -30,6 +30,8 @@ function useRepl({tune, defaultSynth, autolink = true, onEvent}) {
setError(void 0); setError(void 0);
setActiveCode(_code); setActiveCode(_code);
} catch (err) { } catch (err) {
err.message = "evaluation error: " + err.message;
console.warn(err);
setError(err); setError(err);
} }
}; };
@ -68,6 +70,7 @@ function useRepl({tune, defaultSynth, autolink = true, onEvent}) {
try { try {
return pattern?.query(span) || []; return pattern?.query(span) || [];
} catch (err) { } catch (err) {
err.message = "query error: " + err.message;
setError(err); setError(err);
return []; return [];
} }

View file

@ -18,7 +18,7 @@ Pattern.prototype.voicings = function(range) {
range = ["F3", "A4"]; range = ["F3", "A4"];
} }
return this.fmapNested((event) => { return this.fmapNested((event) => {
lastVoicing = getVoicing(event.value, lastVoicing, range); lastVoicing = getVoicing(event.value?.value || event.value, lastVoicing, range);
return stack(...lastVoicing); return stack(...lastVoicing);
}); });
}; };

View file

@ -41646,6 +41646,8 @@ function useRepl({ tune , defaultSynth , autolink =true , onEvent }) {
setError(undefined); setError(undefined);
setActiveCode(_code); setActiveCode(_code);
} catch (err) { } catch (err) {
err.message = 'evaluation error: ' + err.message;
console.warn(err);
setError(err); setError(err);
} }
}; };
@ -41684,6 +41686,7 @@ function useRepl({ tune , defaultSynth , autolink =true , onEvent }) {
try { try {
return pattern?.query(span) || []; return pattern?.query(span) || [];
} catch (err) { } catch (err) {
err.message = 'query error: ' + err.message;
setError(err); setError(err);
return []; return [];
} }
@ -41794,6 +41797,7 @@ hackLiteral(String, [
Object.assign(globalThis, bootstrapped, _tone1, _tone); Object.assign(globalThis, bootstrapped, _tone1, _tone);
const evaluate = (code)=>{ const evaluate = (code)=>{
const shapeshifted = _shapeshifterDefault.default(code); // transform syntactically correct js code to semantically usable code const shapeshifted = _shapeshifterDefault.default(code); // transform syntactically correct js code to semantically usable code
// console.log('shapeshifted', shapeshifted);
let evaluated = eval(shapeshifted); let evaluated = eval(shapeshifted);
if (typeof evaluated === 'function') evaluated = evaluated(); if (typeof evaluated === 'function') evaluated = evaluated();
const pattern = _parse.minify(evaluated); // eval and minify (if user entered a string) const pattern = _parse.minify(evaluated); // eval and minify (if user entered a string)
@ -41890,6 +41894,8 @@ parcelHelpers.export(exports, "invert", ()=>invert
); );
parcelHelpers.export(exports, "inv", ()=>inv parcelHelpers.export(exports, "inv", ()=>inv
); );
parcelHelpers.export(exports, "withLocationOffset", ()=>withLocationOffset
);
var _fractionJs = require("fraction.js"); var _fractionJs = require("fraction.js");
var _fractionJsDefault = parcelHelpers.interopDefault(_fractionJs); var _fractionJsDefault = parcelHelpers.interopDefault(_fractionJs);
var _ramda = require("ramda"); // will remove this as soon as compose is implemented here var _ramda = require("ramda"); // will remove this as soon as compose is implemented here
@ -42712,6 +42718,37 @@ Pattern.prototype.bootstrap = ()=>{
})); }));
return bootstrapped; return bootstrapped;
}; };
// this is wrapped around mini patterns to offset krill parser location into the global js code space
function withLocationOffset(pat, offset) {
// console.log('with offfset',pat,offset);
let startLine;
return pat.fmap((value)=>{
value = typeof value === 'object' && !Array.isArray(value) ? value : {
value
};
let locations = value.locations || [];
startLine = startLine || locations[0].start.line;
locations = locations.map(({ start , end })=>{
const colOffset = startLine === end.line ? offset.start.column : 0;
return {
start: {
...start,
line: start.line - 1 + (offset.start.line - 1) + 1,
column: start.column - 1 + colOffset
},
end: {
...end,
line: end.line - 1 + (offset.start.line - 1) + 1,
column: end.column - 1 + colOffset
}
};
});
return {
...value,
locations
};
});
}
},{"fraction.js":"1Q5M2","ramda":"10uzi","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"1Q5M2":[function(require,module,exports) { },{"fraction.js":"1Q5M2","ramda":"10uzi","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"1Q5M2":[function(require,module,exports) {
/** /**
@ -57806,7 +57843,7 @@ Pattern.prototype.voicings = function(range) {
'A4' 'A4'
]; ];
return this.fmapNested((event)=>{ return this.fmapNested((event)=>{
lastVoicing = getVoicing(event.value, lastVoicing, range); lastVoicing = getVoicing(event.value?.value || event.value, lastVoicing, range);
return _strudelMjs.stack(...lastVoicing); return _strudelMjs.stack(...lastVoicing);
}); });
}; };
@ -62438,7 +62475,7 @@ var _tonal = require("@tonaljs/tonal");
var _strudelMjs = require("../../strudel.mjs"); var _strudelMjs = require("../../strudel.mjs");
const Pattern = _strudelMjs.Pattern; const Pattern = _strudelMjs.Pattern;
function toNoteEvent(event) { function toNoteEvent(event) {
if (typeof event === 'string') return { if (typeof event === 'string' || typeof event === 'number') return {
value: event value: event
}; };
if (event.value) return event; if (event.value) return event;
@ -62488,6 +62525,12 @@ Pattern.prototype._mapNotes = function(func) {
Pattern.prototype._transpose = function(intervalOrSemitones) { Pattern.prototype._transpose = function(intervalOrSemitones) {
return this._mapNotes(({ value , scale })=>{ return this._mapNotes(({ value , scale })=>{
const interval = !isNaN(Number(intervalOrSemitones)) ? _tonal.Interval.fromSemitones(intervalOrSemitones) : String(intervalOrSemitones); const interval = !isNaN(Number(intervalOrSemitones)) ? _tonal.Interval.fromSemitones(intervalOrSemitones) : String(intervalOrSemitones);
if (typeof value === 'number') {
const semitones = typeof interval === 'string' ? _tonal.Interval.semitones(interval) || 0 : interval;
return {
value: value + semitones
};
}
return { return {
value: _tonal.Note.transpose(value, interval), value: _tonal.Note.transpose(value, interval),
scale scale
@ -62501,7 +62544,8 @@ Pattern.prototype._transpose = function(intervalOrSemitones) {
// or even `stack(c3).superimpose(transpose.slowcat(7, 5))` or // or even `stack(c3).superimpose(transpose.slowcat(7, 5))` or
Pattern.prototype._scaleTranspose = function(offset) { Pattern.prototype._scaleTranspose = function(offset) {
return this._mapNotes(({ value , scale })=>{ return this._mapNotes(({ value , scale })=>{
if (!scale) throw new Error('can only use scaleOffset after .scale'); if (!scale) throw new Error('can only use scaleTranspose after .scale');
if (typeof value !== 'string') throw new Error('can only use scaleTranspose with notes');
return { return {
value: scaleTranspose(scale, Number(offset), value), value: scaleTranspose(scale, Number(offset), value),
scale scale
@ -62556,6 +62600,8 @@ Pattern.prototype.define('groove', (groove, pat)=>pat.groove(groove)
},{"../../strudel.mjs":"ggZqJ"}],"67UCx":[function(require,module,exports) { },{"../../strudel.mjs":"ggZqJ"}],"67UCx":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports); parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "addMiniLocations", ()=>addMiniLocations
);
var _indexJs = require("./shift-parser/index.js"); // npm module does not work in the browser var _indexJs = require("./shift-parser/index.js"); // npm module does not work in the browser
var _shiftTraverser = require("./shift-traverser"); // npm module does not work in the browser var _shiftTraverser = require("./shift-traverser"); // npm module does not work in the browser
var _shiftTraverserDefault = parcelHelpers.interopDefault(_shiftTraverser); var _shiftTraverserDefault = parcelHelpers.interopDefault(_shiftTraverser);
@ -62568,26 +62614,49 @@ const { Pattern } = _strudelMjs;
const isNote = (name)=>/^[a-gC-G][bs]?[0-9]$/.test(name) const isNote = (name)=>/^[a-gC-G][bs]?[0-9]$/.test(name)
; ;
const addLocations = true; const addLocations = true;
const addMiniLocations = true;
exports.default = (code)=>{ exports.default = (code)=>{
const ast = _indexJs.parseScriptWithLocation(code); const ast = _indexJs.parseScriptWithLocation(code);
const nodesWithLocation = []; const nodesWithLocation = [];
const parents = []; const parents = [];
const shifted = replace(ast.tree, { const shifted = replace(ast.tree, {
enter (node, parent1) { enter (node, parent) {
parents.push(parent1); parents.push(parent);
const isSynthetic = parents.some((p)=>nodesWithLocation.includes(p) const isSynthetic = parents.some((p)=>nodesWithLocation.includes(p)
); );
if (isSynthetic) return node; if (isSynthetic) return node;
const grandparent = parents[parents.length - 2]; const grandparent = parents[parents.length - 2];
const isPatternArg = (parent)=>parent?.type === 'CallExpression' && Object.keys(Pattern.prototype.factories).includes(parent.callee.name) const isTimeCat = parent?.type === 'ArrayExpression' && isPatternFactory(grandparent);
; const isMarkable = isPatternFactory(parent) || isTimeCat;
const isTimeCat = parent1?.type === 'ArrayExpression' && isPatternArg(grandparent); // operator overloading => still not done
const isMarkable = isPatternArg(parent1) || isTimeCat; const operators = {
'*': 'fast',
'/': 'slow',
'&': 'stack',
'&&': 'append'
};
if (node.type === 'BinaryExpression' && operators[node.operator] && [
'LiteralNumericExpression',
'LiteralStringExpression',
'IdentifierExpression'
].includes(node.right?.type) && canBeOverloaded(node.left)) {
let arg = node.left;
if (node.left.type === 'IdentifierExpression') arg = wrapReify(node.left);
return new _shiftAst.CallExpression({
callee: new _shiftAst.StaticMemberExpression({
property: operators[node.operator],
object: wrapReify(arg)
}),
arguments: [
node.right
]
});
}
// replace pseudo note variables // replace pseudo note variables
if (node.type === 'IdentifierExpression') { if (node.type === 'IdentifierExpression') {
if (isNote(node.name)) { if (isNote(node.name)) {
const value = node.name[1] === 's' ? node.name.replace('s', '#') : node.name; const value = node.name[1] === 's' ? node.name.replace('s', '#') : node.name;
if (addLocations && isMarkable) return addPureWithLocation(value, node, ast.locations, nodesWithLocation); if (addLocations && isMarkable) return reifyWithLocation(value, node, ast.locations, nodesWithLocation);
return new _shiftAst.LiteralStringExpression({ return new _shiftAst.LiteralStringExpression({
value value
}); });
@ -62597,7 +62666,25 @@ exports.default = (code)=>{
}); });
} }
if (addLocations && node.type === 'LiteralStringExpression' && isMarkable) // console.log('add', node); if (addLocations && node.type === 'LiteralStringExpression' && isMarkable) // console.log('add', node);
return addPureWithLocation(node.value, node, ast.locations, nodesWithLocation); return reifyWithLocation(node.value, node, ast.locations, nodesWithLocation);
if (!addMiniLocations) return node;
// mini notation location handling
const miniFunctions = [
'mini',
'm'
];
const isAlreadyWrapped = parent?.type === 'CallExpression' && parent.callee.name === 'withLocationOffset';
if (node.type === 'CallExpression' && miniFunctions.includes(node.callee.name) && !isAlreadyWrapped) {
// mini('c3')
if (node.arguments.length > 1) {
// TODO: transform mini(...args) to cat(...args.map(mini)) ?
console.warn('multi arg mini locations not supported yet...');
return node;
}
return wrapLocationOffset(node, node.arguments, ast.locations, nodesWithLocation);
}
if (node.type === 'StaticMemberExpression' && miniFunctions.includes(node.property) && !isAlreadyWrapped) // 'c3'.mini or 'c3'.m
return wrapLocationOffset(node, node.object, ast.locations, nodesWithLocation);
return node; return node;
}, },
leave () { leave () {
@ -62606,15 +62693,50 @@ exports.default = (code)=>{
}); });
return _shiftCodegenDefault.default(shifted); return _shiftCodegenDefault.default(shifted);
}; };
// turns node in pure(value).withLocation(location), where location is the node's location in the source code function wrapReify(node) {
// with this, the pure pattern can pass its location to the event, to know where to highlight when it's active return new _shiftAst.CallExpression({
function addPureWithLocation(value, node, locations, nodesWithLocation) { callee: new _shiftAst.IdentifierExpression({
// console.log('addPure', value, node); name: 'reify'
}),
arguments: [
node
]
});
}
function isPatternFactory(node) {
return node?.type === 'CallExpression' && Object.keys(Pattern.prototype.factories).includes(node.callee.name);
}
function canBeOverloaded(node) {
return node.type === 'IdentifierExpression' && isNote(node.name) || isPatternFactory(node);
// TODO: support sequence(c3).transpose(3).x.y.z
}
// turn node into withLocationOffset(node, location)
function wrapLocationOffset(node, stringNode, locations, nodesWithLocation) {
// console.log('wrapppp', stringNode);
const expression = {
type: 'CallExpression',
callee: {
type: 'IdentifierExpression',
name: 'withLocationOffset'
},
arguments: [
node,
getLocationObject(stringNode, locations)
]
};
nodesWithLocation.push(expression);
// console.log('wrapped', codegen(expression));
return expression;
}
// turns node in reify(value).withLocation(location), where location is the node's location in the source code
// with this, the reified pattern can pass its location to the event, to know where to highlight when it's active
function reifyWithLocation(value, node, locations, nodesWithLocation) {
// console.log('reifyWithLocation', value, node);
const withLocation = new _shiftAst.CallExpression({ const withLocation = new _shiftAst.CallExpression({
callee: new _shiftAst.StaticMemberExpression({ callee: new _shiftAst.StaticMemberExpression({
object: new _shiftAst.CallExpression({ object: new _shiftAst.CallExpression({
callee: new _shiftAst.IdentifierExpression({ callee: new _shiftAst.IdentifierExpression({
name: 'pure' name: 'reify'
}), }),
arguments: [ arguments: [
new _shiftAst.LiteralStringExpression({ new _shiftAst.LiteralStringExpression({
@ -62638,7 +62760,7 @@ function getLocationObject(node, locations) {
).statements[0].expression.expression; ).statements[0].expression.expression;
console.log("locationAST", locationAST);*/ /*const callAST = parseScript( console.log("locationAST", locationAST);*/ /*const callAST = parseScript(
`pure(${node.name}).withLocation(${JSON.stringify( `reify(${node.name}).withLocation(${JSON.stringify(
ast.locations.get(node) ast.locations.get(node)
)})` )})`
).statements[0].expression;*/ const loc = locations.get(node); ).statements[0].expression;*/ const loc = locations.get(node);
@ -95771,6 +95893,7 @@ parcelHelpers.export(exports, "minify", ()=>minify
var _krillParser = require("../krill-parser"); var _krillParser = require("../krill-parser");
var _strudelMjs = require("../../strudel.mjs"); var _strudelMjs = require("../../strudel.mjs");
var _tonal = require("@tonaljs/tonal"); var _tonal = require("@tonaljs/tonal");
var _shapeshifter = require("./shapeshifter");
const { pure , Pattern , Fraction , stack , slowcat , sequence , timeCat , silence } = _strudelMjs; const { pure , Pattern , Fraction , stack , slowcat , sequence , timeCat , silence } = _strudelMjs;
const applyOptions = (parent)=>(pat, i)=>{ const applyOptions = (parent)=>(pat, i)=>{
const ast = parent.source_[i]; const ast = parent.source_[i];
@ -95816,6 +95939,7 @@ function resolveReplications(ast) {
{ {
type_: 'element', type_: 'element',
source_: child.source_, source_: child.source_,
location_: child.location_,
options_: { options_: {
operator: { operator: {
type_: 'stretch', type_: 'stretch',
@ -95857,7 +95981,21 @@ function patternifyAST(ast) {
return sequence(...children); return sequence(...children);
case 'element': case 'element':
if (ast.source_ === '~') return silence; if (ast.source_ === '~') return silence;
if (typeof ast.source_ !== 'object') return ast.source_; if (typeof ast.source_ !== 'object') {
if (!_shapeshifter.addMiniLocations) return ast.source_;
if (!ast.location_) {
console.warn('no location for', ast);
return ast.source_;
}
const { start , end } = ast.location_;
// return ast.source_;
// the following line expects the shapeshifter to wrap this in withLocationOffset
// because location_ is only relative to the mini string, but we need it relative to whole code
return pure(ast.source_).withLocation({
start,
end
});
}
return patternifyAST(ast.source_); return patternifyAST(ast.source_);
case 'stretch': case 'stretch':
return patternifyAST(ast.source_).slow(ast.arguments_.amount); return patternifyAST(ast.source_).slow(ast.arguments_.amount);
@ -95919,7 +96057,7 @@ function minify(thing) {
return reify(thing); return reify(thing);
} }
},{"../krill-parser":"l2lgS","../../strudel.mjs":"ggZqJ","@tonaljs/tonal":"4q9Lu","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"l2lgS":[function(require,module,exports) { },{"../krill-parser":"l2lgS","../../strudel.mjs":"ggZqJ","@tonaljs/tonal":"4q9Lu","./shapeshifter":"67UCx","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"l2lgS":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports); parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "SyntaxError", ()=>peg$SyntaxError parcelHelpers.export(exports, "SyntaxError", ()=>peg$SyntaxError
@ -97786,6 +97924,7 @@ function peg$parse(input, options1) {
this.type_ = "element"; this.type_ = "element";
this.source_ = source; this.source_ = source;
this.options_ = options; this.options_ = options;
this.location_ = location1();
}; };
var CommandStub = function(name, options) { var CommandStub = function(name, options) {
this.type_ = "command"; this.type_ = "command";
@ -109137,4 +109276,4 @@ exports.default = cx;
},{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}]},["3uVTb"], "3uVTb", "parcelRequire94c2") },{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}]},["3uVTb"], "3uVTb", "parcelRequire94c2")
//# sourceMappingURL=index.98344030.js.map //# sourceMappingURL=index.e1279fc8.js.map

File diff suppressed because one or more lines are too long

View file

@ -11,6 +11,6 @@
<body> <body>
<div id="root"></div> <div id="root"></div>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<script src="/tutorial/index.98344030.js" defer=""></script> <script src="/tutorial/index.e1279fc8.js" defer=""></script>
</body> </body>
</html> </html>