57 lines
1.6 KiB
TypeScript
57 lines
1.6 KiB
TypeScript
/**
|
|
* mutate-cli.ts — CLI wrapper for Push3 mutation operators.
|
|
*
|
|
* Commands:
|
|
* mutate <push3file> <rate> Apply `rate` random mutations.
|
|
* crossover <push3file1> <push3file2> Single-point crossover of two programs.
|
|
*
|
|
* Outputs the resulting Push3 program text to stdout.
|
|
* Exits 1 on invalid input or mutation failure.
|
|
*/
|
|
|
|
import { readFileSync } from 'fs';
|
|
import { parse } from '../push3-transpiler/src/parser';
|
|
import { mutate, crossover, serialize } from './mutate';
|
|
|
|
function loadProgram(filePath: string) {
|
|
const src = readFileSync(filePath, 'utf8');
|
|
return parse(src);
|
|
}
|
|
|
|
const [, , cmd, ...args] = process.argv;
|
|
|
|
switch (cmd) {
|
|
case 'mutate': {
|
|
const [file, rateStr] = args;
|
|
if (!file || !rateStr) {
|
|
process.stderr.write('Usage: mutate-cli mutate <push3file> <rate>\n');
|
|
process.exit(1);
|
|
}
|
|
const rate = parseInt(rateStr, 10);
|
|
if (isNaN(rate) || rate < 0) {
|
|
process.stderr.write(`Invalid rate: ${rateStr}\n`);
|
|
process.exit(1);
|
|
}
|
|
const program = loadProgram(file);
|
|
const mutated = mutate(program, rate);
|
|
process.stdout.write(serialize(mutated) + '\n');
|
|
break;
|
|
}
|
|
|
|
case 'crossover': {
|
|
const [file1, file2] = args;
|
|
if (!file1 || !file2) {
|
|
process.stderr.write('Usage: mutate-cli crossover <push3file1> <push3file2>\n');
|
|
process.exit(1);
|
|
}
|
|
const a = loadProgram(file1);
|
|
const b = loadProgram(file2);
|
|
const crossed = crossover(a, b);
|
|
process.stdout.write(serialize(crossed) + '\n');
|
|
break;
|
|
}
|
|
|
|
default:
|
|
process.stderr.write(`Unknown command: ${cmd}\nCommands: mutate, crossover\n`);
|
|
process.exit(1);
|
|
}
|