Address stack issues in playground, unicode input in playground, fixes to error recovery

This commit is contained in:
2024-12-17 20:44:39 -08:00
parent 2f2a737f00
commit 08cc2637f5
3 changed files with 64 additions and 12 deletions

View File

@@ -205,9 +205,7 @@ export let shim: NodeShim = {
platform: "linux", platform: "linux",
argv: ["", ""], argv: ["", ""],
stdout: { stdout: {
// We'll want to replace this one
write(s) { write(s) {
console.log("*", s);
shim.stdout += s; shim.stdout += s;
}, },
}, },

View File

@@ -102,8 +102,8 @@ document.body.appendChild(iframe);
function run(src: string) { function run(src: string) {
console.log("SEND TO", iframe.contentWindow); console.log("SEND TO", iframe.contentWindow);
const fileName = state.currentFile.value const fileName = state.currentFile.value;
postMessage({ type: 'compileRequest', fileName, src }); postMessage({ type: "compileRequest", fileName, src });
} }
function runOutput() { function runOutput() {
@@ -133,7 +133,6 @@ function setOutput(output: string) {
state.output.value = output; state.output.value = output;
} }
window.onmessage = (ev: MessageEvent<Message>) => { window.onmessage = (ev: MessageEvent<Message>) => {
console.log("window got", ev.data); console.log("window got", ev.data);
if ("messages" in ev.data) state.messages.value = ev.data.messages; if ("messages" in ev.data) state.messages.value = ev.data.messages;
@@ -166,7 +165,7 @@ const state = {
editor: signal<monaco.editor.IStandaloneCodeEditor | null>(null), editor: signal<monaco.editor.IStandaloneCodeEditor | null>(null),
dark: signal(false), dark: signal(false),
files: signal<string[]>(["Tour.newt"]), files: signal<string[]>(["Tour.newt"]),
currentFile: signal<string>(localStorage.currentFile ?? 'Tour.newt') currentFile: signal<string>(localStorage.currentFile ?? "Tour.newt"),
}; };
// Monitor dark mode state (TODO - let user override system setting) // Monitor dark mode state (TODO - let user override system setting)
@@ -197,8 +196,8 @@ async function loadFile(fn: string) {
} else { } else {
state.editor.value!.setValue("module Main\n\n-- File not found\n"); state.editor.value!.setValue("module Main\n\n-- File not found\n");
} }
state.currentFile.value = fn state.currentFile.value = fn;
localStorage.currentFile = fn localStorage.currentFile = fn;
} }
// I keep pressing this. // I keep pressing this.
@@ -222,6 +221,16 @@ interface EditorProps {
initialValue: string; initialValue: string;
} }
const ABBREV: Record<string, string> = {
'\\x': '×',
'\\r': '→',
'\\all': '∀',
'\\\\': '\\',
'\\==': '≡',
'\circ': '∘',
'\\_1': '₁',
}
function Editor({ initialValue }: EditorProps) { function Editor({ initialValue }: EditorProps) {
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
useEffect(() => { useEffect(() => {
@@ -244,6 +253,36 @@ function Editor({ initialValue }: EditorProps) {
run(value); run(value);
localStorage.code = value; localStorage.code = value;
}, 1000); }, 1000);
let last = ev.changes[ev.changes.length - 1];
const model = editor.getModel();
// figure out heuristics here, what chars do we want to trigger?
if (model && last.text && " ')_".includes(last.text)) {
console.log('LAST', last)
let { startLineNumber, startColumn } = last.range;
const text = model.getValueInRange(
new monaco.Range(
startLineNumber,
Math.max(1, startColumn - 10),
startLineNumber,
startColumn
)
);
const m = text.match(/(\\[^ ]+)$/);
if (m) {
let cand = m[0];
console.log("GOT", cand);
let text = ABBREV[cand];
if (text) {
const range = new monaco.Range(
startLineNumber,
startColumn - cand.length,
startLineNumber,
startColumn
);
editor.executeEdits("replaceSequence", [{ range, text: text }]);
}
}
}
}); });
if (initialValue === LOADING) loadFile("Tour.newt"); if (initialValue === LOADING) loadFile("Tour.newt");
else run(initialValue); else run(initialValue);
@@ -363,7 +402,11 @@ function EditWrap({
h( h(
"div", "div",
{ className: "tabBar" }, { className: "tabBar" },
h("select", { onChange: selectFile, value: state.currentFile.value }, options), h(
"select",
{ onChange: selectFile, value: state.currentFile.value },
options
),
h("div", { style: { flex: "1 1" } }), h("div", { style: { flex: "1 1" } }),
h("button", { onClick: runOutput }, svg(play)), h("button", { onClick: runOutput }, svg(play)),
h("button", { onClick: toggle }, svg(d)) h("button", { onClick: toggle }, svg(d))

View File

@@ -26,6 +26,7 @@ import System
import System.Directory import System.Directory
import System.File import System.File
import System.Path import System.Path
import Data.Buffer
fail : String -> M a fail : String -> M a
fail msg = putStrLn msg >> exitFailure fail msg = putStrLn msg >> exitFailure
@@ -69,7 +70,7 @@ writeSource fn = do
parseDecls : String -> Operators -> TokenList -> SnocList Decl -> M (List Decl, Operators) parseDecls : String -> Operators -> TokenList -> SnocList Decl -> M (List Decl, Operators)
parseDecls fn ops [] acc = pure (acc <>> [], ops) parseDecls fn ops [] acc = pure (acc <>> [], ops)
parseDecls fn ops toks acc = parseDecls fn ops toks@(first :: _) acc =
case partialParse fn (sameLevel parseDecl) ops toks of case partialParse fn (sameLevel parseDecl) ops toks of
Left (err, toks) => do Left (err, toks) => do
putStrLn $ showError "" err putStrLn $ showError "" err
@@ -79,7 +80,17 @@ parseDecls fn ops toks acc =
where where
recover : TokenList -> TokenList recover : TokenList -> TokenList
recover [] = [] recover [] = []
recover (tok :: toks) = if tok.bounds.startCol == 0 then (tok :: toks) else recover toks -- skip to top token, but make sure there is progress
recover (tok :: toks) = if tok.bounds.startCol == 0 && tok.bounds /= first.bounds
then (tok :: toks)
else recover toks
fastReadFile : HasIO io => String -> io (Either FileError String)
fastReadFile fn = do
Right buf <- createBufferFromFile fn | Left err => pure $ Left err
len <- rawSize buf
Right <$> getString buf 0 len
||| New style loader, one def at a time ||| New style loader, one def at a time
processModule : String -> List String -> String -> M String processModule : String -> List String -> String -> M String
@@ -88,7 +99,7 @@ processModule base stk name = do
let False := elem name top.loaded | _ => pure "" let False := elem name top.loaded | _ => pure ""
modify { loaded $= (name::) } modify { loaded $= (name::) }
let fn = if base == "" then name ++ ".newt" else base ++ "/" ++ name ++ ".newt" let fn = if base == "" then name ++ ".newt" else base ++ "/" ++ name ++ ".newt"
Right src <- readFile $ fn Right src <- fastReadFile $ fn
| Left err => fail "error reading \{fn}: \{show err}" | Left err => fail "error reading \{fn}: \{show err}"
let Right toks = tokenise fn src let Right toks = tokenise fn src
| Left err => fail (showError src err) | Left err => fail (showError src err)