mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-11 15:24:05 +09:00
more BASIC operators|parsing binary literals
This commit is contained in:
@@ -144,6 +144,81 @@ function resolve(variable) {
|
|||||||
else
|
else
|
||||||
throw "InternalError: unknown variable with type "+variable.type+", with value "+variable.value
|
throw "InternalError: unknown variable with type "+variable.type+", with value "+variable.value
|
||||||
}
|
}
|
||||||
|
function oneArgNonNull(lnum, args, predicate) {
|
||||||
|
if (args.length != 1) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
|
var resolvedargs = args.map(function(it) { return resolve(it); });
|
||||||
|
resolvedargs.forEach(function(v) {
|
||||||
|
if (v === undefined) throw lang.refError(lnum, v.value);
|
||||||
|
});
|
||||||
|
var argum = resolvedargs.map(function(it) {
|
||||||
|
if (it === undefined) throw lang.refError(lnum, it.value);
|
||||||
|
return it;
|
||||||
|
});
|
||||||
|
return predicate(argum[0]);
|
||||||
|
}
|
||||||
|
function oneArgNonNullNumeric(lnum, args, predicate) {
|
||||||
|
if (args.length != 1) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
|
var resolvedargs = args.map(function(it) { return resolve(it); });
|
||||||
|
resolvedargs.forEach(function(v) {
|
||||||
|
if (v === undefined) throw lang.refError(lnum, v.value);
|
||||||
|
if (isNaN(v)) throw lang.illegalType(lnum, v.value);
|
||||||
|
});
|
||||||
|
var argum = resolvedargs.map(function(it) {
|
||||||
|
if (it === undefined) throw lang.refError(lnum, it.value);
|
||||||
|
return it;
|
||||||
|
});
|
||||||
|
return predicate(argum[0]);
|
||||||
|
}
|
||||||
|
function twoArgNonNull(lnum, args, predicate) {
|
||||||
|
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
|
var resolvedargs = args.map(function(it) { return resolve(it); });
|
||||||
|
resolvedargs.forEach(function(v) {
|
||||||
|
if (v === undefined) throw lang.refError(lnum, v.value);
|
||||||
|
});
|
||||||
|
var argum = resolvedargs.map(function(it) {
|
||||||
|
if (it === undefined) throw lang.refError(lnum, it.value);
|
||||||
|
return it;
|
||||||
|
});
|
||||||
|
return predicate(argum[0], argum[1]);
|
||||||
|
}
|
||||||
|
function twoArgNonNullNumeric(lnum, args, predicate) {
|
||||||
|
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
|
var resolvedargs = args.map(function(it) { return resolve(it); });
|
||||||
|
resolvedargs.forEach(function(v) {
|
||||||
|
if (v === undefined) throw lang.refError(lnum, v.value);
|
||||||
|
if (isNaN(v)) throw lang.illegalType(lnum, v.value);
|
||||||
|
});
|
||||||
|
var argum = resolvedargs.map(function(it) {
|
||||||
|
if (it === undefined) throw lang.refError(lnum, it.value);
|
||||||
|
return it;
|
||||||
|
});
|
||||||
|
return predicate(argum[0], argum[1]);
|
||||||
|
}
|
||||||
|
function threeArgNonNull(lnum, args, predicate) {
|
||||||
|
if (args.length != 3) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
|
var resolvedargs = args.map(function(it) { return resolve(it); });
|
||||||
|
resolvedargs.forEach(function(v) {
|
||||||
|
if (v === undefined) throw lang.refError(lnum, v.value);
|
||||||
|
});
|
||||||
|
var argum = resolvedargs.map(function(it) {
|
||||||
|
if (it === undefined) throw lang.refError(lnum, it.value);
|
||||||
|
return it;
|
||||||
|
});
|
||||||
|
return predicate(argum[0], argum[1], argum[2]);
|
||||||
|
}
|
||||||
|
function threeArgNonNullNumeric(lnum, args, predicate) {
|
||||||
|
if (args.length != 3) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
|
var resolvedargs = args.map(function(it) { return resolve(it); });
|
||||||
|
resolvedargs.forEach(function(v) {
|
||||||
|
if (v === undefined) throw lang.refError(lnum, v.value);
|
||||||
|
if (isNaN(v)) throw lang.illegalType(lnum, v.value);
|
||||||
|
});
|
||||||
|
var argum = resolvedargs.map(function(it) {
|
||||||
|
if (it === undefined) throw lang.refError(lnum, it.value);
|
||||||
|
return it;
|
||||||
|
});
|
||||||
|
return predicate(argum[0], argum[1], argum[2]);
|
||||||
|
}
|
||||||
var basicInterpreterStatus = {};
|
var basicInterpreterStatus = {};
|
||||||
basicInterpreterStatus.gosubStack = [];
|
basicInterpreterStatus.gosubStack = [];
|
||||||
basicInterpreterStatus.variables = {};
|
basicInterpreterStatus.variables = {};
|
||||||
@@ -161,88 +236,70 @@ basicInterpreterStatus.builtin = {
|
|||||||
basicInterpreterStatus.variables[parsed.name] = new BasicVar(rh, (parsed.type === undefined) ? "float" : parsed.type);
|
basicInterpreterStatus.variables[parsed.name] = new BasicVar(rh, (parsed.type === undefined) ? "float" : parsed.type);
|
||||||
},
|
},
|
||||||
"==" : function(lnum, args) {
|
"==" : function(lnum, args) {
|
||||||
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
return twoArgNonNull(lnum, args, function(lh, rh) { return lh == rh; });
|
||||||
var lh = resolve(args[0]); var rh = resolve(args[1]);
|
},
|
||||||
if (lh === undefined) throw lang.refError(lnum, args[0].value);
|
"<>" : function(lnum, args) {
|
||||||
if (rh === undefined) throw lang.refError(lnum, args[1].value);
|
return twoArgNonNull(lnum, args, function(lh, rh) { return lh != rh; });
|
||||||
|
},
|
||||||
return (lh == rh);
|
"><" : function(lnum, args) {
|
||||||
|
return twoArgNonNull(lnum, args, function(lh, rh) { return lh != rh; });
|
||||||
|
},
|
||||||
|
"<=" : function(lnum, args) {
|
||||||
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh <= rh; });
|
||||||
|
},
|
||||||
|
"=<" : function(lnum, args) {
|
||||||
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh <= rh; });
|
||||||
|
},
|
||||||
|
">=" : function(lnum, args) {
|
||||||
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh >= rh; });
|
||||||
|
},
|
||||||
|
"=>" : function(lnum, args) {
|
||||||
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh >= rh; });
|
||||||
|
},
|
||||||
|
"<" : function(lnum, args) {
|
||||||
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh < rh; });
|
||||||
|
},
|
||||||
|
">" : function(lnum, args) {
|
||||||
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh > rh; });
|
||||||
|
},
|
||||||
|
"<<" : function(lnum, args) {
|
||||||
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh << rh; });
|
||||||
|
},
|
||||||
|
">>" : function(lnum, args) {
|
||||||
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh >> rh; });
|
||||||
},
|
},
|
||||||
"UNARYMINUS" : function(lnum, args) {
|
"UNARYMINUS" : function(lnum, args) {
|
||||||
if (args.length != 1) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
return oneArgNonNullNumeric(lnum, args, function(lh) { return -lh; });
|
||||||
var lh = resolve(args[0]);
|
|
||||||
if (lh === undefined) throw lang.refError(lnum, args[0].value);
|
|
||||||
if (isNaN(lh)) throw lang.illegalType(lnum, args[0].value);
|
|
||||||
|
|
||||||
return -lh;
|
|
||||||
},
|
},
|
||||||
"UNARYPLUS" : function(lnum, args) {
|
"UNARYPLUS" : function(lnum, args) {
|
||||||
if (args.length != 1) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
return oneArgNonNullNumeric(lnum, args, function(lh) { return +lh; });
|
||||||
var lh = resolve(args[0]);
|
},
|
||||||
if (lh === undefined) throw lang.refError(lnum, args[0].value);
|
"BAND" : function(lnum, args) {
|
||||||
if (isNaN(lh)) throw lang.illegalType(lnum, args[0].value);
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh & rh; });
|
||||||
|
},
|
||||||
return +lh;
|
"BOR" : function(lnum, args) {
|
||||||
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh | rh; });
|
||||||
|
},
|
||||||
|
"BXOR" : function(lnum, args) {
|
||||||
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh ^ rh; });
|
||||||
},
|
},
|
||||||
"+" : function(lnum, args) {
|
"+" : function(lnum, args) {
|
||||||
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
return twoArgNonNull(lnum, args, function(lh, rh) { return lh + rh; });
|
||||||
var lh = resolve(args[0]); var rh = resolve(args[1]);
|
|
||||||
if (lh === undefined) throw lang.refError(lnum, args[0].value);
|
|
||||||
if (rh === undefined) throw lang.refError(lnum, args[1].value);
|
|
||||||
|
|
||||||
//serial.println("BASIC func: + -- LH="+lh+", RH="+rh+", return="+(lh + rh));
|
|
||||||
|
|
||||||
return lh + rh;
|
|
||||||
},
|
},
|
||||||
"-" : function(lnum, args) {
|
"-" : function(lnum, args) {
|
||||||
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh - rh; });
|
||||||
var lh = resolve(args[0]); var rh = resolve(args[1]);
|
|
||||||
if (lh === undefined) throw lang.refError(lnum, args[0].value);
|
|
||||||
if (rh === undefined) throw lang.refError(lnum, args[1].value);
|
|
||||||
if (isNaN(lh)) throw lang.illegalType(lnum, args[0].value);
|
|
||||||
if (isNaN(rh)) throw lang.illegalType(lnum, args[1].value);
|
|
||||||
|
|
||||||
return lh - rh;
|
|
||||||
},
|
},
|
||||||
"*" : function(lnum, args) {
|
"*" : function(lnum, args) {
|
||||||
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh * rh; });
|
||||||
var lh = resolve(args[0]); var rh = resolve(args[1]);
|
|
||||||
if (lh === undefined) throw lang.refError(lnum, args[0].value);
|
|
||||||
if (rh === undefined) throw lang.refError(lnum, args[1].value);
|
|
||||||
if (isNaN(lh)) throw lang.illegalType(lnum, args[0].value);
|
|
||||||
if (isNaN(rh)) throw lang.illegalType(lnum, args[1].value);
|
|
||||||
|
|
||||||
return lh * rh;
|
|
||||||
},
|
},
|
||||||
"/" : function(lnum, args) {
|
"/" : function(lnum, args) {
|
||||||
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh / rh; });
|
||||||
var lh = resolve(args[0]); var rh = resolve(args[1]);
|
|
||||||
if (lh === undefined) throw lang.refError(lnum, args[0].value);
|
|
||||||
if (rh === undefined) throw lang.refError(lnum, args[1].value);
|
|
||||||
if (isNaN(lh)) throw lang.illegalType(lnum, args[0].value);
|
|
||||||
if (isNaN(rh)) throw lang.illegalType(lnum, args[1].value);
|
|
||||||
|
|
||||||
return lh / rh;
|
|
||||||
},
|
},
|
||||||
"MOD" : function(lnum, args) {
|
"MOD" : function(lnum, args) {
|
||||||
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { return lh % rh; });
|
||||||
var lh = resolve(args[0]); var rh = resolve(args[1]);
|
|
||||||
if (lh === undefined) throw lang.refError(lnum, args[0].value);
|
|
||||||
if (rh === undefined) throw lang.refError(lnum, args[1].value);
|
|
||||||
if (isNaN(lh)) throw lang.illegalType(lnum, args[0].value);
|
|
||||||
if (isNaN(rh)) throw lang.illegalType(lnum, args[1].value);
|
|
||||||
|
|
||||||
return lh % rh;
|
|
||||||
},
|
},
|
||||||
"^" : function(lnum, args) {
|
"^" : function(lnum, args) {
|
||||||
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
return twoArgNonNullNumeric(lnum, args, function(lh, rh) { Math.pow(lh, rh); });
|
||||||
var lh = resolve(args[0]); var rh = resolve(args[1]);
|
|
||||||
if (lh === undefined) throw lang.refError(lnum, args[0].value);
|
|
||||||
if (rh === undefined) throw lang.refError(lnum, args[1].value);
|
|
||||||
if (isNaN(lh)) throw lang.illegalType(lnum, args[0].value);
|
|
||||||
if (isNaN(rh)) throw lang.illegalType(lnum, args[1].value);
|
|
||||||
|
|
||||||
return Math.pow(lh, rh);
|
|
||||||
},
|
},
|
||||||
"PRINT" : function(lnum, args) {
|
"PRINT" : function(lnum, args) {
|
||||||
//serial.println("BASIC func: PRINT -- args="+(args.map(function(it) { return it.type+" "+it.value; })).join(", "));
|
//serial.println("BASIC func: PRINT -- args="+(args.map(function(it) { return it.type+" "+it.value; })).join(", "));
|
||||||
@@ -278,32 +335,22 @@ basicInterpreterStatus.builtin = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"POKE" : function(lnum, args) {
|
"POKE" : function(lnum, args) {
|
||||||
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
twoArgNonNullNumeric(lnum, args, function(lh, rh) { sys.poke(lh, rh); });
|
||||||
var lh = resolve(args[0]); var rh = resolve(args[1]);
|
},
|
||||||
if (lh === undefined) throw lang.refError(lnum, args[0].value);
|
"PEEK" : function(lnum, args) {
|
||||||
if (rh === undefined) throw lang.refError(lnum, args[1].value);
|
return oneArgNonNullNumeric(lnum, args, function(lh) { return sys.peek(lh); });
|
||||||
if (isNaN(lh)) throw lang.illegalType(lnum, args[0].value);
|
|
||||||
if (isNaN(rh)) throw lang.illegalType(lnum, args[1].value);
|
|
||||||
|
|
||||||
sys.poke(lh, rh);
|
|
||||||
},
|
},
|
||||||
"GOTO" : function(lnum, args) {
|
"GOTO" : function(lnum, args) {
|
||||||
if (args.length != 1) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
return oneArgNonNullNumeric(lnum, args, function(lh) { return lh; });
|
||||||
var lh = resolve(args[0]);
|
|
||||||
if (lh === undefined) throw lang.refError(lnum, args[0].value);
|
|
||||||
if (isNaN(lh)) throw lang.illegalType(lnum, args[0].value);
|
|
||||||
return lh;
|
|
||||||
},
|
},
|
||||||
"GOSUB" : function(lnum, args) {
|
"GOSUB" : function(lnum, args) {
|
||||||
if (args.length != 1) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
return oneArgNonNullNumeric(lnum, args, function(lh) {
|
||||||
var lh = resolve(args[0]);
|
basicInterpreterStatus.gosubStack.push(lnum + 1);
|
||||||
if (lh === undefined) throw lang.refError(lnum, args[0].value);
|
return lh;
|
||||||
if (isNaN(lh)) throw lang.illegalType(lnum, args[0].value);
|
});
|
||||||
basicInterpreterStatus.gosubStack.push(lnum + 1);
|
|
||||||
return lh;
|
|
||||||
},
|
},
|
||||||
"RETURN" : function(lnum, args) {
|
"RETURN" : function(lnum, args) {
|
||||||
var r = basicInterpreterStatus.gosubStack.pop();
|
var r = basicInterpreterStatus.gosubStack.pop();
|
||||||
if (r === undefined) throw lang.nowhereToReturn(lnum);
|
if (r === undefined) throw lang.nowhereToReturn(lnum);
|
||||||
return r;
|
return r;
|
||||||
},
|
},
|
||||||
@@ -311,15 +358,33 @@ basicInterpreterStatus.builtin = {
|
|||||||
basicInterpreterStatus.variables = {};
|
basicInterpreterStatus.variables = {};
|
||||||
},
|
},
|
||||||
"PLOT" : function(lnum, args) {
|
"PLOT" : function(lnum, args) {
|
||||||
if (args.length != 3) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
threeArgNonNullNumeric(lnum, args, function(xpos, ypos, color) { graphics.plotPixel(xpos, ypos, color); });
|
||||||
var xpos = resolve(args[0]); var ypos = resolve(args[1]); var color = resolve(args[2]);
|
},
|
||||||
if (xpos === undefined) throw lang.refError(lnum, args[0].value);
|
"AND" : function(lnum, args) {
|
||||||
if (ypos === undefined) throw lang.refError(lnum, args[1].value);
|
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
if (color === undefined) throw lang.refError(lnum, args[2].value);
|
var resolvedargs = args.map(function(it) { return resolve(it); });
|
||||||
if (isNaN(xpos)) throw lang.illegalType(lnum, args[0].value);
|
resolvedargs.forEach(function(v) {
|
||||||
if (isNaN(ypos)) throw lang.illegalType(lnum, args[1].value);
|
if (v === undefined) throw lang.refError(lnum, v.value);
|
||||||
if (isNaN(color)) throw lang.illegalType(lnum, args[2].value);
|
if (typeof v !== "boolean") throw lang.illegalType(lnum, v.value);
|
||||||
graphics.plotPixel(xpos, ypos, color);
|
});
|
||||||
|
var argum = resolvedargs.map(function(it) {
|
||||||
|
if (it === undefined) throw lang.refError(lnum, it.value);
|
||||||
|
return it;
|
||||||
|
});
|
||||||
|
return argum[0] && argum[1];
|
||||||
|
},
|
||||||
|
"OR" : function(lnum, args) {
|
||||||
|
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length + " arguments were given");
|
||||||
|
var resolvedargs = args.map(function(it) { return resolve(it); });
|
||||||
|
resolvedargs.forEach(function(v) {
|
||||||
|
if (v === undefined) throw lang.refError(lnum, v.value);
|
||||||
|
if (typeof v !== "boolean") throw lang.illegalType(lnum, v.value);
|
||||||
|
});
|
||||||
|
var argum = resolvedargs.map(function(it) {
|
||||||
|
if (it === undefined) throw lang.refError(lnum, it.value);
|
||||||
|
return it;
|
||||||
|
});
|
||||||
|
return argum[0] || argum[1];
|
||||||
},
|
},
|
||||||
"TEST" : function(lnum, args) {
|
"TEST" : function(lnum, args) {
|
||||||
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");
|
||||||
@@ -754,6 +819,13 @@ basicFunctions._parserElaboration = function(lnum, tokens, states) {
|
|||||||
else if (tokens[k].toUpperCase() == "TRUE" || tokens[k].toUpperCase() == "FALSE")
|
else if (tokens[k].toUpperCase() == "TRUE" || tokens[k].toUpperCase() == "FALSE")
|
||||||
states[k] = "bool";
|
states[k] = "bool";
|
||||||
|
|
||||||
|
// decimalise hex/bin numbers (because Nashorn does not support binary literal)
|
||||||
|
if (states[k] == "number") {
|
||||||
|
if (tokens[k].toUpperCase().startsWith("0B")) {
|
||||||
|
tokens[k] = parseInt(tokens[k].substring(2, tokens[k].length), 2) + "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
k += 1;
|
k += 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user