add basic repl

This commit is contained in:
Felix Roos
2022-02-04 13:32:42 +01:00
parent 83d06ec2af
commit 71a3bdfeac
16 changed files with 15175 additions and 0 deletions
+71
View File
@@ -0,0 +1,71 @@
import React, { useEffect, useState } from 'react';
import logo from './logo.svg';
import * as strudel from '../../strudel.mjs';
import cx from './cx';
const { Fraction, TimeSpan } = strudel;
const fr = (v: number) => new Fraction(v);
const ts = (start: number, end: number) => new TimeSpan(fr(start), fr(end));
const parse = (code: string): Pattern<any> => {
const { sequence, stack, pure } = strudel; // make available to eval
return eval(code);
};
function App() {
const [code, setCode] = useState<string>("sequence('a', 'b', sequence('c', 'd'))");
const [events, setEvents] = useState<Hap<any>[]>([]);
const [error, setError] = useState<Error>();
useEffect(() => {
try {
const pattern = parse(code);
console.log('pattern', pattern);
setEvents(pattern.query(ts(0, 1)));
console.log('events', events);
setError(undefined);
} catch (err: any) {
setError(err);
}
}, [code]);
return (
<div className="h-[100vh] bg-slate-900 flex-row">
<header className="px-2 flex items-center space-x-2 border-b border-gray-200 bg-white">
<img src={logo} className="Tidal-logo w-16 h-16" alt="logo" />
<h1 className="text-2xl">Strudel REPL</h1>
</header>
<section className="grow p-2 text-gray-100">
<div className="relative">
<div className="absolute right-2 bottom-2 text-red-500">{error?.message}</div>
<textarea
className={cx('w-full h-32 bg-slate-600', error ? 'focus:ring-red-500' : 'focus:ring-slate-800')}
value={code}
onChange={(e) => setCode(e.target.value)}
/>
</div>
<textarea className="w-full h-64 bg-slate-600" value={events.map((e) => e.show()).join('\n')} readOnly />
</section>
</div>
);
}
export default App;
declare interface Fraction {
(v: number): Fraction;
d: number;
n: number;
s: number;
}
declare interface TimeSpan {
constructor: any; //?
begin: Fraction;
end: Fraction;
}
declare interface Hap<T> {
whole: TimeSpan;
part: TimeSpan;
value: T;
show: () => string;
}
declare interface Pattern<T> {
query: (span: TimeSpan) => Hap<T>[];
}
+3
View File
@@ -0,0 +1,3 @@
export default function cx(...classes: Array<string | undefined>) {
return classes.filter(Boolean).join(' ');
}
+16
View File
@@ -0,0 +1,16 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root'),
);
// Hot Module Replacement (HMR) - Remove this snippet to remove HMR.
// Learn more: https://snowpack.dev/concepts/hot-module-replacement
if (import.meta.hot) {
import.meta.hot.accept();
}
+33
View File
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 42 KiB