Add latest improvements

This commit is contained in:
Justine Tunney 2021-12-08 11:55:45 -08:00
parent 3aa7a47e15
commit d21e0ab712

147
lisp.js
View file

@ -24,12 +24,12 @@ exit
#endif #endif
#define var int #define var int
#define function #define function
#define Null 0100000 #define Null 16384
var M[Null * 2]; var M[Null * 2];
jmp_buf undefined; jmp_buf undefined;
//` //`
var cx, dx, kT, kEq, kCar, kCdr, kCond, kAtom, kCons, kQuote, kDefine; var cx, dx, lo, kT, kEq, kCar, kCdr, kCond, kAtom, kCons, kQuote, kDefine;
function Set(i, x) { function Set(i, x) {
M[Null + i] = x; M[Null + i] = x;
@ -58,6 +58,7 @@ function Cdr(x) {
function Cons(car, cdr) { function Cons(car, cdr) {
Set(--cx, cdr); Set(--cx, cdr);
Set(--cx, car); Set(--cx, car);
if (cx < lo) lo = cx;
return cx; return cx;
} }
@ -137,17 +138,21 @@ function Read() {
return ReadObject(ReadAtom(0)); return ReadObject(ReadAtom(0));
} }
function Define(a) { function Remove(x, y) {
var x = Read(); if (!y) return y;
return Cons(Cons(x, Read()), a); if (x == Car(Car(y))) return Cdr(y);
return Cons(Car(y), Remove(x, Cdr(y)));
}
function Define(x, y) {
return Cons(Cons(x, Read()), Remove(x, y));
} }
function Gc(A, x) { function Gc(A, x) {
var C, B = cx; var C, B = cx;
x = Copy(x, A, A - B), C = cx; x = Copy(x, A, A - B), C = cx;
while (C < B) Set(--A, Get(--B)); while (C < B) Set(--A, Get(--B));
cx = A; return cx = A, x;
return x;
} }
function Copy(x, m, k) { function Copy(x, m, k) {
@ -196,12 +201,8 @@ function Eval(e, a) {
if (!e) return e; if (!e) return e;
if (e > 0) return Assoc(e, a); if (e > 0) return Assoc(e, a);
if (Car(e) == kQuote) return Car(Cdr(e)); if (Car(e) == kQuote) return Car(Cdr(e));
if (Car(e) == kCond) { if (Car(e) == kCond) return Gc(A, Evcon(Cdr(e), a));
e = Evcon(Cdr(e), a); return Gc(A, Apply(Car(e), Evlis(Cdr(e), a), a));
} else {
e = Apply(Car(e), Evlis(Cdr(e), a), a);
}
return Gc(A, e);
} }
function LoadBuiltins() { function LoadBuiltins() {
@ -233,6 +234,9 @@ PrintChar(b) {
fputwc(b, stdout); fputwc(b, stdout);
} }
SaveMachine(a) {
}
ReadChar() { ReadChar() {
int b, c, t; int b, c, t;
static char *freeme; static char *freeme;
@ -271,7 +275,8 @@ main() {
if (!(x = setjmp(undefined))) { if (!(x = setjmp(undefined))) {
x = Read(); x = Read();
if (x == kDefine) { if (x == kDefine) {
a = Gc(A, Define(a)); a = Gc(0, Define(Read(), a));
SaveMachine(a);
continue; continue;
} }
x = Eval(x, a); x = Eval(x, a);
@ -289,8 +294,8 @@ main() {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// JavaScript Specific Code for https://justine.lol/ // JavaScript Specific Code for https://justine.lol/
var a, code, index, M, Null; var a, code, index, output, M, Null;
var eInput, eOutput, eSubmit, eClear, eLoad, ePrograms; var eInput, eOutput, eSubmit, eReset, eLoad, ePrograms;
function Throw(x) { function Throw(x) {
throw x; throw x;
@ -300,9 +305,22 @@ function Ord(s) {
return s.charCodeAt(0); return s.charCodeAt(0);
} }
function Reset() {
var i;
a = 0;
cx = 0;
lo = 0;
Null = 16384;
M = new Array(Null * 2);
for (i = 0; i < M.length; ++i) {
M[i] = 0; /* make json smaller */
}
Load("NIL T EQ CAR CDR ATOM COND CONS QUOTE DEFINE ");
LoadBuiltins()
}
function PrintChar(c) { function PrintChar(c) {
eOutput.innerText += String.fromCharCode(c); output += String.fromCharCode(c);
SaveOutput();
} }
function ReadChar() { function ReadChar() {
@ -323,6 +341,8 @@ function ReadChar() {
function Lisp() { function Lisp() {
var x, A; var x, A;
lo = cx;
output = '';
while (dx) { while (dx) {
if (dx <= Ord(' ')) { if (dx <= Ord(' ')) {
ReadChar(); ReadChar();
@ -331,7 +351,7 @@ function Lisp() {
try { try {
x = Read(); x = Read();
if (x == kDefine) { if (x == kDefine) {
a = Gc(A, Define(a)); a = Gc(0, Define(Read(), a));
continue; continue;
} }
x = Eval(x, a); x = Eval(x, a);
@ -343,6 +363,10 @@ function Lisp() {
Gc(A, 0); Gc(A, 0);
} }
} }
eOutput.innerText = output;
SaveMachine(a);
SaveOutput();
ReportUsage();
} }
function Load(s) { function Load(s) {
@ -352,13 +376,28 @@ function Load(s) {
} }
function OnSubmit() { function OnSubmit() {
Load(eInput.value); Load(eInput.value.toUpperCase());
Lisp(); Lisp();
} }
function OnClear() { function Dump(a) {
eOutput.innerText = ""; if (!a) return;
Dump(Cdr(a));
output += "DEFINE ";
PrintObject(Car(Car(a)));
output += " ";
PrintObject(Cdr(Car(a)));
output += "\n";
}
function OnReset() {
output = "";
Dump(a);
eOutput.innerText = output;
Reset();
localStorage.removeItem("sectorlisp.machine");
SaveOutput(); SaveOutput();
ReportUsage();
} }
function OnLoad() { function OnLoad() {
@ -366,33 +405,65 @@ function OnLoad() {
} }
function OnWindowClick(event) { function OnWindowClick(event) {
if (!event.target.matches('#load')) { if (!event.target.matches("#load")) {
ePrograms.classList.remove("show"); ePrograms.classList.remove("show");
} }
} }
function SaveOutput() { function SaveMachine(a) {
if (typeof localStorage != 'undefined') { var machine;
localStorage.setItem('output', eOutput.innerText); if (typeof localStorage != "undefined") {
machine = [M, a, cx];
localStorage.setItem("sectorlisp.machine", JSON.stringify(machine));
} }
} }
function RestoreMachine() {
var machine;
if (typeof localStorage != "undefined" &&
(machine = JSON.parse(localStorage.getItem("sectorlisp.machine")))) {
M = machine[0];
a = machine[1];
cx = machine[2];
lo = cx;
}
}
function SaveOutput() {
if (typeof localStorage != "undefined") {
localStorage.setItem("input", document.getElementById("input").value);
localStorage.setItem("output", eOutput.innerText);
}
}
function Number(i) {
return i.toLocaleString();
}
function ReportUsage() {
var i, c;
for (c = i = 0; i < Null; i += 2) {
if (Get(i)) ++c;
}
document.getElementById("usage").innerText =
Number((-cx >> 1) + c) + " / " +
Number((-lo >> 1) + c) + " / " +
Number(Null) + " doublewords";
}
function SetUp() { function SetUp() {
a = 0; Reset();
cx = 0; RestoreMachine();
Null = 0100000; ReportUsage();
M = new Array(Null * 2); eLoad = document.getElementById("load");
Load("NIL T EQ CAR CDR ATOM COND CONS QUOTE DEFINE "); eInput = document.getElementById("input");
LoadBuiltins() eReset = document.getElementById("reset");
eLoad = document.getElementById('load'); eOutput = document.getElementById("output");
eInput = document.getElementById('input'); eSubmit = document.getElementById("submit");
eClear = document.getElementById('clear');
eOutput = document.getElementById('output');
eSubmit = document.getElementById('submit');
ePrograms = document.getElementById("programs"); ePrograms = document.getElementById("programs");
window.onclick = OnWindowClick; window.onclick = OnWindowClick;
eSubmit.onclick = OnSubmit; eSubmit.onclick = OnSubmit;
eClear.onclick = OnClear; eReset.onclick = OnReset;
eLoad.onclick = OnLoad; eLoad.onclick = OnLoad;
} }