mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
migration to graal
This commit is contained in:
20
.idea/libraries/org_graalvm_js_js_20_3_0.xml
generated
Normal file
20
.idea/libraries/org_graalvm_js_js_20_3_0.xml
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
<component name="libraryTable">
|
||||
<library name="org.graalvm.js:js:20.3.0" type="repository">
|
||||
<properties maven-id="org.graalvm.js:js:20.3.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/js-20.3.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/regex-20.3.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/truffle-api-20.3.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/graal-sdk-20.3.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/icu4j-67.1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$PROJECT_DIR$/lib/js-20.3.0-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/regex-20.3.0-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/truffle-api-20.3.0-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/graal-sdk-20.3.0-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/icu4j-67.1-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
14
.idea/libraries/org_graalvm_js_js_scriptengine_20_3_0.xml
generated
Normal file
14
.idea/libraries/org_graalvm_js_js_scriptengine_20_3_0.xml
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
<component name="libraryTable">
|
||||
<library name="org.graalvm.js:js-scriptengine:20.3.0" type="repository">
|
||||
<properties maven-id="org.graalvm.js:js-scriptengine:20.3.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/js-scriptengine-20.3.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/graal-sdk-20.3.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$PROJECT_DIR$/lib/js-scriptengine-20.3.0-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/graal-sdk-20.3.0-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,26 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="org.jetbrains.kotlin:kotlin-scripting-jsr223:1.3.71" type="repository">
|
||||
<properties maven-id="org.jetbrains.kotlin:kotlin-scripting-jsr223:1.3.71" />
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-scripting-jsr223-1.3.71.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-script-runtime-1.3.71.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-stdlib-1.3.71.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-stdlib-common-1.3.71.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/annotations-13.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-scripting-common-1.3.71.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlinx-coroutines-core-1.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-scripting-jvm-1.3.71.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-scripting-jvm-host-1.3.71.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/trove4j-1.0.20181211.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-scripting-compiler-1.3.71.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-scripting-js-1.3.71.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-util-klib-1.3.71.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-util-io-1.3.71.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-scripting-compiler-impl-1.3.71.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-compiler-1.3.71.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-reflect-1.3.71.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
18
.idea/libraries/org_jetbrains_kotlinx_kotlinx_coroutines_core_1_4_1.xml
generated
Normal file
18
.idea/libraries/org_jetbrains_kotlinx_kotlinx_coroutines_core_1_4_1.xml
generated
Normal file
@@ -0,0 +1,18 @@
|
||||
<component name="libraryTable">
|
||||
<library name="org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1" type="repository">
|
||||
<properties maven-id="org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1" />
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlinx-coroutines-core-1.4.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-stdlib-1.4.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/annotations-13.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-stdlib-common-1.4.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlinx-coroutines-core-1.4.1-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-stdlib-1.4.0-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/annotations-13.0-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/kotlin-stdlib-common-1.4.0-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
@@ -1 +1 @@
|
||||
let p=_BIOS.FIRST_BOOTABLE_PORT;com.sendMessage(p[0],"DEVRST\x17");com.sendMessage(p[0],'OPENR"tvdos/TVDOS.SYS",'+p[1]);let r=com.getStatusCode(p[0]);if(0==r)if(com.sendMessage(p[0],"READ"),r=com.getStatusCode([0]),0==r){let g=com.pullMessage(p[0]);eval(g)}else println("I/O Error");else println("TVDOS.SYS not found");println("Shutting down...");println("It is now safe to turn off the power");
|
||||
let p=_BIOS.FIRST_BOOTABLE_PORT;com.sendMessage(p[0],"DEVRST\x17");com.sendMessage(p[0],'OPENR"tvdos/TVDOS.SYS",'+p[1]);let r=com.getStatusCode(p[0]);if(0==r)if(com.sendMessage(p[0],"READ"),r=com.getStatusCode(p[0]),0==r){let g=com.pullMessage(p[0]);eval(g)}else println("I/O Error");else println("TVDOS.SYS not found");println("Shutting down...");println("It is now safe to turn off the power");
|
||||
@@ -80,11 +80,11 @@ fs._flush = function(portNo) {
|
||||
// - java.lang.NullPointerException if path is null
|
||||
// - Error if operation mode is not "R", "W" nor "A"
|
||||
fs.open = function(path, operationMode) {
|
||||
let port = _BIOS.FIRST_BOOTABLE_PORT;
|
||||
var port = _BIOS.FIRST_BOOTABLE_PORT;
|
||||
|
||||
fs._flush(port[0]); fs._close(port[0]);
|
||||
|
||||
let mode = operationMode.toUpperCase();
|
||||
var mode = operationMode.toUpperCase();
|
||||
if (mode != "R" && mode != "W" && mode != "A") {
|
||||
throw Error("Unknown file opening mode: " + mode);
|
||||
}
|
||||
@@ -95,9 +95,9 @@ fs.open = function(path, operationMode) {
|
||||
};
|
||||
// @return the entire contents of the file in String
|
||||
fs.readAll = function() {
|
||||
let port = _BIOS.FIRST_BOOTABLE_PORT;
|
||||
var port = _BIOS.FIRST_BOOTABLE_PORT;
|
||||
com.sendMessage(port[0], "READ");
|
||||
let response = com.getStatusCode(port[0]);
|
||||
var response = com.getStatusCode(port[0]);
|
||||
if (135 == response) {
|
||||
throw Error("File not opened");
|
||||
}
|
||||
@@ -107,9 +107,9 @@ fs.readAll = function() {
|
||||
return com.pullMessage(port[0]);
|
||||
};
|
||||
fs.write = function(string) {
|
||||
let port = _BIOS.FIRST_BOOTABLE_PORT;
|
||||
var port = _BIOS.FIRST_BOOTABLE_PORT;
|
||||
com.sendMessage(port[0], "WRITE"+string.length);
|
||||
let response = com.getStatusCode(port[0]);
|
||||
var response = com.getStatusCode(port[0]);
|
||||
if (135 == response) {
|
||||
throw Error("File not opened");
|
||||
}
|
||||
@@ -125,10 +125,10 @@ Object.freeze(fs);
|
||||
// requirements: reset_graphics(), getch(), curs_set(int), hitterminate(), resetkeybuf(), addch(int)
|
||||
|
||||
let getUsedMemSize = function() {
|
||||
let varsMemSize = 0;
|
||||
var varsMemSize = 0;
|
||||
|
||||
Object.entries(bStatus.vars).forEach(function(pair,i) {
|
||||
let object = pair[1];
|
||||
var object = pair[1];
|
||||
|
||||
if (Array.isArray(object)) {
|
||||
// TODO test 1-D array
|
||||
@@ -441,14 +441,14 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
||||
},
|
||||
"TO" : function(lnum, args) {
|
||||
return twoArgNum(lnum, args, function(from, to) {
|
||||
let a = [];
|
||||
var a = [];
|
||||
if (from <= to) {
|
||||
for (let k = from; k <= to; k++) {
|
||||
for (var k = from; k <= to; k++) {
|
||||
a.push(k);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let k = -from; k <= -to; k++) {
|
||||
for (var k = -from; k <= -to; k++) {
|
||||
a.push(-k);
|
||||
}
|
||||
}
|
||||
@@ -464,7 +464,7 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
||||
var rsvArg1 = resolve(args[1]);
|
||||
if (rsvArg1 === undefined) throw lang.refError(lnum, rsvArg1);
|
||||
if (isNaN(rsvArg1)) throw lang.illegalType(lnum, rsvArg1);
|
||||
let a = []; let stepcnt = 0;
|
||||
var a = []; var stepcnt = 0;
|
||||
rsvArg0.forEach(function(v,i) {
|
||||
if (stepcnt == 0) a.push(v);
|
||||
stepcnt = (stepcnt + 1) % rsvArg1;
|
||||
@@ -474,8 +474,8 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
||||
"DIM" : function(lnum, args) {
|
||||
return oneArgNum(lnum, args, function(size) {
|
||||
if (size <= 0) throw lang.syntaxfehler(lnum, size);
|
||||
let a = [];
|
||||
for (let k = 0; k < size; k++) a.push(0);
|
||||
var a = [];
|
||||
for (var k = 0; k < size; k++) a.push(0);
|
||||
return a;
|
||||
});
|
||||
},
|
||||
@@ -601,12 +601,12 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
||||
return resolve(args[0]);
|
||||
},
|
||||
"FOR" : function(lnum, args) {
|
||||
let asgnObj = resolve(args[0]);
|
||||
var asgnObj = resolve(args[0]);
|
||||
// type check
|
||||
if (asgnObj === undefined) throw lang.syntaxfehler(lnum);
|
||||
if (!Array.isArray(asgnObj.asgnValue)) throw lang.illegalType(lnum, asgnObj);
|
||||
|
||||
let varname = asgnObj.asgnVarName;
|
||||
var varname = asgnObj.asgnVarName;
|
||||
|
||||
// assign new variable
|
||||
// the var itself will have head of the array, and the head itself will be removed from the array
|
||||
@@ -621,7 +621,7 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
||||
// if no args were given
|
||||
if (args.length == 0 || (args.length == 1 && args.troType == "null")) {
|
||||
// go to most recent FOR
|
||||
let forVarname = bStatus.forStack.pop();
|
||||
var forVarname = bStatus.forStack.pop();
|
||||
//serial.println(lnum+" NEXT > forVarname = "+forVarname);
|
||||
if (forVarname === undefined) {
|
||||
throw lang.nextWithoutFor(lnum);
|
||||
@@ -680,7 +680,7 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
||||
*/
|
||||
"INPUT" : function(lnum, args) {
|
||||
// just use tail-end arg as an input variable
|
||||
let endArg = args.pop();
|
||||
var endArg = args.pop();
|
||||
if (endArg === undefined) {
|
||||
system.printerr("INPUT called with no arguments");
|
||||
return undefined;
|
||||
@@ -689,7 +689,7 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
||||
// print out prompt text
|
||||
print("? ");
|
||||
|
||||
let inputstr = sys.read().trim();
|
||||
var inputstr = sys.read().trim();
|
||||
|
||||
// screw with the comma-separating because shrug
|
||||
bStatus.vars[endArg.troValue] = new BasicVar(inputstr, JStoBASICtype(inputstr));
|
||||
@@ -767,12 +767,12 @@ bF._keywords = {
|
||||
|
||||
};
|
||||
bF._tokenise = function(lnum, cmd) {
|
||||
let _debugprintStateTransition = false;
|
||||
let k;
|
||||
let tokens = [];
|
||||
let states = [];
|
||||
let sb = "";
|
||||
let mode = "lit"; // literal, quote, paren, sep, operator, number; operator2, numbersep, number2, limbo, escape, quote_end
|
||||
var _debugprintStateTransition = false;
|
||||
var k;
|
||||
var tokens = [];
|
||||
var states = [];
|
||||
var sb = "";
|
||||
var mode = "lit"; // literal, quote, paren, sep, operator, number; operator2, numbersep, number2, limbo, escape, quote_end
|
||||
|
||||
// NOTE: malformed numbers (e.g. "_b3", "_", "__") must be re-marked as literal or syntax error in the second pass
|
||||
|
||||
@@ -1245,9 +1245,9 @@ bF._parseTokens = function(lnum, tokens, states, recDepth) {
|
||||
return retTreeHead;
|
||||
}
|
||||
|
||||
let k;
|
||||
let headWord = tokens[0].toLowerCase();
|
||||
let treeHead = new BasicAST();
|
||||
var k;
|
||||
var headWord = tokens[0].toLowerCase();
|
||||
var treeHead = new BasicAST();
|
||||
treeHead.astDepth = recDepth;
|
||||
treeHead.astLnum = lnum;
|
||||
|
||||
@@ -1583,7 +1583,7 @@ bF._executeSyntaxTree = function(lnum, syntaxTree, recDepth) {
|
||||
|
||||
// func not in builtins (e.g. array access, user-defined function defuns)
|
||||
if (func === undefined) {
|
||||
let someVar = bStatus.vars[funcName];
|
||||
var someVar = bStatus.vars[funcName];
|
||||
if (someVar === undefined) {
|
||||
throw lang.syntaxfehler(lnum, funcName + " is undefined");
|
||||
}
|
||||
@@ -1741,18 +1741,18 @@ bF.run = function(args) { // RUN function
|
||||
bF.save = function(args) { // SAVE function
|
||||
if (args[1] === undefined) throw lang.missingOperand;
|
||||
fs.open(args[1], "W");
|
||||
let sb = "";
|
||||
var sb = "";
|
||||
cmdbuf.forEach(function(v,i) { sb += i+" "+v+"\n"; });
|
||||
fs.write(sb);
|
||||
};
|
||||
bF.load = function(args) { // LOAD function
|
||||
if (args[1] === undefined) throw lang.missingOperand;
|
||||
let fileOpened = fs.open(args[1], "R");
|
||||
var fileOpened = fs.open(args[1], "R");
|
||||
if (!fileOpened) {
|
||||
throw lang.noSuchFile;
|
||||
return;
|
||||
}
|
||||
let prg = fs.readAll();
|
||||
var prg = fs.readAll();
|
||||
|
||||
// reset the environment
|
||||
cmdbuf = [];
|
||||
@@ -1760,36 +1760,36 @@ bF.load = function(args) { // LOAD function
|
||||
|
||||
// read the source
|
||||
prg.split('\n').forEach(function(line) {
|
||||
let i = line.indexOf(" ");
|
||||
let lnum = line.slice(0, i);
|
||||
var i = line.indexOf(" ");
|
||||
var lnum = line.slice(0, i);
|
||||
if (isNaN(lnum)) throw lang.illegalType();
|
||||
cmdbuf[lnum] = line.slice(i + 1, line.length);
|
||||
});
|
||||
};
|
||||
bF.catalog = function(args) { // CATALOG function
|
||||
if (args[1] === undefined) args[1] = "\\";
|
||||
let pathOpened = fs.open(args[1], 'R');
|
||||
var pathOpened = fs.open(args[1], 'R');
|
||||
if (!pathOpened) {
|
||||
throw lang.noSuchFile;
|
||||
return;
|
||||
}
|
||||
let port = _BIOS.FIRST_BOOTABLE_PORT[0];
|
||||
var port = _BIOS.FIRST_BOOTABLE_PORT[0];
|
||||
com.sendMessage(port, "LIST");
|
||||
println(com.pullMessage(port));
|
||||
};
|
||||
Object.freeze(bF);
|
||||
while (!tbasexit) {
|
||||
let line = sys.read().trim();
|
||||
var line = sys.read().trim();
|
||||
|
||||
cmdbufMemFootPrint += line.length;
|
||||
|
||||
if (reLineNum.test(line)) {
|
||||
let i = line.indexOf(" ");
|
||||
var i = line.indexOf(" ");
|
||||
cmdbuf[line.slice(0, i)] = line.slice(i + 1, line.length);
|
||||
}
|
||||
else if (line.length > 0) {
|
||||
cmdbufMemFootPrint -= line.length;
|
||||
let cmd = line.split(" ");
|
||||
var cmd = line.split(" ");
|
||||
if (bF[cmd[0].toLowerCase()] === undefined) {
|
||||
serial.printerr("Unknown command: "+cmd[0].toLowerCase());
|
||||
println(lang.syntaxfehler());
|
||||
|
||||
@@ -5,7 +5,7 @@ com.sendMessage(p[0], 'OPENR"tvdos/TVDOS.SYS",'+p[1]);
|
||||
let r = com.getStatusCode(p[0]);
|
||||
if (r == 0){
|
||||
com.sendMessage(p[0], "READ");
|
||||
r = com.getStatusCode([0]);
|
||||
r = com.getStatusCode(p[0]);
|
||||
if (r == 0) {
|
||||
let g=com.pullMessage(p[0]);
|
||||
eval(g);
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
println("JS Console");
|
||||
let _cmdHistory = []; // zeroth element is the oldest
|
||||
let _cmdHistoryScroll = 0; // 0 for outside-of-buffer, 1 for most recent
|
||||
while (true) {
|
||||
print("JS> ");
|
||||
|
||||
let _cmdbuf = "";
|
||||
|
||||
while (true) {
|
||||
let key = con.getch();
|
||||
|
||||
// printable chars
|
||||
if (key >= 32 && key <= 126) {
|
||||
let __sss = String.fromCharCode(key);
|
||||
_cmdbuf += __sss;
|
||||
print(__sss);
|
||||
}
|
||||
// backspace
|
||||
else if (key === 8 && _cmdbuf.length > 0) {
|
||||
_cmdbuf = _cmdbuf.substring(0, _cmdbuf.length - 1);
|
||||
print(String.fromCharCode(key));
|
||||
}
|
||||
// enter
|
||||
else if (key === 10 || key === 13) {
|
||||
println();
|
||||
try {
|
||||
let prg = eval("let _appStub=function(){"+_cmdbuf+"};_appStub;"); // making 'exec_args' a app-level global
|
||||
println(prg());
|
||||
}
|
||||
catch (e) {
|
||||
printerrln(e);
|
||||
}
|
||||
finally {
|
||||
if (_cmdbuf.trim().length > 0)
|
||||
_cmdHistory.push(_cmdbuf);
|
||||
|
||||
_cmdHistoryScroll = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// up arrow
|
||||
else if (key === 19 && _cmdHistory.length > 0 && _cmdHistoryScroll < _cmdHistory.length) {
|
||||
_cmdHistoryScroll += 1;
|
||||
|
||||
// back the cursor in order to type new cmd
|
||||
let __xx = 0;
|
||||
for (__xx = 0; __xx < _cmdbuf.length; __xx++) print(String.fromCharCode(8));
|
||||
_cmdbuf = _cmdHistory[_cmdHistory.length - _cmdHistoryScroll];
|
||||
// re-type the new command
|
||||
print(_cmdbuf);
|
||||
|
||||
}
|
||||
// down arrow
|
||||
else if (key === 20) {
|
||||
if (_cmdHistoryScroll > 0) {
|
||||
// back the cursor in order to type new cmd
|
||||
let __xx = 0;
|
||||
for (__xx = 0; __xx < _cmdbuf.length; __xx++) print(String.fromCharCode(8));
|
||||
_cmdbuf = _cmdHistory[_cmdHistory.length - _cmdHistoryScroll];
|
||||
// re-type the new command
|
||||
print(_cmdbuf);
|
||||
|
||||
_cmdHistoryScroll -= 1;
|
||||
}
|
||||
else {
|
||||
// back the cursor in order to type new cmd
|
||||
for (__xx = 0; __xx < _cmdbuf.length; __xx++) print(String.fromCharCode(8));
|
||||
_cmdbuf = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ filesystem._toPorts = function(driveLetter) {
|
||||
if (driveLetter.toUpperCase === undefined) {
|
||||
throw Error("'"+driveLetter+"' (type: "+typeof driveLetter+") is not a valid drive letter");
|
||||
}
|
||||
let port = _TVDOS.DRIVES[driveLetter.toUpperCase()];
|
||||
var port = _TVDOS.DRIVES[driveLetter.toUpperCase()];
|
||||
if (port === undefined) {
|
||||
throw Error("Drive letter '" + driveLetter.toUpperCase() + "' does not exist");
|
||||
}
|
||||
@@ -48,24 +48,24 @@ filesystem._flush = function(portNo) {
|
||||
// - java.lang.NullPointerException if path is null
|
||||
// - Error if operation mode is not "R", "W" nor "A"
|
||||
filesystem.open = function(driveLetter, path, operationMode) {
|
||||
let port = filesystem._toPorts(driveLetter);
|
||||
var port = filesystem._toPorts(driveLetter);
|
||||
|
||||
filesystem._flush(port[0]); filesystem._close(port[0]);
|
||||
|
||||
let mode = operationMode.toUpperCase();
|
||||
var mode = operationMode.toUpperCase();
|
||||
if (mode != "R" && mode != "W" && mode != "A") {
|
||||
throw Error("Unknown file opening mode: " + mode);
|
||||
}
|
||||
|
||||
com.sendMessage(port[0], "OPEN"+mode+'"'+path+'",'+port[1]);
|
||||
let response = com.getStatusCode(port[0]);
|
||||
var response = com.getStatusCode(port[0]);
|
||||
return (response == 0);
|
||||
};
|
||||
// @return the entire contents of the file in String
|
||||
filesystem.readAll = function(driveLetter) {
|
||||
let port = filesystem._toPorts(driveLetter);
|
||||
var port = filesystem._toPorts(driveLetter);
|
||||
com.sendMessage(port[0], "READ");
|
||||
let response = com.getStatusCode(port[0]);
|
||||
var response = com.getStatusCode(port[0]);
|
||||
if (135 == response) {
|
||||
throw Error("File not opened");
|
||||
}
|
||||
@@ -75,9 +75,9 @@ filesystem.readAll = function(driveLetter) {
|
||||
return com.pullMessage(port[0]);
|
||||
};
|
||||
filesystem.write = function(driveLetter, string) {
|
||||
let port = filesystem._toPorts(driveLetter);
|
||||
var port = filesystem._toPorts(driveLetter);
|
||||
com.sendMessage(port[0], "WRITE"+string.length);
|
||||
let response = com.getStatusCode(port[0]);
|
||||
var response = com.getStatusCode(port[0]);
|
||||
if (135 == response) {
|
||||
throw Error("File not opened");
|
||||
}
|
||||
@@ -88,32 +88,32 @@ filesystem.write = function(driveLetter, string) {
|
||||
filesystem._flush(port[0]); filesystem._close(port[0]);
|
||||
};
|
||||
filesystem.isDirectory = function(driveLetter) {
|
||||
let port = filesystem._toPorts(driveLetter);
|
||||
var port = filesystem._toPorts(driveLetter);
|
||||
com.sendMessage(port[0], "LISTFILES");
|
||||
let response = com.getStatusCode(port[0]);
|
||||
var response = com.getStatusCode(port[0]);
|
||||
return (response === 0);
|
||||
};
|
||||
filesystem.mkDir = function(driveLetter) {
|
||||
let port = filesystem._toPorts(driveLetter);
|
||||
var port = filesystem._toPorts(driveLetter);
|
||||
com.sendMessage(port[0], "MKDIR");
|
||||
let response = com.getStatusCode(port[0]);
|
||||
var response = com.getStatusCode(port[0]);
|
||||
|
||||
if (response < 0 || response >= 128) {
|
||||
let status = com.getDeviceStatus(port[0]);
|
||||
var status = com.getDeviceStatus(port[0]);
|
||||
throw Error("Creating a directory failed with ("+response+"): "+status.message+"\n");
|
||||
}
|
||||
return (response === 0); // possible status codes: 0 (success), 1 (fail)
|
||||
};
|
||||
filesystem.touch = function(driveLetter) {
|
||||
let port = filesystem._toPorts(driveLetter);
|
||||
var port = filesystem._toPorts(driveLetter);
|
||||
com.sendMessage(port[0], "TOUCH");
|
||||
let response = com.getStatusCode(port[0]);
|
||||
var response = com.getStatusCode(port[0]);
|
||||
return (response === 0);
|
||||
};
|
||||
filesystem.mkFile = function(driveLetter) {
|
||||
let port = filesystem._toPorts(driveLetter);
|
||||
var port = filesystem._toPorts(driveLetter);
|
||||
com.sendMessage(port[0], "MKFILE");
|
||||
let response = com.getStatusCode(port[0]);
|
||||
var response = com.getStatusCode(port[0]);
|
||||
return (response === 0);
|
||||
};
|
||||
Object.freeze(filesystem);
|
||||
@@ -128,8 +128,8 @@ var GL = eval(filesystem.readAll("A"));
|
||||
// @param args arguments for the program, must be Array, and args[0] is always the name of the program, e.g.
|
||||
// for command line 'echo foo bar', args[0] must be 'echo'
|
||||
var execApp = function(cmdsrc, args) {
|
||||
let prg = eval("let _appStub=function(exec_args){"+cmdsrc+"};_appStub;"); // making 'exec_args' a app-level global
|
||||
return prg(args);
|
||||
var execAppPrg = eval("var _appStub=function(exec_args){"+cmdsrc+"};_appStub;"); // making 'exec_args' a app-level global
|
||||
return execAppPrg(args);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -49,9 +49,9 @@ function greet() {
|
||||
}
|
||||
|
||||
function trimStartRevSlash(s) {
|
||||
let cnt = 0;
|
||||
var cnt = 0;
|
||||
while (cnt < s.length) {
|
||||
let chr = s[cnt];
|
||||
var chr = s[cnt];
|
||||
|
||||
if (chr != '\\') break;
|
||||
|
||||
@@ -66,10 +66,10 @@ shell.getPwd = function() { return shell_pwd; }
|
||||
shell.getCurrentDrive = function() { return CURRENT_DRIVE; }
|
||||
// example input: echo "the string" > subdir\test.txt
|
||||
shell.parse = function(input) {
|
||||
let tokens = [];
|
||||
let stringBuffer = "";
|
||||
let mode = "LITERAL"; // LITERAL, QUOTE, ESCAPE, LIMBO
|
||||
let i = 0
|
||||
var tokens = [];
|
||||
var stringBuffer = "";
|
||||
var mode = "LITERAL"; // LITERAL, QUOTE, ESCAPE, LIMBO
|
||||
var i = 0
|
||||
while (i < input.length) {
|
||||
const c = input[i];
|
||||
/*digraph g {
|
||||
@@ -136,12 +136,12 @@ shell.parse = function(input) {
|
||||
}
|
||||
shell.resolvePathInput = function(input) {
|
||||
// replace slashes into revslashes
|
||||
let pathstr = input.replaceAll('/','\\\\');
|
||||
let startsWithSlash = input.startsWith('\\');
|
||||
let newPwd = [];
|
||||
var pathstr = input.replaceAll('/','\\\\');
|
||||
var startsWithSlash = input.startsWith('\\');
|
||||
var newPwd = [];
|
||||
|
||||
// split them into an array while filtering empty elements except for the root 'head'
|
||||
let ipwd = (startsWithSlash ? [""] : shell_pwd).concat(pathstr.split("\\").filter(function(it) { return (it.length > 0); }));
|
||||
var ipwd = (startsWithSlash ? [""] : shell_pwd).concat(pathstr.split("\\").filter(function(it) { return (it.length > 0); }));
|
||||
|
||||
serial.println("command.js > resolvePathInput > ipwd = "+ipwd);
|
||||
serial.println("command.js > resolvePathInput > newPwd = "+newPwd);
|
||||
@@ -177,12 +177,12 @@ shell.coreutils = {
|
||||
println(CURRENT_DRIVE+":"+shell_pwd.join("\\"));
|
||||
return
|
||||
}
|
||||
let path = shell.resolvePathInput(args[1])
|
||||
var path = shell.resolvePathInput(args[1])
|
||||
if (DEBUG_PRINT) serial.println("command.js > cd > pathstr = "+path.string);
|
||||
|
||||
// check if path is valid
|
||||
filesystem.open(CURRENT_DRIVE, path.string, 'R');
|
||||
let dirOpened = filesystem.isDirectory(CURRENT_DRIVE); // open a dir; if path is nonexistent, file won't actually be opened
|
||||
var dirOpened = filesystem.isDirectory(CURRENT_DRIVE); // open a dir; if path is nonexistent, file won't actually be opened
|
||||
if (!dirOpened) { printerrln("CHDIR failed for '"+path.string+"'"); return; } // if file is not opened, FALSE will be returned
|
||||
|
||||
shell_pwd = path.pwd;
|
||||
@@ -192,12 +192,12 @@ shell.coreutils = {
|
||||
printerrln("Syntax error");
|
||||
return
|
||||
}
|
||||
let path = shell.resolvePathInput(args[1])
|
||||
var path = shell.resolvePathInput(args[1])
|
||||
if (DEBUG_PRINT) serial.println("command.js > mkdir > pathstr = "+path.string);
|
||||
|
||||
// check if path is valid
|
||||
let dirOpened = filesystem.open(CURRENT_DRIVE, path.string, 'W');
|
||||
let mkdird = filesystem.mkDir(CURRENT_DRIVE);
|
||||
var dirOpened = filesystem.open(CURRENT_DRIVE, path.string, 'W');
|
||||
var mkdird = filesystem.mkDir(CURRENT_DRIVE);
|
||||
if (!mkdird) { printerrln("MKDIR failed for '"+path.string+"'"); return; }
|
||||
},
|
||||
cls: function(args) {
|
||||
@@ -225,13 +225,13 @@ shell.coreutils = {
|
||||
}
|
||||
else {
|
||||
// parse key-value pair with splitter '='
|
||||
let key = undefined; let value = undefined;
|
||||
var key = undefined; var value = undefined;
|
||||
// if syntax "<key> = <value>" is used?
|
||||
if ('=' == args[2]) {
|
||||
key = args[1].toUpperCase(); value = args[3];
|
||||
}
|
||||
else if (args[2] === undefined) {
|
||||
let pair = args[1].split('=');
|
||||
var pair = args[1].split('=');
|
||||
key = pair[0].toUpperCase(); value = pair[1];
|
||||
}
|
||||
|
||||
@@ -251,13 +251,13 @@ shell.coreutils = {
|
||||
}
|
||||
},
|
||||
dir: function(args) {
|
||||
let pathstr = (args[1] !== undefined) ? args[1] : "\\"+shell_pwd.join("\\");
|
||||
var pathstr = (args[1] !== undefined) ? args[1] : "\\"+shell_pwd.join("\\");
|
||||
|
||||
// check if path is valid
|
||||
let pathOpened = filesystem.open(CURRENT_DRIVE, pathstr, 'R');
|
||||
var pathOpened = filesystem.open(CURRENT_DRIVE, pathstr, 'R');
|
||||
if (!pathOpened) { printerrln("File not found"); return; }
|
||||
|
||||
let port = filesystem._toPorts(CURRENT_DRIVE)[0]
|
||||
var port = filesystem._toPorts(CURRENT_DRIVE)[0]
|
||||
com.sendMessage(port, "LIST");
|
||||
println(com.pullMessage(port));
|
||||
}
|
||||
@@ -266,24 +266,24 @@ shell.coreutils.chdir = shell.coreutils.cd;
|
||||
Object.freeze(shell.coreutils);
|
||||
shell.execute = function(line) {
|
||||
if (0 == line.size) return;
|
||||
let tokens = shell.parse(line);
|
||||
let cmd = tokens[0];
|
||||
var tokens = shell.parse(line);
|
||||
var cmd = tokens[0];
|
||||
if (cmd === undefined || cmd === '') return 0;
|
||||
|
||||
// handle Ctrl-C
|
||||
if (con.hitterminate()) return 1;
|
||||
|
||||
if (shell.coreutils[cmd.toLowerCase()] !== undefined) {
|
||||
let retval = shell.coreutils[cmd.toLowerCase()](tokens);
|
||||
var retval = shell.coreutils[cmd.toLowerCase()](tokens);
|
||||
return retval|0; // return value of undefined will cast into 0
|
||||
}
|
||||
else {
|
||||
// search through PATH for execution
|
||||
|
||||
let fileExists = false;
|
||||
let searchDir = (cmd.startsWith("\\")) ? [""] : ["\\"+shell_pwd.join("\\")].concat(_TVDOS.getPath());
|
||||
var fileExists = false;
|
||||
var searchDir = (cmd.startsWith("\\")) ? [""] : ["\\"+shell_pwd.join("\\")].concat(_TVDOS.getPath());
|
||||
|
||||
let pathExt = [];
|
||||
var pathExt = []; // it seems Nashorn does not like 'let' too much? this line gets ignored sometimes
|
||||
// fill pathExt using %PATHEXT% but also capitalise them
|
||||
if (cmd.split(".")[1] === undefined)
|
||||
_TVDOS.variables.PATHEXT.split(';').forEach(function(it) { pathExt.push(it); pathExt.push(it.toUpperCase()); });
|
||||
@@ -291,10 +291,10 @@ shell.execute = function(line) {
|
||||
pathExt.push(""); // final empty extension
|
||||
|
||||
searchLoop:
|
||||
for (let i = 0; i < searchDir.length; i++) {
|
||||
for (let j = 0; j < pathExt.length; j++) {
|
||||
let search = searchDir[i]; if (!search.endsWith('\\')) search += '\\';
|
||||
let path = trimStartRevSlash(search + cmd + pathExt[j]);
|
||||
for (var i = 0; i < searchDir.length; i++) {
|
||||
for (var j = 0; j < pathExt.length; j++) {
|
||||
var search = searchDir[i]; if (!search.endsWith('\\')) search += '\\';
|
||||
var path = trimStartRevSlash(search + cmd + pathExt[j]);
|
||||
|
||||
if (DEBUG_PRINT) {
|
||||
serial.println("[command.js > shell.execute] file search path: "+path);
|
||||
@@ -312,21 +312,21 @@ shell.execute = function(line) {
|
||||
return 127;
|
||||
}
|
||||
else {
|
||||
let prg = filesystem.readAll(CURRENT_DRIVE);
|
||||
let extension = undefined;
|
||||
var programCode = filesystem.readAll(CURRENT_DRIVE);
|
||||
var extension = undefined;
|
||||
// get proper extension
|
||||
let dotSepTokens = cmd.split('.');
|
||||
var dotSepTokens = cmd.split('.');
|
||||
if (dotSepTokens.length > 1) extension = dotSepTokens[dotSepTokens.length - 1].toUpperCase();
|
||||
|
||||
if ("BAT" == extension) {
|
||||
// parse and run as batch file
|
||||
let lines = prg.split('\n').filter(function(it) { return it.length > 0; });
|
||||
var lines = programCode.split('\n').filter(function(it) { return it.length > 0; });
|
||||
lines.forEach(function(line) {
|
||||
shell.execute(line);
|
||||
});
|
||||
}
|
||||
else {
|
||||
return execApp(prg, tokens)|0; // return value of undefined will cast into 0
|
||||
return execApp(programCode, tokens)|0; // return value of undefined will cast into 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,7 +339,7 @@ _G.shell = shell;
|
||||
|
||||
if (exec_args[1] !== undefined) {
|
||||
// only meaningful switches would be either /c or /k anyway
|
||||
let firstSwitch = exec_args[1].toLowerCase();
|
||||
var firstSwitch = exec_args[1].toLowerCase();
|
||||
|
||||
// command /c <commands>
|
||||
// ^[0] ^[1] ^[2]
|
||||
@@ -376,14 +376,14 @@ if (goInteractive) {
|
||||
con.reset_graphics();
|
||||
print_prompt_text();
|
||||
|
||||
let cmdbuf = "";
|
||||
var cmdbuf = "";
|
||||
|
||||
while (true) {
|
||||
let key = con.getch();
|
||||
var key = con.getch();
|
||||
|
||||
// printable chars
|
||||
if (key >= 32 && key <= 126) {
|
||||
let s = String.fromCharCode(key);
|
||||
var s = String.fromCharCode(key);
|
||||
cmdbuf += s;
|
||||
print(s);
|
||||
}
|
||||
@@ -421,7 +421,7 @@ if (goInteractive) {
|
||||
cmdHistoryScroll += 1;
|
||||
|
||||
// back the cursor in order to type new cmd
|
||||
let x = 0;
|
||||
var x = 0;
|
||||
for (x = 0; x < cmdbuf.length; x++) print(String.fromCharCode(8));
|
||||
cmdbuf = cmdHistory[cmdHistory.length - cmdHistoryScroll];
|
||||
// re-type the new command
|
||||
@@ -432,7 +432,7 @@ if (goInteractive) {
|
||||
else if (key === 20) {
|
||||
if (cmdHistoryScroll > 0) {
|
||||
// back the cursor in order to type new cmd
|
||||
let x = 0;
|
||||
var x = 0;
|
||||
for (x = 0; x < cmdbuf.length; x++) print(String.fromCharCode(8));
|
||||
cmdbuf = cmdHistory[cmdHistory.length - cmdHistoryScroll];
|
||||
// re-type the new command
|
||||
@@ -442,7 +442,7 @@ if (goInteractive) {
|
||||
}
|
||||
else {
|
||||
// back the cursor in order to type new cmd
|
||||
let x = 0;
|
||||
var x = 0;
|
||||
for (x = 0; x < cmdbuf.length; x++) print(String.fromCharCode(8));
|
||||
cmdbuf = "";
|
||||
}
|
||||
|
||||
BIN
lib/annotations-13.0-javadoc.jar
Normal file
BIN
lib/annotations-13.0-javadoc.jar
Normal file
Binary file not shown.
BIN
lib/graal-sdk-20.3.0-javadoc.jar
Normal file
BIN
lib/graal-sdk-20.3.0-javadoc.jar
Normal file
Binary file not shown.
BIN
lib/graal-sdk-20.3.0.jar
Normal file
BIN
lib/graal-sdk-20.3.0.jar
Normal file
Binary file not shown.
BIN
lib/icu4j-67.1-javadoc.jar
Normal file
BIN
lib/icu4j-67.1-javadoc.jar
Normal file
Binary file not shown.
BIN
lib/icu4j-67.1.jar
Normal file
BIN
lib/icu4j-67.1.jar
Normal file
Binary file not shown.
BIN
lib/js-20.3.0-javadoc.jar
Normal file
BIN
lib/js-20.3.0-javadoc.jar
Normal file
Binary file not shown.
BIN
lib/js-20.3.0.jar
Normal file
BIN
lib/js-20.3.0.jar
Normal file
Binary file not shown.
BIN
lib/js-scriptengine-20.3.0-javadoc.jar
Normal file
BIN
lib/js-scriptengine-20.3.0-javadoc.jar
Normal file
Binary file not shown.
BIN
lib/js-scriptengine-20.3.0.jar
Normal file
BIN
lib/js-scriptengine-20.3.0.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
lib/kotlin-stdlib-1.4.0-javadoc.jar
Normal file
BIN
lib/kotlin-stdlib-1.4.0-javadoc.jar
Normal file
Binary file not shown.
BIN
lib/kotlin-stdlib-1.4.0.jar
Normal file
BIN
lib/kotlin-stdlib-1.4.0.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/kotlin-stdlib-common-1.4.0-javadoc.jar
Normal file
BIN
lib/kotlin-stdlib-common-1.4.0-javadoc.jar
Normal file
Binary file not shown.
BIN
lib/kotlin-stdlib-common-1.4.0.jar
Normal file
BIN
lib/kotlin-stdlib-common-1.4.0.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
lib/kotlinx-coroutines-core-1.4.1-javadoc.jar
Normal file
BIN
lib/kotlinx-coroutines-core-1.4.1-javadoc.jar
Normal file
Binary file not shown.
BIN
lib/kotlinx-coroutines-core-1.4.1.jar
Normal file
BIN
lib/kotlinx-coroutines-core-1.4.1.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/regex-20.3.0-javadoc.jar
Normal file
BIN
lib/regex-20.3.0-javadoc.jar
Normal file
Binary file not shown.
BIN
lib/regex-20.3.0.jar
Normal file
BIN
lib/regex-20.3.0.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/truffle-api-20.3.0-javadoc.jar
Normal file
BIN
lib/truffle-api-20.3.0-javadoc.jar
Normal file
Binary file not shown.
BIN
lib/truffle-api-20.3.0.jar
Normal file
BIN
lib/truffle-api-20.3.0.jar
Normal file
Binary file not shown.
@@ -39,10 +39,10 @@ class GraphicsJSR223Delegate(val vm: VM) {
|
||||
}
|
||||
}
|
||||
|
||||
fun plotPixel(x: Int, y: Int, color: Byte) {
|
||||
fun plotPixel(x: Int, y: Int, color: Int) {
|
||||
getFirstGPU()?.let {
|
||||
if (x in 0 until it.config.width && y in 0 until it.config.height) {
|
||||
it.poke(y.toLong() * it.config.width + x, color)
|
||||
it.poke(y.toLong() * it.config.width + x, color.toByte())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,12 +82,12 @@ class GraphicsJSR223Delegate(val vm: VM) {
|
||||
/**
|
||||
* prints a char as-is; won't interpret them as an escape sequence
|
||||
*/
|
||||
fun putSymbol(char: Byte) {
|
||||
fun putSymbol(c: Int) {
|
||||
getFirstGPU()?.let {
|
||||
val (cx, cy) = it.getCursorPos()
|
||||
|
||||
|
||||
it.putChar(cx, cy, char)
|
||||
it.putChar(cx, cy, c.toByte())
|
||||
it.setCursorPos(cx + 1, cy)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package net.torvald.tsvm
|
||||
|
||||
import net.torvald.UnsafeHelper
|
||||
import net.torvald.UnsafePtr
|
||||
import net.torvald.tsvm.firmware.Firmware
|
||||
import net.torvald.tsvm.peripheral.IOSpace
|
||||
import net.torvald.tsvm.peripheral.PeriBase
|
||||
import net.torvald.tsvm.peripheral.VMProgramRom
|
||||
@@ -21,6 +20,9 @@ class VM(
|
||||
val roms: Array<VMProgramRom?> // first ROM must contain the BIOS
|
||||
) {
|
||||
|
||||
class ErrorIllegalAccess(val addr: Long) : RuntimeException("Segmentation fault at 0x${addr.toString(16).padStart(8, '0')}")
|
||||
|
||||
|
||||
val id = java.util.Random().nextInt()
|
||||
|
||||
val memsize = minOf(USER_SPACE_SIZE, _memsize.toLong())
|
||||
@@ -115,10 +117,10 @@ class VM(
|
||||
internal fun poke(addr: Long, value: Byte) {
|
||||
val (memspace, offset) = translateAddr(addr)
|
||||
if (memspace == null)
|
||||
throw Firmware.ErrorIllegalAccess(addr)
|
||||
throw ErrorIllegalAccess(addr)
|
||||
else if (memspace is UnsafePtr) {
|
||||
if (addr >= memspace.size)
|
||||
throw Firmware.ErrorIllegalAccess(addr)
|
||||
throw ErrorIllegalAccess(addr)
|
||||
else
|
||||
memspace.set(offset, value)
|
||||
}
|
||||
@@ -132,7 +134,7 @@ class VM(
|
||||
null
|
||||
else if (memspace is UnsafePtr) {
|
||||
if (addr >= memspace.size)
|
||||
throw Firmware.ErrorIllegalAccess(addr)
|
||||
throw ErrorIllegalAccess(addr)
|
||||
else
|
||||
memspace.get(offset)
|
||||
}
|
||||
|
||||
@@ -38,15 +38,14 @@ class VMJSR223Delegate(val vm: VM) {
|
||||
return r
|
||||
}
|
||||
|
||||
fun print(s: String) {
|
||||
fun print(s: Any) {
|
||||
//System.out.print("[Nashorn] $s")
|
||||
vm.getPrintStream().write(s.toByteArray(VM.CHARSET))
|
||||
vm.getPrintStream().write("$s".toByteArray(VM.CHARSET))
|
||||
}
|
||||
fun println(s: String) {
|
||||
System.out.println("[Nashorn] $s")
|
||||
vm.getPrintStream().write((s + '\n').toByteArray(VM.CHARSET))
|
||||
fun println(s: Any = "") {
|
||||
System.out.println("[Graal] $s")
|
||||
vm.getPrintStream().write(("$s\n").toByteArray(VM.CHARSET))
|
||||
}
|
||||
fun println() = print('\n')
|
||||
|
||||
/**
|
||||
* @return key being hit, of which:
|
||||
@@ -112,7 +111,7 @@ class VMJSR223Delegate(val vm: VM) {
|
||||
}
|
||||
|
||||
class VMSerialDebugger(val vm: VM) {
|
||||
fun print(s: String) = System.out.print(s)
|
||||
fun println(s: String) = System.out.println(s)
|
||||
fun printerr(s: String) = System.err.println(s)
|
||||
fun print(s: Any) = System.out.print("$s")
|
||||
fun println(s: Any) = System.out.println("$s")
|
||||
fun printerr(s: Any) = System.err.println("$s")
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package net.torvald.tsvm
|
||||
|
||||
import net.torvald.tsvm.firmware.Firmware
|
||||
import org.luaj.vm2.LuaTable
|
||||
import org.luaj.vm2.LuaValue
|
||||
import org.luaj.vm2.lib.ZeroArgFunction
|
||||
import org.luaj.vm2.lib.jse.JsePlatform
|
||||
|
||||
class VMLuaAdapter(val vm: VM) {
|
||||
|
||||
val lua = JsePlatform.standardGlobals()
|
||||
|
||||
init {
|
||||
lua.load(Firmware(vm))
|
||||
lua.load("_G.int = function(n) if n > 0 then return math.floor(n) else return math.ceil(n) end end").call()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,20 +31,6 @@ object VMRunnerFactory {
|
||||
}
|
||||
|
||||
return when (extension) {
|
||||
"lua" -> {
|
||||
object : VMRunner(extension) {
|
||||
|
||||
private val vmLua = VMLuaAdapter(vm)
|
||||
|
||||
override suspend fun executeCommand(command: String) {
|
||||
vmLua.lua.load(command).call()
|
||||
}
|
||||
|
||||
override suspend fun evalGlobal(command: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
"vt2" -> {
|
||||
object : VMRunner(extension) {
|
||||
|
||||
@@ -62,18 +48,13 @@ object VMRunnerFactory {
|
||||
}
|
||||
"js" -> {
|
||||
object : VMRunner(extension) {
|
||||
private val engine: ScriptEngine// = ScriptEngineManager().getEngineByExtension(extension)
|
||||
private val engine: ScriptEngine = ScriptEngineManager().getEngineByName("Graal.js")
|
||||
private val bind = engine.getBindings(ScriptContext.ENGINE_SCOPE)
|
||||
|
||||
init {
|
||||
val engineFactory = NashornScriptEngineFactory()
|
||||
engine = engineFactory.getScriptEngine("--no-java", "--no-syntax-extensions", "--language=es6")
|
||||
assertNotNull(engine, "Script engine for extension $extension not found")
|
||||
}
|
||||
// see https://github.com/graalvm/graaljs/blob/master/docs/user/ScriptEngine.md
|
||||
bind.put("polyglot.js.allowHostAccess", true)
|
||||
|
||||
private val context = SimpleScriptContext()
|
||||
private val bind = context.getBindings(ScriptContext.ENGINE_SCOPE)
|
||||
|
||||
init {
|
||||
bind.put("sys", VMJSR223Delegate(vm)) // TODO use delegator class to access peripheral (do not expose VM itself)
|
||||
bind.put("graphics", GraphicsJSR223Delegate(vm))
|
||||
bind.put("serial", VMSerialDebugger(vm))
|
||||
@@ -84,12 +65,12 @@ object VMRunnerFactory {
|
||||
val fr = FileReader("./assets/JS_INIT.js")
|
||||
val prg = fr.readText()
|
||||
fr.close()
|
||||
engine.eval(sanitiseJS(prg), context)
|
||||
engine.eval(sanitiseJS(prg))
|
||||
}
|
||||
|
||||
override suspend fun executeCommand(command: String) {
|
||||
try {
|
||||
engine.eval(encapsulateJS(sanitiseJS(command)), context)
|
||||
engine.eval(encapsulateJS(sanitiseJS(command)))
|
||||
}
|
||||
catch (e: javax.script.ScriptException) {
|
||||
System.err.println("ScriptException from the script:")
|
||||
@@ -99,7 +80,7 @@ object VMRunnerFactory {
|
||||
}
|
||||
|
||||
override suspend fun evalGlobal(command: String) {
|
||||
engine.eval("\"use strict\";" + sanitiseJS(command), context)
|
||||
engine.eval("\"use strict\";" + sanitiseJS(command))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package net.torvald.tsvm.firmware
|
||||
|
||||
import net.torvald.tsvm.VM
|
||||
import net.torvald.tsvm.kB
|
||||
import org.luaj.vm2.LuaTable
|
||||
import org.luaj.vm2.LuaValue
|
||||
import org.luaj.vm2.lib.OneArgFunction
|
||||
import org.luaj.vm2.lib.TwoArgFunction
|
||||
import org.luaj.vm2.lib.ZeroArgFunction
|
||||
import java.lang.RuntimeException
|
||||
|
||||
internal class Firmware(val vm: VM) : TwoArgFunction() {
|
||||
|
||||
class ErrorIllegalAccess(val addr: Long) : RuntimeException("Segmentation fault at 0x${addr.toString(16).padStart(8, '0')}")
|
||||
|
||||
companion object {
|
||||
internal fun translateAddr(vm : VM, addr: LuaValue): Pair<Any?, Long> {
|
||||
val addr = addr.checklong()
|
||||
return when (addr) {
|
||||
// DO note that numbers in Lua are double precision floats (ignore Lua 5.3 for now)
|
||||
in 0..8192.kB() - 1 -> vm.usermem to addr
|
||||
in -1024.kB()..-1 -> vm.peripheralTable[0].peripheral to (-addr - 1)
|
||||
in -2048.kB()..-1024.kB() - 1 -> vm.peripheralTable[1].peripheral to (-addr - 1 - 1024.kB())
|
||||
in -3072.kB()..-2048.kB() - 1 -> vm.peripheralTable[2].peripheral to (-addr - 1 - 2048.kB())
|
||||
in -4096.kB()..-3072.kB() - 1 -> vm.peripheralTable[3].peripheral to (-addr - 1 - 3072.kB())
|
||||
in -5120.kB()..-4096.kB() - 1 -> vm.peripheralTable[4].peripheral to (-addr - 1 - 4096.kB())
|
||||
in -6144.kB()..-5120.kB() - 1 -> vm.peripheralTable[5].peripheral to (-addr - 1 - 5120.kB())
|
||||
in -7168.kB()..-6144.kB() - 1 -> vm.peripheralTable[6].peripheral to (-addr - 1 - 6144.kB())
|
||||
in -8192.kB()..-7168.kB() - 1 -> vm.peripheralTable[7].peripheral to (-addr - 1 - 7168.kB())
|
||||
else -> null to addr
|
||||
}
|
||||
}
|
||||
|
||||
fun Byte.toLuaValue() = LuaValue.valueOf(this.toInt())
|
||||
}
|
||||
|
||||
class Poke(private val vm: VM) : TwoArgFunction() {
|
||||
override fun call(addr: LuaValue, value: LuaValue): LuaValue {
|
||||
vm.poke(addr.checklong(), value.checkint().toByte())
|
||||
return LuaValue.NIL
|
||||
}
|
||||
}
|
||||
|
||||
class Peek(private val vm: VM) : OneArgFunction() {
|
||||
override fun call(addr: LuaValue): LuaValue {
|
||||
return vm.peek(addr.checklong())?.toLuaValue() ?: LuaValue.NIL
|
||||
}
|
||||
}
|
||||
|
||||
override fun call(modname: LuaValue, env: LuaValue): LuaValue {
|
||||
println("[Firmware] Loading package 'rawamem'")
|
||||
val t = LuaTable()
|
||||
t["poke"] = Poke(vm)
|
||||
t["peek"] = Peek(vm)
|
||||
t["nanoTime"] = object : ZeroArgFunction() {
|
||||
override fun call(): LuaValue {
|
||||
return LuaValue.valueOf(System.nanoTime().toDouble())
|
||||
}
|
||||
}
|
||||
if (!env["package"].isnil()) env["package"]["loaded"]["rawmem"] = t
|
||||
return t
|
||||
}
|
||||
|
||||
}
|
||||
4
tsvm.iml
4
tsvm.iml
@@ -8,6 +8,8 @@
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
|
||||
<orderEntry type="library" name="org.jetbrains.kotlin:kotlin-scripting-jsr223:1.3.71" level="project" />
|
||||
<orderEntry type="library" name="org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1" level="project" />
|
||||
<orderEntry type="library" name="org.graalvm.js:js-scriptengine:20.3.0" level="project" />
|
||||
<orderEntry type="library" name="org.graalvm.js:js:20.3.0" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
Reference in New Issue
Block a user