migration to graal

This commit is contained in:
minjaesong
2020-12-01 14:16:48 +09:00
parent f4c67fee30
commit 6403a84af3
54 changed files with 182 additions and 326 deletions

View 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>

View 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>

View File

@@ -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>

View 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>

View File

@@ -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");

View File

@@ -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());

View File

@@ -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);

View File

@@ -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 = "";
}
}
}
}

View File

@@ -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);
}
///////////////////////////////////////////////////////////////////////////////

View File

@@ -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 = "";
}

Binary file not shown.

Binary file not shown.

BIN
lib/graal-sdk-20.3.0.jar Normal file

Binary file not shown.

BIN
lib/icu4j-67.1-javadoc.jar Normal file

Binary file not shown.

BIN
lib/icu4j-67.1.jar Normal file

Binary file not shown.

BIN
lib/js-20.3.0-javadoc.jar Normal file

Binary file not shown.

BIN
lib/js-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.

BIN
lib/kotlin-stdlib-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.

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/regex-20.3.0.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/truffle-api-20.3.0.jar Normal file

Binary file not shown.

View File

@@ -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)
}
}

View File

@@ -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)
}

View File

@@ -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")
}

View File

@@ -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()
}
}

View File

@@ -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))
}
}
}

View File

@@ -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
}
}

View File

@@ -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>