Files
tsvm/assets/tvdos/command.js
minjaesong a2e74313a1 cmd parser
2020-11-01 18:41:39 +09:00

171 lines
4.4 KiB
JavaScript

let PROMPT_TEXT = ">";
let CURRENT_DRIVE = "A";
let shell_pwd = [""];
const welcome_text = "TSVM Disk Operating System, version " + _TVDOS.VERSION;
function get_prompt_text() {
return CURRENT_DRIVE + ":\\" + shell_pwd.join("\\") + PROMPT_TEXT;
}
function greet() {
println(welcome_text);
println();
}
let shell = {};
// example input: echo "the string" > subdir\test.txt
shell.parse = function(input) {
let tokens = [];
let stringBuffer = "";
let mode = "LITERAL"; // LITERAL, QUOTE, ESCAPE, LIMBO
let i = 0
while (i < input.length) {
const c = input[i];
/*digraph g {
LITERAL -> QUOTE [label="\""]
LITERAL -> LIMBO [label="space"]
LITERAL -> LITERAL [label=else]
QUOTE -> LIMBO [label="\""]
QUOTE -> ESCAPE [label="\\"]
QUOTE -> QUOTE [label=else]
ESCAPE -> QUOTE
LIMBO -> LITERAL [label="not space"]
LIMBO -> QUOTE [label="\""]
LIMBO -> LIMBO [label="space"]
}*/
if (mode == "LITERAL") {
if (c == ' ') {
tokens.push(stringBuffer); stringBuffer = "";
mode = "LIMBO";
}
else if (c == '"') {
tokens.push(stringBuffer); stringBuffer = "";
mode = "QUOTE";
}
else {
stringBuffer += c;
}
}
else if (mode == "LIMBO") {
if (c == '"') {
mode = "QUOTE";
}
else if (c != ' ') {
mode = "LITERAL";
stringBuffer += c;
}
}
else if (mode == "QUOTE") {
if (c == '"') {
tokens.push(stringBuffer); stringBuffer = "";
mode = "LIMBO";
}
else if (c == '\\') {
mode = "ESCAPE";
}
else {
stringBuffer += c;
}
}
else if (mode == "ESCAPE") {
}
i += 1;
}
if (stringBuffer.length > 0) {
tokens.push(stringBuffer);
}
return tokens;
}
if (exec_args !== undefined) return shell;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
println("Starting TVDOS...");
greet();
let cmdHistory = []; // zeroth element is the oldest
let cmdHistoryScroll = 0; // 0 for outside-of-buffer, 1 for most recent
while (true) {
print(get_prompt_text());
let cmdbuf = "";
while (true) {
let key = con.getch();
// printable chars
if (key >= 32 && key <= 126) {
let s = String.fromCharCode(key);
cmdbuf += s;
print(s);
}
// backspace
else if (key === 8 && cmdbuf.length > 0) {
cmdbuf = cmdbuf.substring(0, cmdbuf.length - 1);
print(String.fromCharCode(key));
}
// enter
else if (key === 10 || key === 13) {
println();
try {
let tokens = shell.parse(cmdbuf);
tokens.forEach(function(it) { println(it+"_"); });
}
catch (e) {
printerrln(e);
}
finally {
if (cmdbuf.trim().length > 0)
cmdHistory.push(cmdbuf);
cmdHistoryScroll = 0;
break;
}
}
// up arrow
else if (key === 19 && cmdHistory.length > 0 && cmdHistoryScroll < cmdHistory.length) {
cmdHistoryScroll += 1;
// back the cursor in order to type new cmd
let x = 0;
for (x = 0; x < cmdbuf.length; x++) print(String.fromCharCode(8));
cmdbuf = cmdHistory[cmdHistory.length - cmdHistoryScroll];
// re-type the new command
print(cmdbuf);
}
// down arrow
else if (key === 20) {
if (cmdHistoryScroll > 0) {
// back the cursor in order to type new cmd
let x = 0;
for (x = 0; x < cmdbuf.length; x++) print(String.fromCharCode(8));
cmdbuf = cmdHistory[cmdHistory.length - cmdHistoryScroll];
// re-type the new command
print(cmdbuf);
cmdHistoryScroll -= 1;
}
else {
// back the cursor in order to type new cmd
let x = 0;
for (x = 0; x < cmdbuf.length; x++) print(String.fromCharCode(8));
cmdbuf = "";
}
}
}
}
return 0;