diff --git a/assets/JS_INIT.js b/assets/JS_INIT.js index e74aebf..c729ff5 100644 --- a/assets/JS_INIT.js +++ b/assets/JS_INIT.js @@ -1,20 +1,20 @@ // standard print functions function print(s) { - vm.print(s); + sys.print(s); } function println(s) { if (typeof s == "undefined") - vm.print("\n"); + sys.print("\n"); else - vm.println(s); + sys.println(s); } function read() { - return vm.read(); + return sys.read(); } // ncurses-like terminal control -var con = new Object(); +var con = {}; con.getch = function() { - return vm.readKey(); + return sys.readKey(); }; con.move = function(y, x) { print(String.fromCharCode(27,91)+y+";"+x+"H"); @@ -32,12 +32,12 @@ con.getyx = function() { return graphics.getCursorYX(); }; con.hitterminate = function() { // ^C - vm.poke(-40, 1); - return (vm.peek(-41) == 31 && (vm.peek(-41) == 129 || vm.peek(-41) == 130)); + sys.poke(-40, 1); + return (sys.peek(-41) == 31 && (sys.peek(-41) == 129 || sys.peek(-41) == 130)); }; con.hiteof = function() { // ^D - vm.poke(-40, 1); - return (vm.peek(-41) == 32 && (vm.peek(-41) == 129 || vm.peek(-41) == 130)); + sys.poke(-40, 1); + return (sys.peek(-41) == 32 && (sys.peek(-41) == 129 || sys.peek(-41) == 130)); }; con.color_fore = function(n) { // 0..7; -1 for transparent if (n < 0) @@ -57,11 +57,11 @@ con.color_pair = function(fore, back) { // 0..255 }; Object.freeze(con); // system management function -var sys = new Object(); -sys.maxmem = function() { - return vm.peek(-65) | (vm.peek(-66) << 8) | (vm.peek(-67) << 16) | (vm.peek(-68) << 24); +var system = {}; +system.maxmem = function() { + return sys.peek(-65) | (sys.peek(-66) << 8) | (sys.peek(-67) << 16) | (sys.peek(-68) << 24); }; -sys.halt = function() { +system.halt = function() { exit(); }; -Object.freeze(sys); \ No newline at end of file +Object.freeze(system); \ No newline at end of file diff --git a/assets/bios1.js b/assets/bios1.js index 7520a8f..4f769d7 100644 --- a/assets/bios1.js +++ b/assets/bios1.js @@ -176,7 +176,7 @@ for (var frames = 0; frames < height * divisor; frames++) { } } -var memstring = "USER RAM: " + ((vm.peek(-66) >> 2) + (vm.peek(-67) << 6) + (vm.peek(-68) << 14)); +var memstring = "USER RAM: " + ((sys.peek(-66) >> 2) + (sys.peek(-67) << 6) + (sys.peek(-68) << 14)); if (memstring.length % 2 == 0) memstring += " Kbytes"; else memstring += " Kbytes"; var cy = Math.floor((yoff + height + 14) / 14); var cx = Math.floor(((560 - 7*(memstring.length)) / 2) / 7); diff --git a/assets/phototest.js b/assets/phototest.js index 77f5afc..ca7a654 100644 --- a/assets/phototest.js +++ b/assets/phototest.js @@ -448,10 +448,18 @@ image[445]=[254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, image[446]=[254,254,254,253,194,254,254,254,194,254,254,254,234,254,234,254,254,254,254,254,254,254,254,254,254,194,254,234,254,253,254,254,253,254,194,254,254,194,254,254,254,254,253,254,253,194,254,253,254,254,253,194,254,253,234,254,253,254,194,254,254,254,254,194,254,254,254,234,254,254,234,254,254,254,194,254,253,254,254,254,254,254,254,254,254,194,254,234,254,253,234,254,253,194,254,254,254,254,194,254,254,254,254,254,254,254,254,254,253,254,254,254,254,253,254,254,254,254,253,254,194,254,254,254,254,254,194,254,254,254,254,253,253,254,254,253,254,254,254,194,254,194,254,254,254,253,254,254,253,254,254,234,254,253,254,254,254,234,254,254,254,194,254,254,194,254,254,194,254,254,234,254,194,254,234,254,254,234,254,253,254,253,194,254,254,234,253,254,194,254,254,253,254,254,254,253,254,194,254,253,253,253,194,254,253,194,254,254,253,254,253,254,254,254,253,194,254,254,254,254,254,253,194,254,254,254,254,254,254,254,253,254,254,254,254,254,254,254,254,254,254,253,194,254,254,254,254,254,254,234,254,254,194,239,194,239,194,239,194,239,194,239,254,254,254,194,239,254,239,194,239,254,254,194,239,254,254,254,254,254,194,254,194,254,254,234,254,253,254,254,254,254,254,254,254,254,254,239,254,254,254,239,254,234,254,254,254,254,254,254,254,254,254,194,254,254,254,254,254,254,254,254,254,254,254,194,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,194,254,254,254,239,194,239,254,254,194,239,254,194,254,254,254,254,234,254,254,254,234,254,254,254,254,254,254,194,239,254,254,254,254,254,254,194,254,239,254,254,234,254,254,254,239,194,254,254,254,254,254,253,194,254,254,234,254,254,254,254,253,254,254,234,254,253,194,254,254,254,254,254,254,254,254,194,254,254,254,253,194,254,254,253,254,253,254,194,254,254,254,253,254,234,254,194,254,254,194,254,254,254,254,254,254,254,254,254,254,254,254,194,254,254,234,254,253,234,254,254,254,254,254,194,254,254,254,253,254,253,254,254,254,194,254,254,253,253,254,194,254,254,253,194,254,254,194,254,254,254,254,254,254,254,234,254,234,254,254,254,234,254,254,253,254,254,254,253,254,254,254,254,254,253,254,254,254,254,253,194,254,254,254,254,254,253,254,253,194,254,194,254,253,254,254,253,254,253,253,194,254,253,254,253,194,254,254,254,253,254,254,254,194,254,254,194,254]; image[447]=[253,254,254,254,254,254,254,254,254,253,254,254,254,254,254,254,254,194,254,254,254,194,253,254,254,254,254,254,194,254,254,194,254,254,254,253,254,254,254,194,254,194,254,234,254,254,234,254,194,254,254,254,254,254,254,234,254,254,254,254,194,254,254,254,194,254,254,254,253,254,254,254,254,254,254,194,254,254,254,194,254,254,194,254,254,254,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,194,254,254,254,234,254,194,254,254,254,254,194,254,254,254,254,254,253,254,253,254,254,254,254,254,194,254,254,253,234,253,254,253,254,254,253,254,253,194,254,194,254,194,254,253,254,253,254,254,234,253,254,254,253,254,254,254,254,254,254,253,254,234,254,253,254,254,254,254,254,253,254,254,254,194,254,254,254,254,253,254,254,254,254,254,194,254,254,253,234,254,253,254,253,254,254,254,253,254,254,254,253,253,254,253,254,253,234,254,254,253,254,234,253,253,254,254,254,254,253,254,254,194,253,254,254,254,254,194,254,254,254,194,253,254,254,254,254,254,254,254,254,194,254,254,254,254,239,254,254,254,254,254,254,254,254,194,254,254,239,254,254,234,254,254,194,254,254,254,254,254,253,254,254,254,254,254,254,254,254,254,254,194,254,254,194,254,254,254,254,254,254,254,254,194,254,254,254,254,254,254,239,194,239,194,254,254,254,254,254,254,254,254,254,234,254,254,234,254,254,254,254,254,234,254,254,254,239,194,254,254,254,254,254,254,254,239,254,254,254,254,254,239,194,254,239,254,254,254,239,194,254,254,254,254,254,254,254,254,254,234,239,194,239,254,239,194,254,239,194,254,254,239,254,254,194,254,254,254,254,254,254,254,254,254,254,194,254,234,254,254,253,254,254,253,234,254,254,194,254,253,254,254,254,254,234,254,254,194,253,234,254,254,254,253,254,254,254,254,254,254,254,254,254,254,254,254,234,254,254,254,254,254,254,234,254,254,254,254,194,254,254,194,254,254,254,254,254,254,254,254,254,253,254,254,254,253,254,234,254,254,254,254,194,254,254,194,254,194,253,254,254,253,254,194,253,254,253,253,254,254,253,253,254,253,253,234,254,253,254,253,254,253,254,254,234,254,254,254,254,254,254,254,194,254,254,194,254,253,234,254,234,254,254,194,254,254,254,254,254,254,254,194,254,254,254,254,254,254,194,254,253,254,253,234,254,254,254,253,253,254,254,253,254,194,254,254,253,254,254,254,254,254,254,254]; -for (var y = 0; y < 448; y++) { - for (var x = 0; x < 560; x++) { - graphics.plotPixel(x, y, image[y][x]); - } -} +var indices = []; var i; +for (i = 0; i < 250880; i++) indices[i] = i; +for (i = indices.length - 1; i > 0; i--) { + var j = Math.floor(Math.random() * (i + 1)); + var x = indices[i]; + indices[i] = indices[j]; + indices[j] = x; +} +for (i = 0; i < 250880; i++) { + var x = indices[i] % 560; + var y = (indices[i] / 560)|0; + graphics.plotPixel(x, y, image[y][x]); +} con.color_fore(0); diff --git a/assets/tbas/basic.js b/assets/tbas/basic.js index bf54bcf..c3d0d58 100644 --- a/assets/tbas/basic.js +++ b/assets/tbas/basic.js @@ -1,16 +1,33 @@ /* NOTE: do not allow concatenation of commands! + +Operators + +; - When used by PRINT and INPUT, concatenates two printables; numbers will have one space between them while strings + will not. +, - Function argument separator ++ - Just as in JS; concatenates two strings + */ -var vmemsize = sys.maxmem() - 5236; -var vmemused = 0; +var vmemsize = system.maxmem() - 5236; + var cmdbuf = []; // index: line number +var cmdbufMemFootPrint = 0; var prompt = "Ok"; -var lang = { - syntaxfehler: "Syntax error" +var lang = {}; +lang.syntaxfehler = function(line) { + if (typeof line == "undefined") + return "Syntax error"; + return "Syntax error in " + line; }; +function getUsedMemSize() { + return cmdbufMemFootPrint; // + array's dimsize * 8 + variables' sizeof literal + functions' expression length +} + + var reLineNum = /^[0-9]+ +[^0-9]/; var reFloat = /^([\-+]?[0-9]*[.][0-9]+[eE]*[\-+0-9]*[fF]*|[\-+]?[0-9]+[.eEfF][0-9+\-]*[fF]?)$/; var reDec = /^([\-+]?[0-9_]+)$/; @@ -26,23 +43,83 @@ var tbasexit = false; println("Terran BASIC 1.0 "+vmemsize+" bytes free"); println(prompt); -var basicFunctions = new Object(); +var basicInterpreterStatus = {}; +// variable object constructor +function BasicVar(linenum, literal, type) { + this.literal = literal; + this.type = type; +} +// DEFUN (GW-BASIC equiv. of DEF FN) constructor +function BasicFun(linenum, params, expression) { + this.params = params; + this.expression = expression; +} +// DIM (array) constructor +function BasicArr() { + var args = Array.from(arguments); + if (args.length == 1) + throw lang.syntaxfehler(args[0]); + else if (args.length == 0) + throw "InternalError: pass the line number!"; + else { + // create nested array as defined + var dimsize = Number(args[1]); + var a = new Array(args[1]); + var internal = a; + for (var i = 2; i < args.length; i++) { + dimsize *= Number(args[i]); + var inner = new Array(args[i]); + internal.push(inner); + internal = inner; + } + + this.array = a; + this.dimsize = dimsize; + } +} +basicInterpreterStatus.gosubStack = []; +basicInterpreterStatus.variables = {}; +basicInterpreterStatus.defuns = {}; +basicInterpreterStatus.builtin = {}; +basicInterpreterStatus.builtin.print = function() { + var args = Array.from(arguments); + if (args.length == 0) + println(); + else + println(args.join("\t")); +}; +Object.freeze(basicInterpreterStatus.builtin); +var basicFunctions = {}; basicFunctions._isNumber = function(code) { return (code >= 0x30 && code <= 0x39) || code == 0x2E; }; +basicFunctions._isParenOpen = function(code) { + return (code == 0x28 || code == 0x5B); +}; +basicFunctions._isParenClose = function(code) { + return (code == 0x29 || code == 0x5D); +}; +basicFunctions._isParen = function(code) { + return basicFunctions._isParenOpen(code) || basicFunctions._isParenClose(code); +}; +basicFunctions._isSeparator = function(code) { + return code == 0x2C; +}; basicFunctions._isOperator = function(code) { - return (code == 0x21 || code == 0x23 || code == 0x25 || (code >= 0x2A && code <= 0x2D) || code == 0x2F || (code >= 0x3A && code <= 0x3E) || code == 0x5E || code == 0x7C); + return (code == 0x21 || code == 0x23 || code == 0x25 || code == 0x2A || code == 0x2B || code == 0x2D || code == 0x2E || code == 0x2F || (code >= 0x3C && code <= 0x3E) || code == 0x5E || code == 0x7C); }; // @returns: line number for the next command, normally (lnum + 1); if GOTO or GOSUB was met, returns its line number basicFunctions._interpretLine = function(lnum, cmd) { var _debugprintStateTransition = false; var tokens = []; + var modes = []; var sb = ""; - var mode = "literal"; // literal, escape, number, quote, quote_end, operator, limbo + var mode = "literal"; // literal, escape, number, quote, quote_end, operator, paren, sep, limbo if (_debugprintStateTransition) println("Ln "+lnum+" cmd "+cmd); // TOKENISE + // TODO add separator for (var k = 0; k < cmd.length; k++) { var char = cmd.charAt(k); var charCode = cmd.charCodeAt(k); @@ -51,7 +128,7 @@ basicFunctions._interpretLine = function(lnum, cmd) { if (mode == "literal") { if (0x22 == charCode) { // " - tokens.push(sb); sb = ""; + tokens.push(sb); sb = ""; modes.push(mode); mode = "quote"; } /*else if (charCode == 0x5C) { // reverse solidus @@ -59,13 +136,21 @@ basicFunctions._interpretLine = function(lnum, cmd) { mode = "escape"; }*/ else if (basicFunctions._isOperator(charCode)) { - tokens.push(sb); sb = "" + char; + tokens.push(sb); sb = "" + char; modes.push(mode); mode = "operator"; } + else if (basicFunctions._isParen(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "paren"; + } else if (" " == char) { - tokens.push(sb); sb = ""; + tokens.push(sb); sb = ""; modes.push(mode); mode = "limbo"; } + else if (basicFunctions._isSeparator(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "sep"; + } else { sb += char; } @@ -91,7 +176,7 @@ basicFunctions._interpretLine = function(lnum, cmd) { } else if ("quote" == mode) { if (0x22 == charCode) { - tokens.push(sb); sb = ""; + tokens.push(sb); sb = ""; modes.push(mode); mode = "quote_end"; } else { @@ -114,19 +199,27 @@ basicFunctions._interpretLine = function(lnum, cmd) { sb += char; } else if (" " == char) { - tokens.push(sb); sb = ""; + tokens.push(sb); sb = ""; modes.push(mode); mode = "limbo"; } else if (basicFunctions._isOperator(charCode)) { - tokens.push(sb); sb = "" + char; + tokens.push(sb); sb = "" + char; modes.push(mode); mode = "operator"; } else if (0x22 == charCode) { - tokens.push(sb); sb = "" + char; + tokens.push(sb); sb = "" + char; modes.push(mode); mode = "quote"; } + else if (basicFunctions._isParen(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "paren"; + } + else if (basicFunctions._isSeparator(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "sep"; + } else { - tokens.push(sb); sb = "" + char; + tokens.push(sb); sb = "" + char; modes.push(mode); mode = "literal"; } } @@ -135,16 +228,24 @@ basicFunctions._interpretLine = function(lnum, cmd) { sb += char; } else if (basicFunctions._isNumber(charCode)) { - tokens.push(sb); sb = "" + char; + tokens.push(sb); sb = "" + char; modes.push(mode); mode = "number"; } else if (" " == char) { - tokens.push(sb); sb = ""; + tokens.push(sb); sb = ""; modes.push(mode); mode = "limbo"; } + else if (basicFunctions._isParen(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "paren"; + } + else if (basicFunctions._isSeparator(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "sep"; + } else { - tokens.push(sb); sb = "" + char; - mode = "lteral"; + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "literal"; } } else if ("limbo" == mode) { @@ -163,11 +264,79 @@ basicFunctions._interpretLine = function(lnum, cmd) { sb = ""; mode = "quote" } + else if (basicFunctions._isParen(charCode)) { + sb = ""; + mode = "paren"; + } + else if (basicFunctions._isSeparator(charCode)) { + sb = ""; + mode = "sep"; + } else { sb = "" + char; mode = "literal"; } } + else if ("paren" == mode) { + if (char == " ") { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "limbo"; + } + else if (basicFunctions._isNumber(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "number" + } + else if (basicFunctions._isOperator(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "operator" + } + else if (0x22 == charCode) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "quote" + } + else if (basicFunctions._isParen(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "paren"; + } + else if (basicFunctions._isSeparator(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "sep"; + } + else { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "literal"; + } + } + else if ("sep" == mode) { + if (char == " ") { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "limbo"; + } + else if (basicFunctions._isNumber(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "number" + } + else if (basicFunctions._isOperator(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "operator" + } + else if (0x22 == charCode) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "quote" + } + else if (basicFunctions._isParen(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "paren"; + } + else if (basicFunctions._isSeparator(charCode)) { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "sep"; + } + else { + tokens.push(sb); sb = "" + char; modes.push(mode); + mode = "literal"; + } + } else { throw "Unknown parser state: " + mode; } @@ -176,15 +345,18 @@ basicFunctions._interpretLine = function(lnum, cmd) { } if (sb.length > 0) { - tokens.push(sb); + tokens.push(sb); modes.push(mode); } // END TOKENISE - println(tokens.join("|")); + println(tokens.join("~")); + println(modes.join(" ")); + + return lnum + 1; -}; +}; // end INTERPRETLINE basicFunctions._basicList = function(v, i, arr) { if (i < 10) print(" "); if (i < 100) print(" "); @@ -237,7 +409,16 @@ basicFunctions.renum = function(args) { // RENUM function newcmdbuf[k] = "gosub " + linenumRelation[newcmdbuf[k].match(reNum)[0]]; } } - cmdbuf = newcmdbuf.slice(); + cmdbuf = newcmdbuf.slice(); // make shallow copy + + // recalculate memory footprint + cmdbufMemFootPrint = 0; + cmdbuf.forEach(function(v, i, arr) { + cmdbufMemFootPrint += ("" + i).length + 1 + v.length; + }); +}; +basicFunctions.fre = function(args) { + println(vmemsize - getUsedMemSize()); }; basicFunctions.run = function(args) { // RUN function var linenumber = 1; @@ -258,22 +439,106 @@ basicFunctions.run = function(args) { // RUN function }; Object.freeze(basicFunctions); while (!tbasexit) { - var line = vm.read(); + var line = sys.read(); line = line.trim(); + cmdbufMemFootPrint += line.length; + if (reLineNum.test(line)) { var i = line.indexOf(" "); cmdbuf[line.slice(0, i)] = line.slice(i + 1, line.length); } else if (line.length > 0) { + cmdbufMemFootPrint -= line.length; try { var cmd = line.split(" "); basicFunctions[cmd[0]](cmd); } catch (e) { println(e); - println(lang.syntaxfehler); + println(lang.syntaxfehler()); } println(prompt); } -} \ No newline at end of file +} + + +/* +digraph G { + start -> LITERAL + start -> LINENUMBER [label="reDec"] + + LINENUMBER -> LINENUMBER [label="numbers"] + LINENUMBER -> limbo [label="space"] + LINENUMBER -> LITERAL [label="otherwise"] + + LITERAL -> limbo [label="space"] + LITERAL -> OPERATOR [label="reOps"] + LITERAL -> ESCAPE [label="\\"] + LITERAL -> QUOTE [label="\""] + LITERAL -> PAREN [label="()[]"] + LITERAL -> SEP [label=","] + LITERAL -> LITERAL [label="otherwise"] + + limbo -> NUMBER [label="numbers"] + limbo -> OPERATOR [label="reOps"] + limbo -> QUOTE [label="\""] + limbo -> LITERAL [label="otherwise"] + limbo -> PAREN [label="()[]"] + limbo -> SEP [label=","] + limbo -> limbo [label="space"] + + ESCAPE -> LITERAL + QUOTE -> QUOTE_END [label="\""] + QUOTE -> QUOTE [label="otherwise"] + + QUOTE_END -> limbo [label="space"] + QUOTE_END -> NUMBER [label="numbers"] + QUOTE_END -> OPERATOR [label="reOps"] + QUOTE_END -> PAREN [label="()[]"] + QUOTE_END -> SEP [label=","] + QUOTE_END -> LITERAL [label="otherwise"] + + OPERATOR -> NUMBER [label="numbers"] + OPERATOR -> limbo [label="space"] + OPERATOR -> OPERATOR [label="reOps"] + OPERATOR -> PAREN [label="()[]"] + OPERATOR -> SEP [label=","] + OPERATOR -> LITERAL [label="otherwise"] + + NUMBER -> NUMBER [label="numbers"] + NUMBER -> OPERATOR [label="reOps"] + NUMBER -> QUOTE [label="\""] + NUMBER -> limbo [label="space"] + NUMBER -> PAREN [label="()[]"] + NUMBER -> SEP [label=","] + NUMBER -> LITERAL [label="otherwise"] + + PAREN -> PUSH_AND_PAREN [label="()[]"] + PAREN -> NUMBER [label="numbers"] + PAREN -> OPERATOR [label="reOps"] + PAREN -> QUOTE [label="\""] + PAREN -> limbo [label="space"] + PAREN -> SEP [label=","] + PAREN -> LITERAL [label="otherwise"] + + SEP -> PAREN [label="()[]"] + SEP -> NUMBER [label="numbers"] + SEP -> OPERATOR [label="reOps"] + SEP -> QUOTE [label="\""] + SEP -> limbo [label="space"] + SEP -> PUSH_AND_SEP [label=","] + SEP -> LITERAL [label="otherwise"] + + LITERAL -> end [label="\\n"] + NUMBER -> end [label="\\n"] + QUOTE_END -> end [label="\\n"] + OPERATOR -> end [label="\\n"] + PAREN -> end [label="\\n"] + + start [shape=Mdiamond]; + end [shape=Msquare]; + + concentrate=true; +} +*/ \ No newline at end of file diff --git a/src/net/torvald/tsvm/VMRunnerFactory.kt b/src/net/torvald/tsvm/VMRunnerFactory.kt index b459aba..ff39cd0 100644 --- a/src/net/torvald/tsvm/VMRunnerFactory.kt +++ b/src/net/torvald/tsvm/VMRunnerFactory.kt @@ -50,7 +50,7 @@ object VMRunnerFactory { private val bind = context.getBindings(ScriptContext.ENGINE_SCOPE) init { - bind.put("vm", VMJSR223Delegate(vm)) // TODO use delegator class to access peripheral (do not expose VM itself) + bind.put("sys", VMJSR223Delegate(vm)) // TODO use delegator class to access peripheral (do not expose VM itself) bind.put("graphics", GraphicsJSR223Delegate(vm)) //bind.put("poke", { a: Long, b: Byte -> vm.poke(a, b) }) // kts: lambda does not work... //bind.put("nanotime", { System.nanoTime() })