mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
241 lines
7.0 KiB
JavaScript
241 lines
7.0 KiB
JavaScript
var vmemsize = 60300;
|
|
var vmemused = 0;
|
|
var cmdbuf = []; // index: line number
|
|
var prompt = "Ok";
|
|
|
|
var lang = {
|
|
syntaxfehler: "Syntax error"
|
|
};
|
|
|
|
var reLineNum = /^[0-9]+ +[^0-9]/;
|
|
var reFloat = /^([\-+]?[0-9]*[.][0-9]+[eE]*[\-+0-9]*[fF]*|[\-+]?[0-9]+[.eEfF][0-9+\-]*[fF]?)$/;
|
|
var reDec = /^([\-+]?[0-9_]+)$/;
|
|
var reHex = /^(0[Xx][0-9A-Fa-f_]+?)$/;
|
|
var reBin = /(0[Bb][01_]+)$/;
|
|
var reBool = /true|false/;
|
|
|
|
var charsetNum = /[0-9]+/;
|
|
var charsetNumMeta = /[.BbFfXx_]/;
|
|
var charsetOp = /[()\/|&,]+/;
|
|
var tbasexit = false;
|
|
|
|
println("Terran BASIC 1.0 "+vmemsize+" bytes free");
|
|
println(prompt);
|
|
|
|
var basicFunctions = new Object();
|
|
basicFunctions._isNumber = function(code) {
|
|
|
|
};
|
|
basicFunctions._isOperator = function(code) {
|
|
|
|
};
|
|
// @returns: line number for the next command, normally (lnum + 1); if GOTO or GOSUB was met, returns its line number
|
|
basicFunctions._interpretLine = function(lnum, cmd) {
|
|
var tokens = [];
|
|
var sb = "";
|
|
var mode = "literal"; // literal, escape, number, quote, quote_end, operator, limbo
|
|
|
|
// TOKENISE
|
|
for (var k = 0; k < cmd.length; k++) {
|
|
var char = cmd.charAt(k);
|
|
var charCode = cmd.charCodeAt(k);
|
|
|
|
if (mode == "literal") {
|
|
if (charCode == 0x22) { // "
|
|
tokens.push(sb); sb = "";
|
|
mode = "quote";
|
|
}
|
|
/*else if (charCode == 0x5C) { // reverse solidus
|
|
tokens.push(sb); sb = "";
|
|
mode = "escape";
|
|
}*/
|
|
else if (basicFunctions._isOperator(charCode)) {
|
|
tokens.push(sb); sb = "" + char;
|
|
mode = "operator";
|
|
}
|
|
else if (char == " ") {
|
|
tokens.push(sb); sb = "";
|
|
mode = "limbo";
|
|
}
|
|
else {
|
|
sb += char;
|
|
}
|
|
}
|
|
else if (mode == "escape") {
|
|
if (charCode == 0x5C) // reverse solidus
|
|
sb += String.fromCharCode(0x5C);
|
|
else if (char == "n")
|
|
sb += String.fromCharCode(0x0A);
|
|
else if (char == "t")
|
|
sb += String.fromCharCode(0x09);
|
|
else if (charCode == 0x22) // "
|
|
sb += String.fromCharCode(0x22);
|
|
else if (charCode == 0x27)
|
|
sb += String.fromCharCode(0x27);
|
|
else if (char == "e")
|
|
sb += String.fromCharCode(0x1B);
|
|
else if (char == "a")
|
|
sb += String.fromCharCode(0x07);
|
|
else if (char == "b")
|
|
sb += String.fromCharCode(0x08);
|
|
mode = "quote"; // ESCAPE is only legal when used inside of quote
|
|
}
|
|
else if (mode == "quote") {
|
|
if (charCode = 0x22) {
|
|
tokens.push(sb); sb = "";
|
|
mode = "quote_end";
|
|
}
|
|
else {
|
|
sb += char;
|
|
}
|
|
}
|
|
else if (mode == "quote_end") {
|
|
if (basicFunctions._isNumber(charCode)) {
|
|
mode = "number";
|
|
}
|
|
else if (basicFunctions._isOperator(charCode)) {
|
|
mode = "operator";
|
|
}
|
|
else {
|
|
mode = "limbo";
|
|
}
|
|
}
|
|
else if (mode == "number") {
|
|
if (basicFunctions._isNumber(charCode)) {
|
|
sb += char;
|
|
}
|
|
else if (char == " ") {
|
|
tokens.push(sb); sb = "";
|
|
mode = "limbo";
|
|
}
|
|
else if (basicFunctions._isOperator(charCode)) {
|
|
tokens.push(sb); sb = "" + char;
|
|
mode = "operator";
|
|
}
|
|
else if (charCode == 0x22) {
|
|
tokens.push(sb); sb = "" + char;
|
|
mode = "quote";
|
|
}
|
|
else {
|
|
tokens.push(sb); sb = "" + char;
|
|
mode = "literal";
|
|
}
|
|
}
|
|
else if (mode == "operator") {
|
|
if (basicFunctions._isOperator(charCode)) {
|
|
sb += char;
|
|
}
|
|
else if (basicFunctions._isNumber(charCode)) {
|
|
tokens.push(sb); sb = "" + char;
|
|
mode = "number";
|
|
}
|
|
else if (char == " ") {
|
|
tokens.push(sb); sb = "";
|
|
mode = "limbo";
|
|
}
|
|
else {
|
|
tokens.push(sb); sb = "" + char;
|
|
mode = "lteral";
|
|
}
|
|
}
|
|
else if (mode == "limbo") {
|
|
if (char == " ") {
|
|
/* do nothing */
|
|
}
|
|
else if (basicFunctions._isNumber(charCode)) {
|
|
sb = "" + char;
|
|
mode = "number"
|
|
}
|
|
else if (basicFunctions._isOperator(charCode)) {
|
|
sb = "" + char;
|
|
mode = "operator"
|
|
}
|
|
else if (charCode == 0x22) {
|
|
sb = "" + char;
|
|
mode = "quote"
|
|
}
|
|
else {
|
|
sb = "" + char;
|
|
mode = "literal";
|
|
}
|
|
}
|
|
else {
|
|
throw "Unknown parser state: " + mode;
|
|
}
|
|
}
|
|
// END TOKENISE
|
|
|
|
println(tokens);
|
|
|
|
return lnum + 1;
|
|
};
|
|
basicFunctions._basicList = function(v, i, arr) {
|
|
if (i < 10) print(" ");
|
|
if (i < 100) print(" ");
|
|
print(i);
|
|
print(" ");
|
|
println(v);
|
|
};
|
|
basicFunctions.list = function(args) { // LIST function
|
|
if (args.length == 1) {
|
|
cmdbuf.forEach(basicFunctions._basicList);
|
|
}
|
|
else if (args.length == 2) {
|
|
if (typeof cmdbuf[args[1]] != "undefined")
|
|
basicFunctions._basicList(cmdbuf[args[1]], args[1], undefined);
|
|
}
|
|
else {
|
|
var lastIndex = (args[2] === ".") ? cmdbuf.length - 1 : (args[2] | 0);
|
|
var i = 0;
|
|
for (i = args[1]; i <= lastIndex; i++) {
|
|
var cmd = cmdbuf[i];
|
|
if (typeof cmd != "undefined") {
|
|
basicFunctions._basicList(cmd, i, cmdbuf);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
basicFunctions.system = function(args) { // SYSTEM function
|
|
tbasexit = true;
|
|
};
|
|
basicFunctions.new = function(args) { // NEW function
|
|
cmdbuf = [];
|
|
};
|
|
basicFunctions.run = function(args) { // RUN function
|
|
var linenumber = 1;
|
|
var oldnum = 1;
|
|
do {
|
|
if (typeof cmd != "undefined") {
|
|
oldnum = linenumber;
|
|
linenumber = basicFunctions._interpretLine(linenumber, cmdbuf[linenumber]);
|
|
}
|
|
else {
|
|
linenumber += 1;
|
|
}
|
|
if (con.hitterminate) {
|
|
println("Break in "+oldlnum);
|
|
break;
|
|
}
|
|
} while (linenumber < cmdbuf.length)
|
|
};
|
|
Object.freeze(basicFunctions);
|
|
while (!tbasexit) {
|
|
var line = vm.read();
|
|
line = line.trim();
|
|
|
|
if (reLineNum.test(line)) {
|
|
var i = line.indexOf(" ");
|
|
cmdbuf[line.slice(0, i)] = line.slice(i + 1, line.length);
|
|
}
|
|
else if (line.length > 0) {
|
|
try {
|
|
var cmd = line.split(" ");
|
|
basicFunctions[cmd[0]](cmd);
|
|
}
|
|
catch (e) {
|
|
println(e);
|
|
println(lang.syntaxfehler);
|
|
}
|
|
println(prompt);
|
|
}
|
|
} |