diff --git a/index.ts b/index.ts index 75acb52..5e63b96 100644 --- a/index.ts +++ b/index.ts @@ -4,27 +4,48 @@ import { clearScreen, } from "./window.ts"; import { codeSheet } from "./sheet.ts"; -import { refreshKeyboard } from "./keyboard.ts"; -import { repl } from "./repl.ts"; +import { refreshKeyboard, keyPressed, K } from "./keyboard.ts"; +import { repl, resetRepl } from "./repl.ts"; +import { addToContext } from "./runcode.ts"; const game = codeSheet(0); game.init(); -let mode: "play" | "edit" = "edit"; +let mode: "play" | "edit" | "repl" = "repl"; + +addToContext("play", () => {mode = "play"}); clearScreen(); await mainloop((_t) => { // TODO: use t - if (mode === "play") { - game.update(); - game.draw(); - frame(); - } else if (mode === "edit") { - repl.update(); - repl.draw(); - frame(); + if (keyPressed(K.ESCAPE)) { + console.log('pressed escape'); + if (mode === "play") { + resetRepl(); + } + if (mode === "edit") { + clearScreen(); + } + mode = ({ + play: "repl", + edit: "repl", + repl: "edit", + } as const)[mode]; + } else { + if (mode === "play") { + game.update(); + game.draw(); + frame(); + } else if (mode === "repl") { + repl.update(); + repl.draw(); + frame(); + } else if (mode === "edit") { + clearScreen(); + frame(); + } } refreshKeyboard(); }); diff --git a/keyboard.ts b/keyboard.ts index bbc39df..1705a6a 100644 --- a/keyboard.ts +++ b/keyboard.ts @@ -97,14 +97,14 @@ export const refreshKeyboard = () => { export const keyPressed = (key: string | number) => { if (typeof key === "string") { - key = key.charCodeAt(0); + key = key.toUpperCase().charCodeAt(0); } - return keyboard.has(key) && keyboard.get(key)?.repeat!; + return keyboard.has(key) && (keyboard.get(key)?.first! || keyboard.get(key)?.repeat!); } export const keyDown = (key: string | number) => { if (typeof key === "string") { - key = key.charCodeAt(0); + key = key.toUpperCase().charCodeAt(0); } return keyboard.has(key) && keyboard.get(key)?.held!; } @@ -115,7 +115,7 @@ export const shiftKeyDown = () => { export const keyReleased = (key: string | number) => { if (typeof key === "string") { - key = key.charCodeAt(0); + key = key.toUpperCase().charCodeAt(0); } return keyboard.has(key) && !keyboard.get(key)?.held!; } diff --git a/repl.ts b/repl.ts index df972c5..a944929 100644 --- a/repl.ts +++ b/repl.ts @@ -5,18 +5,22 @@ import { runCode } from "./runcode.ts"; const lineHeight = 6; +const history: Array = []; +let historyIndex = history.length; +let textLinesAbove: Array = []; let maxLineLen = 0; -let line = ""; +let currentLine = ""; let index = 0; -let y = 0; -let result = ""; + +export const resetRepl = () => { + historyIndex = history.length; + textLinesAbove.length = 0; + maxLineLen = 0; + currentLine = ""; + index = 0; +} const update = () => { - if (result) { - console.log("result:", result); - y += lineHeight; // TODO: multiply if multiline - result = ""; - } for (const key of getKeysPressed()) { let char = String.fromCharCode(key).toLowerCase(); if (shiftKeyDown()) { @@ -27,11 +31,11 @@ const update = () => { } } if (char in font) { - line = line.slice(0, index)+char+line.slice(index); + currentLine = currentLine.slice(0, index)+char+currentLine.slice(index); index += 1; } else if (key === K.BACKSPACE) { if (index > 0) { - line = line.slice(0, index-1)+line.slice(index); + currentLine = currentLine.slice(0, index-1)+currentLine.slice(index); index -= 1; } } else if (key === K.ARROW_LEFT) { @@ -41,31 +45,60 @@ const update = () => { } } else if (key === K.ARROW_RIGHT) { index += 1; - if (index > line.length) { - index = line.length; + if (index > currentLine.length) { + index = currentLine.length; } + } else if (key === K.ARROW_UP) { + historyIndex -= 1; + if (historyIndex < 0) { + historyIndex = -1; + } + const lineAtHistory = history[historyIndex] ?? ""; + currentLine = lineAtHistory; + index = currentLine.length; + } else if (key === K.ARROW_DOWN) { + historyIndex += 1; + if (historyIndex > history.length) { + historyIndex = history.length; + } + const lineAtHistory = history[historyIndex] ?? ""; + currentLine = lineAtHistory; + index = currentLine.length; } else if (key === K.ENTER) { - const ran = runCode('return '+line); - console.log('ran:', ran); - result = ran?.toString?.(); + history.push(currentLine); + historyIndex = history.length; + textLinesAbove.push("> "+currentLine); + try { + const ran = runCode('return '+currentLine); + const resultString = ran?.toString?.() ?? null; + if (resultString !== null) { + textLinesAbove.push(...resultString.split("\n")) + } + } catch (err) { + textLinesAbove.push(...(err.name+":\n"+err.message).toLowerCase().split("\n")) + } + textLinesAbove = textLinesAbove.slice(-20); maxLineLen = 0; - line = ""; + currentLine = ""; index = 0; - y += lineHeight; } } - maxLineLen = Math.max(maxLineLen, line.length); + maxLineLen = Math.max(maxLineLen, currentLine.length); +} + +const drawTextAbove = () => { + textLinesAbove.forEach((line, i) => { + faux.draw_rect(0, i*lineHeight, 4*(line.length+1)+1, lineHeight+1, 6); + faux.draw_text(-1, i*lineHeight, line); + }); } const draw = () => { - if (result) { - faux.draw_rect(0, y, 4*result.length+1, lineHeight+1, 6); - faux.draw_text(0, y, result); - } else { - faux.draw_rect(0, y, 4*(2+maxLineLen+1)+1, lineHeight+1, 6); - faux.draw_rect((2+index)*4, y+1, 4, lineHeight-1, 3); - faux.draw_text(0, y, "> "+line); - } + drawTextAbove(); + + faux.draw_rect(0, textLinesAbove.length*lineHeight, 4*(2+maxLineLen+1)+1, lineHeight+1, 6); + faux.draw_rect((2+index)*4, textLinesAbove.length*lineHeight+1, 4, lineHeight-1, 3); + faux.draw_text(-1, textLinesAbove.length*lineHeight, "> "+currentLine); } export const repl = {