yip-core
Version:
basic acces tp the yip (yet-interpreted-programming) c & dr models (Yip compiler & direct-runner)
171 lines (138 loc) ⢠4.63 kB
JavaScript
const fs = require('fs');
const path = require('path');
const { Yip, YipError, YipTokenizer } = require('./yip');
const configPath = path.resolve('.yipconfig.js');
// Make sure the config exists
if (!fs.existsSync(configPath)) {
console.error(`ā Missing .yipconfig.js in current directory.`);
process.exit(1);
}
const baseInstance = require(configPath);
// Grab arguments and flags
let args = process.argv.slice(2);
const hasFebug = args.includes('--febug');
args = args.filter(arg => arg !== '--febug');
const [command, input, output] = args;
const readline = require('readline');
if (!command || command === 'repl') {
console.log('\x1b[1m\x1b[34mYip REPL Mode\x1b[0m ā type `.exit` to quit');
console.log(hasFebug ? '\x1b[35m[REPL Febug Active]\x1b[0m š' : '');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: '\x1b[32mYip> \x1b[0m',
});
rl.prompt();
rl.on('line', (line) => {
if (line.trim() === '.exit') {
rl.close();
return;
}
if (line.trim() === '.help') {
const tokens = new YipTokenizer().tokenize(''); // dummy to construct
const y = new Yip(tokens, 0, '');
Object.assign(y.commands, baseInstance.commands);
Object.assign(y.compiledCommands, baseInstance.compiledCommands);
Object.assign(y.commandMeta, baseInstance.commandMeta);
Object.assign(y.macros, baseInstance.macros);
y.helpMenu();
rl.prompt();
return;
}
const code = line.replace(/\n/g, ' ');
const tokens = new YipTokenizer().tokenize(code);
const y = new Yip(tokens, 0, code);
Object.assign(y.commands, baseInstance.commands);
Object.assign(y.compiledCommands, baseInstance.compiledCommands);
Object.assign(y.commandMeta, baseInstance.commandMeta);
Object.assign(y.macros, baseInstance.macros);
try {
if (!y.validate()) {
console.warn('ā ļø Validation issues detected.');
rl.prompt();
return;
}
if (hasFebug) {
console.log('š¦ Tokens:', tokens);
}
y.runBasedOnCommands();
} catch (err) {
console.error('\x1b[31mError:\x1b[0m', err instanceof YipError ? err.toString() : err.message);
}
rl.prompt();
});
rl.on('close', () => {
console.log('\nš Exiting REPL. Goodbye.');
process.exit(0);
});
return;
}
if (!['run', 'compile', 'repl'].includes(command)) {
console.log(`
\x1b[1m\x1b[34mYip CLI ā Minimal DSL Executor\x1b[0m
\x1b[33mUsage:\x1b[0m
yip repl
yip run <input.yip> [--febug]
yip compile <input.yip> <output.js> [--febug]
\x1b[33mFlags:\x1b[0m
--febug Print tokens, macros, compiled output, and other juicy debug info
Make sure .yipconfig.js exports a pre-configured Yip instance.
`);
process.exit(0);
}
// Read code
if (!input || !fs.existsSync(input)) {
console.error(`ā Input file '${input}' does not exist.`);
process.exit(1);
}
const inputCode = fs.readFileSync(input, 'utf8');
const tokens = new YipTokenizer().tokenize(inputCode.replace(/\n/g, ' '));
// Create a fresh instance and inherit from baseInstance
const y = new Yip(tokens, 0, inputCode);
Object.assign(y.commands, baseInstance.commands);
Object.assign(y.compiledCommands, baseInstance.compiledCommands);
Object.assign(y.commandMeta, baseInstance.commandMeta);
Object.assign(y.macros, baseInstance.macros);
// Febug diagnostics
if (hasFebug) {
console.log('\x1b[35m[Febug Mode Active]\x1b[0m šš');
console.log('š¦ Tokens:', tokens);
console.log('š ļø Commands:', Object.keys(y.commands));
console.log('š§± Compilers:', Object.keys(y.compiledCommands));
console.log('š Macros:', Object.keys(y.macros));
console.log('');
}
// Handle run
if (command === 'run') {
if (hasFebug) console.log('\x1b[36m[Running with execution engine...]\x1b[0m');
try {
y.validate();
y.runBasedOnCommands();
} catch (err) {
console.error('\x1b[31mExecution failed:\x1b[0m', err.message);
process.exit(1);
}
}
// Handle compile
else if (command === 'compile') {
if (!output) {
console.error(`ā Output file not specified for compilation.`);
process.exit(1);
}
try {
if (!y.validate()) {
console.error("ā ļø Validation failed. Compilation aborted.");
process.exit(1);
}
y.compile();
if (hasFebug) {
console.log('\x1b[36m[Compiled Output]\x1b[0m:\n' + y.getCompiled());
}
fs.writeFileSync(output, y.getCompiled());
console.log(`ā
Compiled to ${output}`);
} catch (err) {
console.error('\x1b[31mCompilation failed:\x1b[0m', err.message);
process.exit(1);
}
}