From 2a7003b4433e19b361839e77efcf876415f6038b Mon Sep 17 00:00:00 2001
From: dylan <>
Date: Thu, 4 May 2023 20:14:48 -0700
Subject: [PATCH] Improving repl more

---
 builtins.ts        | 32 +++++++++++++++-------------
 cart_unpacked.json |  4 ++--
 font.ts            |  2 +-
 keyboard.ts        |  4 ++--
 repl.ts            | 53 +++++++++++++++++++++++++++++++---------------
 runcode.ts         | 16 +++++++++++++-
 window.ts          |  4 ++++
 7 files changed, 77 insertions(+), 38 deletions(-)

diff --git a/builtins.ts b/builtins.ts
index 0ae281b..3c8a9d4 100644
--- a/builtins.ts
+++ b/builtins.ts
@@ -1,10 +1,12 @@
 import {
 	setPixelsInRect,
 	clearScreen,
+	fillRect,
 } from "./window.ts";
 import { font } from "./font.ts";
-import { keyDown, keyPressed, keyReleased } from "./keyboard.ts";
+// import { keyDown, keyPressed, keyReleased } from "./keyboard.ts";
 import { addToContext } from "./runcode.ts";
+import { resetRepl } from "./repl.ts";
 
 // deno-fmt-ignore
 const sprites = [
@@ -40,33 +42,33 @@ const sprites = [
 	],
 ]
 
