mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 21:58:31 +00:00
build
This commit is contained in:
parent
1de371e944
commit
f8df4b485d
@ -175,6 +175,13 @@ class Pattern {
|
||||
_withEvents(func) {
|
||||
return new Pattern((span) => func(this.query(span)));
|
||||
}
|
||||
withLocation(location) {
|
||||
return this.fmap((value) => {
|
||||
value = typeof value === "object" && !Array.isArray(value) ? value : {value};
|
||||
const locations = (value.locations || []).concat([location]);
|
||||
return {...value, locations};
|
||||
});
|
||||
}
|
||||
withValue(func) {
|
||||
return new Pattern((span) => this.query(span).map((hap) => hap.withValue(func)));
|
||||
}
|
||||
@ -312,6 +319,7 @@ class Pattern {
|
||||
_patternify(func) {
|
||||
const pat = this;
|
||||
const patterned = function(...args) {
|
||||
args = args.map((arg) => arg.constructor?.name === "Pattern" ? arg.fmap((value) => value.value || value) : arg);
|
||||
const pat_arg = sequence(...args);
|
||||
return pat_arg.fmap((arg) => func.call(pat, arg)).outerJoin();
|
||||
};
|
||||
|
||||
20
docs/dist/App.js
vendored
20
docs/dist/App.js
vendored
@ -1,4 +1,4 @@
|
||||
import React, {useCallback, useLayoutEffect, useRef} from "../_snowpack/pkg/react.js";
|
||||
import React, {useCallback, useLayoutEffect, useMemo, useRef, useState} from "../_snowpack/pkg/react.js";
|
||||
import * as Tone from "../_snowpack/pkg/tone.js";
|
||||
import CodeMirror from "./CodeMirror.js";
|
||||
import cx from "./cx.js";
|
||||
@ -28,9 +28,21 @@ function getRandomTune() {
|
||||
}
|
||||
const randomTune = getRandomTune();
|
||||
function App() {
|
||||
const [editor, setEditor] = useState();
|
||||
const doc = useMemo(() => editor?.getDoc(), [editor]);
|
||||
const {setCode, setPattern, error, code, cycle, dirty, log, togglePlay, activateCode, pattern, pushLog} = useRepl({
|
||||
tune: decoded || randomTune,
|
||||
defaultSynth
|
||||
defaultSynth,
|
||||
onEvent: useCallback((event) => {
|
||||
const locs = event.value.locations;
|
||||
if (!locs) {
|
||||
return;
|
||||
}
|
||||
const marks = locs.map(({start, end}) => doc.markText({line: start.line - 1, ch: start.column}, {line: end.line - 1, ch: end.column}, {css: "background-color: gray;"}));
|
||||
setTimeout(() => {
|
||||
marks.forEach((mark) => mark.clear());
|
||||
}, event.duration * 0.9 * 1e3);
|
||||
}, [doc])
|
||||
});
|
||||
const logBox = useRef();
|
||||
useLayoutEffect(() => {
|
||||
@ -95,10 +107,12 @@ function App() {
|
||||
className: cx("h-full bg-[#2A3236]", error ? "focus:ring-red-500" : "focus:ring-slate-800")
|
||||
}, /* @__PURE__ */ React.createElement(CodeMirror, {
|
||||
value: code,
|
||||
editorDidMount: setEditor,
|
||||
options: {
|
||||
mode: "javascript",
|
||||
theme: "material",
|
||||
lineNumbers: true
|
||||
lineNumbers: true,
|
||||
styleSelectedText: true
|
||||
},
|
||||
onChange: (_2, __, value) => setCode(value)
|
||||
}), /* @__PURE__ */ React.createElement("span", {
|
||||
|
||||
8
docs/dist/CodeMirror.js
vendored
8
docs/dist/CodeMirror.js
vendored
@ -4,15 +4,17 @@ import "../_snowpack/pkg/codemirror/mode/javascript/javascript.js";
|
||||
import "../_snowpack/pkg/codemirror/mode/pegjs/pegjs.js";
|
||||
import "../_snowpack/pkg/codemirror/theme/material.css.proxy.js";
|
||||
import "../_snowpack/pkg/codemirror/lib/codemirror.css.proxy.js";
|
||||
export default function CodeMirror({value, onChange, options}) {
|
||||
export default function CodeMirror({value, onChange, options, editorDidMount}) {
|
||||
options = options || {
|
||||
mode: "javascript",
|
||||
theme: "material",
|
||||
lineNumbers: true
|
||||
lineNumbers: true,
|
||||
styleSelectedText: true
|
||||
};
|
||||
return /* @__PURE__ */ React.createElement(CodeMirror2, {
|
||||
value,
|
||||
options,
|
||||
onBeforeChange: onChange
|
||||
onBeforeChange: onChange,
|
||||
editorDidMount
|
||||
});
|
||||
}
|
||||
|
||||
171
docs/dist/shapeshifter.js
vendored
171
docs/dist/shapeshifter.js
vendored
@ -1,30 +1,189 @@
|
||||
import { parseScript } from './shift-parser/index.js'; // npm module does not work in the browser
|
||||
import { parseScriptWithLocation } from './shift-parser/index.js'; // npm module does not work in the browser
|
||||
import traverser from './shift-traverser/index.js'; // npm module does not work in the browser
|
||||
const { replace } = traverser;
|
||||
import { LiteralStringExpression, IdentifierExpression } from '../_snowpack/pkg/shift-ast.js';
|
||||
import { LiteralStringExpression, IdentifierExpression, CallExpression, StaticMemberExpression } from '../_snowpack/pkg/shift-ast.js';
|
||||
import codegen from '../_snowpack/pkg/shift-codegen.js';
|
||||
import * as strudel from '../_snowpack/link/strudel.js';
|
||||
|
||||
const { Pattern } = strudel;
|
||||
|
||||
const isNote = (name) => /^[a-gC-G][bs]?[0-9]$/.test(name);
|
||||
|
||||
const addLocations = true;
|
||||
|
||||
export default (code) => {
|
||||
const ast = parseScript(code);
|
||||
const shifted = replace(ast, {
|
||||
const ast = parseScriptWithLocation(code);
|
||||
const nodesWithLocation = [];
|
||||
const parents = [];
|
||||
const shifted = replace(ast.tree, {
|
||||
enter(node, parent) {
|
||||
// replace identifiers that are a note with a note string
|
||||
parents.push(parent);
|
||||
const isSynthetic = parents.some((p) => nodesWithLocation.includes(p));
|
||||
if (isSynthetic) {
|
||||
return node;
|
||||
}
|
||||
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' && isPatternArg(grandparent);
|
||||
const isMarkable = isPatternArg(parent) || isTimeCat;
|
||||
// replace pseudo note variables
|
||||
if (node.type === 'IdentifierExpression') {
|
||||
if (isNote(node.name)) {
|
||||
const value = node.name[1] === 's' ? node.name.replace('s', '#') : node.name;
|
||||
if (addLocations && isMarkable) {
|
||||
return addPureWithLocation(value, node, ast.locations, nodesWithLocation);
|
||||
}
|
||||
return new LiteralStringExpression({ value });
|
||||
}
|
||||
if (node.name === 'r') {
|
||||
return new IdentifierExpression({ name: 'silence' });
|
||||
}
|
||||
}
|
||||
if (addLocations && node.type === 'LiteralStringExpression' && isMarkable) {
|
||||
// console.log('add', node);
|
||||
return addPureWithLocation(node.value, node, ast.locations, nodesWithLocation);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
leave() {
|
||||
parents.pop();
|
||||
},
|
||||
});
|
||||
return codegen(shifted);
|
||||
};
|
||||
|
||||
// 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) {
|
||||
// console.log('addPure', value, node);
|
||||
const withLocation = new CallExpression({
|
||||
callee: new StaticMemberExpression({
|
||||
object: new CallExpression({
|
||||
callee: new IdentifierExpression({
|
||||
name: 'pure',
|
||||
}),
|
||||
arguments: [new LiteralStringExpression({ value })],
|
||||
}),
|
||||
property: 'withLocation',
|
||||
}),
|
||||
arguments: [getLocationObject(node, locations)],
|
||||
});
|
||||
nodesWithLocation.push(withLocation);
|
||||
return withLocation;
|
||||
}
|
||||
|
||||
// returns ast for source location object
|
||||
function getLocationObject(node, locations) {
|
||||
/*const locationAST = parseScript(
|
||||
"x=" + JSON.stringify(ast.locations.get(node))
|
||||
).statements[0].expression.expression;
|
||||
|
||||
console.log("locationAST", locationAST);*/
|
||||
|
||||
/*const callAST = parseScript(
|
||||
`pure(${node.name}).withLocation(${JSON.stringify(
|
||||
ast.locations.get(node)
|
||||
)})`
|
||||
).statements[0].expression;*/
|
||||
const loc = locations.get(node);
|
||||
return {
|
||||
type: 'ObjectExpression',
|
||||
properties: [
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'start',
|
||||
},
|
||||
expression: {
|
||||
type: 'ObjectExpression',
|
||||
properties: [
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'line',
|
||||
},
|
||||
expression: {
|
||||
type: 'LiteralNumericExpression',
|
||||
value: loc.start.line,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'column',
|
||||
},
|
||||
expression: {
|
||||
type: 'LiteralNumericExpression',
|
||||
value: loc.start.column,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'offset',
|
||||
},
|
||||
expression: {
|
||||
type: 'LiteralNumericExpression',
|
||||
value: loc.start.offset,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'end',
|
||||
},
|
||||
expression: {
|
||||
type: 'ObjectExpression',
|
||||
properties: [
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'line',
|
||||
},
|
||||
expression: {
|
||||
type: 'LiteralNumericExpression',
|
||||
value: loc.end.line,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'column',
|
||||
},
|
||||
expression: {
|
||||
type: 'LiteralNumericExpression',
|
||||
value: loc.end.column,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'offset',
|
||||
},
|
||||
expression: {
|
||||
type: 'LiteralNumericExpression',
|
||||
value: loc.end.offset,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: turn x.groove['[~ x]*2'] into x.groove('[~ x]*2'.m)
|
||||
// and ['c1*2'].xx into 'c1*2'.m.xx ??
|
||||
// or just all templated strings?? x.groove(`[~ x]*2`)
|
||||
// or just all templated strings?? x.groove(`[~ x]*2`)
|
||||
|
||||
73
docs/dist/tunes.js
vendored
73
docs/dist/tunes.js
vendored
@ -4,11 +4,11 @@ export const timeCatMini = `stack(
|
||||
'[eb4@5 [f4 eb4 d4]@3] [eb4 c4]/2'.mini.slow(8)
|
||||
)`;
|
||||
export const timeCat = `stack(
|
||||
timeCat([3, c3], [1, stack(eb3, g3, m(c4, d4).slow(2))]),
|
||||
m(c2, g2),
|
||||
timeCat([3, c3], [1, stack(eb3, g3, cat(c4, d4).slow(2))]),
|
||||
cat(c2, g2),
|
||||
sequence(
|
||||
timeCat([5, eb4], [3, m(f4, eb4, d4)]),
|
||||
m(eb4, c4).slow(2)
|
||||
timeCat([5, eb4], [3, cat(f4, eb4, d4)]),
|
||||
cat(eb4, c4).slow(2)
|
||||
).slow(4)
|
||||
)`;
|
||||
export const shapeShifted = `stack(
|
||||
@ -120,11 +120,11 @@ export const spanish = `slowcat(
|
||||
stack(ab3,c4,eb4),
|
||||
stack(g3,b3,d4)
|
||||
)`;
|
||||
export const whirlyStrudel = `mini("[e4 [b2 b3] c4]")
|
||||
export const whirlyStrudel = `sequence(e4, [b2, b3], c4)
|
||||
.every(4, fast(2))
|
||||
.every(3, slow(1.5))
|
||||
.fast(slowcat(1.25, 1, 1.5))
|
||||
.every(2, _ => mini("e4 ~ e3 d4 ~"))`;
|
||||
.every(2, _ => sequence(e4, r, e3, d4, r))`;
|
||||
export const swimming = `stack(
|
||||
mini(
|
||||
'~',
|
||||
@ -357,64 +357,3 @@ export const caverave = `() => {
|
||||
synths
|
||||
).slow(2);
|
||||
}`;
|
||||
export const caveravefuture = `() => {
|
||||
const delay = new FeedbackDelay(1/8, .4).chain(vol(0.5), out);
|
||||
const kick = new MembraneSynth().chain(vol(.8), out);
|
||||
const snare = new NoiseSynth().chain(vol(.8), out);
|
||||
const hihat = new MetalSynth().set(adsr(0, .08, 0, .1)).chain(vol(.3).connect(delay),out);
|
||||
const bass = new Synth().set({ ...osc('sawtooth'), ...adsr(0, .1, .4) }).chain(lowpass(900), vol(.5), out);
|
||||
const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out);
|
||||
|
||||
const drums = stack(
|
||||
\`c1*2\`.tone(kick).bypass(\`<0@7 1>/8\`),
|
||||
\`~ <x!7 [x@3 x]>\`.tone(snare).bypass(\`<0@7 1>/4\`),
|
||||
\`[~ c4]*2\`.tone(hihat)
|
||||
);
|
||||
|
||||
const thru = (x) => x.transpose(\`<0 1>/8\`).transpose(-1);
|
||||
const synths = stack(
|
||||
\`<eb4 d4 c4 b3>/2\`.scale(timeCat([3,'C minor'],[1,'C melodic minor']).slow(8)).groove(\`[~ x]*2\`)
|
||||
.edit(
|
||||
scaleTranspose(0).early(0),
|
||||
scaleTranspose(2).early(1/8),
|
||||
scaleTranspose(7).early(1/4),
|
||||
scaleTranspose(8).early(3/8)
|
||||
).edit(thru).tone(keys).bypass(\`<1 0>/16\`),
|
||||
\`<C2 Bb1 Ab1 [G1 [G2 G1]]>/2\`.groove(\`x [~ x] <[~ [~ x]]!3 [x x]>@2\`).edit(thru).tone(bass),
|
||||
\`<Cm7 Bb7 Fm7 G7b13>/2\`.groove(\`~ [x@0.5 ~]\`.fast(2)).voicings().edit(thru).every(2, early(1/8)).tone(keys).bypass(\`<0@7 1>/8\`.early(1/4)),
|
||||
)
|
||||
return stack(
|
||||
drums.fast(2),
|
||||
synths
|
||||
).slow(2);
|
||||
}`;
|
||||
export const caveravefuture2 = `const delay = new FeedbackDelay(1/8, .4).chain(vol(0.5), out);
|
||||
const kick = new MembraneSynth().chain(vol(.8), out);
|
||||
const snare = new NoiseSynth().chain(vol(.8), out);
|
||||
const hihat = new MetalSynth().set(adsr(0, .08, 0, .1)).chain(vol(.3).connect(delay),out);
|
||||
const bass = new Synth().set({ ...osc('sawtooth'), ...adsr(0, .1, .4) }).chain(lowpass(900), vol(.5), out);
|
||||
const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out);
|
||||
|
||||
const drums = stack(
|
||||
"c1*2".tone(kick).bypass("<0@7 1>/8"),
|
||||
"~ <x!7 [x@3 x]>".tone(snare).bypass("<0@7 1>/4"),
|
||||
"[~ c4]*2".tone(hihat)
|
||||
);
|
||||
|
||||
const thru = (x) => x.transpose("<0 1>/8").transpose(-1);
|
||||
const synths = stack(
|
||||
"<eb4 d4 c4 b3>/2".scale(timeCat([3, 'C minor'], [1, 'C melodic minor']).slow(8)).groove("[~ x]*2")
|
||||
.edit(
|
||||
scaleTranspose(0).early(0),
|
||||
scaleTranspose(2).early(1/8),
|
||||
scaleTranspose(7).early(1/4),
|
||||
scaleTranspose(8).early(3/8)
|
||||
).edit(thru).tone(keys).bypass("<1 0>/16"),
|
||||
"<C2 Bb1 Ab1 [G1 [G2 G1]]>/2".groove("x [~ x] <[~ [~ x]]!3 [x x]>@2").edit(thru).tone(bass),
|
||||
"<Cm7 Bb7 Fm7 G7b13>/2".groove("~ [x@0.5 ~]".fast(2)).voicings().edit(thru).every(2, early(1/8)).tone(keys).bypass("<0@7 1>/8".early(1/4)),
|
||||
)
|
||||
$: stack(
|
||||
drums.fast(2),
|
||||
synths
|
||||
).slow(2);
|
||||
`;
|
||||
|
||||
5
docs/dist/useRepl.js
vendored
5
docs/dist/useRepl.js
vendored
@ -6,7 +6,7 @@ import usePostMessage from "./usePostMessage.js";
|
||||
let s4 = () => {
|
||||
return Math.floor((1 + Math.random()) * 65536).toString(16).substring(1);
|
||||
};
|
||||
function useRepl({tune, defaultSynth, autolink = true}) {
|
||||
function useRepl({tune, defaultSynth, autolink = true, onEvent}) {
|
||||
const id = useMemo(() => s4(), []);
|
||||
const [code, setCode] = useState(tune);
|
||||
const [activeCode, setActiveCode] = useState();
|
||||
@ -43,6 +43,7 @@ function useRepl({tune, defaultSynth, autolink = true}) {
|
||||
const cycle = useCycle({
|
||||
onEvent: useCallback((time, event) => {
|
||||
try {
|
||||
onEvent?.(event);
|
||||
if (!event.value?.onTrigger) {
|
||||
const note = event.value?.value || event.value;
|
||||
if (!isNote(note)) {
|
||||
@ -62,7 +63,7 @@ function useRepl({tune, defaultSynth, autolink = true}) {
|
||||
err.message = "unplayable event: " + err?.message;
|
||||
pushLog(err.message);
|
||||
}
|
||||
}, []),
|
||||
}, [onEvent]),
|
||||
onQuery: useCallback((span) => {
|
||||
try {
|
||||
return pattern?.query(span) || [];
|
||||
|
||||
@ -41619,7 +41619,7 @@ var _usePostMessageDefault = parcelHelpers.interopDefault(_usePostMessage);
|
||||
let s4 = ()=>{
|
||||
return Math.floor((1 + Math.random()) * 65536).toString(16).substring(1);
|
||||
};
|
||||
function useRepl({ tune , defaultSynth , autolink =true }) {
|
||||
function useRepl({ tune , defaultSynth , autolink =true , onEvent }) {
|
||||
const id = _react.useMemo(()=>s4()
|
||||
, []);
|
||||
const [code, setCode] = _react.useState(tune);
|
||||
@ -41661,6 +41661,7 @@ function useRepl({ tune , defaultSynth , autolink =true }) {
|
||||
const cycle1 = _useCycleDefault.default({
|
||||
onEvent: _react.useCallback((time, event)=>{
|
||||
try {
|
||||
onEvent?.(event);
|
||||
if (!event.value?.onTrigger) {
|
||||
const note = event.value?.value || event.value;
|
||||
if (!_tone.isNote(note)) throw new Error('not a note: ' + note);
|
||||
@ -41676,7 +41677,9 @@ function useRepl({ tune , defaultSynth , autolink =true }) {
|
||||
err.message = 'unplayable event: ' + err?.message;
|
||||
pushLog(err.message); // not with setError, because then we would have to setError(undefined) on next playable event
|
||||
}
|
||||
}, []),
|
||||
}, [
|
||||
onEvent
|
||||
]),
|
||||
onQuery: _react.useCallback((span)=>{
|
||||
try {
|
||||
return pattern?.query(span) || [];
|
||||
@ -42107,6 +42110,20 @@ class Pattern {
|
||||
return new Pattern((span)=>func(this.query(span))
|
||||
);
|
||||
}
|
||||
withLocation(location) {
|
||||
return this.fmap((value)=>{
|
||||
value = typeof value === 'object' && !Array.isArray(value) ? value : {
|
||||
value
|
||||
};
|
||||
const locations = (value.locations || []).concat([
|
||||
location
|
||||
]);
|
||||
return {
|
||||
...value,
|
||||
locations
|
||||
};
|
||||
});
|
||||
}
|
||||
withValue(func) {
|
||||
// Returns a new pattern, with the function applied to the value of
|
||||
// each event. It has the alias 'fmap'.
|
||||
@ -42273,7 +42290,14 @@ class Pattern {
|
||||
_patternify(func) {
|
||||
const pat = this;
|
||||
const patterned = function(...args) {
|
||||
// the problem here: args could a pattern that has been turned into an object to add location
|
||||
// to avoid object checking for every pattern method, we can remove it here...
|
||||
// in the future, patternified args should be marked as well + some better object handling
|
||||
args = args.map((arg)=>arg.constructor?.name === 'Pattern' ? arg.fmap((value)=>value.value || value
|
||||
) : arg
|
||||
);
|
||||
const pat_arg = sequence(...args);
|
||||
// arg.locations has to go somewhere..
|
||||
return pat_arg.fmap((arg)=>func.call(pat, arg)
|
||||
).outerJoin();
|
||||
};
|
||||
@ -62538,17 +62562,32 @@ var _shiftTraverserDefault = parcelHelpers.interopDefault(_shiftTraverser);
|
||||
var _shiftAst = require("shift-ast");
|
||||
var _shiftCodegen = require("shift-codegen");
|
||||
var _shiftCodegenDefault = parcelHelpers.interopDefault(_shiftCodegen);
|
||||
var _strudelMjs = require("../../strudel.mjs");
|
||||
const { replace } = _shiftTraverserDefault.default;
|
||||
const { Pattern } = _strudelMjs;
|
||||
const isNote = (name)=>/^[a-gC-G][bs]?[0-9]$/.test(name)
|
||||
;
|
||||
const addLocations = true;
|
||||
exports.default = (code)=>{
|
||||
const ast = _indexJs.parseScript(code);
|
||||
const shifted = replace(ast, {
|
||||
enter (node, parent) {
|
||||
// replace identifiers that are a note with a note string
|
||||
const ast = _indexJs.parseScriptWithLocation(code);
|
||||
const nodesWithLocation = [];
|
||||
const parents = [];
|
||||
const shifted = replace(ast.tree, {
|
||||
enter (node, parent1) {
|
||||
parents.push(parent1);
|
||||
const isSynthetic = parents.some((p)=>nodesWithLocation.includes(p)
|
||||
);
|
||||
if (isSynthetic) return node;
|
||||
const grandparent = parents[parents.length - 2];
|
||||
const isPatternArg = (parent)=>parent?.type === 'CallExpression' && Object.keys(Pattern.prototype.factories).includes(parent.callee.name)
|
||||
;
|
||||
const isTimeCat = parent1?.type === 'ArrayExpression' && isPatternArg(grandparent);
|
||||
const isMarkable = isPatternArg(parent1) || isTimeCat;
|
||||
// replace pseudo note variables
|
||||
if (node.type === 'IdentifierExpression') {
|
||||
if (isNote(node.name)) {
|
||||
const value = node.name[1] === 's' ? node.name.replace('s', '#') : node.name;
|
||||
if (addLocations && isMarkable) return addPureWithLocation(value, node, ast.locations, nodesWithLocation);
|
||||
return new _shiftAst.LiteralStringExpression({
|
||||
value
|
||||
});
|
||||
@ -62557,14 +62596,152 @@ exports.default = (code)=>{
|
||||
name: 'silence'
|
||||
});
|
||||
}
|
||||
if (addLocations && node.type === 'LiteralStringExpression' && isMarkable) // console.log('add', node);
|
||||
return addPureWithLocation(node.value, node, ast.locations, nodesWithLocation);
|
||||
return node;
|
||||
},
|
||||
leave () {
|
||||
parents.pop();
|
||||
}
|
||||
});
|
||||
return _shiftCodegenDefault.default(shifted);
|
||||
}; // TODO: turn x.groove['[~ x]*2'] into x.groove('[~ x]*2'.m)
|
||||
};
|
||||
// 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) {
|
||||
// console.log('addPure', value, node);
|
||||
const withLocation = new _shiftAst.CallExpression({
|
||||
callee: new _shiftAst.StaticMemberExpression({
|
||||
object: new _shiftAst.CallExpression({
|
||||
callee: new _shiftAst.IdentifierExpression({
|
||||
name: 'pure'
|
||||
}),
|
||||
arguments: [
|
||||
new _shiftAst.LiteralStringExpression({
|
||||
value
|
||||
})
|
||||
]
|
||||
}),
|
||||
property: 'withLocation'
|
||||
}),
|
||||
arguments: [
|
||||
getLocationObject(node, locations)
|
||||
]
|
||||
});
|
||||
nodesWithLocation.push(withLocation);
|
||||
return withLocation;
|
||||
}
|
||||
// returns ast for source location object
|
||||
function getLocationObject(node, locations) {
|
||||
/*const locationAST = parseScript(
|
||||
"x=" + JSON.stringify(ast.locations.get(node))
|
||||
).statements[0].expression.expression;
|
||||
|
||||
console.log("locationAST", locationAST);*/ /*const callAST = parseScript(
|
||||
`pure(${node.name}).withLocation(${JSON.stringify(
|
||||
ast.locations.get(node)
|
||||
)})`
|
||||
).statements[0].expression;*/ const loc = locations.get(node);
|
||||
return {
|
||||
type: 'ObjectExpression',
|
||||
properties: [
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'start'
|
||||
},
|
||||
expression: {
|
||||
type: 'ObjectExpression',
|
||||
properties: [
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'line'
|
||||
},
|
||||
expression: {
|
||||
type: 'LiteralNumericExpression',
|
||||
value: loc.start.line
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'column'
|
||||
},
|
||||
expression: {
|
||||
type: 'LiteralNumericExpression',
|
||||
value: loc.start.column
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'offset'
|
||||
},
|
||||
expression: {
|
||||
type: 'LiteralNumericExpression',
|
||||
value: loc.start.offset
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'end'
|
||||
},
|
||||
expression: {
|
||||
type: 'ObjectExpression',
|
||||
properties: [
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'line'
|
||||
},
|
||||
expression: {
|
||||
type: 'LiteralNumericExpression',
|
||||
value: loc.end.line
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'column'
|
||||
},
|
||||
expression: {
|
||||
type: 'LiteralNumericExpression',
|
||||
value: loc.end.column
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'DataProperty',
|
||||
name: {
|
||||
type: 'StaticPropertyName',
|
||||
value: 'offset'
|
||||
},
|
||||
expression: {
|
||||
type: 'LiteralNumericExpression',
|
||||
value: loc.end.offset
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
};
|
||||
} // TODO: turn x.groove['[~ x]*2'] into x.groove('[~ x]*2'.m)
|
||||
// and ['c1*2'].xx into 'c1*2'.m.xx ??
|
||||
// or just all templated strings?? x.groove(`[~ x]*2`)
|
||||
|
||||
},{"./shift-parser/index.js":"1kFzJ","./shift-traverser":"bogJs","shift-ast":"ig2Ca","shift-codegen":"1GOrI","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"1kFzJ":[function(require,module,exports) {
|
||||
},{"./shift-parser/index.js":"1kFzJ","./shift-traverser":"bogJs","shift-ast":"ig2Ca","shift-codegen":"1GOrI","../../strudel.mjs":"ggZqJ","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"1kFzJ":[function(require,module,exports) {
|
||||
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
|
||||
parcelHelpers.defineInteropFlag(exports);
|
||||
parcelHelpers.export(exports, "parseModule", ()=>parseModule
|
||||
@ -97727,16 +97904,18 @@ var _javascriptJs = require("codemirror/mode/javascript/javascript.js");
|
||||
var _pegjsJs = require("codemirror/mode/pegjs/pegjs.js");
|
||||
var _materialCss = require("codemirror/theme/material.css");
|
||||
var _codemirrorCss = require("codemirror/lib/codemirror.css");
|
||||
function CodeMirror({ value , onChange , options }) {
|
||||
function CodeMirror({ value , onChange , options , editorDidMount }) {
|
||||
options = options || {
|
||||
mode: 'javascript',
|
||||
theme: 'material',
|
||||
lineNumbers: true
|
||||
lineNumbers: true,
|
||||
styleSelectedText: true
|
||||
};
|
||||
return(/*#__PURE__*/ _jsxRuntime.jsx(_reactCodemirror2.Controlled, {
|
||||
value: value,
|
||||
options: options,
|
||||
onBeforeChange: onChange
|
||||
onBeforeChange: onChange,
|
||||
editorDidMount: editorDidMount
|
||||
}));
|
||||
}
|
||||
exports.default = CodeMirror;
|
||||
@ -108958,4 +109137,4 @@ exports.default = cx;
|
||||
|
||||
},{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}]},["3uVTb"], "3uVTb", "parcelRequire94c2")
|
||||
|
||||
//# sourceMappingURL=index.dc15e374.js.map
|
||||
//# sourceMappingURL=index.98344030.js.map
|
||||
File diff suppressed because one or more lines are too long
@ -11,6 +11,6 @@
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<script src="/tutorial/index.dc15e374.js" defer=""></script>
|
||||
<script src="/tutorial/index.98344030.js" defer=""></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user