import faux from "./builtins.ts"; import { getKeysPressed, shiftKeyDown, shiftMap, K } from "./keyboard.ts"; import { font } from "./font.ts"; import { runCode } from "./runcode.ts"; import { clearScreen } from "./window.ts"; const lineHeight = 6; const history: Array = []; let historyIndex = history.length; let textLinesAbove: Array = []; let maxLineLen = 0; let currentLine = ""; let index = 0; export const resetRepl = () => { historyIndex = history.length; textLinesAbove.length = 0; maxLineLen = 0; currentLine = ""; index = 0; } const update = () => { for (const key of getKeysPressed()) { let char = String.fromCharCode(key).toLowerCase(); if (shiftKeyDown()) { if (char in shiftMap) { char = shiftMap[char as keyof typeof shiftMap]; } else { char = char.toUpperCase(); } } if (char in font) { currentLine = currentLine.slice(0, index)+char+currentLine.slice(index); index += 1; } else if (key === K.BACKSPACE) { if (index > 0) { currentLine = currentLine.slice(0, index-1)+currentLine.slice(index); index -= 1; } } else if (key === K.ARROW_LEFT) { index -= 1; if (index < 0) { index = 0; } } else if (key === K.ARROW_RIGHT) { index += 1; 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) { 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).split("\n")) } textLinesAbove = textLinesAbove.slice(-20); maxLineLen = 0; currentLine = ""; index = 0; } } maxLineLen = Math.max(maxLineLen, currentLine.length); } const drawTextAbove = () => { textLinesAbove.forEach((line, i) => { faux.draw_rect(0, 1+i*lineHeight, 4*(line.length+1)+1, lineHeight+1, 0); faux.draw_text(-1, 1+i*lineHeight, line); }); } const draw = () => { clearScreen(); drawTextAbove(); faux.draw_rect(0, 1+textLinesAbove.length*lineHeight, 4*(2+maxLineLen+1)+1, lineHeight+1, 0); faux.draw_rect((2+index)*4, textLinesAbove.length*lineHeight+1, 4, lineHeight-1, 3); faux.draw_text(-1, 1+textLinesAbove.length*lineHeight, "> "+currentLine); } export const repl = { update, draw }