basic renum function

This commit is contained in:
minjaesong
2020-06-01 04:55:49 +09:00
parent ad830866be
commit 1e0f122aff
2 changed files with 70 additions and 34 deletions

View File

@@ -1,4 +1,8 @@
var vmemsize = 60300; /*
NOTE: do not allow concatenation of commands!
*/
var vmemsize = sys.maxmem() - 5236;
var vmemused = 0; var vmemused = 0;
var cmdbuf = []; // index: line number var cmdbuf = []; // index: line number
var prompt = "Ok"; var prompt = "Ok";
@@ -14,7 +18,7 @@ var reHex = /^(0[Xx][0-9A-Fa-f_]+?)$/;
var reBin = /(0[Bb][01_]+)$/; var reBin = /(0[Bb][01_]+)$/;
var reBool = /true|false/; var reBool = /true|false/;
var charsetNum = /[0-9]+/; var reNum = /[0-9]+/;
var charsetNumMeta = /[.BbFfXx_]/; var charsetNumMeta = /[.BbFfXx_]/;
var charsetOp = /[()\/|&,]+/; var charsetOp = /[()\/|&,]+/;
var tbasexit = false; var tbasexit = false;
@@ -24,24 +28,29 @@ println(prompt);
var basicFunctions = new Object(); var basicFunctions = new Object();
basicFunctions._isNumber = function(code) { basicFunctions._isNumber = function(code) {
return (code >= 0x30 && code <= 0x39) || code == 0x2E;
}; };
basicFunctions._isOperator = function(code) { basicFunctions._isOperator = function(code) {
return (code == 0x21 || code == 0x23 || code == 0x25 || (code >= 0x2A && code <= 0x2D) || code == 0x2F || (code >= 0x3A && code <= 0x3E) || code == 0x5E || code == 0x7C);
}; };
// @returns: line number for the next command, normally (lnum + 1); if GOTO or GOSUB was met, returns its line number // @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) { basicFunctions._interpretLine = function(lnum, cmd) {
var _debugprintStateTransition = false;
var tokens = []; var tokens = [];
var sb = ""; var sb = "";
var mode = "literal"; // literal, escape, number, quote, quote_end, operator, limbo var mode = "literal"; // literal, escape, number, quote, quote_end, operator, limbo
if (_debugprintStateTransition) println("Ln "+lnum+" cmd "+cmd);
// TOKENISE // TOKENISE
for (var k = 0; k < cmd.length; k++) { for (var k = 0; k < cmd.length; k++) {
var char = cmd.charAt(k); var char = cmd.charAt(k);
var charCode = cmd.charCodeAt(k); var charCode = cmd.charCodeAt(k);
if (_debugprintStateTransition) print("Char: "+char+"("+charCode+"), state: "+mode);
if (mode == "literal") { if (mode == "literal") {
if (charCode == 0x22) { // " if (0x22 == charCode) { // "
tokens.push(sb); sb = ""; tokens.push(sb); sb = "";
mode = "quote"; mode = "quote";
} }
@@ -53,7 +62,7 @@ basicFunctions._interpretLine = function(lnum, cmd) {
tokens.push(sb); sb = "" + char; tokens.push(sb); sb = "" + char;
mode = "operator"; mode = "operator";
} }
else if (char == " ") { else if (" " == char) {
tokens.push(sb); sb = ""; tokens.push(sb); sb = "";
mode = "limbo"; mode = "limbo";
} }
@@ -61,27 +70,27 @@ basicFunctions._interpretLine = function(lnum, cmd) {
sb += char; sb += char;
} }
} }
else if (mode == "escape") { else if ("escape" == mode) {
if (charCode == 0x5C) // reverse solidus if (0x5C == charCode) // reverse solidus
sb += String.fromCharCode(0x5C); sb += String.fromCharCode(0x5C);
else if (char == "n") else if ("n" == char)
sb += String.fromCharCode(0x0A); sb += String.fromCharCode(0x0A);
else if (char == "t") else if ("t" == char)
sb += String.fromCharCode(0x09); sb += String.fromCharCode(0x09);
else if (charCode == 0x22) // " else if (0x22 == charCode) // "
sb += String.fromCharCode(0x22); sb += String.fromCharCode(0x22);
else if (charCode == 0x27) else if (0x27 == charCode)
sb += String.fromCharCode(0x27); sb += String.fromCharCode(0x27);
else if (char == "e") else if ("e" == char)
sb += String.fromCharCode(0x1B); sb += String.fromCharCode(0x1B);
else if (char == "a") else if ("a" == char)
sb += String.fromCharCode(0x07); sb += String.fromCharCode(0x07);
else if (char == "b") else if ("b" == char)
sb += String.fromCharCode(0x08); sb += String.fromCharCode(0x08);
mode = "quote"; // ESCAPE is only legal when used inside of quote mode = "quote"; // ESCAPE is only legal when used inside of quote
} }
else if (mode == "quote") { else if ("quote" == mode) {
if (charCode = 0x22) { if (0x22 == charCode) {
tokens.push(sb); sb = ""; tokens.push(sb); sb = "";
mode = "quote_end"; mode = "quote_end";
} }
@@ -89,7 +98,7 @@ basicFunctions._interpretLine = function(lnum, cmd) {
sb += char; sb += char;
} }
} }
else if (mode == "quote_end") { else if ("quote_end" == mode) {
if (basicFunctions._isNumber(charCode)) { if (basicFunctions._isNumber(charCode)) {
mode = "number"; mode = "number";
} }
@@ -100,11 +109,11 @@ basicFunctions._interpretLine = function(lnum, cmd) {
mode = "limbo"; mode = "limbo";
} }
} }
else if (mode == "number") { else if ("number" == mode) {
if (basicFunctions._isNumber(charCode)) { if (basicFunctions._isNumber(charCode)) {
sb += char; sb += char;
} }
else if (char == " ") { else if (" " == char) {
tokens.push(sb); sb = ""; tokens.push(sb); sb = "";
mode = "limbo"; mode = "limbo";
} }
@@ -112,7 +121,7 @@ basicFunctions._interpretLine = function(lnum, cmd) {
tokens.push(sb); sb = "" + char; tokens.push(sb); sb = "" + char;
mode = "operator"; mode = "operator";
} }
else if (charCode == 0x22) { else if (0x22 == charCode) {
tokens.push(sb); sb = "" + char; tokens.push(sb); sb = "" + char;
mode = "quote"; mode = "quote";
} }
@@ -121,7 +130,7 @@ basicFunctions._interpretLine = function(lnum, cmd) {
mode = "literal"; mode = "literal";
} }
} }
else if (mode == "operator") { else if ("operator" == mode) {
if (basicFunctions._isOperator(charCode)) { if (basicFunctions._isOperator(charCode)) {
sb += char; sb += char;
} }
@@ -129,7 +138,7 @@ basicFunctions._interpretLine = function(lnum, cmd) {
tokens.push(sb); sb = "" + char; tokens.push(sb); sb = "" + char;
mode = "number"; mode = "number";
} }
else if (char == " ") { else if (" " == char) {
tokens.push(sb); sb = ""; tokens.push(sb); sb = "";
mode = "limbo"; mode = "limbo";
} }
@@ -138,7 +147,7 @@ basicFunctions._interpretLine = function(lnum, cmd) {
mode = "lteral"; mode = "lteral";
} }
} }
else if (mode == "limbo") { else if ("limbo" == mode) {
if (char == " ") { if (char == " ") {
/* do nothing */ /* do nothing */
} }
@@ -150,8 +159,8 @@ basicFunctions._interpretLine = function(lnum, cmd) {
sb = "" + char; sb = "" + char;
mode = "operator" mode = "operator"
} }
else if (charCode == 0x22) { else if (0x22 == charCode) {
sb = "" + char; sb = "";
mode = "quote" mode = "quote"
} }
else { else {
@@ -162,10 +171,17 @@ basicFunctions._interpretLine = function(lnum, cmd) {
else { else {
throw "Unknown parser state: " + mode; throw "Unknown parser state: " + mode;
} }
if (_debugprintStateTransition) println("->"+mode);
} }
if (sb.length > 0) {
tokens.push(sb);
}
// END TOKENISE // END TOKENISE
println(tokens); println(tokens.join("|"));
return lnum + 1; return lnum + 1;
}; };
@@ -201,19 +217,41 @@ basicFunctions.system = function(args) { // SYSTEM function
basicFunctions.new = function(args) { // NEW function basicFunctions.new = function(args) { // NEW function
cmdbuf = []; cmdbuf = [];
}; };
basicFunctions.renum = function(args) { // RENUM function
var newcmdbuf = [];
var linenumRelation = [[]];
var cnt = 10;
for (var k = 0; k < cmdbuf.length; k++) {
if (typeof cmdbuf[k] != "undefined") {
newcmdbuf[cnt] = cmdbuf[k];
linenumRelation[k] = cnt;
cnt += 10;
}
}
// deal with goto/gosub line numbers
for (k = 0; k < newcmdbuf.length; k++) {
if (typeof newcmdbuf[k] != "undefined" && newcmdbuf[k].toLowerCase().startsWith("goto ")) {
newcmdbuf[k] = "goto " + linenumRelation[newcmdbuf[k].match(reNum)[0]];
}
else if (typeof newcmdbuf[k] != "undefined" && newcmdbuf[k].toLowerCase().startsWith("gosub ")) {
newcmdbuf[k] = "gosub " + linenumRelation[newcmdbuf[k].match(reNum)[0]];
}
}
cmdbuf = newcmdbuf.slice();
};
basicFunctions.run = function(args) { // RUN function basicFunctions.run = function(args) { // RUN function
var linenumber = 1; var linenumber = 1;
var oldnum = 1; var oldnum = 1;
do { do {
if (typeof cmd != "undefined") { if (typeof cmdbuf[linenumber] != "undefined") {
oldnum = linenumber; oldnum = linenumber;
linenumber = basicFunctions._interpretLine(linenumber, cmdbuf[linenumber]); linenumber = basicFunctions._interpretLine(linenumber, cmdbuf[linenumber]);
} }
else { else {
linenumber += 1; linenumber += 1;
} }
if (con.hitterminate) { if (con.hitterminate()) {
println("Break in "+oldlnum); println("Break in "+oldnum);
break; break;
} }
} while (linenumber < cmdbuf.length) } while (linenumber < cmdbuf.length)

View File

@@ -192,8 +192,7 @@ class VM(
internal fun malloc(size: Int): Int { internal fun malloc(size: Int): Int {
val allocBlocks = ceil(size.toDouble() / MALLOC_UNIT).toInt() val allocBlocks = ceil(size.toDouble() / MALLOC_UNIT).toInt()
val blockStart = findEmptySpace(allocBlocks) val blockStart = findEmptySpace(allocBlocks) ?: throw OutOfMemoryError()
if (blockStart == null) throw OutOfMemoryError()
mallocSizes[blockStart] = allocBlocks mallocSizes[blockStart] = allocBlocks
return blockStart * MALLOC_UNIT return blockStart * MALLOC_UNIT
@@ -201,8 +200,7 @@ class VM(
internal fun free(ptr: Int) { internal fun free(ptr: Int) {
val index = ptr / MALLOC_UNIT val index = ptr / MALLOC_UNIT
val count = mallocSizes[index] val count = mallocSizes[index] ?: throw OutOfMemoryError()
if (count == null) throw OutOfMemoryError()
mallocMap.set(index, index + count, false) mallocMap.set(index, index + count, false)
mallocSizes.remove(index) mallocSizes.remove(index)