experimental stuff
This commit is contained in:
@ -10,9 +10,9 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tauri-apps/cli": "^1.4.0",
|
"@tauri-apps/cli": "^1.4.0",
|
||||||
|
"@types/audioworklet": "^0.0.49",
|
||||||
"typescript": "^5.0.2",
|
"typescript": "^5.0.2",
|
||||||
"vite": "^4.4.5",
|
"vite": "^4.4.5"
|
||||||
"@types/audioworklet": "^0.0.49"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/lang-javascript": "^6.1.9",
|
"@codemirror/lang-javascript": "^6.1.9",
|
||||||
@ -20,6 +20,9 @@
|
|||||||
"@codemirror/theme-one-dark": "^6.1.2",
|
"@codemirror/theme-one-dark": "^6.1.2",
|
||||||
"@replit/codemirror-vim": "^6.0.14",
|
"@replit/codemirror-vim": "^6.0.14",
|
||||||
"@strudel.cycles/webaudio": "^0.8.2",
|
"@strudel.cycles/webaudio": "^0.8.2",
|
||||||
|
"acorn": "^8.10.0",
|
||||||
|
"acorn-walk": "^8.2.0",
|
||||||
|
"astring": "^1.8.6",
|
||||||
"autoprefixer": "^10.4.14",
|
"autoprefixer": "^10.4.14",
|
||||||
"codemirror": "^6.0.1",
|
"codemirror": "^6.0.1",
|
||||||
"postcss": "^8.4.27",
|
"postcss": "^8.4.27",
|
||||||
|
|||||||
25
src/API.ts
25
src/API.ts
@ -4,6 +4,9 @@ import { tryEvaluate } from "./Evaluator";
|
|||||||
import { MidiConnection } from "./IO/MidiConnection";
|
import { MidiConnection } from "./IO/MidiConnection";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { webaudioOutput, samples } from '@strudel.cycles/webaudio';
|
import { webaudioOutput, samples } from '@strudel.cycles/webaudio';
|
||||||
|
import { MiniLanguage } from "./Walker";
|
||||||
|
import * as astring from 'astring';
|
||||||
|
|
||||||
|
|
||||||
const sound = (value: any) => ({
|
const sound = (value: any) => ({
|
||||||
value, context: {},
|
value, context: {},
|
||||||
@ -139,7 +142,6 @@ export class UserAPI {
|
|||||||
// would be 1.0, which is the current rate (very speedy).
|
// would be 1.0, which is the current rate (very speedy).
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
script(...args: number[]): void {
|
script(...args: number[]): void {
|
||||||
/**
|
/**
|
||||||
* Evaluates 1-n local script(s)
|
* Evaluates 1-n local script(s)
|
||||||
@ -180,7 +182,6 @@ export class UserAPI {
|
|||||||
}
|
}
|
||||||
cps = this.copyscript
|
cps = this.copyscript
|
||||||
|
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// MIDI related functions
|
// MIDI related functions
|
||||||
// =============================================================
|
// =============================================================
|
||||||
@ -208,7 +209,7 @@ export class UserAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public note(note: number, channel: number, velocity: number, duration: number): void {
|
public note(note: number, channel: number = 0, velocity: number = 100, duration: number = 0.5): void {
|
||||||
/**
|
/**
|
||||||
* Sends a MIDI note to the current MIDI output.
|
* Sends a MIDI note to the current MIDI output.
|
||||||
* TODO: Fix note duration
|
* TODO: Fix note duration
|
||||||
@ -313,15 +314,7 @@ export class UserAPI {
|
|||||||
// Return current iterator value
|
// Return current iterator value
|
||||||
return this.iterators[name].value;
|
return this.iterators[name].value;
|
||||||
}
|
}
|
||||||
it = this.iterator
|
$ = this.iterator
|
||||||
|
|
||||||
get _() {
|
|
||||||
return this.iterator('_');
|
|
||||||
}
|
|
||||||
|
|
||||||
get A() {
|
|
||||||
return this.iterator('A');
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Drunk mechanism
|
// Drunk mechanism
|
||||||
@ -466,7 +459,7 @@ export class UserAPI {
|
|||||||
* @param array - The array of values to pick from
|
* @param array - The array of values to pick from
|
||||||
*/
|
*/
|
||||||
return array[this.app.clock.time_position.pulse % array.length]
|
return array[this.app.clock.time_position.pulse % array.length]
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Randomness functions
|
// Randomness functions
|
||||||
@ -953,4 +946,10 @@ export class UserAPI {
|
|||||||
sound = async (values: object) => {
|
sound = async (values: object) => {
|
||||||
webaudioOutput(sound(values), 0.00)
|
webaudioOutput(sound(values), 0.00)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ast(code: string) {
|
||||||
|
const ast = MiniLanguage.parse(code, { ecmaVersion: 2020 });
|
||||||
|
console.log(astring.generate(ast))
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
66
src/Walker.ts
Normal file
66
src/Walker.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import * as acorn from 'acorn';
|
||||||
|
import * as walk from 'acorn-walk';
|
||||||
|
import * as astring from 'astring';
|
||||||
|
|
||||||
|
// Create a custom Acorn plugin
|
||||||
|
function myPlugin(Parser: typeof acorn.Parser): any {
|
||||||
|
return class extends Parser {
|
||||||
|
parseLiteral(...args: Parameters<acorn.Parser['parseLiteral']>) {
|
||||||
|
const node = super.parseLiteral(...args);
|
||||||
|
|
||||||
|
// Check if the literal is a string and if it's wrapped in single quotes
|
||||||
|
if (typeof node.value === 'string' && this.input.slice(node.start, node.end).startsWith("'")) {
|
||||||
|
const transformed = this.transformMyString(node.value);
|
||||||
|
|
||||||
|
// Replace the Literal node with an ArrayExpression node
|
||||||
|
return {
|
||||||
|
type: 'SpreadElement',
|
||||||
|
argument: {
|
||||||
|
type: 'ArrayExpression',
|
||||||
|
elements: transformed.map(value => ({
|
||||||
|
type: 'Literal',
|
||||||
|
value,
|
||||||
|
raw: value.toString()
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
start: node.start,
|
||||||
|
end: node.end
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
transformMyString(string: string): number[] {
|
||||||
|
const matches = string.match(/\d+!*\d*/g);
|
||||||
|
const values: number[] = [];
|
||||||
|
|
||||||
|
matches?.forEach(match => {
|
||||||
|
const parts = match.split('!');
|
||||||
|
const number = parseInt(parts[0]);
|
||||||
|
const times = parts[1] ? parseInt(parts[1]) : 1;
|
||||||
|
|
||||||
|
for (let i = 0; i < times; i++) {
|
||||||
|
values.push(number);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MiniLanguage = acorn.Parser.extend(myPlugin);
|
||||||
|
|
||||||
|
// Sample code
|
||||||
|
// const code = `
|
||||||
|
// const a = '3!4 5'; // This should become const a = [...[3,3,3,3,5]];
|
||||||
|
// `;
|
||||||
|
|
||||||
|
// Parse the code
|
||||||
|
// const ast = MiniLanguage.parse(code, { ecmaVersion: 2020 });
|
||||||
|
|
||||||
|
// Convert the transformed AST back into source code
|
||||||
|
// const newCode = astring.generate(ast);
|
||||||
|
|
||||||
|
// console.log(newCode);
|
||||||
15
yarn.lock
15
yarn.lock
@ -451,6 +451,16 @@
|
|||||||
resolved "https://registry.npmjs.org/@types/audioworklet/-/audioworklet-0.0.49.tgz"
|
resolved "https://registry.npmjs.org/@types/audioworklet/-/audioworklet-0.0.49.tgz"
|
||||||
integrity sha512-Njo9vdkdTPwBTplwWgIXQk7Xoo5xAErxOfNXoq5pYHcYOZ1Yyp4M23TfeavaLZ+qqQo3y9xIigfWckizkyCKSw==
|
integrity sha512-Njo9vdkdTPwBTplwWgIXQk7Xoo5xAErxOfNXoq5pYHcYOZ1Yyp4M23TfeavaLZ+qqQo3y9xIigfWckizkyCKSw==
|
||||||
|
|
||||||
|
acorn-walk@^8.2.0:
|
||||||
|
version "8.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
|
||||||
|
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
|
||||||
|
|
||||||
|
acorn@^8.10.0:
|
||||||
|
version "8.10.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5"
|
||||||
|
integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
|
||||||
|
|
||||||
any-promise@^1.0.0:
|
any-promise@^1.0.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz"
|
resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz"
|
||||||
@ -469,6 +479,11 @@ arg@^5.0.2:
|
|||||||
resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz"
|
resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz"
|
||||||
integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==
|
integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==
|
||||||
|
|
||||||
|
astring@^1.8.6:
|
||||||
|
version "1.8.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/astring/-/astring-1.8.6.tgz#2c9c157cf1739d67561c56ba896e6948f6b93731"
|
||||||
|
integrity sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==
|
||||||
|
|
||||||
automation-events@^6.0.8:
|
automation-events@^6.0.8:
|
||||||
version "6.0.8"
|
version "6.0.8"
|
||||||
resolved "https://registry.npmjs.org/automation-events/-/automation-events-6.0.8.tgz"
|
resolved "https://registry.npmjs.org/automation-events/-/automation-events-6.0.8.tgz"
|
||||||
|
|||||||
Reference in New Issue
Block a user