import { drawText} from "./builtins.ts"; import { getKeysPressed, shiftKeyDown, shiftMap, K } from "./keyboard.ts"; import { font } from "./font.ts"; import { addToContext, evalCode } from "./runcode.ts"; import { clearScreen, fillRect } from "./window.ts"; import { COLOR } from "./colors.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 print = (arg: unknown) => { textLinesAbove.push(...String(arg).split("\n").flatMap((line)=>{ const wrap = []; while (line.length) { wrap.push(line.slice(0,32)); line = line.slice(32); } return wrap; })); textLinesAbove = textLinesAbove.slice(-20); } const printVal = (arg: unknown) => { print(JSON.stringify(arg)); } addToContext("print", print); addToContext("printVal", printVal); const update = () => { // TODO: model this after the newer editmode.ts version using getKeyboardString 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) { if (currentLine) { history.push(currentLine); historyIndex = history.length; } print("> "+currentLine); try { const ran = evalCode(currentLine); if (ran !== undefined) { printVal(ran); } } catch (err) { print(err.name+":\n"+err.message); } maxLineLen = 0; currentLine = ""; index = 0; } } maxLineLen = Math.max(maxLineLen, currentLine.length); } const drawTextAbove = () => { textLinesAbove.forEach((line, i) => { fillRect(0, 1+i*lineHeight, 4*(line.length+1)+1, lineHeight+1, COLOR.BLACK); drawText(-1, 1+i*lineHeight, line); }); } const draw = () => { clearScreen(); drawTextAbove(); fillRect(0, 1+textLinesAbove.length*lineHeight, 4*(2+maxLineLen+1)+1, lineHeight+1, COLOR.BLACK); fillRect((2+index)*4, textLinesAbove.length*lineHeight+1, 4, lineHeight-1, COLOR.RED); drawText(-1, 1+textLinesAbove.length*lineHeight, "> "+currentLine); } export const repl = { update, draw }