mirror of
https://git.sr.ht/~crc_/retroforth
synced 2024-11-16 19:48:56 +01:00
begin further reorganization of the source tree
FossilOrigin-Name: 4645fa7e95b86179341a90f76786b7a2258fc5861c655f107f1a7117da8770b0
This commit is contained in:
parent
48585c1e90
commit
1be951596f
7 changed files with 0 additions and 610 deletions
|
@ -1,610 +0,0 @@
|
|||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>RETRO FORTH</title>
|
||||
<style type="text/css">
|
||||
*::-webkit-scrollbar {
|
||||
width: 0.5em;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background-color: #333333;
|
||||
outline: 1px solid slategrey;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #212121;
|
||||
color: #ababab;
|
||||
font-size: 22pt;
|
||||
font-family: monospace;
|
||||
height:100%;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.left, .mid, .right {
|
||||
float: left;
|
||||
height: 100vp;
|
||||
overflow: auto; overflow-x:hidden;
|
||||
height:100%;
|
||||
}
|
||||
|
||||
.left, .mid {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.mid {
|
||||
background: #1A1A1A;
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
textarea, iframe {
|
||||
width:100%;
|
||||
height:100%;
|
||||
box-sizing: border-box; /* For IE and modern versions of Chrome */
|
||||
-moz-box-sizing: border-box; /* For Firefox */
|
||||
-webkit-box-sizing: border-box; /* For Safari */
|
||||
background: #212121;
|
||||
color: #ababab;
|
||||
font-size: 22pt;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
button {
|
||||
background: #121212;
|
||||
color: orange;
|
||||
border: 1px solid orange;
|
||||
font-size: 22pt;
|
||||
}
|
||||
</style>
|
||||
<body onLoad='loadproject()'>
|
||||
<div class='left'>
|
||||
<textarea id='input' onchange='saveproject()'>
|
||||
</textarea>
|
||||
</div>
|
||||
<div class='mid'>
|
||||
<div style='float: right; margin-right: 10px;'>
|
||||
<button onclick='cls()'>Clear</button>
|
||||
<button onclick='go()'>Go</button>
|
||||
</div>
|
||||
<div>
|
||||
<xmp id='console'>
|
||||
</xmp>
|
||||
</div>
|
||||
</div>
|
||||
<div class='right'>
|
||||
<iframe src='http://forth.works:9999'></iframe>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
/* Nga ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Copyright (c) 2008 - 2018, Charles Childers
|
||||
Copyright (c) 2009 - 2010, Luke Parrish
|
||||
Copyright (c) 2010, Marc Simpson
|
||||
Copyright (c) 2010, Jay Skeer
|
||||
Copyright (c) 2011, Kenneth Keating
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
var IMAGE_SIZE = 524288 * 4; /* Amount of simulated RAM */
|
||||
var DATA_DEPTH = 8192; /* Depth of data stack */
|
||||
var ADDRESS_DEPTH = 32768; /* Depth of the stacks */
|
||||
|
||||
function Stack(size) {
|
||||
this.sp = 0;
|
||||
this.data = new Array(size);
|
||||
this.push = function(n) {
|
||||
this.sp++;
|
||||
this.data[this.sp] = n;
|
||||
}
|
||||
this.pop = function() {
|
||||
return this.data[this.sp--];
|
||||
}
|
||||
this.depth = function() {
|
||||
return this.sp;
|
||||
}
|
||||
this.tos = function() {
|
||||
return this.data[this.sp];
|
||||
}
|
||||
this.nos = function() {
|
||||
return this.data[this.sp - 1];
|
||||
}
|
||||
this.dup = function() {
|
||||
this.push(this.tos());
|
||||
}
|
||||
this.drop = function() {
|
||||
this.sp--;
|
||||
}
|
||||
this.swap = function() {
|
||||
var a = this.nos();
|
||||
this.data[this.sp - 1] = this.tos();
|
||||
this.data[this.sp] = a;
|
||||
}
|
||||
this.inc = function() {
|
||||
this.data[this.sp]++;
|
||||
}
|
||||
this.dec = function() {
|
||||
this.data[this.sp]--;
|
||||
}
|
||||
this.reset = function() {
|
||||
this.sp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function Opcodes() {
|
||||
this.NOP = 0;
|
||||
this.LIT = 1;
|
||||
this.DUP = 2;
|
||||
this.DROP = 3;
|
||||
this.SWAP = 4;
|
||||
this.PUSH = 5;
|
||||
this.POP = 6;
|
||||
this.JUMP = 7;
|
||||
this.CALL = 8;
|
||||
this.CCALL = 9;
|
||||
this.RETURN = 10;
|
||||
this.EQ = 11;
|
||||
this.NEQ = 12;
|
||||
this.LT = 13;
|
||||
this.GT = 14;
|
||||
this.FETCH = 15;
|
||||
this.STORE = 16;
|
||||
this.ADD = 17;
|
||||
this.SUB = 18;
|
||||
this.MUL = 19;
|
||||
this.DIVMOD = 20;
|
||||
this.AND = 21;
|
||||
this.OR = 22;
|
||||
this.XOR = 23;
|
||||
this.SHIFT = 24;
|
||||
this.ZERO_EXIT = 25;
|
||||
this.END = 26;
|
||||
this.IE = 27;
|
||||
this.IQ = 28;
|
||||
this.II = 29;
|
||||
}
|
||||
var ip = 0;
|
||||
var data = new Stack(DATA_DEPTH);
|
||||
var address = new Stack(ADDRESS_DEPTH);
|
||||
var image = new Array(IMAGE_SIZE);
|
||||
var vm = new Opcodes();
|
||||
var instructions = new Array(vm.II + 1);
|
||||
|
||||
function rxPrepareVM() {
|
||||
ip = 0;
|
||||
data.reset();
|
||||
address.reset();
|
||||
}
|
||||
|
||||
instructions[vm.NOP] = function() {}
|
||||
instructions[vm.LIT] = function() {
|
||||
ip++;
|
||||
data.push(image[ip]);
|
||||
}
|
||||
instructions[vm.DUP] = function() {
|
||||
data.dup();
|
||||
}
|
||||
instructions[vm.DROP] = function() {
|
||||
data.drop();
|
||||
}
|
||||
instructions[vm.SWAP] = function() {
|
||||
data.swap();
|
||||
}
|
||||
instructions[vm.PUSH] = function() {
|
||||
address.push(data.pop());
|
||||
}
|
||||
instructions[vm.POP] = function() {
|
||||
data.push(address.pop())
|
||||
}
|
||||
instructions[vm.JUMP] = function() {
|
||||
ip = data.pop() - 1;
|
||||
}
|
||||
instructions[vm.CALL] = function() {
|
||||
address.push(ip);
|
||||
ip = data.pop() - 1;
|
||||
}
|
||||
instructions[vm.CCALL] = function() {
|
||||
var a, b;
|
||||
a = data.pop();
|
||||
b = data.pop();
|
||||
if (b != 0) {
|
||||
address.push(ip);
|
||||
ip = a - 1;
|
||||
}
|
||||
}
|
||||
instructions[vm.RETURN] = function() {
|
||||
ip = address.pop();
|
||||
}
|
||||
instructions[vm.EQ] = function() {
|
||||
var a, b;
|
||||
a = data.pop();
|
||||
b = data.pop();
|
||||
if (b == a)
|
||||
data.push(-1);
|
||||
else
|
||||
data.push(0);
|
||||
}
|
||||
instructions[vm.NEQ] = function() {
|
||||
var a, b;
|
||||
a = data.pop();
|
||||
b = data.pop();
|
||||
if (b != a)
|
||||
data.push(-1);
|
||||
else
|
||||
data.push(0);
|
||||
}
|
||||
instructions[vm.LT] = function() {
|
||||
var a, b;
|
||||
a = data.pop();
|
||||
b = data.pop();
|
||||
if (b < a)
|
||||
data.push(-1);
|
||||
else
|
||||
data.push(0);
|
||||
}
|
||||
instructions[vm.GT] = function() {
|
||||
var a, b;
|
||||
a = data.pop();
|
||||
b = data.pop();
|
||||
if (b > a)
|
||||
data.push(-1);
|
||||
else
|
||||
data.push(0);
|
||||
}
|
||||
instructions[vm.FETCH] = function() {
|
||||
x = data.pop();
|
||||
if (x == -1)
|
||||
data.push(data.sp);
|
||||
else if (x == -2)
|
||||
data.push(address.sp);
|
||||
else if (x == -3)
|
||||
data.push(IMAGE_SIZE);
|
||||
else if (x == -4)
|
||||
data.push(-2147483648);
|
||||
else if (x == -5)
|
||||
data.push(2147483647);
|
||||
else
|
||||
data.push(image[x]);
|
||||
}
|
||||
instructions[vm.STORE] = function() {
|
||||
image[data.tos()] = data.nos();
|
||||
data.drop();
|
||||
data.drop();
|
||||
}
|
||||
instructions[vm.ADD] = function() {
|
||||
var x = data.pop();
|
||||
var y = data.pop();
|
||||
data.push(x + y);
|
||||
}
|
||||
instructions[vm.SUB] = function() {
|
||||
var x = data.pop();
|
||||
var y = data.pop();
|
||||
data.push(y - x);
|
||||
}
|
||||
instructions[vm.MUL] = function() {
|
||||
var x = data.pop();
|
||||
var y = data.pop();
|
||||
data.push(y * x);
|
||||
}
|
||||
instructions[vm.DIVMOD] = function() {
|
||||
var b = data.pop();
|
||||
var a = data.pop();
|
||||
if (b == 0) {
|
||||
ip = 0;
|
||||
data.sp = 0;
|
||||
address.sp = 0;
|
||||
} else {
|
||||
var x = Math.abs(b);
|
||||
var y = Math.abs(a);
|
||||
var q = Math.floor(y / x);
|
||||
var r = y % x;
|
||||
if (a < 0 && b < 0)
|
||||
r = r * -1;
|
||||
if (a > 0 && b < 0)
|
||||
q = q * -1;
|
||||
if (a < 0 && b > 0) {
|
||||
r = r * -1;
|
||||
q = q * -1;
|
||||
}
|
||||
data.push(r);
|
||||
data.push(q);
|
||||
}
|
||||
}
|
||||
instructions[vm.AND] = function() {
|
||||
var x = data.pop();
|
||||
var y = data.pop();
|
||||
data.push(x & y);
|
||||
}
|
||||
instructions[vm.OR] = function() {
|
||||
var x = data.pop();
|
||||
var y = data.pop();
|
||||
data.push(x | y);
|
||||
}
|
||||
instructions[vm.XOR] = function() {
|
||||
var x = data.pop();
|
||||
var y = data.pop();
|
||||
data.push(x ^ y);
|
||||
}
|
||||
instructions[vm.SHIFT] = function() {
|
||||
var x = data.pop();
|
||||
var y = data.pop();
|
||||
if (x < 0)
|
||||
data.push(y << (x * -1));
|
||||
else
|
||||
data.push(y >>= x);
|
||||
}
|
||||
instructions[vm.ZERO_EXIT] = function() {
|
||||
if (data.tos() == 0) {
|
||||
data.drop();
|
||||
ip = address.pop();
|
||||
}
|
||||
}
|
||||
instructions[vm.END] = function() {
|
||||
ip = IMAGE_SIZE;
|
||||
}
|
||||
instructions[vm.IE] = function() {
|
||||
data.push(1);
|
||||
}
|
||||
instructions[vm.IQ] = function() {
|
||||
data.drop();
|
||||
data.push(0);
|
||||
data.push(0);
|
||||
}
|
||||
instructions[vm.II] = function() {
|
||||
data.pop();
|
||||
var s = String.fromCharCode(data.pop());
|
||||
document.getElementById('console').innerHTML += s;
|
||||
}
|
||||
window.addEventListener('load', function(e) {
|
||||
rxPrepareVM();
|
||||
}, false);
|
||||
|
||||
function processOpcode(opcode) {
|
||||
if (opcode != 0) {
|
||||
instructions[opcode]();
|
||||
checkStack();
|
||||
}
|
||||
}
|
||||
|
||||
function validatePackedOpcodes(opcode) {
|
||||
var raw = opcode;
|
||||
var current;
|
||||
var valid = -1;
|
||||
var i = 0;
|
||||
while (i < 4) {
|
||||
current = raw & 0xFF;
|
||||
if (!current >= 0 && current <= 29)
|
||||
valid = 0;
|
||||
raw = raw >> 8;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
function ngaProcessPackedOpcodes(opcode) {
|
||||
var raw = opcode;
|
||||
ops = new Array(3);
|
||||
ops[0] = raw & (255);
|
||||
raw = raw >> 8;
|
||||
ops[1] = raw & (255);
|
||||
raw = raw >> 8;
|
||||
ops[2] = raw & (255);
|
||||
raw = raw >> 8;
|
||||
ops[3] = raw & (255);
|
||||
processOpcode(ops[0]);
|
||||
processOpcode(ops[1]);
|
||||
processOpcode(ops[2]);
|
||||
processOpcode(ops[3]);
|
||||
}
|
||||
|
||||
var ngaImage = [
|
||||
<<<IMAGE>>>
|
||||
];
|
||||
|
||||
/* Nga - Retro - JavaScript Interface ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Copyright (c) 2008 - 2018, Charles Childers
|
||||
Copyright (c) 2009 - 2010, Luke Parrish
|
||||
Copyright (c) 2010, Marc Simpson
|
||||
Copyright (c) 2010, Jay Skeer
|
||||
Copyright (c) 2011, Kenneth Keating
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
function loadInitialImage() {
|
||||
image = ngaImage.slice();
|
||||
}
|
||||
|
||||
function execute(offset) {
|
||||
var opcode;
|
||||
address.sp = 1;
|
||||
ip = offset;
|
||||
var notfound = d_xt_for("err:notfound");
|
||||
while (ip < IMAGE_SIZE) {
|
||||
opcode = image[ip];
|
||||
if (ip == notfound) {
|
||||
document.getElementById('console').value +=
|
||||
"err:notfound : " + string_extract(1471) + "\n";
|
||||
}
|
||||
if (validatePackedOpcodes(opcode) != 0) {
|
||||
ngaProcessPackedOpcodes(opcode);
|
||||
} else {
|
||||
alert("Invalid instruction!");
|
||||
alert("At " + ip + ", opcode " + opcode);
|
||||
}
|
||||
if (address.sp == 0)
|
||||
ip = IMAGE_SIZE;
|
||||
ip++;
|
||||
}
|
||||
}
|
||||
|
||||
function checkStack() {
|
||||
var depth = data.depth();
|
||||
var adepth = address.depth();
|
||||
var flag = 0;
|
||||
if (depth < 0 || adepth < 0) {
|
||||
flag = -1;
|
||||
}
|
||||
if (depth > DATA_DEPTH || adepth > DATA_DEPTH) {
|
||||
flag = -1;
|
||||
}
|
||||
if (flag == -1) {
|
||||
ip = 0;
|
||||
data.sp = 0;
|
||||
address.sp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function string_inject(str, buffer) {
|
||||
var m = str.length;
|
||||
var i = 0;
|
||||
while (m > 0) {
|
||||
image[buffer + i] = str[i].charCodeAt(0);
|
||||
image[buffer + i + 1] = 0;
|
||||
m--;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
function string_extract(at) {
|
||||
string_data = "";
|
||||
var starting = at;
|
||||
var i = 0;
|
||||
while (image[starting] != 0)
|
||||
string_data += String.fromCharCode(image[starting++]);
|
||||
return string_data;
|
||||
}
|
||||
|
||||
function d_link(dt) {
|
||||
return dt + 0;
|
||||
}
|
||||
|
||||
function d_xt(dt) {
|
||||
return dt + 1;
|
||||
}
|
||||
|
||||
function d_class(dt) {
|
||||
return dt + 2;
|
||||
}
|
||||
|
||||
function d_name(dt) {
|
||||
return dt + 3;
|
||||
}
|
||||
|
||||
function d_count_entries() {
|
||||
var c = 0;
|
||||
var i = image[2];
|
||||
while (image[i] != 0) {
|
||||
c++;
|
||||
i = image[i];
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
function d_lookup(name) {
|
||||
var dt = 0;
|
||||
var i = image[2];
|
||||
var dname;
|
||||
while (image[i] != 0 && i != 0) {
|
||||
dname = string_extract(d_name(i));
|
||||
if (dname == name) {
|
||||
dt = i;
|
||||
i = 0;
|
||||
} else {
|
||||
i = image[i];
|
||||
}
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
|
||||
function d_xt_for(name) {
|
||||
return image[d_xt(d_lookup(name))];
|
||||
}
|
||||
|
||||
function d_class_for(name) {
|
||||
return image[d_class(d_lookup(name))];
|
||||
}
|
||||
|
||||
function evaluate(s) {
|
||||
if (s.length == 0)
|
||||
return;
|
||||
var i = d_xt_for("interpret");
|
||||
string_inject(s, 1471);
|
||||
data.push(1471);
|
||||
execute(i);
|
||||
}
|
||||
|
||||
function cls() {
|
||||
document.getElementById('console').innerHTML = "";
|
||||
}
|
||||
|
||||
function unu(src) {
|
||||
raw = src.split("\n");
|
||||
var i = raw.length;
|
||||
var lines = new Array();
|
||||
var j = 0;
|
||||
var code = 0;
|
||||
while (j < i) {
|
||||
if (code == 1 && raw[j] == "~~~") {
|
||||
code = 0;
|
||||
} else if (code == 0 && raw[j] == "~~~") {
|
||||
code = 1;
|
||||
} else if (code == 1) {
|
||||
lines.push(raw[j]);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
return lines.join(" ");
|
||||
}
|
||||
|
||||
function go() {
|
||||
rxPrepareVM();
|
||||
loadInitialImage();
|
||||
document.getElementById("console").innerHTML = "";
|
||||
src = document.getElementById("input").value;
|
||||
tokens = unu(src).match(/\S+/g);
|
||||
var i = tokens.length;
|
||||
var j = 0;
|
||||
while (j < i) {
|
||||
evaluate(tokens[j]);
|
||||
j++;
|
||||
}
|
||||
s = "";
|
||||
i = data.depth();
|
||||
j = 1;
|
||||
while (j <= i) {
|
||||
s = s + data.data[j] + " ";
|
||||
j++;
|
||||
}
|
||||
document.getElementById("console").innerHTML += "\n" + s;
|
||||
}
|
||||
|
||||
function saveproject() {
|
||||
src = document.getElementById("input").value;
|
||||
console.log('saving ' + src);
|
||||
localStorage.setItem("Snapshot", src);
|
||||
}
|
||||
|
||||
function loadproject() {
|
||||
src = localStorage.getItem("Snapshot");
|
||||
document.getElementById("input").value = src;
|
||||
}
|
||||
</script>
|
||||
</html>
|
||||
<!--
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
-->
|
||||
|
Loading…
Reference in a new issue