Re-root site.

This commit is contained in:
Brad Nelson
2022-02-27 20:59:19 -08:00
parent a26786d7ef
commit fb47179999
131 changed files with 27 additions and 39 deletions

47
web/dump_web_opcodes.c Normal file
View File

@ -0,0 +1,47 @@
// Copyright 2021 Bradley D. Nelson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <string.h>
#include "common/opcodes.h"
#define PLATFORM_OPCODE_LIST \
X("CALL", CALL, sp = Call(sp|0, tos|0) | 0; DROP) \
enum {
#define XV(flags, name, op, code) OP_ ## op,
PLATFORM_OPCODE_LIST
OPCODE_LIST
#undef XV
};
int main(int argc, char *argv[]) {
if (argc == 2 && strcmp(argv[1], "cases") == 0) {
#define XV(flags, name, op, code) \
printf(" case %d: // %s\n %s; break;\n", OP_ ## op, name, #code);
PLATFORM_OPCODE_LIST
OPCODE_LIST
#undef XV
} else if (argc == 2 && strcmp(argv[1], "dict") == 0) {
#define XV(flags, name, op, code) printf(" create(" #name ", %d);\n", OP_ ## op);
PLATFORM_OPCODE_LIST
OPCODE_LIST
#undef XV
} else {
fprintf(stderr, "USAGE: %s cases/dict\n", argv[1]);
return 1;
}
return 0;
}

85
web/fuse_web.js Executable file
View File

@ -0,0 +1,85 @@
#! /usr/bin/env nodejs
// Copyright 2021 Bradley D. Nelson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
var fs = require('fs');
var code = fs.readFileSync(process.argv[2]).toString();
var boot = fs.readFileSync(process.argv[3]).toString();
var dict = fs.readFileSync(process.argv[4]).toString();
var cases = fs.readFileSync(process.argv[5]).toString();
function ReplaceAll(haystack, needle, replacement) {
for (;;) {
var old = haystack;
haystack = haystack.replace(needle, replacement);
if (old === haystack) {
return haystack;
}
}
}
cases = ReplaceAll(cases, 'DROP', 'tos = *sp--');
cases = ReplaceAll(cases, 'DUP', '*++sp = tos');
cases = ReplaceAll(cases, 'tos += *sp--', 'tos = (tos + *sp)|0; --sp');
cases = ReplaceAll(cases, /tos (.)= /, 'tos = tos $1 ');
cases = ReplaceAll(cases, /[*](.)p[+][+]/, '*$1p; ++$1p');
cases = ReplaceAll(cases, /[*](.)p[-][-]/, '*$1p; --$1p');
cases = ReplaceAll(cases, /[*][+][+](.)p/, '++$1p; *$1p');
cases = ReplaceAll(cases, '*(cell_t *) tos = ', 'i32[tos>>2] = ');
cases = ReplaceAll(cases, '*(int32_t *) tos = ', 'i32[tos>>2] = ');
cases = ReplaceAll(cases, '*(uint8_t *) tos = ', 'u8[tos] = ');
cases = ReplaceAll(cases, '*(cell_t *) tos', '(i32[tos>>2]|0)');
cases = ReplaceAll(cases, '*(int32_t *) tos', '(i32[tos>>2]|0)');
cases = ReplaceAll(cases, '*(uint8_t *) tos', '(u8[tos]|0)');
cases = ReplaceAll(cases, /[*](.)p = /, 'i32[$1p>>2] = ');
cases = ReplaceAll(cases, 'sp[-1] = ', 'i32[(sp - 4)>>2] = ');
cases = ReplaceAll(cases, /[*](.)p/, '(i32[$1p>>2]|0)');
cases = ReplaceAll(cases, 'sp[-1]', '(i32[(sp - 4)>>2]|0)');
cases = ReplaceAll(cases, /([+-]).(.)p/, '$2p = ($2p $1 4) | 0');
cases = ReplaceAll(cases, 'sp -= 2', 'sp = (sp - 8) | 0');
cases = ReplaceAll(cases, 'sizeof(cell_t)', '4');
cases = ReplaceAll(cases, '(void *) ', '');
cases = ReplaceAll(cases, '(const char *) ', '');
cases = ReplaceAll(cases, '(cell_t *) ', '');
cases = ReplaceAll(cases, '(cell_t) ', '');
cases = ReplaceAll(cases, /[(]ucell_t[)] ([^ ;]+)/, '($1>>>0)');
cases = ReplaceAll(cases, 'g_sys.state', 'i32[(i32[g_sys>>2] + (3 * 4))>>2]');
cases = ReplaceAll(cases, 'g_sys.DOLIT_XT', 'i32[(i32[g_sys>>2] + (10 * 4))>>2]|0');
cases = ReplaceAll(cases, 'g_sys.DOEXIT_XT', 'i32[(i32[g_sys>>2] + (11 * 4))>>2]|0');
cases = ReplaceAll(cases, '&g_sys', 'g_sys');
cases = ReplaceAll(cases, '&& OP_DOCOL', '0');
cases = ReplaceAll(cases, '&& OP_DOVAR', '1');
cases = ReplaceAll(cases, 'goto **(void **) w', 'break decode');
cases = ReplaceAll(cases, 'SSMOD_FUNC', '');
// Keep Together vvv
cases = ReplaceAll(cases, /tos ([^=]?)= /, 'txx $1= ');
cases = ReplaceAll(cases, ' tos', ' (tos|0)');
cases = ReplaceAll(cases, /txx ([^=]?)= /, 'tos $1= ');
// Keep Together ^^^
cases = ReplaceAll(cases, ' (w>>>0) / (tos>>>0)', ' ((w>>>0) / (tos>>>0))|0');
cases = ReplaceAll(cases, 'COMMA(tos)', 'COMMA(tos|0)');
cases = ReplaceAll(cases, /find\(([^\n]+)\);/, 'find($1)|0;');
cases = ReplaceAll(cases, 'tos = parse(tos, sp)', 'tos = parse(tos|0, sp|0)|0');
cases = ReplaceAll(cases, 'tos = parse(32, sp)', 'tos = parse(32, sp|0)|0');
cases = ReplaceAll(cases, 'sp = evaluate1(sp)', 'sp = evaluate1(sp|0)|0');
cases = ReplaceAll(cases, /convert\(([^\n]+), sp\)/, 'convert($1, sp|0)|0');
cases = ReplaceAll(cases, 'DOES(ip)', 'DOES(ip|0)');
cases = ReplaceAll(cases, 'PARK;', ''); // TODO
cases = ReplaceAll(cases, '; ', ';\n ');
code = code.replace('{{boot}}', function() { return boot; });
code = code.replace('{{dict}}', function() { return dict; });
code = code.replace('{{cases}}', function() { return cases; });
console.log(code);

20
web/terminal.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<!--
Copyright 2021 Bradley D. Nelson
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script src="ueforth.js"></script>
<script type="forth">
needs ansi.fs

262
web/web.template.js Normal file
View File

@ -0,0 +1,262 @@
// Copyright 2021 Bradley D. Nelson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
'use strict';
(function() {
const HEAP_SIZE = (1024 * 1024);
const STACK_CELLS = 4096;
const boot = `
{{boot}}
`;
var heap = new ArrayBuffer(HEAP_SIZE);
var i32 = new Int32Array(heap);
var u8 = new Uint8Array(heap);
var objects = [SetEval];
var g_sys = 256; // Placed past a gap.
var g_tib = g_sys + 0 * 4;
var g_ntib = g_sys + 1 * 4;
var g_tin = g_sys + 2 * 4;
var g_state = g_sys + 3 * 4;
var g_base = g_sys + 4 * 4;
var g_heap = g_sys + 5 * 4;
var g_current = g_sys + 6 * 4;
var g_context = g_sys + 7 * 4;
var g_notfound = g_sys + 8 * 4;
var g_argc = g_sys + 9 * 4;
var g_argv = g_sys + 10 * 4;
var g_ip = g_sys + 11 * 4;
var g_sp = g_sys + 12 * 4;
var g_rp = g_sys + 13 * 4;
function SetEval(sp) {
var index = i32[sp--];
var len = i32[sp--];
var code_addr = i32[sp--];
var code = '';
for (var i = 0; i < len; ++i) {
code += String.fromCharCode(u8[name_addr + i]);
}
objects[index] = eval(code);
}
function Call(sp, tos) {
return objects[tos](sp);
}
function Load(addr, content) {
for (var i = 0; i < content.length; ++i) {
u8[addr++] = content.charCodeAt(i);
}
return addr;
}
function UPPER(a) {
// a = 97, z = 122
return a >= 97 && a <= 122 ? a & 95 : a;
}
function Same(a, b) {
if (a.length != b.length) {
return false;
}
for (var i = 0; i < a.length; ++i) {
if (UPPER(a.charCodeAt(i)) != UPPER(b.charCodeAt(i))) {
return false;
}
}
return true;
}
function GetName(xt) {
var clen = i32[(xt - 3*4)>>2];
var ret = '';
for (var i = 0; i < clen; ++i) {
ret += String.fromCharCode(u8[xt - 3 * 4 - clen + i]);
}
return ret;
}
function Find(name) {
var pos = i32[i32[g_context>>2]>>2];
while (pos) {
if (Same(GetName(pos), name)) {
return pos;
}
pos = i32[(pos - 2*4)>>2];
}
return 0;
}
function create(name, opcode) {
i32[g_heap>>2] = Load(i32[g_heap>>2], name); // name
g_heap = (g_heap + 3) & ~3;
i32[i32[g_heap>>2]>>2] = name.length; // length
i32[g_heap>>2] += 4;
i32[i32[g_heap>>2]>>2] = i32[i32[g_current]>>2]>>2]; // link
i32[g_heap>>2] += 4;
i32[i32[g_heap>>2]>>2] = 0; // flags
i32[g_heap>>2] += 4;
i32[i32[g_current>>2]>>2] = i32[g_heap>>2];
i32[i32[i32[g_current>>2]>>2]>>2] = opcode; // code
i32[g_heap>>2] += 4;
}
function InitDictionary() {
{{dict}}
}
function Init() {
i32[g_heap>>2] = g_sys + 16 * 4;
var source = g_heap;
i32[g_heap>>2] = Load(i32[g_heap>>2], boot);
var source_len = g_heap - source;
InitDictionary();
i32[g_sp>>2] = i32[g_heap>>2] + 1;
i32[g_heap>>2] += STACK_CELLS;
i32[g_rp>>2] = i32[g_heap>>2] + 1;
i32[g_heap>>2] += STACK_CELLS;
i32[((i32[g_current]>>2) - 4)>>2] = 1; // Make ; IMMMEDIATE
// Do not need DOLIT_XT, DOEXIT_XT, YIELD_XT (do by convention)
i32[g_notfound>>2] = Find('DROP');
i32[g_ip>>2] = i32[g_heap>>2];
i32[i32[g_heap>>2]>>2] = Find('EVALUATE1');
i32[g_heap>>2] += 4;
i32[i32[g_heap>>2]>>2] = Find('BRANCH');
i32[g_heap>>2] += 4;
i32[i32[g_heap>>2]>>2] = g_ip;
i32[g_heap>>2] += 4;
// argc, argv would have gone here.
i32[g_heap>>2] += 4;
i32[g_base>>2] = 10;
i32[g_tib>>2] = source;
i32[g_ntib>>2] = source_len;
}
function VM(stdlib, foreign, heap) {
"use asm";
var imul = stdlib.Math.imul;
var SSMOD = foreign.SSMOD;
var Call = foreign.Call;
var COMMA = foreign.COMMA;
var DOES = foreign.DOES;
var DOIMMEDIATE = foreign.DOIMMEDIATE;
var UNSMUDGE = foreign.UNSMUDGE;
var create = foreign.create;
var find = foreign.find;
var parse = foreign.parse;
var memset = foreign.memset;
var memmove = foreign.memmove;
var convert = foreign.convert;
var evaluate1 = foreign.evaluate1;
var log = foreign.log;
var u8 = new stdlib.Uint8Array(heap);
var i32 = new stdlib.Int32Array(heap);
const g_sys = 256;
const g_ip = 296; // g_sys + 10 * 4
const g_sp = 300; // g_sys + 11 * 4
const g_rp = 304; // g_sys + 12 * 4
function run() {
var tos = 0;
var ip = 0;
var sp = 0;
var rp = 0;
var w = 0;
var ir = 0;
sp = i32[g_sp>>2]|0;
rp = i32[g_rp>>2]|0;
ip = i32[g_ip>>2]|0;
tos = i32[sp>>2]|0; sp = (sp - 4)|0;
for (;;) {
w = i32[ip>>2]|0;
log(ip|0);
ip = (ip + 4)|0;
decode: for (;;) {
ir = u8[w]|0;
log(ir|0);
switch (ir&0xff) {
case 0: // OP_DOCOL
rp = (rp + 4) | 0;
i32[rp>>2] = ip;
ip = (w + 4) | 0;
break;
case 1: // OP_DOVAR
sp = (sp + 4) | 0;
i32[sp>>2] = tos;
tos = (w + 8) | 0; // 4 * 2
break;
case 2: // OP_DODOES
sp = (sp + 4) | 0;
i32[sp>>2] = tos;
tos = (w + 8) | 0; // 4 * 2
rp = (rp + 4) | 0;
i32[rp>>2] = ip;
ip = i32[(w + 4)>>2] | 0;
break;
{{cases}}
default:
return;
}
break;
}
}
}
return {run: run};
}
var ffi = {
Call: Call,
create: function() { console.log('create'); },
parse: function() { console.log('parse'); },
COMMA: function(n) { i32[i32[g_heap>>2]] = n; i32[g_heap>>2] += 4; console.log('comma'); },
SSMOD: function() { console.log('ssmod'); },
DOES: function() { console.log('does'); },
DOIMMEDIATE: function() { console.log('immediate'); },
UNSMUDGE: function() { console.log('unsmudge'); },
parse: function() { console.log('parse'); },
find: function() { console.log('find'); },
convert: function() { console.log('convert'); },
evaluate1: function() { console.log('evaluate1'); },
log: function(n) { console.log(n); }
};
heap[128 + 6] = 256 * 4; // set g_sys.heap = 256 * 4;
var globalObj;
if (typeof window === 'undefined') {
globalObj = global;
} else {
globalObj = window;
}
var module = VM(globalObj, ffi, heap);
Init();
setTimeout(function() {
module.run();
}, 10);
})();