From 810e9e0c0b6d2502d7639b7a511972da7241cc26 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Mon, 15 Jun 2020 18:54:52 +0900 Subject: [PATCH] working goto but ^C doesnt work --- assets/tbas/basic.js | 57 ++++-- guicursor.kra | 4 +- src/net/torvald/tsvm/peripheral/TTY.kt | 245 +++++++++++++++++++++++++ tty.kra | 3 + tty.png | Bin 0 -> 24678 bytes 5 files changed, 294 insertions(+), 15 deletions(-) create mode 100644 src/net/torvald/tsvm/peripheral/TTY.kt create mode 100644 tty.kra create mode 100644 tty.png diff --git a/assets/tbas/basic.js b/assets/tbas/basic.js index 64570ef..94f833a 100644 --- a/assets/tbas/basic.js +++ b/assets/tbas/basic.js @@ -253,6 +253,21 @@ basicInterpreterStatus.builtin = { if (isNaN(lh) || isNaN(rh)) throw lang.illegalType(lnum); sys.poke(lh, rh); +}, +"GOTO" : function(lnum, args) { + if (args.length != 1) throw lang.syntaxfehler(lnum); + var lh = resolve(args[0]); + if (lh === undefined) throw lang.refError(lnum); + if (isNaN(lh)) throw lang.illegalType(lnum); + return lh; +}, +"GOSUB" : function(lnum, args) { + if (args.length != 1) throw lang.syntaxfehler(lnum); + var lh = resolve(args[0]); + if (lh === undefined || rh === undefined) throw lang.refError(lnum); + if (isNaN(lh)) throw lang.illegalType(lnum); + basicInterpreterStatus.gosubStack.push(lnum + 1); + return lh; } }; Object.freeze(basicInterpreterStatus.builtin); @@ -757,7 +772,7 @@ for input "DEFUN sinc(x) = sin(x) / x" "quote" == state || "number" == state || "bool" == state || "literal" == state; } - var _debugSyntaxAnalysis = true; + var _debugSyntaxAnalysis = false; if (_debugSyntaxAnalysis) println("@@ SYNTAX ANALYSIS @@"); @@ -1012,8 +1027,14 @@ function JStoBASICtype(object) { else if (object === undefined) return "null"; else throw "InternalError: un-translatable object with typeof "+(typeof object)+"\n"+object; } +function SyntaxTreeReturnObj(type, value, nextLine) { + this.type = type; + this.value = value; + this.nextLine = nextLine; +} +basicFunctions._gotoCmds = { GOTO:1, GOSUB:1 }; basicFunctions._executeSyntaxTree = function(lnum, syntaxTree, recDepth) { - var _debugExec = true; + var _debugExec = false; var recWedge = "> ".repeat(recDepth); if (_debugExec) serial.println(recWedge+"@@ EXECUTE @@"); @@ -1023,26 +1044,32 @@ basicFunctions._executeSyntaxTree = function(lnum, syntaxTree, recDepth) { else if (syntaxTree.type == "function" || syntaxTree.type == "operator") { if (_debugExec) serial.println(recWedge+"function|operator"); if (_debugExec) serial.println(recWedge+syntaxTree.toString()); - var func = basicInterpreterStatus.builtin[syntaxTree.value.toUpperCase()]; + var funcName = syntaxTree.value.toUpperCase(); + var func = basicInterpreterStatus.builtin[funcName]; var args = syntaxTree.leaves.map(function(it) { return basicFunctions._executeSyntaxTree(lnum, it, recDepth + 1); }); if (_debugExec) { - serial.println(recWedge+"fn call name: "+syntaxTree.value.toUpperCase()); + serial.println(recWedge+"fn call name: "+funcName); serial.println(recWedge+"fn call args: "+(args.map(function(it) { return it.type+" "+it.value; })).join(", ")); } var funcCallResult = func(lnum, args); - return { type:JStoBASICtype(funcCallResult), value:funcCallResult }; + + return new SyntaxTreeReturnObj( + JStoBASICtype(funcCallResult), + funcCallResult, + (basicFunctions._gotoCmds[funcName] !== undefined) ? funcCallResult : lnum + 1 + ); } else if (syntaxTree.type == "number") { if (_debugExec) serial.println(recWedge+"number"); - return { type:syntaxTree.type, value:+(syntaxTree.value) }; + return new SyntaxTreeReturnObj(syntaxTree.type, +(syntaxTree.value), lnum + 1); } else if (syntaxTree.type == "string" || syntaxTree.type == "literal") { - if (_debugExec) serial.println(recWedge+"string|operator"); - return { type:syntaxTree.type, value:syntaxTree.value }; + if (_debugExec) serial.println(recWedge+"string|literal"); + return new SyntaxTreeReturnObj(syntaxTree.type, syntaxTree.value, lnum + 1); } else if (syntaxTree.type == "null") { - return basicFunctions._executeSyntaxTree(lnum, syntaxTree.leaves[0], recDepth + 1); + return new basicFunctions._executeSyntaxTree(lnum, syntaxTree.leaves[0], recDepth + 1); } else { serial.println(recWedge+"Parse error in "+lnum); @@ -1052,7 +1079,7 @@ basicFunctions._executeSyntaxTree = function(lnum, syntaxTree, recDepth) { }; // @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 _debugprintHighestLevel = true; + var _debugprintHighestLevel = false; // TOKENISE var tokenisedObject = basicFunctions._tokenise(lnum, cmd); @@ -1068,12 +1095,12 @@ basicFunctions._interpretLine = function(lnum, cmd) { if (_debugprintHighestLevel) serial.println("Final syntax tree:"); if (_debugprintHighestLevel) serial.println(syntaxTree.toString()); - basicFunctions._executeSyntaxTree(lnum, syntaxTree, 0); + var execResult = basicFunctions._executeSyntaxTree(lnum, syntaxTree, 0); // EXECUTE - return lnum + 1; + return execResult.nextLine; }; // end INTERPRETLINE @@ -1143,6 +1170,9 @@ basicFunctions.fre = function(args) { basicFunctions.run = function(args) { // RUN function var linenumber = 1; var oldnum = 1; + + var countup = 0; + do { if (cmdbuf[linenumber] !== undefined) { oldnum = linenumber; @@ -1151,7 +1181,8 @@ basicFunctions.run = function(args) { // RUN function else { linenumber += 1; } - if (con.hitterminate()) { + countup += 1; + if (con.hitterminate() || countup >= 100) { println("Break in "+oldnum); break; } diff --git a/guicursor.kra b/guicursor.kra index 1d35fb9..f19c277 100644 --- a/guicursor.kra +++ b/guicursor.kra @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f0df1e8c678058e829058c3244e535363a3e552f43918d94df13ecb726b74050 -size 63938 +oid sha256:92a751f926661ee1a57e7949a7693d6421b908e5fe5986352fc4f30e8fb1e9ca +size 495180 diff --git a/src/net/torvald/tsvm/peripheral/TTY.kt b/src/net/torvald/tsvm/peripheral/TTY.kt new file mode 100644 index 0000000..1269b4d --- /dev/null +++ b/src/net/torvald/tsvm/peripheral/TTY.kt @@ -0,0 +1,245 @@ +package net.torvald.tsvm.peripheral + +import com.badlogic.gdx.graphics.Texture +import net.torvald.UnsafeHelper +import net.torvald.tsvm.VM +import java.io.InputStream +import java.io.OutputStream + +class TTY(val vm: VM) : GlassTty(TEXT_ROWS, TEXT_COLS), PeriBase { + + companion object { + const val TEXT_ROWS = 25 + const val TEXT_COLS = 80 + } + + private val chrrom = Texture("./tty.png") + private val textBuffer = UnsafeHelper.allocate(TEXT_ROWS * TEXT_COLS * 2L) + override var rawCursorPos = 0 + + private val TEXT_AREA_SIZE = TEXT_COLS * TEXT_ROWS + private val memTextOffset = 0L + private val memTextAttrOffset = TEXT_AREA_SIZE.toLong() + + override var ttyFore = 0 // 0: normal, 1: intense, 2: dim + override var ttyBack: Int + get() = 0 + set(value) {} + var ttyInv = false + override var blinkCursor = true + override var ttyRawMode = false + + override fun getCursorPos() = rawCursorPos % TEXT_COLS to rawCursorPos / TEXT_COLS + /** + * Think of it as a real paper tty; + * setCursorPos must "wrap" the cursor properly when x-value goes out of screen bound. + * For y-value, only when y < 0, set y to zero and don't care about the y-value goes out of bound. + */ + override fun setCursorPos(x: Int, y: Int) { + var newx = x + var newy = y + + if (newx >= TEXT_COLS) { + newx = 0 + newy += 1 + } + else if (newx < 0) { + newx = 0 + } + + if (newy < 0) { + newy = 0 // DON'T SCROLL when cursor goes ABOVE the screen + } + + rawCursorPos = toTtyTextOffset(newx, newy) + } + private fun toTtyTextOffset(x: Int, y: Int) = y * TEXT_COLS + x + + + override fun peek(addr: Long): Byte? { + TODO("Not yet implemented") + } + + override fun poke(addr: Long, byte: Byte) { + TODO("Not yet implemented") + } + + override fun mmio_read(addr: Long): Byte? { + TODO("Not yet implemented") + } + + override fun mmio_write(addr: Long, byte: Byte) { + TODO("Not yet implemented") + } + + override fun getVM() = vm + + override fun putChar(x: Int, y: Int, text: Byte, foreColour: Byte, backColour: Byte) { + val textOff = toTtyTextOffset(x, y) + textBuffer[memTextAttrOffset + textOff] = 0 + textBuffer[memTextOffset + textOff] = text + } + + override fun resetTtyStatus() { + ttyFore = 0 + ttyInv = false + } + + override fun cursorUp(arg: Int) { + val (x, y) = getCursorPos() + setCursorPos(x, y - arg) + } + + override fun cursorDown(arg: Int) { + val (x, y) = getCursorPos() + val newy = y + arg + setCursorPos(x, if (newy >= TEXT_ROWS) TEXT_ROWS - 1 else newy) + } + + override fun cursorFwd(arg: Int) { + val (x, y) = getCursorPos() + setCursorPos(x + arg, y) + } + + override fun cursorBack(arg: Int) { + val (x, y) = getCursorPos() + setCursorPos(x - arg, y) + } + + override fun cursorNextLine(arg: Int) { + val (_, y) = getCursorPos() + val newy = y + arg + setCursorPos(0, if (newy >= TEXT_ROWS) TEXT_ROWS - 1 else newy) + if (newy >= TEXT_ROWS) { + scrollUp(newy - TEXT_ROWS + 1) + } + } + + override fun cursorPrevLine(arg: Int) { + val (_, y) = getCursorPos() + setCursorPos(0, y - arg) + } + + override fun cursorX(arg: Int) { + val (_, y) = getCursorPos() + setCursorPos(arg, y) + } + + override fun eraseInDisp(arg: Int) { + when (arg) { + else -> TODO() + } + } + + override fun eraseInLine(arg: Int) { + when (arg) { + else -> TODO() + } + } + + override fun sgrOneArg(arg: Int) { + TODO("Not yet implemented") + } + + override fun sgrTwoArg(arg1: Int, arg2: Int) { + TODO("Not yet implemented") + } + + override fun sgrThreeArg(arg1: Int, arg2: Int, arg3: Int) { + TODO("Not yet implemented") + } + + override fun cursorXY(arg1: Int, arg2: Int) { + TODO("Not yet implemented") + } + + override fun ringBell() { + TODO("Not yet implemented") + } + + override fun insertTab() { + TODO("Not yet implemented") + } + + override fun crlf() { + TODO("Not yet implemented") + } + + override fun backspace() { + TODO("Not yet implemented") + } + + override fun privateSeqH(arg: Int) { + TODO("Not yet implemented") + } + + override fun privateSeqL(arg: Int) { + TODO("Not yet implemented") + } + + override fun getPrintStream(): OutputStream { + TODO("Not yet implemented") + } + + override fun getErrorStream(): OutputStream { + TODO("Not yet implemented") + } + + override fun getInputStream(): InputStream { + TODO("Not yet implemented") + } + + override fun putKey(key: Int) { + vm.poke(-39, key.toByte()) + } + + /** + * @return key code in 0..255 (TODO: JInput Keycode or ASCII-Code?) + */ + override fun takeKey(): Int { + return vm.peek(-38)!!.toInt().and(255) + } + + /** New lines are added at the bottom */ + override fun scrollUp(arg: Int) { + val displacement = arg.toLong() * TEXT_COLS + UnsafeHelper.memcpy( + textBuffer.ptr + memTextOffset + displacement, + textBuffer.ptr + memTextOffset, + TEXT_AREA_SIZE - displacement + ) + UnsafeHelper.memcpy( + textBuffer.ptr + memTextAttrOffset + displacement, + textBuffer.ptr + memTextAttrOffset, + TEXT_AREA_SIZE - displacement + ) + for (i in 0 until displacement) { + textBuffer[memTextOffset + TEXT_AREA_SIZE - displacement + i] = 0 + textBuffer[memTextAttrOffset + TEXT_AREA_SIZE - displacement + i] = ttyFore.toByte() + } + } + + /** New lines are added at the top */ + override fun scrollDown(arg: Int) { + val displacement = arg.toLong() * TEXT_COLS + UnsafeHelper.memcpy( + textBuffer.ptr + memTextOffset, + textBuffer.ptr + memTextOffset + displacement, + TEXT_AREA_SIZE - displacement + ) + UnsafeHelper.memcpy( + textBuffer.ptr + memTextAttrOffset, + textBuffer.ptr + memTextAttrOffset + displacement, + TEXT_AREA_SIZE - displacement + ) + for (i in 0 until displacement) { + textBuffer[memTextOffset + TEXT_AREA_SIZE + i] = 0 + textBuffer[memTextAttrOffset + TEXT_AREA_SIZE + i] = ttyFore.toByte() + } + } + + + override fun dispose() { + chrrom.dispose() + } +} \ No newline at end of file diff --git a/tty.kra b/tty.kra new file mode 100644 index 0000000..4f90460 --- /dev/null +++ b/tty.kra @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd6045f47f85bea71f4eb6896bd15618e0931abb258eaa948c72dba713eede84 +size 534281 diff --git a/tty.png b/tty.png new file mode 100644 index 0000000000000000000000000000000000000000..e0e42b16a80d1a391c97eb6f9704613a993782be GIT binary patch literal 24678 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 literal 0 HcmV?d00001