mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2026-04-19 08:27:40 +00:00
Deploying to gh-pages from @ sehugg/8bitworkshop@7cf87649ff 🚀
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
#!/usr/bin/env node
|
||||
"use strict";
|
||||
// 8bws - 8bitworkshop CLI tool for compilation, ROM execution, and platform info
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = __importStar(require("fs"));
|
||||
const testlib_1 = require("./testlib");
|
||||
function outputJSON(result) {
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
}
|
||||
function usage() {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: 'help',
|
||||
data: {
|
||||
commands: {
|
||||
'compile': 'compile --tool <tool> --platform <platform> [--output <file>] <source>',
|
||||
'check': 'check --tool <tool> --platform <platform> <source>',
|
||||
'run': 'run --platform <platform> [--frames N] <rom>',
|
||||
'list-tools': 'list-tools',
|
||||
'list-platforms': 'list-platforms',
|
||||
}
|
||||
},
|
||||
error: 'No command specified'
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
function parseArgs(argv) {
|
||||
var command = argv[2];
|
||||
var args = {};
|
||||
var positional = [];
|
||||
for (var i = 3; i < argv.length; i++) {
|
||||
if (argv[i].startsWith('--')) {
|
||||
var key = argv[i].substring(2);
|
||||
if (i + 1 < argv.length && !argv[i + 1].startsWith('--')) {
|
||||
args[key] = argv[++i];
|
||||
}
|
||||
else {
|
||||
args[key] = 'true';
|
||||
}
|
||||
}
|
||||
else {
|
||||
positional.push(argv[i]);
|
||||
}
|
||||
}
|
||||
return { command, args, positional };
|
||||
}
|
||||
async function doCompile(args, positional, checkOnly) {
|
||||
var tool = args['tool'];
|
||||
var platform = args['platform'];
|
||||
var outputFile = args['output'];
|
||||
var sourceFile = positional[0];
|
||||
if (!tool || !platform || !sourceFile) {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: checkOnly ? 'check' : 'compile',
|
||||
error: 'Required: --tool <tool> --platform <platform> <source>'
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
if (!testlib_1.TOOLS[tool]) {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: checkOnly ? 'check' : 'compile',
|
||||
error: `Unknown tool: ${tool}. Use list-tools to see available tools.`
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
// Preload the tool's filesystem if needed
|
||||
var preloadKey = tool;
|
||||
if (testlib_1.TOOL_PRELOADFS[tool + '-' + platform]) {
|
||||
preloadKey = tool;
|
||||
}
|
||||
await (0, testlib_1.preload)(tool, platform);
|
||||
var result = await (0, testlib_1.compileSourceFile)(tool, platform, sourceFile);
|
||||
if (!result.success) {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: checkOnly ? 'check' : 'compile',
|
||||
data: { errors: result.errors }
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
if (checkOnly) {
|
||||
outputJSON({
|
||||
success: true,
|
||||
command: 'check',
|
||||
data: {
|
||||
tool: tool,
|
||||
platform: platform,
|
||||
source: sourceFile,
|
||||
outputSize: result.output ? (result.output.code ? result.output.code.length : result.output.length) : 0,
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Write output if requested
|
||||
if (outputFile && result.output) {
|
||||
var outData = result.output.code || result.output;
|
||||
if (outData instanceof Uint8Array) {
|
||||
fs.writeFileSync(outputFile, outData);
|
||||
}
|
||||
else if (typeof outData === 'object') {
|
||||
fs.writeFileSync(outputFile, JSON.stringify(outData));
|
||||
}
|
||||
else {
|
||||
fs.writeFileSync(outputFile, outData);
|
||||
}
|
||||
}
|
||||
var outputSize = 0;
|
||||
if (result.output) {
|
||||
outputSize = result.output.code ? result.output.code.length : result.output.length;
|
||||
}
|
||||
outputJSON({
|
||||
success: true,
|
||||
command: 'compile',
|
||||
data: {
|
||||
tool: tool,
|
||||
platform: platform,
|
||||
source: sourceFile,
|
||||
outputSize: outputSize,
|
||||
outputFile: outputFile || null,
|
||||
hasListings: result.listings ? Object.keys(result.listings).length > 0 : false,
|
||||
hasSymbolmap: !!result.symbolmap,
|
||||
}
|
||||
});
|
||||
}
|
||||
async function doRun(args, positional) {
|
||||
var platform = args['platform'];
|
||||
var frames = parseInt(args['frames'] || '1');
|
||||
var romFile = positional[0];
|
||||
if (!platform || !romFile) {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: 'run',
|
||||
error: 'Required: --platform <platform> <rom>'
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
// Dynamic import of MachineRunner
|
||||
try {
|
||||
var runmachine = require('./runmachine.js');
|
||||
var MachineRunner = runmachine.MachineRunner;
|
||||
}
|
||||
catch (e) {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: 'run',
|
||||
error: `Could not load MachineRunner: ${e.message}`
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: 'run',
|
||||
error: 'Run command not yet fully implemented (requires platform machine loading)'
|
||||
});
|
||||
}
|
||||
function doListTools() {
|
||||
var tools = (0, testlib_1.listTools)();
|
||||
outputJSON({
|
||||
success: true,
|
||||
command: 'list-tools',
|
||||
data: {
|
||||
tools: tools,
|
||||
count: tools.length
|
||||
}
|
||||
});
|
||||
}
|
||||
function doListPlatforms() {
|
||||
var platforms = (0, testlib_1.listPlatforms)();
|
||||
var details = {};
|
||||
for (var p of platforms) {
|
||||
details[p] = {
|
||||
arch: testlib_1.PLATFORM_PARAMS[p].arch || 'unknown',
|
||||
};
|
||||
}
|
||||
outputJSON({
|
||||
success: true,
|
||||
command: 'list-platforms',
|
||||
data: {
|
||||
platforms: details,
|
||||
count: platforms.length
|
||||
}
|
||||
});
|
||||
}
|
||||
async function main() {
|
||||
if (process.argv.length < 3) {
|
||||
usage();
|
||||
}
|
||||
var { command, args, positional } = parseArgs(process.argv);
|
||||
try {
|
||||
switch (command) {
|
||||
case 'compile':
|
||||
await (0, testlib_1.initialize)();
|
||||
await doCompile(args, positional, false);
|
||||
break;
|
||||
case 'check':
|
||||
await (0, testlib_1.initialize)();
|
||||
await doCompile(args, positional, true);
|
||||
break;
|
||||
case 'run':
|
||||
await doRun(args, positional);
|
||||
break;
|
||||
case 'list-tools':
|
||||
await (0, testlib_1.initialize)();
|
||||
doListTools();
|
||||
break;
|
||||
case 'list-platforms':
|
||||
await (0, testlib_1.initialize)();
|
||||
doListPlatforms();
|
||||
break;
|
||||
default:
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: command,
|
||||
error: `Unknown command: ${command}`
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: command,
|
||||
error: e.message || String(e)
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
main();
|
||||
//# sourceMappingURL=8bws.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,205 @@
|
||||
"use strict";
|
||||
// testlib - Clean async API for compiling and testing 8bitworkshop projects
|
||||
// Wraps the worker build system for use in tests and CLI tools
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TOOLS = exports.PLATFORM_PARAMS = exports.TOOL_PRELOADFS = exports.store = void 0;
|
||||
exports.initialize = initialize;
|
||||
exports.preload = preload;
|
||||
exports.compile = compile;
|
||||
exports.compileFile = compileFile;
|
||||
exports.compileSourceFile = compileSourceFile;
|
||||
exports.listTools = listTools;
|
||||
exports.listPlatforms = listPlatforms;
|
||||
exports.ab2str = ab2str;
|
||||
exports.createMockLocalStorage = createMockLocalStorage;
|
||||
const fs = __importStar(require("fs"));
|
||||
const workerlib_1 = require("../worker/workerlib");
|
||||
Object.defineProperty(exports, "store", { enumerable: true, get: function () { return workerlib_1.store; } });
|
||||
Object.defineProperty(exports, "TOOL_PRELOADFS", { enumerable: true, get: function () { return workerlib_1.TOOL_PRELOADFS; } });
|
||||
const platforms_1 = require("../worker/platforms");
|
||||
Object.defineProperty(exports, "PLATFORM_PARAMS", { enumerable: true, get: function () { return platforms_1.PLATFORM_PARAMS; } });
|
||||
const workertools_1 = require("../worker/workertools");
|
||||
Object.defineProperty(exports, "TOOLS", { enumerable: true, get: function () { return workertools_1.TOOLS; } });
|
||||
let initialized = false;
|
||||
/**
|
||||
* Initialize the Node.js environment for compilation.
|
||||
* Must be called once before any compile/preload calls.
|
||||
*/
|
||||
async function initialize() {
|
||||
if (initialized)
|
||||
return;
|
||||
(0, workerlib_1.setupNodeEnvironment)();
|
||||
// The worker tools are already registered through the import chain:
|
||||
// workerlib -> workertools -> tools/* and builder -> TOOLS
|
||||
// No need to load the esbuild bundle.
|
||||
initialized = true;
|
||||
}
|
||||
/**
|
||||
* Preload a tool's filesystem (e.g. CC65 standard libraries).
|
||||
*/
|
||||
async function preload(tool, platform) {
|
||||
await initialize();
|
||||
var msg = { preload: tool };
|
||||
if (platform)
|
||||
msg.platform = platform;
|
||||
await (0, workerlib_1.handleMessage)(msg);
|
||||
}
|
||||
/**
|
||||
* Compile source code with the specified tool and platform.
|
||||
*/
|
||||
async function compile(options) {
|
||||
await initialize();
|
||||
// Reset the store for a clean build
|
||||
await (0, workerlib_1.handleMessage)({ reset: true });
|
||||
let result;
|
||||
if (options.files && options.buildsteps) {
|
||||
// Multi-file build
|
||||
var msg = {
|
||||
updates: options.files.map(f => ({ path: f.path, data: f.data })),
|
||||
buildsteps: options.buildsteps
|
||||
};
|
||||
result = await (0, workerlib_1.handleMessage)(msg);
|
||||
}
|
||||
else {
|
||||
// Single-file build
|
||||
var msg = {
|
||||
code: options.code,
|
||||
platform: options.platform,
|
||||
tool: options.tool,
|
||||
path: options.path || ('src.' + options.tool),
|
||||
mainfile: options.mainfile !== false
|
||||
};
|
||||
result = await (0, workerlib_1.handleMessage)(msg);
|
||||
}
|
||||
return workerResultToCompileResult(result);
|
||||
}
|
||||
/**
|
||||
* Compile a file from the presets directory.
|
||||
*/
|
||||
async function compileFile(tool, platform, presetPath) {
|
||||
await initialize();
|
||||
var code = fs.readFileSync('presets/' + platform + '/' + presetPath, 'utf-8');
|
||||
return compile({
|
||||
tool: tool,
|
||||
platform: platform,
|
||||
code: code,
|
||||
path: presetPath,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Compile an arbitrary source file path.
|
||||
*/
|
||||
async function compileSourceFile(tool, platform, filePath) {
|
||||
await initialize();
|
||||
var code = fs.readFileSync(filePath, 'utf-8');
|
||||
var basename = filePath.split('/').pop();
|
||||
return compile({
|
||||
tool: tool,
|
||||
platform: platform,
|
||||
code: code,
|
||||
path: basename,
|
||||
});
|
||||
}
|
||||
function workerResultToCompileResult(result) {
|
||||
if (!result) {
|
||||
return { success: true, unchanged: true };
|
||||
}
|
||||
if ('unchanged' in result && result.unchanged) {
|
||||
return { success: true, unchanged: true };
|
||||
}
|
||||
if ('errors' in result && result.errors && result.errors.length > 0) {
|
||||
return {
|
||||
success: false,
|
||||
errors: result.errors,
|
||||
};
|
||||
}
|
||||
if ('output' in result) {
|
||||
return {
|
||||
success: true,
|
||||
output: result.output,
|
||||
listings: result.listings,
|
||||
symbolmap: result.symbolmap,
|
||||
params: result.params,
|
||||
};
|
||||
}
|
||||
return { success: false, errors: [{ line: 0, msg: 'Unknown result format' }] };
|
||||
}
|
||||
/**
|
||||
* List available compilation tools.
|
||||
*/
|
||||
function listTools() {
|
||||
return Object.keys(workertools_1.TOOLS);
|
||||
}
|
||||
/**
|
||||
* List available target platforms.
|
||||
*/
|
||||
function listPlatforms() {
|
||||
return Object.keys(platforms_1.PLATFORM_PARAMS);
|
||||
}
|
||||
/**
|
||||
* Convert a binary buffer to a hex string for display.
|
||||
*/
|
||||
function ab2str(buf) {
|
||||
return String.fromCharCode.apply(null, new Uint16Array(buf));
|
||||
}
|
||||
// Platform test harness utilities
|
||||
/**
|
||||
* Create a mock localStorage for tests that need it.
|
||||
*/
|
||||
function createMockLocalStorage() {
|
||||
var items = {};
|
||||
return {
|
||||
get length() {
|
||||
return Object.keys(items).length;
|
||||
},
|
||||
clear() {
|
||||
items = {};
|
||||
},
|
||||
getItem(k) {
|
||||
return items[k] || null;
|
||||
},
|
||||
setItem(k, v) {
|
||||
items[k] = v;
|
||||
},
|
||||
removeItem(k) {
|
||||
delete items[k];
|
||||
},
|
||||
key(i) {
|
||||
return Object.keys(items)[i] || null;
|
||||
}
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=testlib.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"testlib.js","sourceRoot":"","sources":["../../src/tools/testlib.ts"],"names":[],"mappings":"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"}
|
||||
@@ -1 +1 @@
|
||||
{"root":["../src/common/analysis.ts","../src/common/audio.ts","../src/common/baseplatform.ts","../src/common/binutils.ts","../src/common/devices.ts","../src/common/emu.ts","../src/common/mameplatform.ts","../src/common/probe.ts","../src/common/recorder.ts","../src/common/teletype.ts","../src/common/tokenizer.ts","../src/common/util.ts","../src/common/vlist.ts","../src/common/wasmplatform.ts","../src/common/workertypes.ts","../src/common/audio/CommodoreTape.ts","../src/common/basic/compiler.ts","../src/common/basic/fuzz.ts","../src/common/basic/run.ts","../src/common/basic/runtime.ts","../src/common/cpu/6809.ts","../src/common/cpu/ARM.ts","../src/common/cpu/MOS6502.ts","../src/common/cpu/SM83.ts","../src/common/cpu/ZilogZ80.ts","../src/common/cpu/disasm6502.ts","../src/common/cpu/disasmHuC6280.ts","../src/common/cpu/disasmSM83.ts","../src/common/cpu/disasmz80.ts","../src/common/ecs/binpack.ts","../src/common/ecs/compiler.ts","../src/common/ecs/decoder.ts","../src/common/ecs/ecs.ts","../src/common/ecs/main.ts","../src/common/hdl/fuzz.ts","../src/common/hdl/hdlruntime.ts","../src/common/hdl/hdltypes.ts","../src/common/hdl/hdlwasm.ts","../src/common/hdl/vxmlparser.ts","../src/common/hdl/vxmltest.ts","../src/common/video/tms9918a.ts","../src/common/wasi/libretro.ts","../src/common/wasi/wasishim.ts","../src/ide/analytics.ts","../src/ide/dialogs.ts","../src/ide/embedui.ts","../src/ide/pixeleditor.ts","../src/ide/project.ts","../src/ide/services.ts","../src/ide/shareexport.ts","../src/ide/sync.ts","../src/ide/toolbar.ts","../src/ide/ui.ts","../src/ide/waveform.ts","../src/ide/windows.ts","../src/ide/views/asseteditor.ts","../src/ide/views/baseviews.ts","../src/ide/views/debug.ts","../src/ide/views/debugviews.ts","../src/ide/views/editors.ts","../src/ide/views/filters.ts","../src/ide/views/gutter.ts","../src/ide/views/tabs.ts","../src/ide/views/traceviews.ts","../src/ide/views/treeviews.ts","../src/ide/views/visuals.ts","../src/machine/apple2.ts","../src/machine/arm32.ts","../src/machine/astrocade.ts","../src/machine/atari7800.ts","../src/machine/atari8.ts","../src/machine/c64.ts","../src/machine/coleco.ts","../src/machine/cpc.ts","../src/machine/devel.ts","../src/machine/exidy.ts","../src/machine/galaxian.ts","../src/machine/gb.ts","../src/machine/kim1.ts","../src/machine/msx.ts","../src/machine/mw8080bw.ts","../src/machine/sms.ts","../src/machine/vdp_z80.ts","../src/machine/vic20.ts","../src/machine/vicdual.ts","../src/machine/williams.ts","../src/machine/zx.ts","../src/machine/chips/antic.ts","../src/machine/chips/gtia.ts","../src/machine/chips/pokey.ts","../src/parser/lang-6502.ts","../src/parser/lang-basic.ts","../src/parser/lang-bataribasic.ts","../src/parser/lang-fastbasic.ts","../src/parser/lang-inform6.ts","../src/parser/lang-verilog.ts","../src/parser/lang-wiz.ts","../src/parser/lang-z80.ts","../src/parser/tokens-6502.ts","../src/platform/_index.ts","../src/platform/apple2.ts","../src/platform/arm32.ts","../src/platform/astrocade.ts","../src/platform/atari7800.ts","../src/platform/atari8.ts","../src/platform/basic.ts","../src/platform/c64.ts","../src/platform/coleco.ts","../src/platform/cpc.ts","../src/platform/devel.ts","../src/platform/exidy.ts","../src/platform/galaxian.ts","../src/platform/gb.ts","../src/platform/kim1.ts","../src/platform/markdown.ts","../src/platform/msx.ts","../src/platform/mw8080bw.ts","../src/platform/nes.ts","../src/platform/pce.ts","../src/platform/sms.ts","../src/platform/sound_konami.ts","../src/platform/sound_williams.ts","../src/platform/vcs.ts","../src/platform/vector.ts","../src/platform/vectrex.ts","../src/platform/verilog.ts","../src/platform/vic20.ts","../src/platform/vicdual.ts","../src/platform/williams.ts","../src/platform/x86.ts","../src/platform/zmachine.ts","../src/platform/zx.ts","../src/themes/cobalt.ts","../src/themes/disassemblyTheme.ts","../src/themes/editorTheme.ts","../src/themes/mbo.ts","../src/tools/runmachine.ts","../src/tools/sim6502.ts","../src/worker/assembler.ts","../src/worker/builder.ts","../src/worker/listingutils.ts","../src/worker/platforms.ts","../src/worker/wasiutils.ts","../src/worker/wasmutils.ts","../src/worker/workermain.ts","../src/worker/workertools.ts","../src/worker/server/buildenv.ts","../src/worker/server/clang.ts","../src/worker/server/server.ts","../src/worker/tools/acme.ts","../src/worker/tools/arm.ts","../src/worker/tools/bataribasic.ts","../src/worker/tools/cc2600.ts","../src/worker/tools/cc65.ts","../src/worker/tools/cc7800.ts","../src/worker/tools/dasm.ts","../src/worker/tools/ecs.ts","../src/worker/tools/m6502.ts","../src/worker/tools/m6809.ts","../src/worker/tools/mcpp.ts","../src/worker/tools/misc.ts","../src/worker/tools/oscar64.ts","../src/worker/tools/remote.ts","../src/worker/tools/sdcc.ts","../src/worker/tools/verilog.ts","../src/worker/tools/x86.ts","../src/worker/tools/z80.ts"],"version":"5.9.3"}
|
||||
{"root":["../src/common/analysis.ts","../src/common/audio.ts","../src/common/baseplatform.ts","../src/common/binutils.ts","../src/common/devices.ts","../src/common/emu.ts","../src/common/mameplatform.ts","../src/common/probe.ts","../src/common/recorder.ts","../src/common/teletype.ts","../src/common/tokenizer.ts","../src/common/util.ts","../src/common/vlist.ts","../src/common/wasmplatform.ts","../src/common/workertypes.ts","../src/common/audio/CommodoreTape.ts","../src/common/basic/compiler.ts","../src/common/basic/fuzz.ts","../src/common/basic/run.ts","../src/common/basic/runtime.ts","../src/common/cpu/6809.ts","../src/common/cpu/ARM.ts","../src/common/cpu/MOS6502.ts","../src/common/cpu/SM83.ts","../src/common/cpu/ZilogZ80.ts","../src/common/cpu/disasm6502.ts","../src/common/cpu/disasmHuC6280.ts","../src/common/cpu/disasmSM83.ts","../src/common/cpu/disasmz80.ts","../src/common/ecs/binpack.ts","../src/common/ecs/compiler.ts","../src/common/ecs/decoder.ts","../src/common/ecs/ecs.ts","../src/common/ecs/main.ts","../src/common/hdl/fuzz.ts","../src/common/hdl/hdlruntime.ts","../src/common/hdl/hdltypes.ts","../src/common/hdl/hdlwasm.ts","../src/common/hdl/vxmlparser.ts","../src/common/hdl/vxmltest.ts","../src/common/video/tms9918a.ts","../src/common/wasi/libretro.ts","../src/common/wasi/wasishim.ts","../src/ide/analytics.ts","../src/ide/dialogs.ts","../src/ide/embedui.ts","../src/ide/pixeleditor.ts","../src/ide/project.ts","../src/ide/services.ts","../src/ide/shareexport.ts","../src/ide/sync.ts","../src/ide/toolbar.ts","../src/ide/ui.ts","../src/ide/waveform.ts","../src/ide/windows.ts","../src/ide/views/asseteditor.ts","../src/ide/views/baseviews.ts","../src/ide/views/debug.ts","../src/ide/views/debugviews.ts","../src/ide/views/editors.ts","../src/ide/views/filters.ts","../src/ide/views/gutter.ts","../src/ide/views/tabs.ts","../src/ide/views/traceviews.ts","../src/ide/views/treeviews.ts","../src/ide/views/visuals.ts","../src/machine/apple2.ts","../src/machine/arm32.ts","../src/machine/astrocade.ts","../src/machine/atari7800.ts","../src/machine/atari8.ts","../src/machine/c64.ts","../src/machine/coleco.ts","../src/machine/cpc.ts","../src/machine/devel.ts","../src/machine/exidy.ts","../src/machine/galaxian.ts","../src/machine/gb.ts","../src/machine/kim1.ts","../src/machine/msx.ts","../src/machine/mw8080bw.ts","../src/machine/sms.ts","../src/machine/vdp_z80.ts","../src/machine/vic20.ts","../src/machine/vicdual.ts","../src/machine/williams.ts","../src/machine/zx.ts","../src/machine/chips/antic.ts","../src/machine/chips/gtia.ts","../src/machine/chips/pokey.ts","../src/parser/lang-6502.ts","../src/parser/lang-basic.ts","../src/parser/lang-bataribasic.ts","../src/parser/lang-fastbasic.ts","../src/parser/lang-inform6.ts","../src/parser/lang-verilog.ts","../src/parser/lang-wiz.ts","../src/parser/lang-z80.ts","../src/parser/tokens-6502.ts","../src/platform/_index.ts","../src/platform/apple2.ts","../src/platform/arm32.ts","../src/platform/astrocade.ts","../src/platform/atari7800.ts","../src/platform/atari8.ts","../src/platform/basic.ts","../src/platform/c64.ts","../src/platform/coleco.ts","../src/platform/cpc.ts","../src/platform/devel.ts","../src/platform/exidy.ts","../src/platform/galaxian.ts","../src/platform/gb.ts","../src/platform/kim1.ts","../src/platform/markdown.ts","../src/platform/msx.ts","../src/platform/mw8080bw.ts","../src/platform/nes.ts","../src/platform/pce.ts","../src/platform/sms.ts","../src/platform/sound_konami.ts","../src/platform/sound_williams.ts","../src/platform/vcs.ts","../src/platform/vector.ts","../src/platform/vectrex.ts","../src/platform/verilog.ts","../src/platform/vic20.ts","../src/platform/vicdual.ts","../src/platform/williams.ts","../src/platform/x86.ts","../src/platform/zmachine.ts","../src/platform/zx.ts","../src/themes/cobalt.ts","../src/themes/disassemblyTheme.ts","../src/themes/editorTheme.ts","../src/themes/mbo.ts","../src/tools/8bws.ts","../src/tools/runmachine.ts","../src/tools/sim6502.ts","../src/tools/testlib.ts","../src/worker/assembler.ts","../src/worker/builder.ts","../src/worker/listingutils.ts","../src/worker/platforms.ts","../src/worker/wasiutils.ts","../src/worker/wasmutils.ts","../src/worker/workerlib.ts","../src/worker/workermain.ts","../src/worker/workertools.ts","../src/worker/server/buildenv.ts","../src/worker/server/clang.ts","../src/worker/server/server.ts","../src/worker/tools/acme.ts","../src/worker/tools/arm.ts","../src/worker/tools/bataribasic.ts","../src/worker/tools/cc2600.ts","../src/worker/tools/cc65.ts","../src/worker/tools/cc7800.ts","../src/worker/tools/dasm.ts","../src/worker/tools/ecs.ts","../src/worker/tools/m6502.ts","../src/worker/tools/m6809.ts","../src/worker/tools/mcpp.ts","../src/worker/tools/misc.ts","../src/worker/tools/oscar64.ts","../src/worker/tools/remote.ts","../src/worker/tools/sdcc.ts","../src/worker/tools/verilog.ts","../src/worker/tools/x86.ts","../src/worker/tools/z80.ts"],"version":"5.9.3"}
|
||||
@@ -0,0 +1,175 @@
|
||||
"use strict";
|
||||
// workerlib.ts - Node.js-friendly entry point for the worker build system
|
||||
// Re-exports core worker functionality without Web Worker onmessage/postMessage wiring
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TOOLS = exports.PLATFORM_PARAMS = exports.TOOL_PRELOADFS = exports.builder = exports.store = void 0;
|
||||
exports.setupNodeEnvironment = setupNodeEnvironment;
|
||||
exports.handleMessage = handleMessage;
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const util_1 = require("../common/util");
|
||||
const workertools_1 = require("./workertools");
|
||||
Object.defineProperty(exports, "TOOL_PRELOADFS", { enumerable: true, get: function () { return workertools_1.TOOL_PRELOADFS; } });
|
||||
const builder_1 = require("./builder");
|
||||
Object.defineProperty(exports, "store", { enumerable: true, get: function () { return builder_1.store; } });
|
||||
Object.defineProperty(exports, "builder", { enumerable: true, get: function () { return builder_1.builder; } });
|
||||
const wasmutils_1 = require("./wasmutils");
|
||||
const workermain_1 = require("./workermain");
|
||||
var platforms_1 = require("./platforms");
|
||||
Object.defineProperty(exports, "PLATFORM_PARAMS", { enumerable: true, get: function () { return platforms_1.PLATFORM_PARAMS; } });
|
||||
var workertools_2 = require("./workertools");
|
||||
Object.defineProperty(exports, "TOOLS", { enumerable: true, get: function () { return workertools_2.TOOLS; } });
|
||||
class Blob {
|
||||
constructor(data) {
|
||||
this.data = data;
|
||||
this.size = data.length;
|
||||
this.length = data.length;
|
||||
}
|
||||
slice(a, b) {
|
||||
return new Blob(this.data.slice(a, b));
|
||||
}
|
||||
arrayBuffer() {
|
||||
return this.asArrayBuffer();
|
||||
}
|
||||
asArrayBuffer() {
|
||||
var buf = new ArrayBuffer(this.data.length);
|
||||
var arr = new Uint8Array(buf);
|
||||
for (var i = 0; i < this.data.length; i++)
|
||||
arr[i] = this.data.charCodeAt(i);
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set up the Node.js environment to provide XMLHttpRequest, fetch, and other
|
||||
* browser globals that the worker build system expects.
|
||||
* Call this once before using handleMessage/builder.
|
||||
*/
|
||||
function setupNodeEnvironment() {
|
||||
// Basic globals expected by various parts of the worker system
|
||||
wasmutils_1.emglobal.window = wasmutils_1.emglobal;
|
||||
wasmutils_1.emglobal.exports = {};
|
||||
wasmutils_1.emglobal.self = wasmutils_1.emglobal;
|
||||
wasmutils_1.emglobal.location = { href: '.' };
|
||||
wasmutils_1.emglobal.path = path;
|
||||
wasmutils_1.emglobal.btoa = require('btoa');
|
||||
wasmutils_1.emglobal.atob = require('atob');
|
||||
try {
|
||||
wasmutils_1.emglobal.navigator = wasmutils_1.emglobal;
|
||||
}
|
||||
catch (e) { /* read-only in newer Node */ }
|
||||
wasmutils_1.emglobal.ResizeObserver = class {
|
||||
observe() { }
|
||||
};
|
||||
// XMLHttpRequest shim that reads from the local filesystem
|
||||
wasmutils_1.emglobal.XMLHttpRequest = function () {
|
||||
this.open = function (method, url, async) {
|
||||
if (this.responseType == 'json') {
|
||||
var txt = fs.readFileSync('src/worker/' + url, 'utf-8');
|
||||
this.response = JSON.parse(txt);
|
||||
}
|
||||
else if (this.responseType == 'blob') {
|
||||
var data = fs.readFileSync('src/worker/' + url, { encoding: 'binary' });
|
||||
this.response = new Blob(data);
|
||||
}
|
||||
else if (this.responseType == 'arraybuffer') {
|
||||
var data = fs.readFileSync('src/worker/' + url, { encoding: 'binary' });
|
||||
this.response = new Blob(data).asArrayBuffer();
|
||||
}
|
||||
this.status = this.response ? 200 : 404;
|
||||
};
|
||||
this.send = function () { };
|
||||
};
|
||||
// FileReaderSync shim
|
||||
wasmutils_1.emglobal.FileReaderSync = function () {
|
||||
this.readAsArrayBuffer = function (blob) {
|
||||
return blob.asArrayBuffer();
|
||||
};
|
||||
};
|
||||
// fetch shim that reads from the local filesystem
|
||||
wasmutils_1.emglobal.fetch = function (filepath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
var bin = fs.readFileSync(filepath, { encoding: 'binary' });
|
||||
var response = new Blob(bin);
|
||||
resolve(response);
|
||||
}
|
||||
catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
// importScripts shim - runs scripts in the global context like a web worker would.
|
||||
// In the web worker, importScripts loads relative to the worker bundle.
|
||||
// PWORKER is "../../src/worker/", so paths like "../../src/worker/asmjs/dasm.js"
|
||||
// need to be resolved to the actual file on disk.
|
||||
var vm = require('vm');
|
||||
wasmutils_1.emglobal.importScripts = function (scriptPath) {
|
||||
// Strip the PWORKER prefix and load from src/worker/
|
||||
var resolved = scriptPath.replace(/^\.\.\/\.\.\//, '');
|
||||
var fullPath = path.resolve(process.cwd(), resolved);
|
||||
var code = fs.readFileSync(fullPath, 'utf-8');
|
||||
vm.runInThisContext(code, fullPath);
|
||||
};
|
||||
// Suppress onmessage/postMessage (not used in Node mode)
|
||||
wasmutils_1.emglobal.onmessage = null;
|
||||
wasmutils_1.emglobal.postMessage = null;
|
||||
// Set up the require function for WASM modules
|
||||
(0, workermain_1.setupRequireFunction)();
|
||||
}
|
||||
/**
|
||||
* Handle a worker message (preload, reset, or build).
|
||||
* Same logic as workermain.ts handleMessage but exported for direct use.
|
||||
*/
|
||||
async function handleMessage(data) {
|
||||
// preload file system
|
||||
if (data.preload) {
|
||||
var fsName = workertools_1.TOOL_PRELOADFS[data.preload];
|
||||
if (!fsName && data.platform)
|
||||
fsName = workertools_1.TOOL_PRELOADFS[data.preload + '-' + (0, util_1.getBasePlatform)(data.platform)];
|
||||
if (!fsName && data.platform)
|
||||
fsName = workertools_1.TOOL_PRELOADFS[data.preload + '-' + (0, util_1.getRootBasePlatform)(data.platform)];
|
||||
if (fsName && !wasmutils_1.fsMeta[fsName])
|
||||
(0, wasmutils_1.loadFilesystem)(fsName);
|
||||
return;
|
||||
}
|
||||
// clear filesystem?
|
||||
if (data.reset) {
|
||||
builder_1.store.reset();
|
||||
return;
|
||||
}
|
||||
return builder_1.builder.handleMessage(data);
|
||||
}
|
||||
//# sourceMappingURL=workerlib.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"workerlib.js","sourceRoot":"","sources":["../../src/worker/workerlib.ts"],"names":[],"mappings":"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"}
|
||||
Generated
+3
@@ -30,6 +30,9 @@
|
||||
"octokat": "^0.10.0",
|
||||
"split.js": "^1.6.2"
|
||||
},
|
||||
"bin": {
|
||||
"8bws": "gen/cli/8bws.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lezer/generator": "^1.8.0",
|
||||
"@types/bootbox": "^5.1.3",
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
"url": "git+https://github.com/sehugg/8bitworkshop.git"
|
||||
},
|
||||
"license": "GPL-3.0",
|
||||
"bin": {
|
||||
"8bws": "./gen/cli/8bws.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/commands": "^6.10.2",
|
||||
"@codemirror/lang-cpp": "^6.0.3",
|
||||
@@ -88,6 +91,7 @@
|
||||
"fuzzbasic": "jsfuzz gen/common/basic/fuzz.js ~/basic/corpus/ --versifier false",
|
||||
"fuzzhdl": "jsfuzz -r binaryen gen/common/hdl/fuzz.js ~/verilator/corpus/ --versifier false",
|
||||
"machine": "node gen/tools/runmachine.js",
|
||||
"cli": "node gen/tools/8bws.js",
|
||||
"mkdoc": "typedoc --out web/jsdoc src/common/"
|
||||
},
|
||||
"keywords": [
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// 8bws - 8bitworkshop CLI tool for compilation, ROM execution, and platform info
|
||||
|
||||
import * as fs from 'fs';
|
||||
import { initialize, compile, compileSourceFile, preload, listTools, listPlatforms, PLATFORM_PARAMS, TOOLS, TOOL_PRELOADFS } from './testlib';
|
||||
|
||||
interface CLIResult {
|
||||
success: boolean;
|
||||
command: string;
|
||||
data?: any;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
function outputJSON(result: CLIResult): void {
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
}
|
||||
|
||||
function usage(): void {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: 'help',
|
||||
data: {
|
||||
commands: {
|
||||
'compile': 'compile --tool <tool> --platform <platform> [--output <file>] <source>',
|
||||
'check': 'check --tool <tool> --platform <platform> <source>',
|
||||
'run': 'run --platform <platform> [--frames N] <rom>',
|
||||
'list-tools': 'list-tools',
|
||||
'list-platforms': 'list-platforms',
|
||||
}
|
||||
},
|
||||
error: 'No command specified'
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function parseArgs(argv: string[]): { command: string; args: { [key: string]: string }; positional: string[] } {
|
||||
var command = argv[2];
|
||||
var args: { [key: string]: string } = {};
|
||||
var positional: string[] = [];
|
||||
|
||||
for (var i = 3; i < argv.length; i++) {
|
||||
if (argv[i].startsWith('--')) {
|
||||
var key = argv[i].substring(2);
|
||||
if (i + 1 < argv.length && !argv[i + 1].startsWith('--')) {
|
||||
args[key] = argv[++i];
|
||||
} else {
|
||||
args[key] = 'true';
|
||||
}
|
||||
} else {
|
||||
positional.push(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return { command, args, positional };
|
||||
}
|
||||
|
||||
async function doCompile(args: { [key: string]: string }, positional: string[], checkOnly: boolean): Promise<void> {
|
||||
var tool = args['tool'];
|
||||
var platform = args['platform'];
|
||||
var outputFile = args['output'];
|
||||
var sourceFile = positional[0];
|
||||
|
||||
if (!tool || !platform || !sourceFile) {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: checkOnly ? 'check' : 'compile',
|
||||
error: 'Required: --tool <tool> --platform <platform> <source>'
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!TOOLS[tool]) {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: checkOnly ? 'check' : 'compile',
|
||||
error: `Unknown tool: ${tool}. Use list-tools to see available tools.`
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Preload the tool's filesystem if needed
|
||||
var preloadKey = tool;
|
||||
if (TOOL_PRELOADFS[tool + '-' + platform]) {
|
||||
preloadKey = tool;
|
||||
}
|
||||
await preload(tool, platform);
|
||||
|
||||
var result = await compileSourceFile(tool, platform, sourceFile);
|
||||
|
||||
if (!result.success) {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: checkOnly ? 'check' : 'compile',
|
||||
data: { errors: result.errors }
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (checkOnly) {
|
||||
outputJSON({
|
||||
success: true,
|
||||
command: 'check',
|
||||
data: {
|
||||
tool: tool,
|
||||
platform: platform,
|
||||
source: sourceFile,
|
||||
outputSize: result.output ? (result.output.code ? result.output.code.length : result.output.length) : 0,
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Write output if requested
|
||||
if (outputFile && result.output) {
|
||||
var outData = result.output.code || result.output;
|
||||
if (outData instanceof Uint8Array) {
|
||||
fs.writeFileSync(outputFile, outData);
|
||||
} else if (typeof outData === 'object') {
|
||||
fs.writeFileSync(outputFile, JSON.stringify(outData));
|
||||
} else {
|
||||
fs.writeFileSync(outputFile, outData);
|
||||
}
|
||||
}
|
||||
|
||||
var outputSize = 0;
|
||||
if (result.output) {
|
||||
outputSize = result.output.code ? result.output.code.length : result.output.length;
|
||||
}
|
||||
|
||||
outputJSON({
|
||||
success: true,
|
||||
command: 'compile',
|
||||
data: {
|
||||
tool: tool,
|
||||
platform: platform,
|
||||
source: sourceFile,
|
||||
outputSize: outputSize,
|
||||
outputFile: outputFile || null,
|
||||
hasListings: result.listings ? Object.keys(result.listings).length > 0 : false,
|
||||
hasSymbolmap: !!result.symbolmap,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function doRun(args: { [key: string]: string }, positional: string[]): Promise<void> {
|
||||
var platform = args['platform'];
|
||||
var frames = parseInt(args['frames'] || '1');
|
||||
var romFile = positional[0];
|
||||
|
||||
if (!platform || !romFile) {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: 'run',
|
||||
error: 'Required: --platform <platform> <rom>'
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Dynamic import of MachineRunner
|
||||
try {
|
||||
var runmachine = require('./runmachine.js');
|
||||
var MachineRunner = runmachine.MachineRunner;
|
||||
} catch (e) {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: 'run',
|
||||
error: `Could not load MachineRunner: ${e.message}`
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: 'run',
|
||||
error: 'Run command not yet fully implemented (requires platform machine loading)'
|
||||
});
|
||||
}
|
||||
|
||||
function doListTools(): void {
|
||||
var tools = listTools();
|
||||
outputJSON({
|
||||
success: true,
|
||||
command: 'list-tools',
|
||||
data: {
|
||||
tools: tools,
|
||||
count: tools.length
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function doListPlatforms(): void {
|
||||
var platforms = listPlatforms();
|
||||
var details: { [key: string]: any } = {};
|
||||
for (var p of platforms) {
|
||||
details[p] = {
|
||||
arch: PLATFORM_PARAMS[p].arch || 'unknown',
|
||||
};
|
||||
}
|
||||
outputJSON({
|
||||
success: true,
|
||||
command: 'list-platforms',
|
||||
data: {
|
||||
platforms: details,
|
||||
count: platforms.length
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
if (process.argv.length < 3) {
|
||||
usage();
|
||||
}
|
||||
|
||||
var { command, args, positional } = parseArgs(process.argv);
|
||||
|
||||
try {
|
||||
switch (command) {
|
||||
case 'compile':
|
||||
await initialize();
|
||||
await doCompile(args, positional, false);
|
||||
break;
|
||||
case 'check':
|
||||
await initialize();
|
||||
await doCompile(args, positional, true);
|
||||
break;
|
||||
case 'run':
|
||||
await doRun(args, positional);
|
||||
break;
|
||||
case 'list-tools':
|
||||
await initialize();
|
||||
doListTools();
|
||||
break;
|
||||
case 'list-platforms':
|
||||
await initialize();
|
||||
doListPlatforms();
|
||||
break;
|
||||
default:
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: command,
|
||||
error: `Unknown command: ${command}`
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
} catch (e) {
|
||||
outputJSON({
|
||||
success: false,
|
||||
command: command,
|
||||
error: e.message || String(e)
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,195 @@
|
||||
|
||||
// testlib - Clean async API for compiling and testing 8bitworkshop projects
|
||||
// Wraps the worker build system for use in tests and CLI tools
|
||||
|
||||
import * as fs from 'fs';
|
||||
import type { WorkerResult, WorkerMessage, WorkerErrorResult, WorkerOutputResult } from "../common/workertypes";
|
||||
import { setupNodeEnvironment, handleMessage, store, TOOL_PRELOADFS } from "../worker/workerlib";
|
||||
import { PLATFORM_PARAMS } from "../worker/platforms";
|
||||
import { TOOLS } from "../worker/workertools";
|
||||
|
||||
export { store, TOOL_PRELOADFS, PLATFORM_PARAMS, TOOLS };
|
||||
|
||||
export interface CompileOptions {
|
||||
tool: string;
|
||||
platform: string;
|
||||
code?: string;
|
||||
path?: string;
|
||||
files?: { path: string; data: string | Uint8Array }[];
|
||||
buildsteps?: { path: string; platform: string; tool: string }[];
|
||||
mainfile?: boolean;
|
||||
}
|
||||
|
||||
export interface CompileResult {
|
||||
success: boolean;
|
||||
output?: Uint8Array | any;
|
||||
errors?: { line: number; msg: string; path?: string }[];
|
||||
listings?: any;
|
||||
symbolmap?: any;
|
||||
params?: any;
|
||||
unchanged?: boolean;
|
||||
}
|
||||
|
||||
let initialized = false;
|
||||
|
||||
/**
|
||||
* Initialize the Node.js environment for compilation.
|
||||
* Must be called once before any compile/preload calls.
|
||||
*/
|
||||
export async function initialize(): Promise<void> {
|
||||
if (initialized) return;
|
||||
setupNodeEnvironment();
|
||||
// The worker tools are already registered through the import chain:
|
||||
// workerlib -> workertools -> tools/* and builder -> TOOLS
|
||||
// No need to load the esbuild bundle.
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Preload a tool's filesystem (e.g. CC65 standard libraries).
|
||||
*/
|
||||
export async function preload(tool: string, platform?: string): Promise<void> {
|
||||
await initialize();
|
||||
var msg: WorkerMessage = { preload: tool } as any;
|
||||
if (platform) (msg as any).platform = platform;
|
||||
await handleMessage(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile source code with the specified tool and platform.
|
||||
*/
|
||||
export async function compile(options: CompileOptions): Promise<CompileResult> {
|
||||
await initialize();
|
||||
|
||||
// Reset the store for a clean build
|
||||
await handleMessage({ reset: true } as any);
|
||||
|
||||
let result: WorkerResult;
|
||||
|
||||
if (options.files && options.buildsteps) {
|
||||
// Multi-file build
|
||||
var msg: any = {
|
||||
updates: options.files.map(f => ({ path: f.path, data: f.data })),
|
||||
buildsteps: options.buildsteps
|
||||
};
|
||||
result = await handleMessage(msg);
|
||||
} else {
|
||||
// Single-file build
|
||||
var msg: any = {
|
||||
code: options.code,
|
||||
platform: options.platform,
|
||||
tool: options.tool,
|
||||
path: options.path || ('src.' + options.tool),
|
||||
mainfile: options.mainfile !== false
|
||||
};
|
||||
result = await handleMessage(msg);
|
||||
}
|
||||
|
||||
return workerResultToCompileResult(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a file from the presets directory.
|
||||
*/
|
||||
export async function compileFile(tool: string, platform: string, presetPath: string): Promise<CompileResult> {
|
||||
await initialize();
|
||||
|
||||
var code = fs.readFileSync('presets/' + platform + '/' + presetPath, 'utf-8');
|
||||
return compile({
|
||||
tool: tool,
|
||||
platform: platform,
|
||||
code: code,
|
||||
path: presetPath,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile an arbitrary source file path.
|
||||
*/
|
||||
export async function compileSourceFile(tool: string, platform: string, filePath: string): Promise<CompileResult> {
|
||||
await initialize();
|
||||
|
||||
var code = fs.readFileSync(filePath, 'utf-8');
|
||||
var basename = filePath.split('/').pop();
|
||||
return compile({
|
||||
tool: tool,
|
||||
platform: platform,
|
||||
code: code,
|
||||
path: basename,
|
||||
});
|
||||
}
|
||||
|
||||
function workerResultToCompileResult(result: WorkerResult): CompileResult {
|
||||
if (!result) {
|
||||
return { success: true, unchanged: true };
|
||||
}
|
||||
if ('unchanged' in result && result.unchanged) {
|
||||
return { success: true, unchanged: true };
|
||||
}
|
||||
if ('errors' in result && result.errors && result.errors.length > 0) {
|
||||
return {
|
||||
success: false,
|
||||
errors: result.errors,
|
||||
};
|
||||
}
|
||||
if ('output' in result) {
|
||||
return {
|
||||
success: true,
|
||||
output: result.output,
|
||||
listings: (result as any).listings,
|
||||
symbolmap: (result as any).symbolmap,
|
||||
params: (result as any).params,
|
||||
};
|
||||
}
|
||||
return { success: false, errors: [{ line: 0, msg: 'Unknown result format' }] };
|
||||
}
|
||||
|
||||
/**
|
||||
* List available compilation tools.
|
||||
*/
|
||||
export function listTools(): string[] {
|
||||
return Object.keys(TOOLS);
|
||||
}
|
||||
|
||||
/**
|
||||
* List available target platforms.
|
||||
*/
|
||||
export function listPlatforms(): string[] {
|
||||
return Object.keys(PLATFORM_PARAMS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a binary buffer to a hex string for display.
|
||||
*/
|
||||
export function ab2str(buf: Buffer | ArrayBuffer): string {
|
||||
return String.fromCharCode.apply(null, new Uint16Array(buf));
|
||||
}
|
||||
|
||||
// Platform test harness utilities
|
||||
|
||||
/**
|
||||
* Create a mock localStorage for tests that need it.
|
||||
*/
|
||||
export function createMockLocalStorage(): Storage {
|
||||
var items: { [key: string]: string } = {};
|
||||
return {
|
||||
get length() {
|
||||
return Object.keys(items).length;
|
||||
},
|
||||
clear() {
|
||||
items = {};
|
||||
},
|
||||
getItem(k: string) {
|
||||
return items[k] || null;
|
||||
},
|
||||
setItem(k: string, v: string) {
|
||||
items[k] = v;
|
||||
},
|
||||
removeItem(k: string) {
|
||||
delete items[k];
|
||||
},
|
||||
key(i: number) {
|
||||
return Object.keys(items)[i] || null;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
|
||||
// workerlib.ts - Node.js-friendly entry point for the worker build system
|
||||
// Re-exports core worker functionality without Web Worker onmessage/postMessage wiring
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import type { WorkerResult, WorkerMessage } from "../common/workertypes";
|
||||
import { getBasePlatform, getRootBasePlatform } from "../common/util";
|
||||
import { TOOL_PRELOADFS } from "./workertools";
|
||||
import { store, builder } from "./builder";
|
||||
import { emglobal, fsMeta, loadFilesystem } from "./wasmutils";
|
||||
import { setupRequireFunction } from "./workermain";
|
||||
|
||||
export { store, builder, TOOL_PRELOADFS };
|
||||
export { PLATFORM_PARAMS } from "./platforms";
|
||||
export { TOOLS } from "./workertools";
|
||||
|
||||
class Blob {
|
||||
private data: string;
|
||||
size: number;
|
||||
length: number;
|
||||
constructor(data: string) {
|
||||
this.data = data;
|
||||
this.size = data.length;
|
||||
this.length = data.length;
|
||||
}
|
||||
slice(a: number, b: number): Blob {
|
||||
return new Blob(this.data.slice(a, b));
|
||||
}
|
||||
arrayBuffer(): Uint8Array {
|
||||
return this.asArrayBuffer();
|
||||
}
|
||||
asArrayBuffer(): Uint8Array {
|
||||
var buf = new ArrayBuffer(this.data.length);
|
||||
var arr = new Uint8Array(buf);
|
||||
for (var i = 0; i < this.data.length; i++)
|
||||
arr[i] = this.data.charCodeAt(i);
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the Node.js environment to provide XMLHttpRequest, fetch, and other
|
||||
* browser globals that the worker build system expects.
|
||||
* Call this once before using handleMessage/builder.
|
||||
*/
|
||||
export function setupNodeEnvironment() {
|
||||
// Basic globals expected by various parts of the worker system
|
||||
emglobal.window = emglobal;
|
||||
emglobal.exports = {};
|
||||
emglobal.self = emglobal;
|
||||
emglobal.location = { href: '.' };
|
||||
emglobal.path = path;
|
||||
emglobal.btoa = require('btoa');
|
||||
emglobal.atob = require('atob');
|
||||
try { emglobal.navigator = emglobal; } catch (e) { /* read-only in newer Node */ }
|
||||
emglobal.ResizeObserver = class { observe() { } };
|
||||
|
||||
// XMLHttpRequest shim that reads from the local filesystem
|
||||
emglobal.XMLHttpRequest = function () {
|
||||
this.open = function (method: string, url: string, async?: boolean) {
|
||||
if (this.responseType == 'json') {
|
||||
var txt = fs.readFileSync('src/worker/' + url, 'utf-8');
|
||||
this.response = JSON.parse(txt);
|
||||
} else if (this.responseType == 'blob') {
|
||||
var data = fs.readFileSync('src/worker/' + url, { encoding: 'binary' });
|
||||
this.response = new Blob(data);
|
||||
} else if (this.responseType == 'arraybuffer') {
|
||||
var data = fs.readFileSync('src/worker/' + url, { encoding: 'binary' });
|
||||
this.response = new Blob(data).asArrayBuffer();
|
||||
}
|
||||
this.status = this.response ? 200 : 404;
|
||||
};
|
||||
this.send = function () { };
|
||||
};
|
||||
|
||||
// FileReaderSync shim
|
||||
emglobal.FileReaderSync = function () {
|
||||
this.readAsArrayBuffer = function (blob: any) {
|
||||
return blob.asArrayBuffer();
|
||||
};
|
||||
};
|
||||
|
||||
// fetch shim that reads from the local filesystem
|
||||
emglobal.fetch = function (filepath: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
var bin = fs.readFileSync(filepath, { encoding: 'binary' });
|
||||
var response = new Blob(bin);
|
||||
resolve(response);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// importScripts shim - runs scripts in the global context like a web worker would.
|
||||
// In the web worker, importScripts loads relative to the worker bundle.
|
||||
// PWORKER is "../../src/worker/", so paths like "../../src/worker/asmjs/dasm.js"
|
||||
// need to be resolved to the actual file on disk.
|
||||
var vm = require('vm');
|
||||
emglobal.importScripts = function (scriptPath: string) {
|
||||
// Strip the PWORKER prefix and load from src/worker/
|
||||
var resolved = scriptPath.replace(/^\.\.\/\.\.\//, '');
|
||||
var fullPath = path.resolve(process.cwd(), resolved);
|
||||
var code = fs.readFileSync(fullPath, 'utf-8');
|
||||
vm.runInThisContext(code, fullPath);
|
||||
};
|
||||
|
||||
// Suppress onmessage/postMessage (not used in Node mode)
|
||||
emglobal.onmessage = null;
|
||||
emglobal.postMessage = null;
|
||||
|
||||
// Set up the require function for WASM modules
|
||||
setupRequireFunction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a worker message (preload, reset, or build).
|
||||
* Same logic as workermain.ts handleMessage but exported for direct use.
|
||||
*/
|
||||
export async function handleMessage(data: WorkerMessage): Promise<WorkerResult> {
|
||||
// preload file system
|
||||
if (data.preload) {
|
||||
var fsName = TOOL_PRELOADFS[data.preload];
|
||||
if (!fsName && data.platform)
|
||||
fsName = TOOL_PRELOADFS[data.preload + '-' + getBasePlatform(data.platform)];
|
||||
if (!fsName && data.platform)
|
||||
fsName = TOOL_PRELOADFS[data.preload + '-' + getRootBasePlatform(data.platform)];
|
||||
if (fsName && !fsMeta[fsName])
|
||||
loadFilesystem(fsName);
|
||||
return;
|
||||
}
|
||||
// clear filesystem?
|
||||
if (data.reset) {
|
||||
store.reset();
|
||||
return;
|
||||
}
|
||||
return builder.handleMessage(data);
|
||||
}
|
||||
Reference in New Issue
Block a user