generated from rnentjes/kotlin-server-web-undertow
Add platform-specific requestAnimationFrame, refactor redundant string accessor methods, and introduce BufferedImage and Color classes for emulator graphics rendering.
This commit is contained in:
@@ -400,7 +400,7 @@ class Assembler {
|
||||
): Graphic {
|
||||
val graphic = Graphic(labelTokens, token.line)
|
||||
val filename = token.stringValue
|
||||
val file = File(File(this.srcName).getParent(), filename)
|
||||
val file = File(File(this.srcName).parent, filename)
|
||||
val index = graphics.size
|
||||
|
||||
data.setValue(token, byteArrayOf(((index shr 8) and 0xFF).toByte(), (index and 0xFF).toByte()))
|
||||
@@ -732,7 +732,7 @@ class Assembler {
|
||||
val first = tokenizer!!.consume()
|
||||
tokens.add(first)
|
||||
while (tokenizer!!.more() &&
|
||||
first.line == tokenizer!!.currentToken().line
|
||||
first.line == tokenizer!!.getCurrentToken().line
|
||||
) {
|
||||
tokens.add(tokenizer!!.consume())
|
||||
}
|
||||
|
||||
28
src/commonMain/kotlin/mtmc/emulator/BufferedImage.kt
Normal file
28
src/commonMain/kotlin/mtmc/emulator/BufferedImage.kt
Normal file
@@ -0,0 +1,28 @@
|
||||
package mtmc.emulator
|
||||
|
||||
class BufferedImage(width: Int, height: Int, type: Int) {
|
||||
fun getWidth(): Int {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
fun getHeight(): Int {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
fun getRGB(x: Int, y: Int): Int {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
fun getType(): Int {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
fun setRGB(x: Int, y: Int, intVal: Int) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
class Dimension(
|
||||
val width: Int,
|
||||
val height: Int
|
||||
)
|
||||
8
src/commonMain/kotlin/mtmc/emulator/Color.kt
Normal file
8
src/commonMain/kotlin/mtmc/emulator/Color.kt
Normal file
@@ -0,0 +1,8 @@
|
||||
package mtmc.emulator
|
||||
|
||||
class Color(
|
||||
val r: Int,
|
||||
val g: Int,
|
||||
val b: Int,
|
||||
) {
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package mtmc.emulator
|
||||
|
||||
import mtmc.emulator.MonTanaMiniComputer.ComputerStatus
|
||||
import mtmc.util.currentTimeMillis
|
||||
import mtmc.util.requestAnimationFrame
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
@@ -11,49 +12,43 @@ import kotlin.math.max
|
||||
class MTMCClock(
|
||||
private val computer: MonTanaMiniComputer
|
||||
) {
|
||||
var instructions: Long = 0
|
||||
var ips: Long = 0
|
||||
var expected: Long = 0
|
||||
var virtual: Long = 0
|
||||
|
||||
var startTime = currentTimeMillis()
|
||||
|
||||
var speed: Long = 0
|
||||
|
||||
var instructionsToRun = 0.0
|
||||
|
||||
fun run() {
|
||||
var instructions: Long = 0
|
||||
var ips: Long = 0
|
||||
var expected: Long = 0
|
||||
var virtual: Long = 0
|
||||
requestAnimationFrame { handleFrame(it) }
|
||||
}
|
||||
|
||||
var startTime = currentTimeMillis()
|
||||
var deltaStart: Long
|
||||
var delta: Long
|
||||
fun handleFrame(time: Double) {
|
||||
// figure out how many instructions to execute this 'time' duration
|
||||
// maximize time so we don't hang if the emulator is too slow
|
||||
val actualTime = max(time, 0.16)
|
||||
|
||||
var speed: Long = 0
|
||||
var pulse: Long
|
||||
var ms: Long = 10
|
||||
|
||||
while (computer.getStatus() == ComputerStatus.EXECUTING) {
|
||||
// assume 1Hz = 1 instruction/second
|
||||
if (computer.getStatus() == ComputerStatus.EXECUTING) {
|
||||
speed = max(computer.speed, 0).toLong()
|
||||
pulse = (if (speed <= 0) 1000000 else max(speed / 100, 1))
|
||||
ms = (if (pulse < 10) 1000 / speed else 10)
|
||||
|
||||
deltaStart = currentTimeMillis()
|
||||
delta = ms - (currentTimeMillis() - deltaStart)
|
||||
|
||||
|
||||
/* We've lost more than a second. Recalibrate. */
|
||||
if ((expected - virtual) > pulse * 100) {
|
||||
startTime = deltaStart
|
||||
virtual = 0
|
||||
if (speed == 0L) {
|
||||
speed = 1000000L
|
||||
}
|
||||
|
||||
|
||||
/* Throttles to every 10ms, but "catches up" if we're behind */
|
||||
if (delta > 0 && (expected - virtual) < pulse && speed != 0L) {
|
||||
try {
|
||||
Thread.sleep(delta)
|
||||
} catch (e: InterruptedException) {
|
||||
}
|
||||
}
|
||||
instructionsToRun += time * speed
|
||||
val pulse: Long = instructionsToRun.toLong()
|
||||
instructionsToRun -= pulse
|
||||
|
||||
instructions += computer.pulse(pulse)
|
||||
|
||||
virtual += pulse
|
||||
ips = (virtual * 1000) / max(1, currentTimeMillis() - startTime)
|
||||
expected = (currentTimeMillis() - startTime) * speed / 1000
|
||||
virtual += instructions
|
||||
ips = (instructions / time).toLong()
|
||||
|
||||
requestAnimationFrame { handleFrame(it) }
|
||||
}
|
||||
|
||||
//println("Executed " + instructions + " instructions at a rate of " + ips + " ips (speed = " + speed + ")")
|
||||
|
||||
@@ -1,22 +1,13 @@
|
||||
package mtmc.emulator
|
||||
|
||||
import java.awt.Color
|
||||
import java.awt.Dimension
|
||||
import java.awt.RenderingHints
|
||||
import java.awt.image.BufferedImage
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import javax.imageio.ImageIO
|
||||
import kotlin.math.min
|
||||
|
||||
class MTMCDisplay(private val computer: MonTanaMiniComputer) {
|
||||
private val buffer = BufferedImage(
|
||||
COLS,
|
||||
ROWS,
|
||||
BufferedImage.TYPE_INT_ARGB
|
||||
)
|
||||
1
|
||||
) // BufferedImage.TYPE_INT_ARGB
|
||||
private var currentColor: DisplayColor? = null
|
||||
private var graphics: Array<BufferedImage> = arrayOf()
|
||||
private var byteArray: ByteArray = ByteArray(0)
|
||||
@@ -69,24 +60,25 @@ class MTMCDisplay(private val computer: MonTanaMiniComputer) {
|
||||
}
|
||||
|
||||
private fun loadSplashScreen() {
|
||||
try {
|
||||
val bytes: ByteArray = Base64.getDecoder().decode(SPLASH_SCREEN)
|
||||
val bais = ByteArrayInputStream(bytes)
|
||||
var img: BufferedImage? = null
|
||||
img = ImageIO.read(bais)
|
||||
loadScaledImage(img)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
/* try {
|
||||
val bytes: ByteArray = Base64.getDecoder().decode(SPLASH_SCREEN)
|
||||
val bais = ByteArrayInputStream(bytes)
|
||||
var img: BufferedImage? = null
|
||||
img = ImageIO.read(bais)
|
||||
loadScaledImage(img)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}*/
|
||||
}
|
||||
|
||||
private fun loadImage(data: ByteArray): BufferedImage? {
|
||||
try {
|
||||
return ImageIO.read(ByteArrayInputStream(data))
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
throw IllegalStateException(e)
|
||||
}
|
||||
/* try {
|
||||
return ImageIO.read(ByteArrayInputStream(data))
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
throw IllegalStateException(e)
|
||||
}*/
|
||||
return null
|
||||
}
|
||||
|
||||
fun loadGraphics(data: Array<ByteArray>) {
|
||||
@@ -96,7 +88,7 @@ class MTMCDisplay(private val computer: MonTanaMiniComputer) {
|
||||
}
|
||||
|
||||
graphics = Array(data.size) { index ->
|
||||
loadImage(data[index]) ?: BufferedImage(160, 144, BufferedImage.TYPE_INT_RGB)
|
||||
loadImage(data[index]) ?: BufferedImage(160, 144, 1) //BufferedImage.TYPE_INT_RGB)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,31 +120,31 @@ class MTMCDisplay(private val computer: MonTanaMiniComputer) {
|
||||
}
|
||||
|
||||
fun drawLine(startCol: Short, startRow: Short, endCol: Short, endRow: Short) {
|
||||
val graphics = buffer.getGraphics()
|
||||
graphics.setColor(currentColor!!.javaColor)
|
||||
graphics.drawLine(startCol.toInt(), startRow.toInt(), endCol.toInt(), endRow.toInt())
|
||||
graphics.dispose()
|
||||
// val graphics = buffer.getGraphics()
|
||||
// graphics.setColor(currentColor!!.javaColor)
|
||||
// graphics.drawLine(startCol.toInt(), startRow.toInt(), endCol.toInt(), endRow.toInt())
|
||||
// graphics.dispose()
|
||||
}
|
||||
|
||||
fun drawRectangle(startCol: Short, startRow: Short, width: Short, height: Short) {
|
||||
val graphics = buffer.getGraphics()
|
||||
graphics.setColor(currentColor!!.javaColor)
|
||||
graphics.fillRect(startCol.toInt(), startRow.toInt(), width.toInt(), height.toInt())
|
||||
graphics.dispose()
|
||||
// val graphics = buffer.getGraphics()
|
||||
// graphics.setColor(currentColor!!.javaColor)
|
||||
// graphics.fillRect(startCol.toInt(), startRow.toInt(), width.toInt(), height.toInt())
|
||||
// graphics.dispose()
|
||||
}
|
||||
|
||||
fun drawImage(image: Int, x: Int, y: Int) {
|
||||
val graphic = graphics!![image]
|
||||
val graphics = buffer.getGraphics()
|
||||
graphics.drawImage(graphic, x, y, null)
|
||||
graphics.dispose()
|
||||
// val graphics = buffer.getGraphics()
|
||||
// graphics.drawImage(graphic, x, y, null)
|
||||
// graphics.dispose()
|
||||
}
|
||||
|
||||
fun drawImage(image: Int, x: Int, y: Int, width: Int, height: Int) {
|
||||
val graphic = graphics!![image]
|
||||
val graphics = buffer.getGraphics()
|
||||
graphics.drawImage(graphic, x, y, width, height, null)
|
||||
graphics.dispose()
|
||||
// val graphics = buffer.getGraphics()
|
||||
// graphics.drawImage(graphic, x, y, width, height, null)
|
||||
// graphics.dispose()
|
||||
}
|
||||
|
||||
fun drawImage(
|
||||
@@ -167,20 +159,20 @@ class MTMCDisplay(private val computer: MonTanaMiniComputer) {
|
||||
dh: Int
|
||||
) {
|
||||
val graphic = graphics!![image]
|
||||
val graphics = buffer.getGraphics()
|
||||
graphics.drawImage(graphic, dx, dy, dx + dw, dy + dh, sx, sy, sx + sw, sy + sh, null)
|
||||
graphics.dispose()
|
||||
// val graphics = buffer.getGraphics()
|
||||
// graphics.drawImage(graphic, dx, dy, dx + dw, dy + dh, sx, sy, sx + sw, sy + sh, null)
|
||||
// graphics.dispose()
|
||||
}
|
||||
|
||||
fun sync() {
|
||||
val baos = ByteArrayOutputStream()
|
||||
try {
|
||||
buffer.flush()
|
||||
ImageIO.write(buffer, "png", baos)
|
||||
byteArray = baos.toByteArray()
|
||||
} catch (e: IOException) {
|
||||
throw RuntimeException(e)
|
||||
}
|
||||
/* val baos = ByteArrayOutputStream()
|
||||
try {
|
||||
buffer.flush()
|
||||
ImageIO.write(buffer, "png", baos)
|
||||
byteArray = baos.toByteArray()
|
||||
} catch (e: IOException) {
|
||||
throw RuntimeException(e)
|
||||
}*/
|
||||
computer.notifyOfDisplayUpdate()
|
||||
}
|
||||
|
||||
@@ -240,21 +232,24 @@ class MTMCDisplay(private val computer: MonTanaMiniComputer) {
|
||||
|
||||
fun scaleImage(original: BufferedImage, scaleDimensions: Dimension): BufferedImage {
|
||||
val resized = BufferedImage(scaleDimensions.width, scaleDimensions.height, original.getType())
|
||||
val g = resized.createGraphics()
|
||||
g.setRenderingHint(
|
||||
RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BILINEAR
|
||||
)
|
||||
g.drawImage(
|
||||
original, 0, 0, scaleDimensions.width, scaleDimensions.height, 0, 0, original.getWidth(),
|
||||
original.getHeight(), null
|
||||
)
|
||||
g.dispose()
|
||||
/*
|
||||
val g = resized.createGraphics()
|
||||
g.setRenderingHint(
|
||||
RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BILINEAR
|
||||
)
|
||||
g.drawImage(
|
||||
original, 0, 0, scaleDimensions.width, scaleDimensions.height, 0, 0, original.getWidth(),
|
||||
original.getHeight(), null
|
||||
)
|
||||
g.dispose()
|
||||
*/
|
||||
return resized
|
||||
}
|
||||
|
||||
fun convertImage(image: BufferedImage): BufferedImage {
|
||||
val arbg = BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR)
|
||||
val arbg =
|
||||
BufferedImage(image.getWidth(), image.getHeight(), 2) //BufferedImage.TYPE_4BYTE_ABGR)
|
||||
for (x in 0..<image.getWidth()) {
|
||||
for (y in 0..<image.getHeight()) {
|
||||
val rgb = image.getRGB(x, y)
|
||||
|
||||
@@ -51,59 +51,59 @@ class MTOS(private val computer: MonTanaMiniComputer) {
|
||||
fun handleSysCall(syscallNumber: Short) {
|
||||
if (syscallNumber == getValue("exit").toShort()) {
|
||||
computer.setStatus(MonTanaMiniComputer.ComputerStatus.FINISHED)
|
||||
} else if (syscallNumber == getValue("rint").toShort()) {
|
||||
// rint
|
||||
if (!computer.console.hasShortValue()) {
|
||||
computer.notifyOfRequestInteger()
|
||||
}
|
||||
while (!computer.console.hasShortValue() && computer.getStatus() == MonTanaMiniComputer.ComputerStatus.EXECUTING) {
|
||||
try {
|
||||
Thread.sleep(10)
|
||||
} catch (e: InterruptedException) {
|
||||
}
|
||||
}
|
||||
val `val` = computer.console.readInt()
|
||||
computer.setRegisterValue(Register.RV, `val`.toInt())
|
||||
// } else if (syscallNumber == getValue("rint").toShort()) {
|
||||
// // rint
|
||||
// if (!computer.console.hasShortValue()) {
|
||||
// computer.notifyOfRequestInteger()
|
||||
// }
|
||||
// while (!computer.console.hasShortValue() && computer.getStatus() == MonTanaMiniComputer.ComputerStatus.EXECUTING) {
|
||||
// try {
|
||||
// Thread.sleep(10)
|
||||
// } catch (e: InterruptedException) {
|
||||
// }
|
||||
// }
|
||||
// val `val` = computer.console.readInt()
|
||||
// computer.setRegisterValue(Register.RV, `val`.toInt())
|
||||
} else if (syscallNumber == getValue("wint").toShort()) {
|
||||
// wint
|
||||
val value = computer.getRegisterValue(Register.A0)
|
||||
computer.console.writeInt(value)
|
||||
} else if (syscallNumber == getValue("rchr").toShort()) {
|
||||
if (!computer.console.hasShortValue()) {
|
||||
computer.notifyOfRequestCharacter()
|
||||
}
|
||||
while (!computer.console.hasShortValue() && computer.getStatus() == MonTanaMiniComputer.ComputerStatus.EXECUTING) {
|
||||
try {
|
||||
Thread.sleep(10)
|
||||
} catch (e: InterruptedException) {
|
||||
}
|
||||
}
|
||||
val `val` = computer.console.readChar()
|
||||
computer.setRegisterValue(Register.RV, `val`.code)
|
||||
// } else if (syscallNumber == getValue("rchr").toShort()) {
|
||||
// if (!computer.console.hasShortValue()) {
|
||||
// computer.notifyOfRequestCharacter()
|
||||
// }
|
||||
// while (!computer.console.hasShortValue() && computer.getStatus() == MonTanaMiniComputer.ComputerStatus.EXECUTING) {
|
||||
// try {
|
||||
// Thread.sleep(10)
|
||||
// } catch (e: InterruptedException) {
|
||||
// }
|
||||
// }
|
||||
// val `val` = computer.console.readChar()
|
||||
// computer.setRegisterValue(Register.RV, `val`.code)
|
||||
} else if (syscallNumber == getValue("wchr").toShort()) {
|
||||
val value = computer.getRegisterValue(Register.A0)
|
||||
computer.console.print("" + Char(value.toUShort()))
|
||||
} else if (syscallNumber == getValue("rstr").toShort()) {
|
||||
// rstr
|
||||
val pointer = computer.getRegisterValue(Register.A0)
|
||||
val maxLen = computer.getRegisterValue(Register.A1)
|
||||
if (!computer.console.hasReadString()) {
|
||||
computer.notifyOfRequestString()
|
||||
}
|
||||
while (!computer.console.hasReadString() && computer.getStatus() == MonTanaMiniComputer.ComputerStatus.EXECUTING) {
|
||||
try {
|
||||
Thread.sleep(10)
|
||||
} catch (e: InterruptedException) {
|
||||
}
|
||||
}
|
||||
val string = computer.console.readString()
|
||||
val bytes = string!!.encodeToByteArray()
|
||||
val bytesToRead = min(bytes.size, maxLen.toInt())
|
||||
for (i in 0..<bytesToRead) {
|
||||
val aByte = bytes[i]
|
||||
computer.writeByteToMemory(pointer + i, aByte)
|
||||
}
|
||||
computer.setRegisterValue(Register.RV, bytesToRead)
|
||||
// } else if (syscallNumber == getValue("rstr").toShort()) {
|
||||
// // rstr
|
||||
// val pointer = computer.getRegisterValue(Register.A0)
|
||||
// val maxLen = computer.getRegisterValue(Register.A1)
|
||||
// if (!computer.console.hasReadString()) {
|
||||
// computer.notifyOfRequestString()
|
||||
// }
|
||||
// while (!computer.console.hasReadString() && computer.getStatus() == MonTanaMiniComputer.ComputerStatus.EXECUTING) {
|
||||
// try {
|
||||
// Thread.sleep(10)
|
||||
// } catch (e: InterruptedException) {
|
||||
// }
|
||||
// }
|
||||
// val string = computer.console.readString()
|
||||
// val bytes = string!!.encodeToByteArray()
|
||||
// val bytesToRead = min(bytes.size, maxLen.toInt())
|
||||
// for (i in 0..<bytesToRead) {
|
||||
// val aByte = bytes[i]
|
||||
// computer.writeByteToMemory(pointer + i, aByte)
|
||||
// }
|
||||
// computer.setRegisterValue(Register.RV, bytesToRead)
|
||||
} else if (syscallNumber == getValue("wstr").toShort()) {
|
||||
// wstr
|
||||
val pointer = computer.getRegisterValue(Register.A0)
|
||||
@@ -171,14 +171,14 @@ class MTOS(private val computer: MonTanaMiniComputer) {
|
||||
}
|
||||
|
||||
computer.setRegisterValue(Register.RV, random.nextInt(low.toInt(), high + 1))
|
||||
} else if (syscallNumber == getValue("sleep").toShort()) {
|
||||
// sleep
|
||||
val millis = computer.getRegisterValue(Register.A0)
|
||||
try {
|
||||
if (millis > 0) Thread.sleep(millis.toLong())
|
||||
} catch (e: InterruptedException) {
|
||||
throw RuntimeException(e)
|
||||
}
|
||||
// } else if (syscallNumber == getValue("sleep").toShort()) {
|
||||
// // sleep
|
||||
// val millis = computer.getRegisterValue(Register.A0)
|
||||
// try {
|
||||
// if (millis > 0) Thread.sleep(millis.toLong())
|
||||
// } catch (e: InterruptedException) {
|
||||
// throw RuntimeException(e)
|
||||
// }
|
||||
} else if (syscallNumber == getValue("fbreset").toShort()) {
|
||||
// fbreset
|
||||
computer.display.reset()
|
||||
|
||||
@@ -20,8 +20,6 @@ class File(
|
||||
|
||||
constructor(name: String) : this(null, name)
|
||||
|
||||
fun getParent(): File = parent ?: error("No parent")
|
||||
|
||||
fun getPath(): String = if (parent == null) {
|
||||
name
|
||||
} else {
|
||||
|
||||
@@ -12,4 +12,14 @@ class Path {
|
||||
fun resolve(filename: String): Path {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
fun toAbsolutePath(): Path {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun of(string: String): Path {
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,7 +96,7 @@ object Shell {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
cmd = identifier.stringValue()
|
||||
cmd = identifier.stringValue
|
||||
}
|
||||
if (isCommand(cmd)) {
|
||||
COMMANDS[cmd.lowercase()]!!.exec(tokens, computer)
|
||||
@@ -106,7 +106,7 @@ object Shell {
|
||||
asm.addAll(tokens.tokens)
|
||||
val updatedAsm = Assembler.transformSyntheticInstructions(asm)
|
||||
val firstToken = updatedAsm.peekFirst()
|
||||
val firstTokenStr = firstToken?.stringValue() ?: error("Unexpected null token")
|
||||
val firstTokenStr = firstToken?.stringValue ?: error("Unexpected null token")
|
||||
if (!updatedAsm.isEmpty() && isInstruction(firstTokenStr)) {
|
||||
val assembler = Assembler()
|
||||
val result = assembler.assemble(command)
|
||||
|
||||
@@ -17,11 +17,11 @@ class GetCommand : ShellCommand() {
|
||||
if (memLocation == null) {
|
||||
val register = tokens.matchAndConsume(MTMCToken.TokenType.IDENTIFIER)
|
||||
if (register == null) usageException()
|
||||
val reg = Register.toInteger(register!!.stringValue())
|
||||
val reg = Register.toInteger(register!!.stringValue)
|
||||
if (reg >= 0) {
|
||||
computer.console.println(register.stringValue() + ": " + computer.getRegisterValue(reg))
|
||||
computer.console.println(register.stringValue + ": " + computer.getRegisterValue(reg))
|
||||
} else {
|
||||
throw IllegalArgumentException("Bad register: " + register.stringValue())
|
||||
throw IllegalArgumentException("Bad register: " + register.stringValue)
|
||||
}
|
||||
} else {
|
||||
if (memLocation.type === MTMCToken.TokenType.INTEGER || memLocation.type === MTMCToken.TokenType.BINARY || memLocation.type === MTMCToken.TokenType.HEX) {
|
||||
|
||||
@@ -23,11 +23,11 @@ class SetCommand : ShellCommand() {
|
||||
MTMCToken.TokenType.BINARY
|
||||
)
|
||||
if (value == null) usageException()
|
||||
val reg = Register.toInteger(register!!.stringValue())
|
||||
val reg = Register.toInteger(register!!.stringValue)
|
||||
if (reg >= 0) {
|
||||
computer.setRegisterValue(reg, value!!.intValue())
|
||||
} else {
|
||||
throw IllegalArgumentException("Bad register: " + register.stringValue())
|
||||
throw IllegalArgumentException("Bad register: " + register.stringValue)
|
||||
}
|
||||
} else {
|
||||
val value = tokens.matchAndConsume(
|
||||
@@ -42,7 +42,7 @@ class SetCommand : ShellCommand() {
|
||||
} else {
|
||||
computer.writeStringToMemory(
|
||||
memLocation.intValue(),
|
||||
value!!.stringValue().encodeToByteArray()
|
||||
value!!.stringValue.encodeToByteArray()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,6 @@ data class MTMCToken(
|
||||
return stringValue
|
||||
}
|
||||
|
||||
fun stringValue(): String {
|
||||
return stringValue
|
||||
}
|
||||
|
||||
fun charValue(): Char {
|
||||
return stringValue.get(0)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ class MTMCTokenizer(var source: String, lineCommentStart: String) {
|
||||
var tokens: MutableList<MTMCToken> = MTMCScanner(source, lineCommentStart).tokenize()
|
||||
var currentToken: Int = 0
|
||||
|
||||
fun currentToken(): MTMCToken {
|
||||
fun getCurrentToken(): MTMCToken {
|
||||
return tokens.get(currentToken)
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ class MTMCTokenizer(var source: String, lineCommentStart: String) {
|
||||
}
|
||||
|
||||
fun matchAndConsume(identifier: String?): Boolean {
|
||||
if (currentToken().type == MTMCToken.TokenType.IDENTIFIER &&
|
||||
currentToken().stringValue == identifier
|
||||
if (getCurrentToken().type == MTMCToken.TokenType.IDENTIFIER &&
|
||||
getCurrentToken().stringValue == identifier
|
||||
) {
|
||||
return true
|
||||
} else {
|
||||
@@ -39,7 +39,7 @@ class MTMCTokenizer(var source: String, lineCommentStart: String) {
|
||||
|
||||
fun match(vararg type: MTMCToken.TokenType?): Boolean {
|
||||
for (tokenType in type) {
|
||||
if (currentToken().type == tokenType) {
|
||||
if (getCurrentToken().type == tokenType) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class MTMCTokenizer(var source: String, lineCommentStart: String) {
|
||||
}
|
||||
|
||||
fun more(): Boolean {
|
||||
return currentToken().type != MTMCToken.TokenType.EOF
|
||||
return getCurrentToken().type != MTMCToken.TokenType.EOF
|
||||
}
|
||||
|
||||
fun previousToken(): MTMCToken? {
|
||||
@@ -83,7 +83,7 @@ class MTMCTokenizer(var source: String, lineCommentStart: String) {
|
||||
do {
|
||||
last = consume()
|
||||
sb.append(last.stringValue)
|
||||
next = currentToken()
|
||||
next = getCurrentToken()
|
||||
} while (more() && last.end == next.start)
|
||||
return sb.toString()
|
||||
} else {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
package mtmc.util
|
||||
|
||||
expect fun currentTimeMillis(): Long
|
||||
expect fun currentTimeMillis(): Long
|
||||
|
||||
expect fun requestAnimationFrame(action: (Double) -> Unit)
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package mtmc.util
|
||||
|
||||
import kotlinx.browser.window
|
||||
import kotlin.js.Date
|
||||
|
||||
actual fun currentTimeMillis(): Long = Date().getTime().toLong()
|
||||
actual fun requestAnimationFrame(action: (Double) -> Unit) {
|
||||
window.requestAnimationFrame(action)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
package mtmc.util
|
||||
|
||||
actual fun currentTimeMillis(): Long = System.currentTimeMillis()
|
||||
actual fun currentTimeMillis(): Long = System.currentTimeMillis()
|
||||
actual fun requestAnimationFrame(action: (Double) -> Unit) {
|
||||
error("requestAnimationFrame is not supported on JVM")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user