mirror of
https://github.com/remko/waforth
synced 2024-12-27 09:59:29 +01:00
webpack -> esbuild
This commit is contained in:
parent
e50fbe7e1c
commit
6b9de10002
34 changed files with 2568 additions and 5149 deletions
|
@ -1 +1 @@
|
||||||
dist
|
public/waforth/dist
|
||||||
|
|
14
.eslintrc
14
.eslintrc
|
@ -1,14 +0,0 @@
|
||||||
env:
|
|
||||||
browser: true
|
|
||||||
es6: true
|
|
||||||
extends: eslint:recommended
|
|
||||||
parserOptions:
|
|
||||||
sourceType: module
|
|
||||||
globals:
|
|
||||||
WebAssembly: true
|
|
||||||
require: true
|
|
||||||
rules:
|
|
||||||
no-console: 0
|
|
||||||
settings:
|
|
||||||
react:
|
|
||||||
version: "16.0"
|
|
23
.eslintrc.yml
Normal file
23
.eslintrc.yml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
env:
|
||||||
|
browser: true
|
||||||
|
es2021: true
|
||||||
|
node: true
|
||||||
|
extends:
|
||||||
|
- 'eslint:recommended'
|
||||||
|
- 'plugin:react/recommended'
|
||||||
|
- "plugin:react-hooks/recommended"
|
||||||
|
parserOptions:
|
||||||
|
ecmaFeatures:
|
||||||
|
jsx: true
|
||||||
|
ecmaVersion: 12
|
||||||
|
sourceType: module
|
||||||
|
plugins:
|
||||||
|
- prettier
|
||||||
|
- react
|
||||||
|
settings:
|
||||||
|
react:
|
||||||
|
version: detect
|
||||||
|
rules:
|
||||||
|
"prettier/prettier": "error"
|
||||||
|
react/display-name: 0
|
||||||
|
react/prop-types: 0
|
20
.github/workflows/build.yml
vendored
Normal file
20
.github/workflows/build.yml
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
name: Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: 14
|
||||||
|
cache: 'yarn'
|
||||||
|
- run: sudo apt-get install wabt
|
||||||
|
- run: yarnpkg --pure-lockfile
|
||||||
|
- run: yarnpkg build
|
||||||
|
- run: yarnpkg lint
|
||||||
|
- run: yarnpkg test --coverage
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,7 +1,6 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.cache/
|
|
||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
public/waforth/
|
||||||
src/waforth.bulkmem.wat
|
src/waforth.bulkmem.wat
|
||||||
src/waforth.vanilla.wat
|
src/waforth.vanilla.wat
|
||||||
*.wasm
|
*.wasm
|
||||||
|
|
36
.vscode/settings.json
vendored
Normal file
36
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"files.exclude": {
|
||||||
|
"bin/": true,
|
||||||
|
"build/": true,
|
||||||
|
"**/node_modules/": true,
|
||||||
|
"coverage/": true
|
||||||
|
},
|
||||||
|
"search.exclude": {
|
||||||
|
"**/node_modules": true
|
||||||
|
},
|
||||||
|
"[javascript]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
|
"editor.formatOnSave": true
|
||||||
|
},
|
||||||
|
"[json]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
|
"editor.formatOnSave": true
|
||||||
|
},
|
||||||
|
"[jsonc]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
|
"editor.formatOnSave": true
|
||||||
|
},
|
||||||
|
"[typescript]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
|
"editor.formatOnSave": true
|
||||||
|
},
|
||||||
|
"[typescriptreact]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
|
"editor.formatOnSave": true
|
||||||
|
},
|
||||||
|
"[css]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
|
"editor.formatOnSave": true
|
||||||
|
}
|
||||||
|
}
|
24
Makefile
24
Makefile
|
@ -5,15 +5,19 @@ ifeq ($(DEBUG),1)
|
||||||
WAT2WASM_FLAGS:=$(WAT2WASM_FLAGS) --debug-names
|
WAT2WASM_FLAGS:=$(WAT2WASM_FLAGS) --debug-names
|
||||||
endif
|
endif
|
||||||
|
|
||||||
WASM_FILES=src/waforth.wasm src/waforth.bulkmem.wasm tests/benchmarks/sieve-vanilla.wasm
|
all:
|
||||||
|
|
||||||
all: $(WASM_FILES)
|
|
||||||
yarn -s build
|
yarn -s build
|
||||||
|
|
||||||
dev-server: $(WASM_FILES)
|
dev:
|
||||||
yarn -s dev-server
|
yarn -s dev
|
||||||
|
|
||||||
wasm: $(WASM_FILES) src/waforth.assembled.wat src/tools/quadruple.wasm.hex
|
check: src/waforth.wasm
|
||||||
|
yarn -s test
|
||||||
|
|
||||||
|
check-watch: src/waforth.wasm
|
||||||
|
yarn -s test-watch
|
||||||
|
|
||||||
|
wasm: src/waforth.assembled.wat src/tools/quadruple.wasm.hex
|
||||||
|
|
||||||
process: src/waforth.vanilla.wat
|
process: src/waforth.vanilla.wat
|
||||||
cp $< src/waforth.wat
|
cp $< src/waforth.wat
|
||||||
|
@ -30,7 +34,7 @@ src/waforth.bulkmem.wasm: src/waforth.bulkmem.wat
|
||||||
src/waforth.bulkmem.wat: src/waforth.wat
|
src/waforth.bulkmem.wat: src/waforth.wat
|
||||||
./src/tools/process.js --enable-bulk-memory $< > $@
|
./src/tools/process.js --enable-bulk-memory $< > $@
|
||||||
|
|
||||||
tests/benchmarks/sieve-vanilla.wasm: tests/benchmarks/sieve-vanilla.wat
|
src/benchmarks/sieve-vanilla.wasm: src/benchmarks/sieve-vanilla.wat
|
||||||
$(WAT2WASM) $(WAT2WASM_FLAGS) -o $@ $<
|
$(WAT2WASM) $(WAT2WASM_FLAGS) -o $@ $<
|
||||||
|
|
||||||
src/tools/quadruple.wasm: src/tools/quadruple.wat
|
src/tools/quadruple.wasm: src/tools/quadruple.wat
|
||||||
|
@ -42,11 +46,5 @@ src/tools/quadruple.wasm.hex: src/tools/quadruple.wasm
|
||||||
clean:
|
clean:
|
||||||
-rm -rf $(WASM_FILES) src/tools/quadruple.wasm src/tools/quadruple.wasm.hex src/waforth.wat.tmp dist
|
-rm -rf $(WASM_FILES) src/tools/quadruple.wasm src/tools/quadruple.wasm.hex src/waforth.wat.tmp dist
|
||||||
|
|
||||||
check: $(WASM_FILES)
|
|
||||||
yarn -s test
|
|
||||||
|
|
||||||
check-watch: $(WASM_FILES)
|
|
||||||
yarn -s test-watch
|
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
yarn -s lint
|
yarn -s lint
|
||||||
|
|
|
@ -40,7 +40,7 @@ To build everything:
|
||||||
|
|
||||||
To run the development server:
|
To run the development server:
|
||||||
|
|
||||||
make dev-server
|
make dev
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
|
|
161
build.js
Executable file
161
build.js
Executable file
|
@ -0,0 +1,161 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
/* eslint-env node */
|
||||||
|
|
||||||
|
const esbuild = require("esbuild");
|
||||||
|
const path = require("path");
|
||||||
|
const fs = require("fs");
|
||||||
|
const { createServer } = require("http");
|
||||||
|
const nstatic = require("node-static");
|
||||||
|
const { promisify } = require("util");
|
||||||
|
const exec = promisify(require("child_process").exec);
|
||||||
|
|
||||||
|
function withWatcher(config, handleBuildFinished = () => {}, port = 8880) {
|
||||||
|
const watchClients = [];
|
||||||
|
createServer((req, res) => {
|
||||||
|
return watchClients.push(
|
||||||
|
res.writeHead(200, {
|
||||||
|
"Content-Type": "text/event-stream",
|
||||||
|
"Cache-Control": "no-cache",
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
Connection: "keep-alive",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}).listen(port);
|
||||||
|
return {
|
||||||
|
...config,
|
||||||
|
banner: {
|
||||||
|
js: `(function () { new EventSource("http://localhost:${port}").onmessage = function() { location.reload();};})();`,
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
async onRebuild(error, result) {
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
} else {
|
||||||
|
// Doing this first, because this may do some ES5 transformations
|
||||||
|
await handleBuildFinished(result);
|
||||||
|
|
||||||
|
watchClients.forEach((res) => res.write("data: update\n\n"));
|
||||||
|
watchClients.length = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let dev = false;
|
||||||
|
let watch = false;
|
||||||
|
for (const arg of process.argv.slice(2)) {
|
||||||
|
switch (arg) {
|
||||||
|
case "--development":
|
||||||
|
dev = true;
|
||||||
|
break;
|
||||||
|
case "--watch":
|
||||||
|
watch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let buildConfig = {
|
||||||
|
bundle: true,
|
||||||
|
logLevel: "info",
|
||||||
|
entryPoints: [
|
||||||
|
path.join(__dirname, "src", "shell", "shell"),
|
||||||
|
path.join(__dirname, "src", "tests", "tests"),
|
||||||
|
path.join(__dirname, "src", "benchmarks", "benchmarks"),
|
||||||
|
],
|
||||||
|
entryNames: dev ? "[name]" : "[name]-c$[hash]",
|
||||||
|
assetNames: "[name]-c$[hash]",
|
||||||
|
// target: "es6",
|
||||||
|
outdir: path.join(__dirname, "public/waforth/dist"),
|
||||||
|
external: ["fs", "stream", "util", "events"],
|
||||||
|
minify: !dev,
|
||||||
|
loader: {
|
||||||
|
".wasm": "binary",
|
||||||
|
".js": "jsx",
|
||||||
|
".png": "file",
|
||||||
|
".m4a": "file",
|
||||||
|
".woff2": "file",
|
||||||
|
".svg": "file",
|
||||||
|
".woff": "file",
|
||||||
|
".ttf": "file",
|
||||||
|
".eot": "file",
|
||||||
|
".md": "text",
|
||||||
|
},
|
||||||
|
sourcemap: true,
|
||||||
|
metafile: true,
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
name: "wat",
|
||||||
|
setup(build) {
|
||||||
|
build.onResolve({ filter: /.\.wat$/ }, async (args) => {
|
||||||
|
if (args.resolveDir === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const watPath = path.isAbsolute(args.path)
|
||||||
|
? args.path
|
||||||
|
: path.join(args.resolveDir, args.path);
|
||||||
|
return {
|
||||||
|
path: watPath,
|
||||||
|
namespace: "wat",
|
||||||
|
watchFiles: [watPath],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
build.onLoad({ filter: /.*/, namespace: "wat" }, async (args) => {
|
||||||
|
// Would be handy if we could get output from stdout without going through file
|
||||||
|
const out = args.path.replace(".wat", ".wasm");
|
||||||
|
const flags = "";
|
||||||
|
// flags = --debug-names
|
||||||
|
// console.log("wat: compiling %s", args.path);
|
||||||
|
await exec(`wat2wasm ${flags} --output=${out} ${args.path}`);
|
||||||
|
return {
|
||||||
|
contents: await fs.promises.readFile(out),
|
||||||
|
loader: "binary",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const INDEX_TEMPLATE = `<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<link href="/waforth/dist/$BASE.css" rel="stylesheet" />
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script type="text/javascript" src="/waforth/dist/$BASE.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
async function handleBuildFinished(result) {
|
||||||
|
let index = INDEX_TEMPLATE.replace(/\$BASE/g, "shell");
|
||||||
|
let testIndex = INDEX_TEMPLATE.replace(/\$BASE/g, "tests");
|
||||||
|
let benchmarksIndex = INDEX_TEMPLATE.replace(/\$BASE/g, "benchmarks");
|
||||||
|
// console.log(JSON.stringify(result.metafile.outputs, undefined, 2));
|
||||||
|
for (const [out] of Object.entries(result.metafile.outputs)) {
|
||||||
|
const outfile = path.basename(out);
|
||||||
|
const sourcefile = outfile.replace(/-c\$[^.]+\./, ".");
|
||||||
|
// console.log("%s -> %s", sourcefile, outfile);
|
||||||
|
index = index.replace(`/${sourcefile}`, `/${outfile}`);
|
||||||
|
testIndex = testIndex.replace(`/${sourcefile}`, `/${outfile}`);
|
||||||
|
benchmarksIndex = benchmarksIndex.replace(`/${sourcefile}`, `/${outfile}`);
|
||||||
|
}
|
||||||
|
fs.writeFileSync("public/waforth/index.html", index);
|
||||||
|
fs.mkdirSync("public/waforth/tests", { recursive: true });
|
||||||
|
fs.writeFileSync("public/waforth/tests/index.html", testIndex);
|
||||||
|
fs.mkdirSync("public/waforth/benchmarks", { recursive: true });
|
||||||
|
fs.writeFileSync("public/waforth/benchmarks/index.html", benchmarksIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (watch) {
|
||||||
|
const file = new nstatic.Server(path.join(__dirname, "public"));
|
||||||
|
createServer(function (req, res) {
|
||||||
|
file.serve(req, res);
|
||||||
|
}).listen(8080);
|
||||||
|
console.log("listening on port 8080");
|
||||||
|
buildConfig = withWatcher(buildConfig, handleBuildFinished, 8081);
|
||||||
|
}
|
||||||
|
esbuild.build(buildConfig).then(handleBuildFinished, () => process.exit(1));
|
|
@ -40,7 +40,7 @@ function here() {
|
||||||
|
|
||||||
WebAssembly.instantiate(coreWasm, {
|
WebAssembly.instantiate(coreWasm, {
|
||||||
shell: {
|
shell: {
|
||||||
emit: c => {
|
emit: (c) => {
|
||||||
process.stdout.write(String.fromCharCode(c));
|
process.stdout.write(String.fromCharCode(c));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ WebAssembly.instantiate(coreWasm, {
|
||||||
return buffer.pop();
|
return buffer.pop();
|
||||||
},
|
},
|
||||||
|
|
||||||
debug: c => {
|
debug: (c) => {
|
||||||
process.stderr.write(String.fromCharCode(c));
|
process.stderr.write(String.fromCharCode(c));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -64,11 +64,11 @@ WebAssembly.instantiate(coreWasm, {
|
||||||
var module = new WebAssembly.Module(data);
|
var module = new WebAssembly.Module(data);
|
||||||
modules.push(new Uint8Array(Array.from(data)));
|
modules.push(new Uint8Array(Array.from(data)));
|
||||||
new WebAssembly.Instance(module, {
|
new WebAssembly.Instance(module, {
|
||||||
env: { table, memory, tos: -1 }
|
env: { table, memory, tos: -1 },
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}).then(instance => {
|
}).then((instance) => {
|
||||||
core = instance.instance;
|
core = instance.instance;
|
||||||
table = core.exports.table;
|
table = core.exports.table;
|
||||||
memory = core.exports.memory;
|
memory = core.exports.memory;
|
||||||
|
@ -99,7 +99,7 @@ WebAssembly.instantiate(coreWasm, {
|
||||||
"#define WAFORTH_HERE " + savedHere + "\n",
|
"#define WAFORTH_HERE " + savedHere + "\n",
|
||||||
"#define WAFORTH_TABLE_SIZE " + tableSize + "\n",
|
"#define WAFORTH_TABLE_SIZE " + tableSize + "\n",
|
||||||
"void waforth_modules_init();",
|
"void waforth_modules_init();",
|
||||||
"#undef WASM_RT_MODULE_PREFIX"
|
"#undef WASM_RT_MODULE_PREFIX",
|
||||||
];
|
];
|
||||||
const init = [
|
const init = [
|
||||||
"#include <memory.h>",
|
"#include <memory.h>",
|
||||||
|
@ -112,7 +112,7 @@ WebAssembly.instantiate(coreWasm, {
|
||||||
dictionaryStart +
|
dictionaryStart +
|
||||||
"], dictionary, " +
|
"], dictionary, " +
|
||||||
(savedHere - dictionaryStart) +
|
(savedHere - dictionaryStart) +
|
||||||
");"
|
");",
|
||||||
];
|
];
|
||||||
const moduleFiles = [];
|
const moduleFiles = [];
|
||||||
for (let i = 0; i < modules.length; ++i) {
|
for (let i = 0; i < modules.length; ++i) {
|
||||||
|
|
45
package.json
45
package.json
|
@ -2,37 +2,34 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"immutability-helper": "^3.0.0",
|
|
||||||
"jq-console": "^2.13.2",
|
"jq-console": "^2.13.2",
|
||||||
"jquery": "^3.5.0",
|
"jquery": "^3.5.0",
|
||||||
"preact": "^8.2.9",
|
|
||||||
"promise-polyfill": "^7.1.2"
|
"promise-polyfill": "^7.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.3.4",
|
"@babel/core": "^7.17.9",
|
||||||
"@babel/preset-env": "^7.3.4",
|
"@babel/preset-env": "^7.16.11",
|
||||||
"@babel/register": "^7.0.0",
|
"@babel/register": "^7.17.7",
|
||||||
"babel-loader": "^8.0.5",
|
"chai": "^4.3.6",
|
||||||
"babel-preset-preact": "^2.0.0",
|
"commander": "^9.1.0",
|
||||||
"bin-loader": "^0.1.0",
|
"esbuild": "^0.14.36",
|
||||||
"chai": "^4.2.0",
|
"eslint": "^8.13.0",
|
||||||
"commander": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
"css-loader": "^2.1.1",
|
"eslint-plugin-react": "^7.29.4",
|
||||||
"eslint": "5.15.1",
|
"eslint-plugin-react-hooks": "^4.4.0",
|
||||||
"eslint-plugin-react": "^7.12.4",
|
"immutability-helper": "^3.1.1",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mocha": "^6.1.4",
|
"mocha": "^9.2.2",
|
||||||
"style-loader": "^0.23.1",
|
"node-static": "^0.7.11",
|
||||||
"webpack": "^4.41.5",
|
"prettier": "^2.6.2",
|
||||||
"webpack-cli": "^3.2.3",
|
"react": "^18.0.0",
|
||||||
"webpack-dev-server": "^3.2.1"
|
"react-dom": "^18.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack --mode=production",
|
"build": "./build.js",
|
||||||
"test": "mocha tests/index-node.js",
|
"dev": "./build.js --watch --development",
|
||||||
"test-watch": "mocha --watch tests/index-node.js",
|
"test": "mocha src/tests/tests.node.js",
|
||||||
"lint": "eslint .",
|
"test-watch": "mocha --watch src/tests/tests.node.js",
|
||||||
"dev-server": "webpack-dev-server --open --openPage waforth --content-base public"
|
"lint": "eslint ."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
import React from "react";
|
||||||
|
import { createRoot } from "react-dom/client";
|
||||||
import WAForth from "../../src/shell/WAForth";
|
import WAForth from "../../src/shell/WAForth";
|
||||||
import sieve from "../../src/shell/sieve";
|
import sieve from "../../src/shell/sieve";
|
||||||
import sieveVanillaModule from "./sieve-vanilla.wasm";
|
import sieveVanillaModule from "./sieve-vanilla.wat";
|
||||||
import { Component, render, h } from "preact";
|
|
||||||
import update from "immutability-helper";
|
import update from "immutability-helper";
|
||||||
import "./index.css";
|
import "./benchmarks.css";
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Initial setup
|
// Initial setup
|
||||||
|
@ -13,7 +14,7 @@ const setup = [];
|
||||||
|
|
||||||
const forth = new WAForth();
|
const forth = new WAForth();
|
||||||
let outputBuffer = [];
|
let outputBuffer = [];
|
||||||
forth.onEmit = c => {
|
forth.onEmit = (c) => {
|
||||||
outputBuffer.push(String.fromCharCode(c));
|
outputBuffer.push(String.fromCharCode(c));
|
||||||
};
|
};
|
||||||
setup.push(
|
setup.push(
|
||||||
|
@ -26,9 +27,9 @@ let sieveVanilla;
|
||||||
setup.push(
|
setup.push(
|
||||||
WebAssembly.instantiate(sieveVanillaModule, {
|
WebAssembly.instantiate(sieveVanillaModule, {
|
||||||
js: {
|
js: {
|
||||||
print: x => console.log(x)
|
print: (x) => console.log(x),
|
||||||
}
|
},
|
||||||
}).then(instance => {
|
}).then((instance) => {
|
||||||
sieveVanilla = instance.instance.exports.sieve;
|
sieveVanilla = instance.instance.exports.sieve;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -44,7 +45,7 @@ const benchmarks = [
|
||||||
outputBuffer = [];
|
outputBuffer = [];
|
||||||
forth.run(`${LIMIT} sieve`);
|
forth.run(`${LIMIT} sieve`);
|
||||||
return outputBuffer.join("");
|
return outputBuffer.join("");
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "sieve-direct",
|
name: "sieve-direct",
|
||||||
|
@ -52,21 +53,21 @@ const benchmarks = [
|
||||||
outputBuffer = [];
|
outputBuffer = [];
|
||||||
forth.run(`${LIMIT} sieve_direct .`);
|
forth.run(`${LIMIT} sieve_direct .`);
|
||||||
return outputBuffer.join("");
|
return outputBuffer.join("");
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "sieve-vanilla",
|
name: "sieve-vanilla",
|
||||||
fn: () => {
|
fn: () => {
|
||||||
return sieveVanilla(LIMIT);
|
return sieveVanilla(LIMIT);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const iterations = Array.from(Array(ITERATIONS).keys());
|
const iterations = Array.from(Array(ITERATIONS).keys());
|
||||||
|
|
||||||
class Benchmarks extends Component {
|
class Benchmarks extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
const results = {};
|
const results = {};
|
||||||
|
@ -74,7 +75,7 @@ class Benchmarks extends Component {
|
||||||
this.state = {
|
this.state = {
|
||||||
initialized: false,
|
initialized: false,
|
||||||
done: false,
|
done: false,
|
||||||
results
|
results,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,10 +92,10 @@ class Benchmarks extends Component {
|
||||||
results: update(this.state.results, {
|
results: update(this.state.results, {
|
||||||
[benchmarks[benchmarkIndex].name]: {
|
[benchmarks[benchmarkIndex].name]: {
|
||||||
[benchmarkIteration]: {
|
[benchmarkIteration]: {
|
||||||
$set: { time: (t2 - t1) / 1000.0, output }
|
$set: { time: (t2 - t1) / 1000.0, output },
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
}),
|
||||||
});
|
});
|
||||||
if (benchmarkIteration < ITERATIONS - 1) {
|
if (benchmarkIteration < ITERATIONS - 1) {
|
||||||
benchmarkIteration += 1;
|
benchmarkIteration += 1;
|
||||||
|
@ -122,7 +123,9 @@ class Benchmarks extends Component {
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th />
|
<th />
|
||||||
{iterations.map(i => <th key={i}>{i}</th>)}
|
{iterations.map((i) => (
|
||||||
|
<th key={i}>{i}</th>
|
||||||
|
))}
|
||||||
<th>Avg</th>
|
<th>Avg</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -133,7 +136,7 @@ class Benchmarks extends Component {
|
||||||
return [
|
return [
|
||||||
<tr key={`${name}-time`}>
|
<tr key={`${name}-time`}>
|
||||||
<th>{name}</th>
|
<th>{name}</th>
|
||||||
{iterations.map(i => (
|
{iterations.map((i) => (
|
||||||
<td key={i}>
|
<td key={i}>
|
||||||
{benchmark[i] == null ? null : (
|
{benchmark[i] == null ? null : (
|
||||||
<span>{benchmark[i].time.toFixed(2)}s</span>
|
<span>{benchmark[i].time.toFixed(2)}s</span>
|
||||||
|
@ -150,14 +153,14 @@ class Benchmarks extends Component {
|
||||||
</tr>,
|
</tr>,
|
||||||
<tr key={`${name}-output`}>
|
<tr key={`${name}-output`}>
|
||||||
<th />
|
<th />
|
||||||
{iterations.map(i => (
|
{iterations.map((i) => (
|
||||||
<td key={i}>
|
<td key={i}>
|
||||||
<pre className="output">
|
<pre className="output">
|
||||||
{benchmark[i] == null ? null : benchmark[i].output}
|
{benchmark[i] == null ? null : benchmark[i].output}
|
||||||
</pre>
|
</pre>
|
||||||
</td>
|
</td>
|
||||||
))}
|
))}
|
||||||
</tr>
|
</tr>,
|
||||||
];
|
];
|
||||||
})}
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -166,4 +169,7 @@ class Benchmarks extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
render(<Benchmarks />, document.body);
|
|
||||||
|
const rootEl = document.createElement("div");
|
||||||
|
document.body.appendChild(rootEl);
|
||||||
|
createRoot(rootEl).render(<Benchmarks />);
|
|
@ -5,7 +5,7 @@ const isSafari =
|
||||||
class WAForth {
|
class WAForth {
|
||||||
constructor(wasmModule, arrayToBase64) {
|
constructor(wasmModule, arrayToBase64) {
|
||||||
if (wasmModule == null) {
|
if (wasmModule == null) {
|
||||||
this.wasmModule = require("../waforth.wasm");
|
this.wasmModule = require("../waforth.wat");
|
||||||
} else {
|
} else {
|
||||||
this.wasmModule = wasmModule;
|
this.wasmModule = wasmModule;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ class WAForth {
|
||||||
return buffer.pop();
|
return buffer.pop();
|
||||||
},
|
},
|
||||||
|
|
||||||
debug: d => {
|
debug: (d) => {
|
||||||
console.log("DEBUG: ", d, String.fromCharCode(d));
|
console.log("DEBUG: ", d, String.fromCharCode(d));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -88,11 +88,11 @@ class WAForth {
|
||||||
// console.log("Load", index, this.arrayToBase64(data));
|
// console.log("Load", index, this.arrayToBase64(data));
|
||||||
var module = new WebAssembly.Module(data);
|
var module = new WebAssembly.Module(data);
|
||||||
new WebAssembly.Instance(module, {
|
new WebAssembly.Instance(module, {
|
||||||
env: { table, memory, tos: -1 }
|
env: { table, memory, tos: -1 },
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}).then(instance => {
|
}).then((instance) => {
|
||||||
this.core = instance.instance;
|
this.core = instance.instance;
|
||||||
table = this.core.exports.table;
|
table = this.core.exports.table;
|
||||||
memory = this.core.exports.memory;
|
memory = this.core.exports.memory;
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="console"></div>
|
|
||||||
<div class="messageContainer">
|
|
||||||
<div class="message" id="message"></div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -20,15 +20,15 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.message.error {
|
.message.error {
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The console container element */
|
/* The console container element */
|
||||||
#console {
|
.console {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color:black;
|
background-color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The inner console element. */
|
/* The inner console element. */
|
||||||
|
@ -49,31 +49,31 @@ body {
|
||||||
|
|
||||||
/* The cursor. */
|
/* The cursor. */
|
||||||
.jqconsole-cursor {
|
.jqconsole-cursor {
|
||||||
background-color: gray;
|
background-color: gray;
|
||||||
}
|
}
|
||||||
/* The cursor color when the console looses focus. */
|
/* The cursor color when the console looses focus. */
|
||||||
.jqconsole-blurred .jqconsole-cursor {
|
.jqconsole-blurred .jqconsole-cursor {
|
||||||
background-color: #666;
|
background-color: #666;
|
||||||
}
|
}
|
||||||
/* The current prompt text color */
|
/* The current prompt text color */
|
||||||
.jqconsole-prompt {
|
.jqconsole-prompt {
|
||||||
color: #dd0;
|
color: #dd0;
|
||||||
}
|
}
|
||||||
/* The command history */
|
/* The command history */
|
||||||
.jqconsole-old-prompt {
|
.jqconsole-old-prompt {
|
||||||
color: #bb0;
|
color: #bb0;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
/* The text color when in input mode. */
|
/* The text color when in input mode. */
|
||||||
.jqconsole-input {
|
.jqconsole-input {
|
||||||
color: #0d0;
|
color: #0d0;
|
||||||
}
|
}
|
||||||
/* Previously entered input. */
|
/* Previously entered input. */
|
||||||
.jqconsole-old-input {
|
.jqconsole-old-input {
|
||||||
color: #0b0;
|
color: #0b0;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
/* The text color of the output. */
|
/* The text color of the output. */
|
||||||
.jqconsole-output {
|
.jqconsole-output {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
|
@ -2,25 +2,38 @@ import "promise-polyfill/src/polyfill";
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
import WAForth from "./WAForth";
|
import WAForth from "./WAForth";
|
||||||
import sieve from "./sieve";
|
import sieve from "./sieve";
|
||||||
import "./index.css";
|
import "./shell.css";
|
||||||
|
|
||||||
window.jQuery = $;
|
window.jQuery = $;
|
||||||
require("jq-console");
|
require("jq-console");
|
||||||
|
|
||||||
|
document.title = "WAForth";
|
||||||
|
|
||||||
const forth = new WAForth();
|
const forth = new WAForth();
|
||||||
|
|
||||||
let jqconsole = $("#console").jqconsole("WAForth\n", "");
|
const consoleEl = document.createElement("div");
|
||||||
$("#console").hide();
|
consoleEl.className = "console";
|
||||||
|
document.body.appendChild(consoleEl);
|
||||||
|
|
||||||
|
const messageContainerEl = document.createElement("div");
|
||||||
|
messageContainerEl.className = "messageContainer";
|
||||||
|
const messageEl = document.createElement("div");
|
||||||
|
messageEl.className = "message";
|
||||||
|
messageContainerEl.appendChild(messageEl);
|
||||||
|
document.body.appendChild(messageContainerEl);
|
||||||
|
|
||||||
|
let jqconsole = $(consoleEl).jqconsole("WAForth\n", "");
|
||||||
|
$(consoleEl).hide();
|
||||||
$(".jqconsole-header").html(
|
$(".jqconsole-header").html(
|
||||||
"<span><a target='_blank' href='https://github.com/remko/waforth'>WAForth</a>\n</span>"
|
"<span><a target='_blank' href='https://github.com/remko/waforth'>WAForth</a>\n</span>"
|
||||||
);
|
);
|
||||||
let outputBuffer = [];
|
let outputBuffer = [];
|
||||||
forth.onEmit = c => {
|
forth.onEmit = (c) => {
|
||||||
outputBuffer.push(String.fromCharCode(c));
|
outputBuffer.push(String.fromCharCode(c));
|
||||||
};
|
};
|
||||||
|
|
||||||
function prompt() {
|
function prompt() {
|
||||||
jqconsole.Prompt(false, input => {
|
jqconsole.Prompt(false, (input) => {
|
||||||
jqconsole.Write(" ");
|
jqconsole.Write(" ");
|
||||||
|
|
||||||
// Avoid console inserting a newline
|
// Avoid console inserting a newline
|
||||||
|
@ -38,18 +51,16 @@ function prompt() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#message").text("Loading...");
|
$(messageEl).text("Loading...");
|
||||||
forth.start().then(
|
forth.start().then(
|
||||||
() => {
|
() => {
|
||||||
forth.run(sieve);
|
forth.run(sieve);
|
||||||
outputBuffer = [];
|
outputBuffer = [];
|
||||||
$("#message").hide();
|
$(messageEl).hide();
|
||||||
$("#console").show();
|
$(consoleEl).show();
|
||||||
prompt();
|
prompt();
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
$("#message")
|
$(messageEl).addClass("error").text("Error");
|
||||||
.addClass("error")
|
|
||||||
.text("Error");
|
|
||||||
}
|
}
|
||||||
);
|
);
|
|
@ -1,5 +1,5 @@
|
||||||
import WAForth from "../src/shell/WAForth";
|
import WAForth from "../shell/WAForth";
|
||||||
import sieve from "../src/shell/sieve";
|
import sieve from "../shell/sieve";
|
||||||
import standardTestSuiteTester from "./standard-testsuite/tester.f";
|
import standardTestSuiteTester from "./standard-testsuite/tester.f";
|
||||||
import standardCoreWordsTestSuite from "./standard-testsuite/core.f";
|
import standardCoreWordsTestSuite from "./standard-testsuite/core.f";
|
||||||
import { expect, assert } from "chai";
|
import { expect, assert } from "chai";
|
||||||
|
@ -10,7 +10,7 @@ function loadTests(wasmModule, arrayToBase64) {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
forth = new WAForth(wasmModule, arrayToBase64);
|
forth = new WAForth(wasmModule, arrayToBase64);
|
||||||
forth.onEmit = c => {
|
forth.onEmit = (c) => {
|
||||||
output = output + String.fromCharCode(c);
|
output = output + String.fromCharCode(c);
|
||||||
// console.log(output);
|
// console.log(output);
|
||||||
};
|
};
|
||||||
|
@ -25,7 +25,7 @@ function loadTests(wasmModule, arrayToBase64) {
|
||||||
stack = new Int32Array(core.memory.buffer, core.tos(), 0x100);
|
stack = new Int32Array(core.memory.buffer, core.tos(), 0x100);
|
||||||
initialTOS = core.tos();
|
initialTOS = core.tos();
|
||||||
},
|
},
|
||||||
err => {
|
(err) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -81,7 +81,7 @@ function loadTests(wasmModule, arrayToBase64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function run(ss, expectErrors = false) {
|
function run(ss, expectErrors = false) {
|
||||||
ss.split("\n").forEach(s => {
|
ss.split("\n").forEach((s) => {
|
||||||
// console.log("Running: ", s);
|
// console.log("Running: ", s);
|
||||||
const r = forth.run(s);
|
const r = forth.run(s);
|
||||||
if (expectErrors) {
|
if (expectErrors) {
|
18
src/tests/tests.js
Normal file
18
src/tests/tests.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import mocha from "mocha/mocha.js";
|
||||||
|
import loadTests from "./suite";
|
||||||
|
import "mocha/mocha.css";
|
||||||
|
|
||||||
|
const h1El = document.createElement("h1");
|
||||||
|
h1El.style = "font-family: sans-serif; margin: 1rem;";
|
||||||
|
h1El.appendChild(document.createTextNode("WAForth Unit Tests"));
|
||||||
|
document.body.appendChild(h1El);
|
||||||
|
|
||||||
|
const mochaEl = document.createElement("div");
|
||||||
|
mochaEl.id = "mocha";
|
||||||
|
document.body.appendChild(mochaEl);
|
||||||
|
|
||||||
|
mocha.setup("bdd");
|
||||||
|
loadTests();
|
||||||
|
// mocha.checkLeaks();
|
||||||
|
mocha.globals(["jQuery"]);
|
||||||
|
mocha.run();
|
10
src/tests/tests.node.js
Normal file
10
src/tests/tests.node.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
require("@babel/register")({
|
||||||
|
presets: ["@babel/preset-env"],
|
||||||
|
});
|
||||||
|
const loadTests = require("./suite.js").default;
|
||||||
|
const wasmModule = fs.readFileSync(path.join(__dirname, "../waforth.wasm"));
|
||||||
|
loadTests(wasmModule, (s) => {
|
||||||
|
return Buffer.from(s).toString("base64");
|
||||||
|
});
|
|
@ -26,7 +26,7 @@ const dictionaryEntry = [
|
||||||
encodeLE(latest, 4),
|
encodeLE(latest, 4),
|
||||||
encodeLE(name.length | flags, 1),
|
encodeLE(name.length | flags, 1),
|
||||||
_.padEnd(name, 4 * Math.floor((name.length + 4) / 4) - 1, "0"),
|
_.padEnd(name, 4 * Math.floor((name.length + 4) / 4) - 1, "0"),
|
||||||
encodeLE(nextTableIndex, 4)
|
encodeLE(nextTableIndex, 4),
|
||||||
];
|
];
|
||||||
console.log(
|
console.log(
|
||||||
"(data (i32.const 0x" +
|
"(data (i32.const 0x" +
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
TODO
|
// TODO
|
||||||
;;; !moduleHeaderSize := (string-length !moduleHeader))
|
// ;;; !moduleHeaderSize := (string-length !moduleHeader))
|
||||||
;;; !moduleHeaderCodeSizeOffset := (char-index (string->list !moduleHeader) \FF 0))
|
// ;;; !moduleHeaderCodeSizeOffset := (char-index (string->list !moduleHeader) \FF 0))
|
||||||
;;; !moduleHeaderBodySizeOffset := (char-index (string->list !moduleHeader) \FE 0))
|
// ;;; !moduleHeaderBodySizeOffset := (char-index (string->list !moduleHeader) \FE 0))
|
||||||
;;; !moduleHeaderLocalCountOffset := (char-index (string->list !moduleHeader) \FD 0))
|
// ;;; !moduleHeaderLocalCountOffset := (char-index (string->list !moduleHeader) \FD 0))
|
||||||
;;; !moduleHeaderTableIndexOffset := (char-index (string->list !moduleHeader) \FC 0))
|
// ;;; !moduleHeaderTableIndexOffset := (char-index (string->list !moduleHeader) \FC 0))
|
||||||
;;; !moduleHeaderTableInitialSizeOffset := (char-index (string->list !moduleHeader) \FB 0))
|
// ;;; !moduleHeaderTableInitialSizeOffset := (char-index (string->list !moduleHeader) \FB 0))
|
||||||
;;; !moduleHeaderFunctionTypeOffset := (char-index (string->list !moduleHeader) \FA 0))
|
// ;;; !moduleHeaderFunctionTypeOffset := (char-index (string->list !moduleHeader) \FA 0))
|
||||||
|
|
|
@ -12,22 +12,19 @@ program
|
||||||
"--enable-bulk-memory",
|
"--enable-bulk-memory",
|
||||||
"use bulk memory operations instead of own implementation"
|
"use bulk memory operations instead of own implementation"
|
||||||
)
|
)
|
||||||
.action(f => {
|
.action((f) => {
|
||||||
file = f;
|
file = f;
|
||||||
});
|
});
|
||||||
program.parse(process.argv);
|
program.parse(process.argv);
|
||||||
|
|
||||||
const lines = fs
|
const lines = fs.readFileSync(file).toString().split("\n");
|
||||||
.readFileSync(file)
|
|
||||||
.toString()
|
|
||||||
.split("\n");
|
|
||||||
|
|
||||||
const definitions = {};
|
const definitions = {};
|
||||||
let skipLevel = 0;
|
let skipLevel = 0;
|
||||||
let skippingDefinition = false;
|
let skippingDefinition = false;
|
||||||
lines.forEach(line => {
|
lines.forEach((line) => {
|
||||||
// Constants
|
// Constants
|
||||||
Object.keys(definitions).forEach(k => {
|
Object.keys(definitions).forEach((k) => {
|
||||||
line = line.replace(
|
line = line.replace(
|
||||||
new RegExp(
|
new RegExp(
|
||||||
"(\\s)([^\\s])+(\\s)+\\(; = " + _.escapeRegExp(k) + " ;\\)",
|
"(\\s)([^\\s])+(\\s)+\\(; = " + _.escapeRegExp(k) + " ;\\)",
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
/* global __dirname, Buffer */
|
|
||||||
const fs = require("fs");
|
|
||||||
const path = require("path");
|
|
||||||
require("@babel/register")({
|
|
||||||
presets: ["@babel/preset-env"]
|
|
||||||
});
|
|
||||||
const loadTests = require("./tests.js").default;
|
|
||||||
const wasmModule = fs.readFileSync(path.join(__dirname, "../src/waforth.wasm"));
|
|
||||||
loadTests(wasmModule, s => {
|
|
||||||
return Buffer.from(s).toString("base64");
|
|
||||||
});
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
|
||||||
<link href="https://cdn.jsdelivr.net/gh/mochajs/mocha@2.2.5/mocha.css" rel="stylesheet" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1 style="font-family: sans-serif; margin: 1rem; ">
|
|
||||||
<%= htmlWebpackPlugin.options.title %>
|
|
||||||
</h1>
|
|
||||||
<div style="margin-top: 30px;" id="mocha"></div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,8 +0,0 @@
|
||||||
import { mocha } from "mocha";
|
|
||||||
import loadTests from "./tests";
|
|
||||||
|
|
||||||
mocha.setup("bdd");
|
|
||||||
loadTests();
|
|
||||||
// mocha.checkLeaks();
|
|
||||||
mocha.globals(["jQuery"]);
|
|
||||||
mocha.run();
|
|
|
@ -1,91 +0,0 @@
|
||||||
/*eslint-env node*/
|
|
||||||
|
|
||||||
const path = require("path");
|
|
||||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
|
||||||
const webpack = require("webpack");
|
|
||||||
|
|
||||||
function config({ entry, outputDir, title, template, mode }) {
|
|
||||||
mode = mode || "development";
|
|
||||||
const result = {
|
|
||||||
mode,
|
|
||||||
entry,
|
|
||||||
output: {
|
|
||||||
filename: "index.js",
|
|
||||||
path: path.resolve(__dirname, "dist", outputDir),
|
|
||||||
publicPath: "/" + outputDir
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /\.js$|\.jsx$/,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
use: {
|
|
||||||
loader: "babel-loader",
|
|
||||||
options: {
|
|
||||||
presets: [["@babel/preset-env", { modules: false }], "preact"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.css$/,
|
|
||||||
use: [{ loader: "style-loader" }, { loader: "css-loader" }]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.wasm$/,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
type: "javascript/auto",
|
|
||||||
use: { loader: "bin-loader" }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
new webpack.ContextReplacementPlugin(/mocha\/lib/, "", false),
|
|
||||||
new HtmlWebpackPlugin(
|
|
||||||
Object.assign(
|
|
||||||
{
|
|
||||||
title,
|
|
||||||
meta: {
|
|
||||||
viewport: "width=device-width, initial-scale=1, shrink-to-fit=no"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
template ? { template } : {}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
],
|
|
||||||
// Mocha requires this
|
|
||||||
node: {
|
|
||||||
fs: "empty"
|
|
||||||
},
|
|
||||||
// Mocha requires this
|
|
||||||
performance: { hints: false }
|
|
||||||
};
|
|
||||||
if (mode === "development") {
|
|
||||||
result.devtool = "cheap-module-eval-source-map";
|
|
||||||
} else {
|
|
||||||
result.devtool = "source-map";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = (env, argv) => [
|
|
||||||
config({
|
|
||||||
title: "WAForth",
|
|
||||||
template: "./src/shell/index.html",
|
|
||||||
entry: "./src/shell/index.js",
|
|
||||||
outputDir: "waforth",
|
|
||||||
mode: argv.mode
|
|
||||||
}),
|
|
||||||
config({
|
|
||||||
title: "WAForth Unit Tests",
|
|
||||||
template: "./tests/index.html",
|
|
||||||
entry: "./tests/index.js",
|
|
||||||
outputDir: "tests",
|
|
||||||
mode: argv.mode
|
|
||||||
}),
|
|
||||||
config({
|
|
||||||
title: "Benchmarks",
|
|
||||||
entry: "./tests/benchmarks/index.js",
|
|
||||||
outputDir: "benchmarks",
|
|
||||||
mode: argv.mode
|
|
||||||
})
|
|
||||||
];
|
|
Loading…
Reference in a new issue