//@ts-check const { Lexer } = require('../lib/sheebr/lexer') const { getline } = require('../lib/sheebr/utils') const fs = require('fs') let environment = require('../lib/sheebr/environment') let aliases = require("../lib/sheebr/aliases") let { spawn } = require('child_process') //utiliser ce code au lieux de execSync permet d'afficher le stdout au fur et a mesure ce qui fait qu'on a les logs quand une application throw une erreur /** * @param { string } cmd * @param { import('child_process').SpawnOptionsWithoutStdio } [option] */ async function spawnAndWait(cmd, option) { const child = spawn(cmd, option) child.stdout.pipe(process.stdout) child.stderr.pipe(process.stderr) process.stdin.pipe(child.stdin) await new Promise((res, rej) => { child.on('exit', () => { res() }) }) process.stdin.unpipe(child.stdin) } let current_dir = process.cwd() start() async function start(){ while(true){ const input = await getline("sheebr> "); if(input === "exit") break; if(!input) continue; else await evaluate(input); } } /** * @param { string } input * @returns */ async function evaluate(input){ let lexer = new Lexer(input) let args = lexer.scanTokens() args = evaluateAliases(args) args = evaluateEnvironmentVariables(args); switch(args[0]){ case "cd": if(args.length != 2){ console.log("Wrong number of arguments"); return;} if(!fs.existsSync(args[1])){console.log("Folder does not exist"); return;} current_dir = args[1][0] == "/" ? args[1] : current_dir + '/' + args[1]; //console.log(current_dir) break; case "set": environment[args[1]] = args[2]; break; case "alias": if(args.length == 1) console.log(aliases); else if(args.length == 2){ console.error("Wrong number of argument") } else{ aliases[args[1]] = args[2].split(" ") } break; case "clear": console.clear(); break; default: await evaluateProgram(args) } } /** * @param {string[]} args */ async function evaluateProgram(args){ let found = false; for(let path of environment.path.split(':')){ let tobreak = false; const files = fs.readdirSync(path); if(files.includes(`${args[0]}.js`)){ found = true; try { await spawnAndWait(`${environment.node} ${path + '/' + args[0]}.js ${args.map(arg => {return arg.includes(' ') ? `"${arg}"` : arg}).join(' ')}`, {cwd: current_dir, env: environment, shell: true}); tobreak = true; } catch(e) { console.log("Program crashed") } } if(tobreak) break; } if(!found){ console.log("Program not found") } } /** * @param {string[]} args * @returns */ function evaluateEnvironmentVariables(args){ let newArgs = [] for(let arg of args){ if(arg.startsWith('$')){ if (arg.slice(1) in environment) newArgs.push(JSON.stringify(environment[arg.slice(1)])); else console.error(`variable ${arg.slice(1)} does not exist.`); } else{ newArgs.push(arg) } } return newArgs; } /** * @param { string[] } args * @returns */ function evaluateAliases(args){ if(args[0] in aliases){ return aliases[args[0]].concat(args.slice(1)) } return args; }