-const drawSprite = (x: number, y: number, spr: number) => {
+export const drawSprite = (x: number, y: number, spr: number) => {
 	setPixelsInRect(x, y, 8, sprites[spr]);
 }
 
-const drawChar = (x: number, y: number, char: string) => {
+export const drawChar = (x: number, y: number, char: string) => {
 	setPixelsInRect(x, y, 4, font[char]);
 }
 
-const drawText = (x: number, y: number, text: string) => {
+export const drawText = (x: number, y: number, text: string) => {
 	[...text].forEach((char, i) => {
 		drawChar(x+4*i, y, char);
 	});
 }
 
-const drawRect = (x: number, y: number, w: number, h: number, color: number) => {
-	setPixelsInRect(x, y, w, Array(w*h).fill(color));
-}
-
 const faux = {
-	clear_screen: clearScreen,
-	draw_sprite: drawSprite,
-	draw_text: drawText,
-	draw_rect: drawRect,
-	key_down: keyDown,
-	key_pressed: keyPressed,
-	key_released: keyReleased,
+	cls: () => {
+		resetRepl();
+		clearScreen();
+	},
+	spr: drawSprite,
+	txt: drawText,
+	rect: fillRect,
+	// key_down: keyDown,
+	// key_pressed: keyPressed,
+	// key_released: keyReleased,
 	log: console.log,
+	JSON: JSON,
 };
 
 for (const key in faux) {
diff --git a/cart_unpacked.json b/cart_unpacked.json
index ad30e81..57e291a 100644
--- a/cart_unpacked.json
+++ b/cart_unpacked.json
@@ -1,10 +1,10 @@
 [
 	{
 		"sheet_type": "code",
-		"value": "x = code_sheet(1);\nreturn {init: () => {y = 0}, update: () => {y += speed; if (y > 127) {y = -6}}, draw: () => {clear_screen(); draw_text(x, y, 'hello world')}}"
+		"value": "x = code_sheet(1);\nreturn ({init: () => {y = 0}, update: () => {y += speed; if (y > 127) {y = -6}}, draw: () => {clear_screen(); draw_text(x, y, 'hello world')}})"
 	},
 	{
 		"sheet_type": "code",
-		"value": "speed = 2; return 8"
+		"value": "speed = 2; return (8)"
 	}
 ]
\ No newline at end of file
diff --git a/font.ts b/font.ts
index 26070e2..aa11fd5 100644
--- a/font.ts
+++ b/font.ts
@@ -181,7 +181,7 @@ export const font: {[key: string]: Array<number>} = {
 		0, 1, 0, 1,
 		0, 1, 0, 1,
 		0, 1, 0, 1,
-		0, 1, 1, 0,
+		0, 0, 1, 1,
 		0, 0, 0, 0,
 	],
 	"V": [
diff --git a/keyboard.ts b/keyboard.ts
index 1705a6a..9cc654b 100644
--- a/keyboard.ts
+++ b/keyboard.ts
@@ -61,7 +61,7 @@ export const shiftMap = {
 }
 
 addEventListener("keydown", (evt) => {
-	console.log("keydown", evt.key, evt.key.charCodeAt(0));
+	// console.log("keydown", evt.key, evt.key.charCodeAt(0));
 	const key = evt.key.charCodeAt(0);
 	const isRepeat = keyboard.has(key) && keyboard.get(key)?.held!;
 	keyboard.set(key, {
@@ -72,7 +72,7 @@ addEventListener("keydown", (evt) => {
 });
 
 addEventListener("keyup", (evt) => {
-	console.log("keyup", evt.key, evt.key.charCodeAt(0));
+	// console.log("keyup", evt.key, evt.key.charCodeAt(0));
 	const key = evt.key.charCodeAt(0);
 	keyboard.set(key, {
 		first: false,
diff --git a/repl.ts b/repl.ts
index e8c9eb8..54c2123 100644
--- a/repl.ts
+++ b/repl.ts
@@ -1,8 +1,8 @@
-import faux from "./builtins.ts";
+import { drawText} 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";
+import { addToContext, evalCode } from "./runcode.ts";
+import { clearScreen, fillRect } from "./window.ts";
 
 const lineHeight = 6;
 
@@ -21,6 +21,25 @@ export const resetRepl = () => {
 	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 = () => {
 	for (const key of getKeysPressed()) {
 		let char = String.fromCharCode(key).toLowerCase();
@@ -66,19 +85,19 @@ const update = () => {
 			currentLine = lineAtHistory;
 			index = currentLine.length;
 		} else if (key === K.ENTER) {
-			history.push(currentLine);
-			historyIndex = history.length;
-			textLinesAbove.push("> "+currentLine);
+			if (currentLine) {
+				history.push(currentLine);
+				historyIndex = history.length;
+			}
+			print("> "+currentLine);
 			try {
-				const ran = runCode('return '+currentLine);
-				const resultString = ran?.toString?.() ?? null;
-				if (resultString !== null) {
-					textLinesAbove.push(...resultString.split("\n"))
+				const ran = evalCode(currentLine);
+				if (ran !== undefined) {
+					printVal(ran);
 				}
 			} catch (err) {
-				textLinesAbove.push(...(err.name+":\n"+err.message).split("\n"))
+				print(err.name+":\n"+err.message);
 			}
-			textLinesAbove = textLinesAbove.slice(-20);
 			maxLineLen = 0;
 			currentLine = "";
 			index = 0;
@@ -89,8 +108,8 @@ const update = () => {
 
 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);
+		fillRect(0, 1+i*lineHeight, 4*(line.length+1)+1, lineHeight+1, 0);
+		drawText(-1, 1+i*lineHeight, line);
 	});
 }
 
@@ -99,9 +118,9 @@ const draw = () => {
 
 	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);
+	fillRect(0, 1+textLinesAbove.length*lineHeight, 4*(2+maxLineLen+1)+1, lineHeight+1, 0);
+	fillRect((2+index)*4, textLinesAbove.length*lineHeight+1, 4, lineHeight-1, 3);
+	drawText(-1, 1+textLinesAbove.length*lineHeight, "> "+currentLine);
 }
 
 export const repl = {
diff --git a/runcode.ts b/runcode.ts
index 4ea0a58..88107eb 100644
--- a/runcode.ts
+++ b/runcode.ts
@@ -1,5 +1,7 @@
 // deno-lint-ignore no-explicit-any
-const G: any = {};
+const G: any = {
+	eval: eval,
+};
 const context = new Proxy(G, {
 	get: (target, prop) => {
 		return target[prop];
@@ -27,6 +29,18 @@ export const runCode = (code: string) => {
 	return fn(context);
 }
 
+export const evalCode = (code: string) => {
+	try {
+		return runCode(`return eval("(${code.replaceAll('"', '\\"')})");`);
+	} catch (err) {
+		if (err.name === "SyntaxError") {
+			return runCode(`return eval("${code.replaceAll('"', '\\"')}");`);
+		} else {
+			throw err;
+		}
+	}
+}
+
 // deno-lint-ignore no-explicit-any
 export const addToContext = (name: string, value: any) => {
 	G[name] = value;
diff --git a/window.ts b/window.ts
index be9e07f..72585a8 100644
--- a/window.ts
+++ b/window.ts
@@ -153,6 +153,10 @@ export const setPixelsInRect = (x: number, y: number, w: number, pixels: Array<n
 	}
 }
 
+export const fillRect = (x: number, y: number, w: number, h: number, color: number) => {
+	setPixelsInRect(x, y, w, Array(w*h).fill(color));
+}
+
 export const clearScreen = () => {
 	allPixelColors.fill(0);
 }