mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-10 15:04:03 +09:00
basic:array indexing and assigning at the index
This commit is contained in:
@@ -238,7 +238,9 @@ let literalTypes = ["string", "number", "bool", "array"];
|
|||||||
BASIC variable table and return the literal value of the BasicVar; undefined will be returned if no such var exists.
|
BASIC variable table and return the literal value of the BasicVar; undefined will be returned if no such var exists.
|
||||||
*/
|
*/
|
||||||
let resolve = function(variable) {
|
let resolve = function(variable) {
|
||||||
if (literalTypes.includes(variable.troType) || variable.troType.startsWith("internal_"))
|
if (variable.troType === "internal_arrindexing_lazy")
|
||||||
|
return variable.troValue.arrValue;
|
||||||
|
else if (literalTypes.includes(variable.troType) || variable.troType.startsWith("internal_"))
|
||||||
return variable.troValue;
|
return variable.troValue;
|
||||||
else if (variable.troType == "literal") {
|
else if (variable.troType == "literal") {
|
||||||
var basicVar = bStatus.vars[parseSigil(variable.troValue).sgName];
|
var basicVar = bStatus.vars[parseSigil(variable.troValue).sgName];
|
||||||
@@ -252,55 +254,55 @@ let resolve = function(variable) {
|
|||||||
let oneArg = function(lnum, args, action) {
|
let oneArg = function(lnum, args, action) {
|
||||||
if (args.length != 1) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
if (args.length != 1) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
var rsvArg0 = resolve(args[0]);
|
var rsvArg0 = resolve(args[0]);
|
||||||
if (rsvArg0 === undefined) throw lang.refError(lnum, rsvArg0);
|
if (rsvArg0 === undefined) throw lang.refError(lnum, args[0]);
|
||||||
return action(rsvArg0);
|
return action(rsvArg0);
|
||||||
}
|
}
|
||||||
let oneArgNum = function(lnum, args, action) {
|
let oneArgNum = function(lnum, args, action) {
|
||||||
if (args.length != 1) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
if (args.length != 1) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
var rsvArg0 = resolve(args[0]);
|
var rsvArg0 = resolve(args[0]);
|
||||||
if (rsvArg0 === undefined) throw lang.refError(lnum, rsvArg0);
|
if (rsvArg0 === undefined) throw lang.refError(lnum, args[0]);
|
||||||
if (isNaN(rsvArg0)) throw lang.illegalType(lnum, rsvArg0);
|
if (isNaN(rsvArg0)) throw lang.illegalType(lnum, args[0]);
|
||||||
return action(rsvArg0);
|
return action(rsvArg0);
|
||||||
}
|
}
|
||||||
let twoArg = function(lnum, args, action) {
|
let twoArg = function(lnum, args, action) {
|
||||||
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
var rsvArg0 = resolve(args[0]);
|
var rsvArg0 = resolve(args[0]);
|
||||||
if (rsvArg0 === undefined) throw lang.refError(lnum, rsvArg0);
|
if (rsvArg0 === undefined) throw lang.refError(lnum, args[0]);
|
||||||
var rsvArg1 = resolve(args[1]);
|
var rsvArg1 = resolve(args[1]);
|
||||||
if (rsvArg1 === undefined) throw lang.refError(lnum, rsvArg1);
|
if (rsvArg1 === undefined) throw lang.refError(lnum, args[1]);
|
||||||
return action(rsvArg0, rsvArg1);
|
return action(rsvArg0, rsvArg1);
|
||||||
}
|
}
|
||||||
let twoArgNum = function(lnum, args, action) {
|
let twoArgNum = function(lnum, args, action) {
|
||||||
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
var rsvArg0 = resolve(args[0]);
|
var rsvArg0 = resolve(args[0]);
|
||||||
if (rsvArg0 === undefined) throw lang.refError(lnum, rsvArg0);
|
if (rsvArg0 === undefined) throw lang.refError(lnum, args[0]);
|
||||||
if (isNaN(rsvArg0)) throw lang.illegalType(lnum, rsvArg0);
|
if (isNaN(rsvArg0)) throw lang.illegalType(lnum, args[0]);
|
||||||
var rsvArg1 = resolve(args[1]);
|
var rsvArg1 = resolve(args[1]);
|
||||||
if (rsvArg1 === undefined) throw lang.refError(lnum, rsvArg1);
|
if (rsvArg1 === undefined) throw lang.refError(lnum, args[1]);
|
||||||
if (isNaN(rsvArg1)) throw lang.illegalType(lnum, rsvArg1);
|
if (isNaN(rsvArg1)) throw lang.illegalType(lnum, args[1]);
|
||||||
return action(rsvArg0, rsvArg1);
|
return action(rsvArg0, rsvArg1);
|
||||||
}
|
}
|
||||||
let threeArg = function(lnum, args, action) {
|
let threeArg = function(lnum, args, action) {
|
||||||
if (args.length != 3) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
if (args.length != 3) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
var rsvArg0 = resolve(args[0]);
|
var rsvArg0 = resolve(args[0]);
|
||||||
if (rsvArg0 === undefined) throw lang.refError(lnum, rsvArg0);
|
if (rsvArg0 === undefined) throw lang.refError(lnum, args[0]);
|
||||||
var rsvArg1 = resolve(args[1]);
|
var rsvArg1 = resolve(args[1]);
|
||||||
if (rsvArg1 === undefined) throw lang.refError(lnum, rsvArg1);
|
if (rsvArg1 === undefined) throw lang.refError(lnum, args[1]);
|
||||||
var rsvArg2 = resolve(args[2]);
|
var rsvArg2 = resolve(args[2]);
|
||||||
if (rsvArg2 === undefined) throw lang.refError(lnum, rsvArg2);
|
if (rsvArg2 === undefined) throw lang.refError(lnum, args[2]);
|
||||||
return action(rsvArg0, rsvArg1, rsvArg2);
|
return action(rsvArg0, rsvArg1, rsvArg2);
|
||||||
}
|
}
|
||||||
let threeArgNum = function(lnum, args, action) {
|
let threeArgNum = function(lnum, args, action) {
|
||||||
if (args.length != 3) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
if (args.length != 3) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
var rsvArg0 = resolve(args[0]);
|
var rsvArg0 = resolve(args[0]);
|
||||||
if (rsvArg0 === undefined) throw lang.refError(lnum, rsvArg0);
|
if (rsvArg0 === undefined) throw lang.refError(lnum, args[0]);
|
||||||
if (isNaN(rsvArg0)) throw lang.illegalType(lnum, rsvArg0);
|
if (isNaN(rsvArg0)) throw lang.illegalType(lnum, args[0]);
|
||||||
var rsvArg1 = resolve(args[1]);
|
var rsvArg1 = resolve(args[1]);
|
||||||
if (rsvArg1 === undefined) throw lang.refError(lnum, rsvArg1);
|
if (rsvArg1 === undefined) throw lang.refError(lnum, args[1]);
|
||||||
if (isNaN(rsvArg1)) throw lang.illegalType(lnum, rsvArg1);
|
if (isNaN(rsvArg1)) throw lang.illegalType(lnum, args[1]);
|
||||||
var rsvArg2 = resolve(args[2]);
|
var rsvArg2 = resolve(args[2]);
|
||||||
if (rsvArg2 === undefined) throw lang.refError(lnum, rsvArg2);
|
if (rsvArg2 === undefined) throw lang.refError(lnum, args[2]);
|
||||||
if (isNaN(rsvArg2)) throw lang.illegalType(lnum, rsvArg2);
|
if (isNaN(rsvArg2)) throw lang.illegalType(lnum, args[2]);
|
||||||
return action(rsvArg0, rsvArg1, rsvArg2);
|
return action(rsvArg0, rsvArg1, rsvArg2);
|
||||||
}
|
}
|
||||||
let initBvars = function() {
|
let initBvars = function() {
|
||||||
@@ -319,7 +321,7 @@ bStatus.vars = initBvars(); // contains instances of BasicVars
|
|||||||
bStatus.consts = {"NIL":1}; Object.freeze(bStatus.consts);
|
bStatus.consts = {"NIL":1}; Object.freeze(bStatus.consts);
|
||||||
bStatus.defuns = {};
|
bStatus.defuns = {};
|
||||||
bStatus.rnd = 0; // stores mantissa (23 bits long) of single precision floating point number
|
bStatus.rnd = 0; // stores mantissa (23 bits long) of single precision floating point number
|
||||||
bStatus.getArrayIndexFun = function(lnum, array) {
|
bStatus.getArrayIndexFun = function(lnum, arrayName, array) {
|
||||||
return function(lnum, args) {
|
return function(lnum, args) {
|
||||||
// TODO test 1-d array
|
// TODO test 1-d array
|
||||||
// NOTE: BASIC arrays are index in column-major order, which is OPPOSITE of C/JS/etc.
|
// NOTE: BASIC arrays are index in column-major order, which is OPPOSITE of C/JS/etc.
|
||||||
@@ -327,7 +329,7 @@ bStatus.getArrayIndexFun = function(lnum, array) {
|
|||||||
if (rsvArg0 === undefined) throw lang.refError(lnum, rsvArg0);
|
if (rsvArg0 === undefined) throw lang.refError(lnum, rsvArg0);
|
||||||
if (isNaN(rsvArg0)) throw lang.illegalType(lnum, rsvArg0);
|
if (isNaN(rsvArg0)) throw lang.illegalType(lnum, rsvArg0);
|
||||||
|
|
||||||
return array[rsvArg0];
|
return {arrValue: array[rsvArg0], arrObj: array, arrIndex: rsvArg0, arrName: arrayName}; //array[rsvArg0];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
bStatus.builtin = {
|
bStatus.builtin = {
|
||||||
@@ -341,13 +343,27 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
|||||||
"REM" : function(lnum, args) {},
|
"REM" : function(lnum, args) {},
|
||||||
"=" : function(lnum, args) {
|
"=" : function(lnum, args) {
|
||||||
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
var sigil = parseSigil(args[0].troValue);
|
var troValue = args[0].troValue;
|
||||||
|
|
||||||
var rh = resolve(args[1]);
|
var rh = resolve(args[1]);
|
||||||
if (rh === undefined) throw lang.refError(lnum, args[1].troValue);
|
if (rh === undefined) throw lang.refError(lnum, "RH:"+args[1].troValue);
|
||||||
var type = sigil.sgType || JStoBASICtype(rh);
|
|
||||||
if (bStatus.consts[sigil.sgName]) throw lang.asgnOnConst(lnum, sigil.sgName);
|
if (troValue.arrObj !== undefined) {
|
||||||
bStatus.vars[sigil.sgName] = new BasicVar(rh, type);
|
if (isNaN(rh)) throw lang.illegalType(lnum, rh);
|
||||||
return {asgnVarName: sigil.sgName, asgnValue: rh};
|
|
||||||
|
troValue.arrObj[troValue.arrIndex] = rh;
|
||||||
|
return {asgnVarName: troValue.arrName, asgnValue: rh};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var sigil = parseSigil(troValue);
|
||||||
|
var type = sigil.sgType || JStoBASICtype(rh);
|
||||||
|
|
||||||
|
if (bStatus.consts[sigil.sgName]) throw lang.asgnOnConst(lnum, sigil.sgName);
|
||||||
|
|
||||||
|
bStatus.vars[sigil.sgName] = new BasicVar(rh, type);
|
||||||
|
return {asgnVarName: sigil.sgName, asgnValue: rh};
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
"==" : function(lnum, args) {
|
"==" : function(lnum, args) {
|
||||||
return twoArg(lnum, args, function(lh, rh) { return lh == rh; });
|
return twoArg(lnum, args, function(lh, rh) { return lh == rh; });
|
||||||
@@ -601,7 +617,7 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
|||||||
if (asgnObj === undefined) throw lang.syntaxfehler(lnum);
|
if (asgnObj === undefined) throw lang.syntaxfehler(lnum);
|
||||||
if (!Array.isArray(asgnObj.asgnValue)) throw lang.illegalType(lnum, asgnObj);
|
if (!Array.isArray(asgnObj.asgnValue)) throw lang.illegalType(lnum, asgnObj);
|
||||||
|
|
||||||
let varname = asgnObj.asgnVarName
|
let varname = asgnObj.asgnVarName;
|
||||||
|
|
||||||
// assign new variable
|
// assign new variable
|
||||||
// the var itself will have head of the array, and the head itself will be removed from the array
|
// the var itself will have head of the array, and the head itself will be removed from the array
|
||||||
@@ -1499,6 +1515,7 @@ let JStoBASICtype = function(object) {
|
|||||||
else if (typeof object === "string" || object instanceof String) return "string";
|
else if (typeof object === "string" || object instanceof String) return "string";
|
||||||
else if (object === undefined) return "null";
|
else if (object === undefined) return "null";
|
||||||
else if (object.asgnVarName !== undefined) return "internal_assignment_object";
|
else if (object.asgnVarName !== undefined) return "internal_assignment_object";
|
||||||
|
else if (object.arrValue !== undefined) return "internal_arrindexing_lazy";
|
||||||
else throw "BasicIntpError: un-translatable object with typeof "+(typeof object)+",\ntoString = "+object+",\nentries = "+Object.entries(object);
|
else throw "BasicIntpError: un-translatable object with typeof "+(typeof object)+",\ntoString = "+object+",\nentries = "+Object.entries(object);
|
||||||
}
|
}
|
||||||
let SyntaxTreeReturnObj = function(type, value, nextLine) {
|
let SyntaxTreeReturnObj = function(type, value, nextLine) {
|
||||||
@@ -1571,7 +1588,7 @@ bF._executeSyntaxTree = function(lnum, syntaxTree, recDepth) {
|
|||||||
|
|
||||||
// TODO calling from bStatus.defuns
|
// TODO calling from bStatus.defuns
|
||||||
|
|
||||||
func = bStatus.getArrayIndexFun(lnum, someVar.bvLiteral);
|
func = bStatus.getArrayIndexFun(lnum, funcName, someVar.bvLiteral);
|
||||||
}
|
}
|
||||||
// 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 {
|
||||||
@@ -76,7 +76,7 @@ if (portNumber < 4) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sys.mapRom(1);
|
sys.mapRom(1);
|
||||||
let response = eval("let _appStub=function(exec_args){"+sys.romReadAll()+"};_appStub;")();
|
let response = eval("let basica=function(exec_args){"+sys.romReadAll()+"};basica;")();
|
||||||
|
|
||||||
if (response !== 0) println("No ROM BASIC system halted");
|
if (response !== 0) println("No ROM BASIC system halted");
|
||||||
}
|
}
|
||||||
@@ -18,4 +18,4 @@ Object.freeze(_BIOS);
|
|||||||
|
|
||||||
// load a BASIC rom
|
// load a BASIC rom
|
||||||
sys.mapRom(1);
|
sys.mapRom(1);
|
||||||
eval("let _appStub=function(exec_args){"+sys.romReadAll()+"};_appStub;")();
|
eval("let basicrom=function(exec_args){"+sys.romReadAll()+"};basicrom;")();
|
||||||
BIN
hp2640.kra
LFS
BIN
hp2640.kra
LFS
Binary file not shown.
BIN
hp2640.png
BIN
hp2640.png
Binary file not shown.
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
@@ -27,9 +27,9 @@ public class AppLoader {
|
|||||||
|
|
||||||
|
|
||||||
// val vm = VM(64.kB(), TheRealWorld(), arrayOf(GenericBios))
|
// val vm = VM(64.kB(), TheRealWorld(), arrayOf(GenericBios))
|
||||||
//VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{GenericBios.INSTANCE});
|
VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{GenericBios.INSTANCE});
|
||||||
//VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{BasicBios.INSTANCE, BasicRom.INSTANCE});
|
//VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{BasicBios.INSTANCE, BasicRom.INSTANCE});
|
||||||
VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{OEMBios.INSTANCE, BasicRom.INSTANCE});
|
//VM vm = new VM(64 << 10, new TheRealWorld(), new VMProgramRom[]{OEMBios.INSTANCE, BasicRom.INSTANCE});
|
||||||
new LwjglApplication(new VMGUI(vm, appConfig), appConfig);
|
new LwjglApplication(new VMGUI(vm, appConfig), appConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ object BasicRom : VMProgramRom {
|
|||||||
private val contents: ByteArray
|
private val contents: ByteArray
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val bytes = File("./assets/tbas/basic.js").readBytes()
|
val bytes = File("./assets/basic.js").readBytes()
|
||||||
contents = bytes.sliceArray(0 until minOf(65536, bytes.size))
|
contents = bytes.sliceArray(0 until minOf(65536, bytes.size))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user