basic:more helpful errmsgs

This commit is contained in:
minjaesong
2020-12-04 11:54:53 +09:00
parent e7f4b07326
commit e06a7eac59

View File

@@ -17,6 +17,7 @@ Test Programs:
*/
let INDEX_BASE = 0;
let TRACEON = false;
let DBGON = true;
if (system.maxmem() < 8192) {
println("Out of memory. BASIC requires 8K or more User RAM");
@@ -43,10 +44,13 @@ lang.syntaxfehler = function(line, reason) {
return "Syntax error" + ((line !== undefined) ? (" in "+line) : "") + ((reason !== undefined) ? (": "+reason) : "");
};
lang.illegalType = function(line, obj) {
return "Type mismatch" + ((obj !== undefined) ? ' "' + obj + '"' : "") + ((line !== undefined) ? (" in "+line) : "");
return "Type mismatch" + ((obj !== undefined) ? ` "${obj} (typeof ${typeof obj})"` : "") + ((line !== undefined) ? (" in "+line) : "");
};
lang.refError = function(line, obj) {
return "Unresolved reference" + ((obj !== undefined) ? ' "' + obj + '"' : "") + ((line !== undefined) ? (" in "+line) : "");
serial.printerr(`${line} Unresolved reference:`);
serial.printerr(` object: ${obj}, typeof: ${typeof obj}`);
serial.printerr(` entries: ${Object.entries(obj)}`);
return "Unresolved reference" + ((obj !== undefined) ? ` "${obj}"` : "") + ((line !== undefined) ? (" in "+line) : "");
};
lang.nowhereToReturn = function(line) { return "RETURN without GOSUB in " + line; };
lang.errorinline = function(line, stmt, errobj) {
@@ -64,10 +68,16 @@ lang.dupDef = function(line, varname) {
lang.asgnOnConst = function(line, constname) {
return 'Trying to modify constant "'+constname+'" in '+line;
};
lang.subscrOutOfRng = function(line, object) {
return "Subscript out of range"+(object !== undefined ? (' for "'+object+'"') : '')+(line !== undefined ? (" in "+line) : "")
lang.subscrOutOfRng = function(line, object, index, maxlen) {
return "Subscript out of range"+(object !== undefined ? (' for "'+object+'"') : '')+(index !== undefined ? (` (index: ${index}, len: ${maxlen})`) : "")+(line !== undefined ? (" in "+line) : "");
};
lang.aG = " arguments were given";
lang.ord = function(n) {
if (n % 10 == 1 && n % 100 != 11) return n+"st";
if (n % 10 == 2 && n % 100 != 12) return n+"nd";
if (n % 10 == 3 && n % 100 != 13) return n+"rd";
return n+"th";
}
Object.freeze(lang);
let fs = {};
@@ -224,34 +234,40 @@ let resolve = function(variable) {
else
throw "BasicIntpError: unknown variable with type "+variable.troType+", with value "+variable.troValue
}
let argCheckErr = function(lnum, o) {
if (o === undefined || o.troType == "null") throw lang.refError(lnum, o);
if (o.troType == "lit" && bStatus.vars[o.troValue] === undefined) throw lang.refError(lnum, o);
if (o.troValue.arrObj !== undefined && o.troValue.arrIndex >= o.troValue.arrObj.length)
throw lang.subscrOutOfRng(line, o.troValue.arrName, o.troValue.arrIndex, o.troValue.arrObj.length);
}
let oneArg = function(lnum, args, action) {
if (args.length != 1) throw lang.syntaxfehler(lnum, args.length+lang.aG);
argCheckErr(lnum, args[0]);
var rsvArg0 = resolve(args[0]);
if (rsvArg0 === undefined) throw lang.refError(lnum, args[0]);
return action(rsvArg0);
}
let oneArgNum = function(lnum, args, action) {
if (args.length != 1) throw lang.syntaxfehler(lnum, args.length+lang.aG);
argCheckErr(lnum, args[0]);
var rsvArg0 = resolve(args[0]);
if (rsvArg0 === undefined) throw lang.refError(lnum, args[0]);
if (isNaN(rsvArg0)) throw lang.illegalType(lnum, args[0]);
return action(rsvArg0);
}
let twoArg = function(lnum, args, action) {
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length+lang.aG);
argCheckErr(lnum, args[0]);
var rsvArg0 = resolve(args[0]);
if (rsvArg0 === undefined) throw lang.refError(lnum, "LH:"+Object.entries(args[0]));
argCheckErr(lnum, args[1]);
var rsvArg1 = resolve(args[1]);
if (rsvArg1 === undefined) throw lang.refError(lnum, "RH:"+Object.entries(args[1]));
return action(rsvArg0, rsvArg1);
}
let twoArgNum = function(lnum, args, action) {
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length+lang.aG);
argCheckErr(lnum, args[0]);
var rsvArg0 = resolve(args[0]);
if (rsvArg0 === undefined) throw lang.refError(lnum, args[0]);
if (isNaN(rsvArg0)) throw lang.illegalType(lnum, "LH:"+Object.entries(args[0]));
argCheckErr(lnum, args[1]);
var rsvArg1 = resolve(args[1]);
if (rsvArg1 === undefined) throw lang.refError(lnum, args[1]);
if (isNaN(rsvArg1)) throw lang.illegalType(lnum, "RH:"+Object.entries(args[1]));
return action(rsvArg0, rsvArg1);
}
@@ -382,15 +398,33 @@ bStatus.getArrayIndexFun = function(lnum, arrayName, array) {
return varArgNum(lnum, args, (dims) => {
let indexingstr = "";
if (TRACEON) serial.println("ar dims: "+dims);
let dimcnt = 1;
let oldIstr = "";
let istr = "";
// check error beforehand
dims.reverse().forEach((d) => {
oldIstr = istr;
istr += `[${d-INDEX_BASE}]`;
// test for index out of bounds
if (eval(`array${istr}`) === undefined) {
throw lang.subscrOutOfRng(lnum, `${arrayName}${oldIstr} (${lang.ord(dimcnt)} dim)`, d-INDEX_BASE, eval(`array${oldIstr}`).length);
}
dimcnt += 1;
})
// actually build indexing string (trust me, indexing fails with code above; test with 'amazing.bas')
dims.forEach((d) => {
indexingstr = `[${d-INDEX_BASE}]${indexingstr}`;
})
if (TRACEON)
serial.println("ar indexedValue = "+`/*ar1*/array${indexingstr}`);
let indexedValue = eval(`/*ar1*/array${indexingstr}`);
let index = dims[0]-INDEX_BASE;
if (TRACEON)
serial.println("ar parentArr = "+`/*ar2*/array${indexingstr.substring(0, indexingstr.length - 2 - (""+index).length)}`);
//let parentArr = eval(`/*ar2*/array${oldIndexingStr}`);
let parentArr = eval(`/*ar2*/array${indexingstr.substring(0, indexingstr.length - 2 - (""+index).length)}`);
if (index < 0) throw lang.subscrOutOfRng(lnum, arrayName);
@@ -888,6 +922,42 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
INDEX_BASE = lh|0;
});
},
"RESOLVE" : function(lnum, args) {
if (DBGON) {
return oneArg(lnum, args, (it) => {
println(it);
});
}
else {
throw lang.syntaxfehler(lnum);
}
},
"RESOLVE0" : function(lnum, args) {
if (DBGON) {
return oneArg(lnum, args, (it) => {
println(Object.entries(it));
});
}
else {
throw lang.syntaxfehler(lnum);
}
},
"UNRESOLVE" : function(lnum, args) {
if (DBGON) {
println(args[0]);
}
else {
throw lang.syntaxfehler(lnum);
}
},
"UNRESOLVE0" : function(lnum, args) {
if (DBGON) {
println(Object.entries(args[0]));
}
else {
throw lang.syntaxfehler(lnum);
}
}
};
Object.freeze(bStatus.builtin);
let bF = {};
@@ -1702,7 +1772,7 @@ let JStoBASICtype = function(object) {
else if (object.asgnVarName !== undefined) return "internal_assignment_object";
else if (object.arrValue !== undefined) return "internal_arrindexing_lazy";
// buncha error msgs
else if (object.arrIndex-INDEX_BASE >= object.arrObj.length) throw lang.subscrOutOfRng(undefined, `${object.arrName}(${object.arrIndex}, len:${object.arrObj.length})`);
else if (object.arrIndex >= object.arrObj.length) throw lang.subscrOutOfRng(undefined, `${object.arrName}(${object.arrIndex}, len:${object.arrObj.length})`);
else throw "BasicIntpError: un-translatable object with typeof "+(typeof object)+",\ntoString = "+object+",\nentries = "+Object.entries(object);
}
let SyntaxTreeReturnObj = function(type, value, nextLine) {