Files
Linux.js---javascript-OS/rootfs overrides/usr/bin/sheebr.js
T
2022-02-08 13:35:49 +01:00

136 lines
3.6 KiB
JavaScript

//@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;
}