diff --git a/docs/_snowpack/pkg/codemirror/mode/pegjs/pegjs.js b/docs/_snowpack/pkg/codemirror/mode/pegjs/pegjs.js new file mode 100644 index 00000000..1d55e7d9 --- /dev/null +++ b/docs/_snowpack/pkg/codemirror/mode/pegjs/pegjs.js @@ -0,0 +1,115 @@ +import { c as createCommonjsModule } from '../../../common/_commonjsHelpers-8c19dec8.js'; +import { c as codemirror } from '../../../common/codemirror-d650d44d.js'; +import javascript from '../javascript/javascript.js'; + +var pegjs = createCommonjsModule(function (module, exports) { +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: https://codemirror.net/LICENSE + +(function(mod) { + mod(codemirror, javascript); +})(function(CodeMirror) { + +CodeMirror.defineMode("pegjs", function (config) { + var jsMode = CodeMirror.getMode(config, "javascript"); + + function identifier(stream) { + return stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/); + } + + return { + startState: function () { + return { + inString: false, + stringType: null, + inComment: false, + inCharacterClass: false, + braced: 0, + lhs: true, + localState: null + }; + }, + token: function (stream, state) { + if (stream) + + //check for state changes + if (!state.inString && !state.inComment && ((stream.peek() == '"') || (stream.peek() == "'"))) { + state.stringType = stream.peek(); + stream.next(); // Skip quote + state.inString = true; // Update state + } + if (!state.inString && !state.inComment && stream.match('/*')) { + state.inComment = true; + } + + //return state + if (state.inString) { + while (state.inString && !stream.eol()) { + if (stream.peek() === state.stringType) { + stream.next(); // Skip quote + state.inString = false; // Clear flag + } else if (stream.peek() === '\\') { + stream.next(); + stream.next(); + } else { + stream.match(/^.[^\\\"\']*/); + } + } + return state.lhs ? "property string" : "string"; // Token style + } else if (state.inComment) { + while (state.inComment && !stream.eol()) { + if (stream.match('*/')) { + state.inComment = false; // Clear flag + } else { + stream.match(/^.[^\*]*/); + } + } + return "comment"; + } else if (state.inCharacterClass) { + while (state.inCharacterClass && !stream.eol()) { + if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./))) { + state.inCharacterClass = false; + } + } + } else if (stream.peek() === '[') { + stream.next(); + state.inCharacterClass = true; + return 'bracket'; + } else if (stream.match('//')) { + stream.skipToEnd(); + return "comment"; + } else if (state.braced || stream.peek() === '{') { + if (state.localState === null) { + state.localState = CodeMirror.startState(jsMode); + } + var token = jsMode.token(stream, state.localState); + var text = stream.current(); + if (!token) { + for (var i = 0; i < text.length; i++) { + if (text[i] === '{') { + state.braced++; + } else if (text[i] === '}') { + state.braced--; + } + } } + return token; + } else if (identifier(stream)) { + if (stream.peek() === ':') { + return 'variable'; + } + return 'variable-2'; + } else if (['[', ']', '(', ')'].indexOf(stream.peek()) != -1) { + stream.next(); + return 'bracket'; + } else if (!stream.eatSpace()) { + stream.next(); + } + return null; + } + }; +}, "javascript"); + +}); +}); + +export default pegjs; diff --git a/docs/_snowpack/pkg/import-map.json b/docs/_snowpack/pkg/import-map.json index d7ecc589..314df7d0 100644 --- a/docs/_snowpack/pkg/import-map.json +++ b/docs/_snowpack/pkg/import-map.json @@ -3,6 +3,7 @@ "@tonaljs/tonal": "./@tonaljs/tonal.js", "codemirror/lib/codemirror.css": "./codemirror/lib/codemirror.css", "codemirror/mode/javascript/javascript.js": "./codemirror/mode/javascript/javascript.js", + "codemirror/mode/pegjs/pegjs.js": "./codemirror/mode/pegjs/pegjs.js", "codemirror/theme/material.css": "./codemirror/theme/material.css", "fraction.js": "./fractionjs.js", "react": "./react.js", diff --git a/docs/dist/App.js b/docs/dist/App.js index d2f7453f..86d580ab 100644 --- a/docs/dist/App.js +++ b/docs/dist/App.js @@ -19,6 +19,7 @@ synth.set({ } }); function App() { + const [mode, setMode] = useState("javascript"); const [code, setCode] = useState(tetrisHaskell); const [log, setLog] = useState(""); const logBox = useRef(); @@ -49,7 +50,14 @@ function App() { }); useEffect(() => { try { - const _pattern = parse(code); + let _pattern; + try { + _pattern = h(code); + setMode("pegjs"); + } catch (err) { + setMode("javascript"); + _pattern = parse(code); + } setPattern(_pattern); setError(void 0); } catch (err) { @@ -78,6 +86,11 @@ function App() { className: cx("h-full bg-slate-600", error ? "focus:ring-red-500" : "focus:ring-slate-800") }, /* @__PURE__ */ React.createElement(CodeMirror, { value: code, + options: { + mode, + theme: "material", + lineNumbers: true + }, onChange: (_, __, value) => { setLog((log2) => log2 + `${log2 ? "\n\n" : ""}✏️ edit ${code} diff --git a/docs/dist/CodeMirror.js b/docs/dist/CodeMirror.js index 69e828da..1b7734b1 100644 --- a/docs/dist/CodeMirror.js +++ b/docs/dist/CodeMirror.js @@ -1,6 +1,7 @@ import React from "../_snowpack/pkg/react.js"; import {Controlled as CodeMirror2} from "../_snowpack/pkg/react-codemirror2.js"; 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}) { diff --git a/docs/dist/parse.js b/docs/dist/parse.js index da747f1e..3329c590 100644 --- a/docs/dist/parse.js +++ b/docs/dist/parse.js @@ -76,6 +76,5 @@ export const mini = (...strings) => { }; export const h = (string) => { const ast = krill.parse(string); - console.log("ast", ast); return patternifyAST(ast); }; diff --git a/docs/dist/tunes.js b/docs/dist/tunes.js index dfd32bac..6ce65d8c 100644 --- a/docs/dist/tunes.js +++ b/docs/dist/tunes.js @@ -62,7 +62,7 @@ export const tetrisMini = `mini(\`[[e5 [b4 c5] d5 [c5 b4]] [[b1 b2]*2 [e2 e3]*2] [[a1 a2]*4]\`)._slow(16); `; -export const tetrisHaskell = `h(\`slow 16 $ "[[e5 [b4 c5] d5 [c5 b4]] +export const tetrisHaskellH = `h(\`slow 16 $ "[[e5 [b4 c5] d5 [c5 b4]] [a4 [a4 c5] e5 [d5 c5]] [b4 [~ c5] d5 e5] [c5 a4 a4 ~] @@ -79,6 +79,23 @@ export const tetrisHaskell = `h(\`slow 16 $ "[[e5 [b4 c5] d5 [c5 b4]] [[b1 b2]*2 [e2 e3]*2] [[a1 a2]*4]"\`) `; +export const tetrisHaskell = `slow 16 $ "[[e5 [b4 c5] d5 [c5 b4]] +[a4 [a4 c5] e5 [d5 c5]] +[b4 [~ c5] d5 e5] +[c5 a4 a4 ~] +[[~ d5] [~ f5] a5 [g5 f5]] +[e5 [~ c5] e5 [d5 c5]] +[b4 [b4 c5] d5 e5] +[c5 a4 a4 ~]], +[[e2 e3]*4] +[[a2 a3]*4] +[[g#2 g#3]*2 [e2 e3]*2] +[a2 a3 a2 a3 a2 a3 b1 c2] +[[d2 d3]*4] +[[c2 c3]*4] +[[b1 b2]*2 [e2 e3]*2] +[[a1 a2]*4]" +`; export const spanish = `slowcat( stack('c4','eb4','g4'), stack('bb3','d4','f4'), diff --git a/repl/src/tunes.ts b/repl/src/tunes.ts index 2f195d54..ff326c39 100644 --- a/repl/src/tunes.ts +++ b/repl/src/tunes.ts @@ -65,7 +65,7 @@ export const tetrisMini = `mini(\`[[e5 [b4 c5] d5 [c5 b4]] [[a1 a2]*4]\`)._slow(16); `; -export const tetrisHaskell = `h(\`slow 16 $ "[[e5 [b4 c5] d5 [c5 b4]] +export const tetrisHaskellH = `h(\`slow 16 $ "[[e5 [b4 c5] d5 [c5 b4]] [a4 [a4 c5] e5 [d5 c5]] [b4 [~ c5] d5 e5] [c5 a4 a4 ~] @@ -82,6 +82,23 @@ export const tetrisHaskell = `h(\`slow 16 $ "[[e5 [b4 c5] d5 [c5 b4]] [[b1 b2]*2 [e2 e3]*2] [[a1 a2]*4]"\`) `; +export const tetrisHaskell = `slow 16 $ "[[e5 [b4 c5] d5 [c5 b4]] +[a4 [a4 c5] e5 [d5 c5]] +[b4 [~ c5] d5 e5] +[c5 a4 a4 ~] +[[~ d5] [~ f5] a5 [g5 f5]] +[e5 [~ c5] e5 [d5 c5]] +[b4 [b4 c5] d5 e5] +[c5 a4 a4 ~]], +[[e2 e3]*4] +[[a2 a3]*4] +[[g#2 g#3]*2 [e2 e3]*2] +[a2 a3 a2 a3 a2 a3 b1 c2] +[[d2 d3]*4] +[[c2 c3]*4] +[[b1 b2]*2 [e2 e3]*2] +[[a1 a2]*4]" +`; /* export const tetrisHaskell = `h(\`slow 16 $ "[[e5 [b4 c5] d5 [c5 b4]] [a4 [a4 c5] e5 [d5 c5]] [b4 [~ c5] d5 e5] [c5 a4 a4 ~] [[~ d5] [~ f5] a5 [g5 f5]] [e5 [~ c5] e5 [d5 c5]] [b4 [b4 c5] d5 e5] [c5 a4 a4 ~]], [[e2 e3]*4] [[a2 a3]*4] [[g#2 g#3]*2 [e2 e3]*2] [a2 a3 a2 a3 a2 a3 b1 c2] [[d2 d3]*4] [[c2 c3]*4] [[b1 b2]*2 [e2 e3]*2] [[a1 a2]*4]"\`)`;