mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-08 22:34:03 +09:00
basic: allowing object array
This commit is contained in:
@@ -31,7 +31,7 @@ if (exec_args !== undefined && exec_args[1] !== undefined && exec_args[1].starts
|
|||||||
|
|
||||||
const THEVERSION = "1.0";
|
const THEVERSION = "1.0";
|
||||||
|
|
||||||
const PROD = true;
|
const PROD = false;
|
||||||
let INDEX_BASE = 0;
|
let INDEX_BASE = 0;
|
||||||
let TRACEON = (!PROD) && true;
|
let TRACEON = (!PROD) && true;
|
||||||
let DBGON = (!PROD) && true;
|
let DBGON = (!PROD) && true;
|
||||||
@@ -603,9 +603,9 @@ bStatus.getDefunThunk = function(lnum, stmtnum, exprTree) {
|
|||||||
* @params troValue Variable to assign into
|
* @params troValue Variable to assign into
|
||||||
* @params rh the value, resolved
|
* @params rh the value, resolved
|
||||||
*/
|
*/
|
||||||
bStatus.addAsBasicVar = function(troValue, rh) {
|
bStatus.addAsBasicVar = function(lnum, troValue, rh) {
|
||||||
if (troValue.arrFull !== undefined) { // assign to existing array
|
if (troValue.arrFull !== undefined) { // assign to existing array
|
||||||
if (isNaN(rh) && !Array.isArray(rh)) throw lang.illegalType(lnum, rh);
|
if (Array.isArray(rh)) throw lang.illegalType(lnum, rh); // no ragged array!
|
||||||
let arr = eval("troValue.arrFull"+troValue.arrKey);
|
let arr = eval("troValue.arrFull"+troValue.arrKey);
|
||||||
if (Array.isArray(arr)) throw lang.subscrOutOfRng(lnum, arr);
|
if (Array.isArray(arr)) throw lang.subscrOutOfRng(lnum, arr);
|
||||||
eval("troValue.arrFull"+troValue.arrKey+"=rh");
|
eval("troValue.arrFull"+troValue.arrKey+"=rh");
|
||||||
@@ -644,7 +644,7 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
|||||||
//try { println(lnum+" = rh resolved entries: "+Object.entries(rh)); }
|
//try { println(lnum+" = rh resolved entries: "+Object.entries(rh)); }
|
||||||
//catch (_) {}
|
//catch (_) {}
|
||||||
|
|
||||||
return bStatus.addAsBasicVar(troValue, rh);
|
return bStatus.addAsBasicVar(lnum, troValue, rh);
|
||||||
}},
|
}},
|
||||||
"IN" : {f:function(lnum, stmtnum, args) { // almost same as =, but don't actually make new variable. Used by FOR statement
|
"IN" : {f:function(lnum, stmtnum, args) { // almost same as =, but don't actually make new variable. Used by FOR statement
|
||||||
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length+lang.aG);
|
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length+lang.aG);
|
||||||
@@ -1076,7 +1076,7 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
|||||||
// NOTE: empty string will be cast to 0, which corresponds to GW-BASIC
|
// NOTE: empty string will be cast to 0, which corresponds to GW-BASIC
|
||||||
if (!isNaN(rh)) rh = rh*1
|
if (!isNaN(rh)) rh = rh*1
|
||||||
|
|
||||||
return bStatus.addAsBasicVar(troValue, rh);
|
return bStatus.addAsBasicVar(lnum, troValue, rh);
|
||||||
}},
|
}},
|
||||||
"CIN" : {f:function(lnum, stmtnum, args) {
|
"CIN" : {f:function(lnum, stmtnum, args) {
|
||||||
return sys.read().trim();
|
return sys.read().trim();
|
||||||
@@ -1152,7 +1152,7 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
|||||||
let rh = DATA_CONSTS[DATA_CURSOR++];
|
let rh = DATA_CONSTS[DATA_CURSOR++];
|
||||||
if (rh === undefined) throw lang.outOfData(lnum);
|
if (rh === undefined) throw lang.outOfData(lnum);
|
||||||
|
|
||||||
return bStatus.addAsBasicVar(troValue, rh);
|
return bStatus.addAsBasicVar(lnum, troValue, rh);
|
||||||
}},
|
}},
|
||||||
"DGET" : {f:function(lnum, stmtnum, args) {
|
"DGET" : {f:function(lnum, stmtnum, args) {
|
||||||
let r = DATA_CONSTS[DATA_CURSOR++];
|
let r = DATA_CONSTS[DATA_CURSOR++];
|
||||||
@@ -1621,15 +1621,15 @@ bF._tokenise = function(lnum, cmd) {
|
|||||||
tokens.push(sb); sb = ""; states.push(mode);
|
tokens.push(sb); sb = ""; states.push(mode);
|
||||||
mode = "quote_end";
|
mode = "quote_end";
|
||||||
}
|
}
|
||||||
else if (charCode == 0x5C) { // reverse solidus
|
/*else if (charCode == 0x5C) { // reverse solidus
|
||||||
tokens.push(sb); sb = "";
|
tokens.push(sb); sb = "";
|
||||||
mode = "escape";
|
mode = "escape";
|
||||||
}
|
}*/
|
||||||
else {
|
else {
|
||||||
sb += char;
|
sb += char;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ("escape" == mode) {
|
/*else if ("escape" == mode) {
|
||||||
if (0x5C == charCode) // reverse solidus
|
if (0x5C == charCode) // reverse solidus
|
||||||
sb += String.fromCharCode(0x5C);
|
sb += String.fromCharCode(0x5C);
|
||||||
else if ("n" == char)
|
else if ("n" == char)
|
||||||
@@ -1647,7 +1647,7 @@ bF._tokenise = function(lnum, cmd) {
|
|||||||
else if ("b" == char)
|
else if ("b" == char)
|
||||||
sb += String.fromCharCode(0x08);
|
sb += String.fromCharCode(0x08);
|
||||||
mode = "qot"; // ESCAPE is only legal when used inside of quote
|
mode = "qot"; // ESCAPE is only legal when used inside of quote
|
||||||
}
|
}*/
|
||||||
else if ("quote_end" == mode) {
|
else if ("quote_end" == mode) {
|
||||||
if (" " == char) {
|
if (" " == char) {
|
||||||
sb = "";
|
sb = "";
|
||||||
@@ -1788,7 +1788,10 @@ bF._tokenise = function(lnum, cmd) {
|
|||||||
else if (states[k] == "n2" || states[k] == "nsep") states[k] = "num";
|
else if (states[k] == "n2" || states[k] == "nsep") states[k] = "num";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokens.length != states.length) throw new InternalError("size of tokens and states does not match (line: "+lnum+")");
|
if (tokens.length != states.length) {
|
||||||
|
throw new InternalError("size of tokens and states does not match (line: "+lnum+")\n"+
|
||||||
|
tokens+"\n"+states);
|
||||||
|
}
|
||||||
|
|
||||||
return { "tokens": tokens, "states": states };
|
return { "tokens": tokens, "states": states };
|
||||||
};
|
};
|
||||||
@@ -1816,6 +1819,7 @@ bF._parserElaboration = function(lnum, tokens, states) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
k += 1;
|
k += 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -2778,13 +2782,14 @@ bF._executeSyntaxTree = function(lnum, stmtnum, syntaxTree, recDepth) {
|
|||||||
if (func === undefined) {
|
if (func === undefined) {
|
||||||
var someVar = bStatus.vars[funcName];
|
var someVar = bStatus.vars[funcName];
|
||||||
|
|
||||||
|
if (someVar === undefined) {
|
||||||
|
throw lang.syntaxfehler(lnum, funcName + " is undefined");
|
||||||
|
}
|
||||||
|
|
||||||
if (DBGON) {
|
if (DBGON) {
|
||||||
serial.println(lnum+" _executeSyntaxTree: "+Object.entries(someVar));
|
serial.println(lnum+" _executeSyntaxTree: "+Object.entries(someVar));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (someVar === undefined) {
|
|
||||||
throw lang.syntaxfehler(lnum, funcName + " is undefined");
|
|
||||||
}
|
|
||||||
else if ("array" == someVar.bvType) {
|
else if ("array" == someVar.bvType) {
|
||||||
func = bStatus.getArrayIndexFun(lnum, stmtnum, funcName, someVar.bvLiteral);
|
func = bStatus.getArrayIndexFun(lnum, stmtnum, funcName, someVar.bvLiteral);
|
||||||
}
|
}
|
||||||
@@ -2797,6 +2802,10 @@ bF._executeSyntaxTree = function(lnum, stmtnum, syntaxTree, recDepth) {
|
|||||||
}
|
}
|
||||||
// call whatever the 'func' has whether it's builtin or we just made shit up right above
|
// call whatever the 'func' has whether it's builtin or we just made shit up right above
|
||||||
try {
|
try {
|
||||||
|
if (func === undefined) {
|
||||||
|
throw lang.syntaxfehler(lnum, funcName + " is undefined");
|
||||||
|
}
|
||||||
|
|
||||||
let funcCallResult = func(lnum, stmtnum, args, syntaxTree.astSeps);
|
let funcCallResult = func(lnum, stmtnum, args, syntaxTree.astSeps);
|
||||||
|
|
||||||
if (funcCallResult instanceof SyntaxTreeReturnObj) return funcCallResult;
|
if (funcCallResult instanceof SyntaxTreeReturnObj) return funcCallResult;
|
||||||
|
|||||||
Reference in New Issue
Block a user