started mini notation highlighting

currently deactivated by addMiniLocations flag
This commit is contained in:
Felix Roos 2022-02-20 23:46:45 +01:00
parent 358ba0101e
commit acd07c31ff
5 changed files with 75 additions and 2 deletions

View file

@ -1,6 +1,7 @@
import * as krill from '../krill-parser';
import * as strudel from '../../strudel.mjs';
import { Scale, Note, Interval } from '@tonaljs/tonal';
import { addMiniLocations } from './shapeshifter';
const { pure, Pattern, Fraction, stack, slowcat, sequence, timeCat, silence } = strudel;
@ -91,7 +92,18 @@ export function patternifyAST(ast: any): any {
return silence;
}
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 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_);
case 'stretch':

View file

@ -10,6 +10,7 @@ const { Pattern } = strudel;
const isNote = (name) => /^[a-gC-G][bs]?[0-9]$/.test(name);
const addLocations = true;
export const addMiniLocations = false;
export default (code) => {
const ast = parseScriptWithLocation(code);
@ -44,6 +45,25 @@ export default (code) => {
// console.log('add', node);
return addPureWithLocation(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;
},
leave() {
@ -53,6 +73,22 @@ export default (code) => {
return codegen(shifted);
};
// 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 pure(value).withLocation(location), where location is the node's location in the source code
// with this, the pure pattern can pass its location to the event, to know where to highlight when it's active
function addPureWithLocation(value, node, locations, nodesWithLocation) {