diff --git a/.idea/misc.xml b/.idea/misc.xml
index 2ac0fd5..c621e3a 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,7 +3,7 @@
-
+
diff --git a/build.gradle.kts b/build.gradle.kts
index 276852b..84bd6d3 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,70 +1,75 @@
@file:OptIn(ExperimentalDistributionDsl::class)
-import org.codehaus.groovy.tools.shell.util.Logger.io
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalDistributionDsl
plugins {
- kotlin("multiplatform") version "2.1.20"
+ kotlin("multiplatform") version "2.1.20"
}
group = "nl.astraeus"
version = "0.1.0-SNAPSHOT"
repositories {
- mavenCentral()
- maven {
- url = uri("https://gitea.astraeus.nl/api/packages/rnentjes/maven")
- }
- maven {
- url = uri("https://gitea.astraeus.nl:8443/api/packages/rnentjes/maven")
- }
+ mavenCentral()
+ maven {
+ url = uri("https://gitea.astraeus.nl/api/packages/rnentjes/maven")
+ }
+ maven {
+ url = uri("https://gitea.astraeus.nl:8443/api/packages/rnentjes/maven")
+ }
}
kotlin {
- jvmToolchain(17)
- jvm()
- js {
- binaries.executable()
- browser {
- distribution {
- outputDirectory.set(File("$projectDir/web/"))
- }
- }
+ jvmToolchain(21)
+ jvm()
+ js {
+ binaries.executable()
+ browser {
+ distribution {
+ outputDirectory.set(File("$projectDir/web/"))
+ }
}
- sourceSets {
- val commonMain by getting {
- dependencies {
- api("nl.astraeus:kotlin-simple-logging:1.1.1")
- api("nl.astraeus:kotlin-css-generator:1.0.10")
+ }
- implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0")
- }
- }
- val commonTest by getting
- val jvmMain by getting {
- dependencies {
- implementation("io.undertow:undertow-core:2.3.14.Final")
- implementation("org.jetbrains.kotlinx:kotlinx-html-jvm:0.11.0")
+ // Add this to enable ExperimentalStdlibApi globally
+ sourceSets.all {
+ languageSettings.optIn("kotlin.ExperimentalStdlibApi")
+ }
- implementation("org.xerial:sqlite-jdbc:3.32.3.2")
- implementation("com.zaxxer:HikariCP:4.0.3")
- implementation("nl.astraeus:simple-jdbc-stats:1.6.1") {
- exclude(group = "org.slf4j", module = "slf4j-api")
- }
+ sourceSets {
+ val commonMain by getting {
+ dependencies {
+ api("nl.astraeus:kotlin-simple-logging:1.1.1")
+ api("nl.astraeus:kotlin-css-generator:1.0.10")
- implementation("io.pebbletemplates:pebble:3.2.3")
- implementation("com.google.code.gson:gson:2.12.1")
- }
- }
- val jvmTest by getting {
- dependencies {
- }
- }
- val jsMain by getting {
- dependencies {
- implementation("nl.astraeus:kotlin-komponent:1.2.5")
- }
- }
- val jsTest by getting
+ implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0")
+ }
}
-}
\ No newline at end of file
+ val commonTest by getting
+ val jvmMain by getting {
+ dependencies {
+ implementation("io.undertow:undertow-core:2.3.14.Final")
+ implementation("org.jetbrains.kotlinx:kotlinx-html-jvm:0.11.0")
+
+ implementation("org.xerial:sqlite-jdbc:3.32.3.2")
+ implementation("com.zaxxer:HikariCP:4.0.3")
+ implementation("nl.astraeus:simple-jdbc-stats:1.6.1") {
+ exclude(group = "org.slf4j", module = "slf4j-api")
+ }
+
+ implementation("io.pebbletemplates:pebble:3.2.3")
+ implementation("com.google.code.gson:gson:2.12.1")
+ }
+ }
+ val jvmTest by getting {
+ dependencies {
+ }
+ }
+ val jsMain by getting {
+ dependencies {
+ implementation("nl.astraeus:kotlin-komponent:1.2.5")
+ }
+ }
+ val jsTest by getting
+ }
+}
diff --git a/src/jvmMain/kotlin/mtmc/asm/ASMElement.kt b/src/commonMain/kotlin/mtmc/asm/ASMElement.kt
similarity index 90%
rename from src/jvmMain/kotlin/mtmc/asm/ASMElement.kt
rename to src/commonMain/kotlin/mtmc/asm/ASMElement.kt
index 9deb269..e5887c7 100644
--- a/src/jvmMain/kotlin/mtmc/asm/ASMElement.kt
+++ b/src/commonMain/kotlin/mtmc/asm/ASMElement.kt
@@ -4,9 +4,8 @@ import mtmc.tokenizer.MTMCToken
abstract class ASMElement(
val labels: List,
- @JvmField var lineNumber: Int
+ var lineNumber: Int
) : HasLocation {
- @JvmField
var errors: MutableList = ArrayList()
override var location: Int = 0
override var sizeInBytes: Int = 0
diff --git a/src/jvmMain/kotlin/mtmc/asm/ASMError.kt b/src/commonMain/kotlin/mtmc/asm/ASMError.kt
similarity index 69%
rename from src/jvmMain/kotlin/mtmc/asm/ASMError.kt
rename to src/commonMain/kotlin/mtmc/asm/ASMError.kt
index e6f692e..e20b46c 100644
--- a/src/jvmMain/kotlin/mtmc/asm/ASMError.kt
+++ b/src/commonMain/kotlin/mtmc/asm/ASMError.kt
@@ -2,10 +2,9 @@ package mtmc.asm
import mtmc.tokenizer.MTMCToken
-@JvmRecord
data class ASMError(
- @JvmField val token: MTMCToken,
- @JvmField val error: String
+ val token: MTMCToken,
+ val error: String
) {
fun formattedErrorMessage(): String {
return "Line " + token.line + ": " + error
diff --git a/src/jvmMain/kotlin/mtmc/asm/Assembler.kt b/src/commonMain/kotlin/mtmc/asm/Assembler.kt
similarity index 88%
rename from src/jvmMain/kotlin/mtmc/asm/Assembler.kt
rename to src/commonMain/kotlin/mtmc/asm/Assembler.kt
index 67c06f8..02d4588 100644
--- a/src/jvmMain/kotlin/mtmc/asm/Assembler.kt
+++ b/src/commonMain/kotlin/mtmc/asm/Assembler.kt
@@ -25,12 +25,16 @@ import mtmc.emulator.Register.Companion.isReadable
import mtmc.emulator.Register.Companion.isWriteable
import mtmc.os.SysCall
import mtmc.os.exec.Executable
+import mtmc.os.fs.File
import mtmc.tokenizer.MTMCToken
import mtmc.tokenizer.MTMCTokenizer
-import java.io.File
-import java.nio.charset.StandardCharsets
-import java.util.*
-import java.util.stream.Collectors
+
+fun MutableList.poll() = this.removeFirst()
+fun MutableList.peekFirst() = if (this.isEmpty()) {
+ null
+} else {
+ this[0]
+}
class Assembler {
var instructions: MutableList = ArrayList()
@@ -88,7 +92,7 @@ class Assembler {
var location = 0
var originalLineNumber = 0
- val currentLocals: MutableMap = TreeMap()
+ val currentLocals: MutableMap = mutableMapOf()
for (instruction in instructions) {
val asmLineNumber = instruction.lineNumber
if (instruction is MetaInstruction) {
@@ -145,10 +149,8 @@ class Assembler {
val result = assemble(srcName, asm)
if (!result.errors.isEmpty()) {
throw RuntimeException(
- "Errors:\n" + result.errors
- .stream()
- .map { e: ASMError? -> " - " + e!!.formattedErrorMessage() }
- .collect(Collectors.joining("\n")))
+ "Errors:\n" + result.errors.joinToString("\n") { e: ASMError? -> " - " + e!!.formattedErrorMessage() }
+ )
}
return Executable(
@@ -261,7 +263,10 @@ class Assembler {
for (labelToken in labelTokens) {
val labelData = Data(labelTokens, labelToken.line)
if (hasLabel(labelToken.stringValue)) {
- labelData.addError(tokens.poll(), "Label already defined: " + labelToken.stringValue)
+ labelData.addError(
+ tokens.removeFirst(),
+ "Label already defined: " + labelToken.stringValue
+ )
} else {
this.labels.put(labelToken.labelValue(), labelData)
}
@@ -274,7 +279,7 @@ class Assembler {
}
}
- private fun parseMetaDirective(tokens: LinkedList): Boolean {
+ private fun parseMetaDirective(tokens: MutableList): Boolean {
if (tokens.size >= 2 && tokens.get(0).type == MTMCToken.TokenType.AT) {
tokens.removeFirst()
val metaInstruction = MetaInstruction(tokens.removeFirst())
@@ -306,26 +311,26 @@ class Assembler {
return false
}
- private fun parseModeFlag(tokens: LinkedList): ASMMode? {
+ private fun parseModeFlag(tokens: MutableList): ASMMode? {
if (tokens.size >= 2 && tokens.get(0).type == MTMCToken.TokenType.DOT && tokens.get(1).type == MTMCToken.TokenType.IDENTIFIER && tokens.get(
0
).end == tokens.get(1).start && (tokens.get(1).stringValue == "data" ||
tokens.get(1).stringValue == "text")
) {
- return ASMMode.valueOf(tokens.get(1).stringValue.uppercase(Locale.getDefault()))
+ return ASMMode.valueOf(tokens.get(1).stringValue.uppercase())
}
return null
}
- private fun parseData(tokens: LinkedList, labelTokens: MutableList) {
+ private fun parseData(tokens: MutableList, labelTokens: MutableList) {
lastLabels = mutableListOf()
- var dataToken = tokens.poll()
+ var dataToken = tokens.removeFirst()
var dataElt = Data(labelTokens, if (dataToken == null) 0 else dataToken.line)
if (dataToken != null) {
if (dataToken.type == MTMCToken.TokenType.STRING) {
- val stringBytes = dataToken.stringValue.toByteArray(StandardCharsets.US_ASCII)
+ val stringBytes = dataToken.stringValue.encodeToByteArray()
val nullTerminated = ByteArray(stringBytes.size + 1)
- System.arraycopy(stringBytes, 0, nullTerminated, 0, stringBytes.size)
+ stringBytes.copyInto(nullTerminated, 0, 0, stringBytes.size)
nullTerminated[stringBytes.size] = '\u0000'.code.toByte()
dataElt.setValue(dataToken, nullTerminated)
} else if (isInteger(dataToken)) {
@@ -338,7 +343,7 @@ class Assembler {
byteArrayOf((integerValue ushr 8).toByte(), integerValue.toByte())
)
} else if (dataToken.type == MTMCToken.TokenType.DOT) {
- dataToken = tokens.poll()
+ dataToken = tokens.removeFirst()
dataElt = Data(labelTokens, dataToken.line)
if (dataToken.stringValue == "int") {
val intToken = requireIntegerToken(tokens, dataElt, MonTanaMiniComputer.MEMORY_SIZE)
@@ -359,7 +364,7 @@ class Assembler {
dataElt.addError(dataToken, "only data types are .int, .byte, and .image")
}
} else if (dataToken.type == MTMCToken.TokenType.MINUS) {
- val nextToken = tokens.poll() // get next
+ val nextToken = tokens.removeFirst() // get next
if (nextToken == null || (nextToken.type != MTMCToken.TokenType.INTEGER && nextToken.type != MTMCToken.TokenType.HEX && nextToken.type != MTMCToken.TokenType.BINARY)) {
dataElt.addError(dataToken, "Number is too negative")
} else {
@@ -380,7 +385,7 @@ class Assembler {
for (labelToken in labelTokens) {
if (hasLabel(labelToken.stringValue)) {
- dataElt.addError(tokens.poll(), "Label already defined: " + labelToken.stringValue)
+ dataElt.addError(tokens.removeFirst(), "Label already defined: " + labelToken.stringValue)
} else {
labels.put(labelToken.labelValue(), dataElt)
}
@@ -405,9 +410,16 @@ class Assembler {
return graphic
}
- private fun parseInstruction(tokens: LinkedList, labelTokens: MutableList) {
+ private fun parseInstruction(
+ tokens: MutableList,
+ labelTokens: MutableList
+ ) {
var tokens = tokens
- var instructionToken = tokens.peekFirst()
+ var instructionToken = if (tokens.isEmpty()) {
+ null
+ } else {
+ tokens[0]
+ }
if (instructionToken == null) return
lastLabels = mutableListOf()
@@ -510,7 +522,7 @@ class Assembler {
}
// if there is a stack register specified, consume it
- if (!tokens.isEmpty() && tokens.peekFirst().type == MTMCToken.TokenType.IDENTIFIER) {
+ if (!tokens.isEmpty() && tokens.peekFirst()?.type == MTMCToken.TokenType.IDENTIFIER) {
val stackReg = requireReadableRegister(tokens, stackInst)
stackInst.setStackRegister(stackReg)
}
@@ -550,7 +562,7 @@ class Assembler {
loadInst.setPointerToken(pointerReg)
// if there is an offset register specified, consume it
- if (!tokens.isEmpty() && tokens.peekFirst().type == MTMCToken.TokenType.IDENTIFIER) {
+ if (!tokens.isEmpty() && tokens.peekFirst()?.type == MTMCToken.TokenType.IDENTIFIER) {
val offsetReg = requireReadableRegister(tokens, loadInst)
loadInst.setOffsetToken(offsetReg)
}
@@ -598,7 +610,7 @@ class Assembler {
//===================================================
// tokenization helper functions
//===================================================
- private fun requireSysCall(tokens: LinkedList, inst: Instruction): MTMCToken {
+ private fun requireSysCall(tokens: MutableList, inst: Instruction): MTMCToken {
val sysCallType = tokens.poll()
if (sysCallType == null) {
inst.addError("Syscall required")
@@ -610,7 +622,7 @@ class Assembler {
return sysCallType!!
}
- private fun requireAluOp(tokens: LinkedList, inst: Instruction): MTMCToken {
+ private fun requireAluOp(tokens: MutableList, inst: Instruction): MTMCToken {
val sysCallType = tokens.poll()
if (sysCallType == null) {
inst.addError("Syscall required")
@@ -623,7 +635,7 @@ class Assembler {
}
private fun requireWriteableRegister(
- tokens: LinkedList,
+ tokens: MutableList,
instruction: Instruction
): MTMCToken {
val nextToken = tokens.poll()
@@ -638,7 +650,7 @@ class Assembler {
}
private fun requireReadableRegister(
- tokens: LinkedList,
+ tokens: MutableList,
instruction: Instruction
): MTMCToken {
val nextToken = tokens.poll()
@@ -652,7 +664,7 @@ class Assembler {
return nextToken!!
}
- private fun requireALUOp(tokens: LinkedList, instruction: Instruction): MTMCToken {
+ private fun requireALUOp(tokens: MutableList, instruction: Instruction): MTMCToken {
val nextToken = tokens.poll()
if (nextToken == null || nextToken.type != MTMCToken.TokenType.IDENTIFIER || !isALUOp(nextToken.stringValue)) {
instruction.addError("ALU operation required")
@@ -660,7 +672,7 @@ class Assembler {
return nextToken!!
}
- private fun requireString(tokens: LinkedList, instruction: ASMElement): MTMCToken {
+ private fun requireString(tokens: MutableList, instruction: ASMElement): MTMCToken {
val nextToken = tokens.poll()
if (nextToken == null || nextToken.type != MTMCToken.TokenType.STRING) {
instruction.addError("String required")
@@ -669,7 +681,7 @@ class Assembler {
}
private fun requireIntegerToken(
- tokens: LinkedList,
+ tokens: MutableList,
inst: ASMElement,
max: Int
): MTMCToken {
@@ -688,7 +700,7 @@ class Assembler {
}
private fun requireToken(
- tokens: LinkedList,
+ tokens: MutableList,
type: MTMCToken.TokenType,
inst: ASMElement
): MTMCToken? {
@@ -700,7 +712,7 @@ class Assembler {
}
private fun requireIntegerOrLabelReferenceToken(
- tokens: LinkedList,
+ tokens: MutableList,
inst: LoadStoreInstruction
): MTMCToken {
val token = tokens.poll()
@@ -713,9 +725,9 @@ class Assembler {
}
- private val tokensForLine: LinkedList
+ private val tokensForLine: MutableList
get() {
- val tokens = LinkedList()
+ val tokens = mutableListOf()
if (tokenizer!!.more()) {
val first = tokenizer!!.consume()
tokens.add(first)
@@ -742,51 +754,51 @@ class Assembler {
}
companion object {
- fun transformSyntheticInstructions(tokens: LinkedList): LinkedList {
+ fun transformSyntheticInstructions(tokens: MutableList): MutableList {
if (!tokens.isEmpty()) {
- val first = tokens.peekFirst()
+ val first = tokens.first()
if (first.type == MTMCToken.TokenType.IDENTIFIER) {
val stringVal = first.stringValue
if (stringVal.endsWith("i")) {
val op = stringVal.substring(0, stringVal.length - 1)
if (isALUOp(op)) {
val syntheticImmediate = tokens.removeFirst()
- tokens.addFirst(syntheticImmediate.cloneWithVal(op))
- tokens.addFirst(syntheticImmediate.cloneWithVal("imm"))
+ tokens.add(0, syntheticImmediate.cloneWithVal(op))
+ tokens.add(0, syntheticImmediate.cloneWithVal("imm"))
}
} else if (stringVal.startsWith("s")) {
val op = stringVal.substring(1, stringVal.length)
if (isALUOp(op)) {
val syntheticImmediate = tokens.removeFirst()
- tokens.addFirst(syntheticImmediate.cloneWithVal(op))
- tokens.addFirst(syntheticImmediate.cloneWithVal("sop"))
+ tokens.add(0, syntheticImmediate.cloneWithVal(op))
+ tokens.add(0, syntheticImmediate.cloneWithVal("sop"))
}
} else if (stringVal == "la") {
val syntheticImmediate = tokens.removeFirst()
- tokens.addFirst(syntheticImmediate.cloneWithVal("li"))
+ tokens.add(0, syntheticImmediate.cloneWithVal("li"))
} else if (stringVal == "ret") {
val syntheticImmediate = tokens.removeFirst()
- tokens.addFirst(syntheticImmediate.cloneWithVal("ra"))
- tokens.addFirst(syntheticImmediate.cloneWithVal("jr"))
+ tokens.add(0, syntheticImmediate.cloneWithVal("ra"))
+ tokens.add(0, syntheticImmediate.cloneWithVal("jr"))
}
}
}
return tokens
}
- private fun maybeGetLabels(tokens: LinkedList): MutableList {
- val labels = LinkedList()
- while (!tokens.isEmpty() && tokens.getFirst().type == MTMCToken.TokenType.LABEL) {
- val label = tokens.poll()
+ private fun maybeGetLabels(tokens: MutableList): MutableList {
+ val labels = mutableListOf()
+ while (!tokens.isEmpty() && tokens.first().type == MTMCToken.TokenType.LABEL) {
+ val label = tokens.removeFirst()
labels.add(label!!)
}
return labels
}
- private fun maybeGetLabelReference(tokens: LinkedList): MTMCToken? {
+ private fun maybeGetLabelReference(tokens: MutableList): MTMCToken? {
var label: MTMCToken? = null
- if (tokens.getFirst().type == MTMCToken.TokenType.IDENTIFIER) {
- label = tokens.poll()
+ if (tokens.first().type == MTMCToken.TokenType.IDENTIFIER) {
+ label = tokens.removeFirst()
}
return label
}
diff --git a/src/jvmMain/kotlin/mtmc/asm/AssemblyResult.kt b/src/commonMain/kotlin/mtmc/asm/AssemblyResult.kt
similarity index 74%
rename from src/jvmMain/kotlin/mtmc/asm/AssemblyResult.kt
rename to src/commonMain/kotlin/mtmc/asm/AssemblyResult.kt
index 38e88d8..c7b18c3 100644
--- a/src/jvmMain/kotlin/mtmc/asm/AssemblyResult.kt
+++ b/src/commonMain/kotlin/mtmc/asm/AssemblyResult.kt
@@ -2,13 +2,12 @@ package mtmc.asm
import mtmc.emulator.DebugInfo
-@JvmRecord
data class AssemblyResult(
- @JvmField val code: ByteArray,
+ val code: ByteArray,
val data: ByteArray,
val graphics: Array,
- @JvmField val debugInfo: DebugInfo?,
- @JvmField val errors: MutableList
+ val debugInfo: DebugInfo?,
+ val errors: MutableList
) {
fun printErrors(): String {
val builder = StringBuilder("Errors:\n")
diff --git a/src/jvmMain/kotlin/mtmc/asm/HasLocation.kt b/src/commonMain/kotlin/mtmc/asm/HasLocation.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/asm/HasLocation.kt
rename to src/commonMain/kotlin/mtmc/asm/HasLocation.kt
diff --git a/src/jvmMain/kotlin/mtmc/asm/data/Data.kt b/src/commonMain/kotlin/mtmc/asm/data/Data.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/asm/data/Data.kt
rename to src/commonMain/kotlin/mtmc/asm/data/Data.kt
diff --git a/src/commonMain/kotlin/mtmc/asm/graphics/Graphic.kt b/src/commonMain/kotlin/mtmc/asm/graphics/Graphic.kt
new file mode 100644
index 0000000..070011c
--- /dev/null
+++ b/src/commonMain/kotlin/mtmc/asm/graphics/Graphic.kt
@@ -0,0 +1,45 @@
+package mtmc.asm.graphics
+
+import mtmc.asm.ASMElement
+import mtmc.tokenizer.MTMCToken
+
+/**
+ *
+ * @author jbanes
+ */
+class Graphic(labels: MutableList, lineNumber: Int) : ASMElement(labels, lineNumber) {
+ private var filename: String? = null
+ var imageData: ByteArray = ByteArray(0)
+
+ fun setImage(filename: String) {
+ /* try {
+ var image = ImageIO.read(File(filename))
+ val buffer = ByteArrayOutputStream()
+
+ if (image.getWidth() > 1024 || image.getHeight() > 1024) {
+ addError(filename + " is too large. Maximum image size is 1024x1024")
+ }
+
+ image = convertImage(image)
+
+ ImageIO.write(image, "png", buffer)
+
+ this.filename = filename
+ this.imageData = buffer.toByteArray()
+ } catch (e: FileNotFoundException) {
+ e.printStackTrace()
+ addError("$filename not found")
+ } catch (e: IOException) {
+ e.printStackTrace()
+ addError(e.message ?: "error in Graphic") // TODO: Verify these messages are meaningful
+ }*/
+ }
+
+ override fun addError(err: String) {
+ addError(labels.last(), err)
+ }
+
+ override var sizeInBytes: Int
+ get() = 2
+ set(value) {}
+}
diff --git a/src/jvmMain/kotlin/mtmc/asm/instructions/ALUInstruction.kt b/src/commonMain/kotlin/mtmc/asm/instructions/ALUInstruction.kt
similarity index 95%
rename from src/jvmMain/kotlin/mtmc/asm/instructions/ALUInstruction.kt
rename to src/commonMain/kotlin/mtmc/asm/instructions/ALUInstruction.kt
index d70534f..0befdae 100644
--- a/src/jvmMain/kotlin/mtmc/asm/instructions/ALUInstruction.kt
+++ b/src/commonMain/kotlin/mtmc/asm/instructions/ALUInstruction.kt
@@ -5,7 +5,6 @@ import mtmc.emulator.Register.Companion.fromInteger
import mtmc.emulator.Register.Companion.toInteger
import mtmc.tokenizer.MTMCToken
import mtmc.util.BinaryUtils
-import java.util.Locale
class ALUInstruction(
type: InstructionType,
@@ -38,7 +37,7 @@ class ALUInstruction(
}
val isBinaryOp: Boolean
- get() = !ALUOp.valueOf(instructionToken.stringValue.uppercase(Locale.getDefault())).isUnary
+ get() = !ALUOp.valueOf(instructionToken.stringValue.uppercase()).isUnary
override fun genCode(output: ByteArray, assembler: Assembler) {
val opCode = ALUOp.toInteger(instructionToken.stringValue)
@@ -62,13 +61,12 @@ class ALUInstruction(
}
companion object {
- @JvmStatic
fun disassemble(instruction: Short): String? {
if (BinaryUtils.getBits(16, 4, instruction).toInt() == 1) {
val builder = StringBuilder()
val opCode = BinaryUtils.getBits(12, 4, instruction)
val op = ALUOp.fromInt(opCode)
- val aluOp = ALUOp.valueOf(op.uppercase(Locale.getDefault()))
+ val aluOp = ALUOp.valueOf(op.uppercase())
if (aluOp == ALUOp.IMM) {
builder.append(op).append(" ")
builder.append(fromInteger(BinaryUtils.getBits(8, 4, instruction).toInt())).append(" ")
diff --git a/src/jvmMain/kotlin/mtmc/asm/instructions/ALUOp.kt b/src/commonMain/kotlin/mtmc/asm/instructions/ALUOp.kt
similarity index 72%
rename from src/jvmMain/kotlin/mtmc/asm/instructions/ALUOp.kt
rename to src/commonMain/kotlin/mtmc/asm/instructions/ALUOp.kt
index 821897f..3f33d51 100644
--- a/src/jvmMain/kotlin/mtmc/asm/instructions/ALUOp.kt
+++ b/src/commonMain/kotlin/mtmc/asm/instructions/ALUOp.kt
@@ -1,7 +1,5 @@
package mtmc.asm.instructions
-import java.util.*
-
enum class ALUOp(val opCode: Int, val isUnary: Boolean) {
ADD(0x0000, false),
SUB(0x0001, false),
@@ -21,20 +19,17 @@ enum class ALUOp(val opCode: Int, val isUnary: Boolean) {
IMM(0x000F, true);
companion object {
- @JvmStatic
fun toInteger(instruction: String): Int {
- return valueOf(instruction.uppercase(Locale.getDefault())).opCode
+ return valueOf(instruction.uppercase()).opCode
}
- @JvmStatic
fun fromInt(opCode: Short): String {
- return entries[opCode.toInt()].name.lowercase(Locale.getDefault())
+ return entries[opCode.toInt()].name.lowercase()
}
- @JvmStatic
fun isALUOp(op: String): Boolean {
try {
- val aluOp = valueOf(op.uppercase(Locale.getDefault()))
+ val aluOp = valueOf(op.uppercase())
return true
} catch (e: IllegalArgumentException) {
return false
diff --git a/src/jvmMain/kotlin/mtmc/asm/instructions/ErrorInstruction.kt b/src/commonMain/kotlin/mtmc/asm/instructions/ErrorInstruction.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/asm/instructions/ErrorInstruction.kt
rename to src/commonMain/kotlin/mtmc/asm/instructions/ErrorInstruction.kt
diff --git a/src/jvmMain/kotlin/mtmc/asm/instructions/Instruction.kt b/src/commonMain/kotlin/mtmc/asm/instructions/Instruction.kt
similarity index 95%
rename from src/jvmMain/kotlin/mtmc/asm/instructions/Instruction.kt
rename to src/commonMain/kotlin/mtmc/asm/instructions/Instruction.kt
index 0f08b63..867a240 100644
--- a/src/jvmMain/kotlin/mtmc/asm/instructions/Instruction.kt
+++ b/src/commonMain/kotlin/mtmc/asm/instructions/Instruction.kt
@@ -7,9 +7,9 @@ import mtmc.emulator.MonTanaMiniComputer.Companion.isDoubleWordInstruction
import mtmc.tokenizer.MTMCToken
abstract class Instruction(
- @JvmField val type: InstructionType,
+ val type: InstructionType,
labels: List,
- @JvmField val instructionToken: MTMCToken
+ val instructionToken: MTMCToken
) : ASMElement(labels, instructionToken.line) {
open fun validateLabel(assembler: Assembler) {
// default does nothing
@@ -25,7 +25,6 @@ abstract class Instruction(
get() = type.sizeInBytes
companion object {
- @JvmStatic
fun isInstruction(cmd: String): Boolean {
return InstructionType.fromString(cmd) != null
}
diff --git a/src/jvmMain/kotlin/mtmc/asm/instructions/InstructionType.kt b/src/commonMain/kotlin/mtmc/asm/instructions/InstructionType.kt
similarity index 92%
rename from src/jvmMain/kotlin/mtmc/asm/instructions/InstructionType.kt
rename to src/commonMain/kotlin/mtmc/asm/instructions/InstructionType.kt
index 5267bdb..d557b08 100644
--- a/src/jvmMain/kotlin/mtmc/asm/instructions/InstructionType.kt
+++ b/src/commonMain/kotlin/mtmc/asm/instructions/InstructionType.kt
@@ -1,9 +1,7 @@
package mtmc.asm.instructions
-import java.util.*
-
-enum class InstructionType @JvmOverloads constructor(
- @JvmField val instructionClass: InstructionClass?,
+enum class InstructionType constructor(
+ val instructionClass: InstructionClass?,
val sizeInBytes: Int = 2
) {
SYS(InstructionClass.MISC),
@@ -86,10 +84,9 @@ enum class InstructionType @JvmOverloads constructor(
}
companion object {
- @JvmStatic
fun fromString(string: String): InstructionType? {
try {
- return valueOf(string.uppercase(Locale.getDefault()))
+ return valueOf(string.uppercase())
} catch (e: IllegalArgumentException) {
return null
}
diff --git a/src/jvmMain/kotlin/mtmc/asm/instructions/JumpInstruction.kt b/src/commonMain/kotlin/mtmc/asm/instructions/JumpInstruction.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/asm/instructions/JumpInstruction.kt
rename to src/commonMain/kotlin/mtmc/asm/instructions/JumpInstruction.kt
diff --git a/src/jvmMain/kotlin/mtmc/asm/instructions/JumpRegisterInstruction.kt b/src/commonMain/kotlin/mtmc/asm/instructions/JumpRegisterInstruction.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/asm/instructions/JumpRegisterInstruction.kt
rename to src/commonMain/kotlin/mtmc/asm/instructions/JumpRegisterInstruction.kt
diff --git a/src/jvmMain/kotlin/mtmc/asm/instructions/LoadStoreInstruction.kt b/src/commonMain/kotlin/mtmc/asm/instructions/LoadStoreInstruction.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/asm/instructions/LoadStoreInstruction.kt
rename to src/commonMain/kotlin/mtmc/asm/instructions/LoadStoreInstruction.kt
diff --git a/src/jvmMain/kotlin/mtmc/asm/instructions/LoadStoreRegisterInstruction.kt b/src/commonMain/kotlin/mtmc/asm/instructions/LoadStoreRegisterInstruction.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/asm/instructions/LoadStoreRegisterInstruction.kt
rename to src/commonMain/kotlin/mtmc/asm/instructions/LoadStoreRegisterInstruction.kt
diff --git a/src/jvmMain/kotlin/mtmc/asm/instructions/MetaInstruction.kt b/src/commonMain/kotlin/mtmc/asm/instructions/MetaInstruction.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/asm/instructions/MetaInstruction.kt
rename to src/commonMain/kotlin/mtmc/asm/instructions/MetaInstruction.kt
diff --git a/src/jvmMain/kotlin/mtmc/asm/instructions/MiscInstruction.kt b/src/commonMain/kotlin/mtmc/asm/instructions/MiscInstruction.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/asm/instructions/MiscInstruction.kt
rename to src/commonMain/kotlin/mtmc/asm/instructions/MiscInstruction.kt
diff --git a/src/jvmMain/kotlin/mtmc/asm/instructions/StackInstruction.kt b/src/commonMain/kotlin/mtmc/asm/instructions/StackInstruction.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/asm/instructions/StackInstruction.kt
rename to src/commonMain/kotlin/mtmc/asm/instructions/StackInstruction.kt
diff --git a/src/jvmMain/kotlin/mtmc/asm/instructions/TestInstruction.kt b/src/commonMain/kotlin/mtmc/asm/instructions/TestInstruction.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/asm/instructions/TestInstruction.kt
rename to src/commonMain/kotlin/mtmc/asm/instructions/TestInstruction.kt
diff --git a/src/commonMain/kotlin/mtmc/emulator/DebugInfo.kt b/src/commonMain/kotlin/mtmc/emulator/DebugInfo.kt
new file mode 100644
index 0000000..ed6ed09
--- /dev/null
+++ b/src/commonMain/kotlin/mtmc/emulator/DebugInfo.kt
@@ -0,0 +1,47 @@
+package mtmc.emulator
+
+import nl.astraeus.logger.getTimestamp
+
+data class DebugInfo(
+ val debugStrings: MutableList,
+ val assemblyFile: String?,
+ val assemblySource: String,
+ val assemblyLineNumbers: IntArray,
+ val originalFile: String,
+ val originalLineNumbers: IntArray,
+ val globals: Array,
+ val locals: Array>
+) {
+ fun handleDebugString(
+ debugIndex: Short,
+ monTanaMiniComputer: MonTanaMiniComputer
+ ) {
+ val debugString = debugStrings!!.get(debugIndex.toInt())
+ /*
+ val compile = Pattern.compile("(\\$[a-zA-Z][a-zA-Z0-9])")
+ val matcher = compile.matcher(debugString)
+ val formattedString = StringBuilder()
+ var start = 0
+ var end: Int
+ while (matcher.find()) {
+ val match = matcher.group().substring(1)
+ try {
+ end = matcher.start()
+ formattedString.append(debugString, start, end)
+ val register = Register.valueOf(match.uppercase())
+ formattedString.append(monTanaMiniComputer.getRegisterValue(register).toInt())
+ start = matcher.end()
+ } catch (e: Exception) {
+ formattedString.append(match)
+ }
+ }
+ formattedString.append(debugString.substring(start))
+ println("DEBUG[" + getTimestamp() + "] : " + formattedString)
+ */
+ println("DEBUG[" + getTimestamp() + "] : " + debugString)
+ }
+
+ data class GlobalInfo(val name: String?, val location: Int, val type: String?)
+
+ data class LocalInfo(val name: String?, val offset: Int, val type: String?)
+}
\ No newline at end of file
diff --git a/src/jvmMain/kotlin/mtmc/emulator/MTMCClock.kt b/src/commonMain/kotlin/mtmc/emulator/MTMCClock.kt
similarity index 73%
rename from src/jvmMain/kotlin/mtmc/emulator/MTMCClock.kt
rename to src/commonMain/kotlin/mtmc/emulator/MTMCClock.kt
index d440874..4b91a06 100644
--- a/src/jvmMain/kotlin/mtmc/emulator/MTMCClock.kt
+++ b/src/commonMain/kotlin/mtmc/emulator/MTMCClock.kt
@@ -1,21 +1,23 @@
package mtmc.emulator
import mtmc.emulator.MonTanaMiniComputer.ComputerStatus
+import mtmc.util.currentTimeMillis
import kotlin.math.max
/**
*
* @author jbanes
*/
-class MTMCClock
- (private val computer: MonTanaMiniComputer) {
+class MTMCClock(
+ private val computer: MonTanaMiniComputer
+) {
fun run() {
var instructions: Long = 0
var ips: Long = 0
var expected: Long = 0
var virtual: Long = 0
- var startTime = System.currentTimeMillis()
+ var startTime = currentTimeMillis()
var deltaStart: Long
var delta: Long
@@ -28,8 +30,8 @@ class MTMCClock
pulse = (if (speed <= 0) 1000000 else max(speed / 100, 1))
ms = (if (pulse < 10) 1000 / speed else 10)
- deltaStart = System.currentTimeMillis()
- delta = ms - (System.currentTimeMillis() - deltaStart)
+ deltaStart = currentTimeMillis()
+ delta = ms - (currentTimeMillis() - deltaStart)
/* We've lost more than a second. Recalibrate. */
@@ -50,11 +52,11 @@ class MTMCClock
instructions += computer.pulse(pulse)
virtual += pulse
- ips = (virtual * 1000) / max(1, System.currentTimeMillis() - startTime)
- expected = (System.currentTimeMillis() - startTime) * speed / 1000
+ ips = (virtual * 1000) / max(1, currentTimeMillis() - startTime)
+ expected = (currentTimeMillis() - startTime) * speed / 1000
}
- System.err.println("Executed " + instructions + " instructions at a rate of " + ips + " ips (speed = " + speed + ")")
+ //println("Executed " + instructions + " instructions at a rate of " + ips + " ips (speed = " + speed + ")")
}
fun step() {
diff --git a/src/jvmMain/kotlin/mtmc/emulator/MTMCConsole.kt b/src/commonMain/kotlin/mtmc/emulator/MTMCConsole.kt
similarity index 91%
rename from src/jvmMain/kotlin/mtmc/emulator/MTMCConsole.kt
rename to src/commonMain/kotlin/mtmc/emulator/MTMCConsole.kt
index 75fb03f..64cba70 100644
--- a/src/jvmMain/kotlin/mtmc/emulator/MTMCConsole.kt
+++ b/src/commonMain/kotlin/mtmc/emulator/MTMCConsole.kt
@@ -1,16 +1,17 @@
package mtmc.emulator
+import mtmc.os.fs.Console
+import mtmc.os.fs.System
import mtmc.os.shell.Shell
import mtmc.tokenizer.MTMCScanner
import mtmc.tokenizer.MTMCToken
-import java.io.Console
class MTMCConsole(private val computer: MonTanaMiniComputer) {
var mode: Mode = Mode.NON_INTERACTIVE
var sysConsole: Console? = null
// non-interactive data
- private val output = StringBuffer()
+ private val output = StringBuilder()
private var shortValueSet = false
private var shortValue: Short = 0
private var stringValue: String? = null
@@ -18,7 +19,7 @@ class MTMCConsole(private val computer: MonTanaMiniComputer) {
// TODO invert so shell is driving and console is just IO
fun start() {
mode = Mode.INTERACTIVE
- sysConsole = System.console()
+ sysConsole = System.console
Shell.printShellWelcome(computer)
while (true) {
val cmd = sysConsole!!.readLine("mtmc > ")
@@ -48,7 +49,7 @@ class MTMCConsole(private val computer: MonTanaMiniComputer) {
if (mode == Mode.INTERACTIVE) {
val tokens = MTMCScanner(sysConsole!!.readLine(), "#").tokenize()
val token = tokens.first()
- assert(token.type === MTMCToken.TokenType.CHAR)
+ check(token.type === MTMCToken.TokenType.CHAR)
return token.charValue()
} else {
this.shortValueSet = false
@@ -88,7 +89,7 @@ class MTMCConsole(private val computer: MonTanaMiniComputer) {
val text = if (index >= 0) output.substring(0, index + 1) else ""
if (index >= 0) {
- output.delete(0, index + 1)
+ output.removeRange(0, index + 1)
}
return text
@@ -121,7 +122,7 @@ class MTMCConsole(private val computer: MonTanaMiniComputer) {
}
fun resetOutput() {
- output.delete(0, output.length)
+ output.removeRange(0, output.length)
}
enum class Mode {
diff --git a/src/jvmMain/kotlin/mtmc/emulator/MTMCDisplay.kt b/src/commonMain/kotlin/mtmc/emulator/MTMCDisplay.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/emulator/MTMCDisplay.kt
rename to src/commonMain/kotlin/mtmc/emulator/MTMCDisplay.kt
diff --git a/src/jvmMain/kotlin/mtmc/emulator/MTMCIO.kt b/src/commonMain/kotlin/mtmc/emulator/MTMCIO.kt
similarity index 69%
rename from src/jvmMain/kotlin/mtmc/emulator/MTMCIO.kt
rename to src/commonMain/kotlin/mtmc/emulator/MTMCIO.kt
index 5cbec59..d71683a 100644
--- a/src/jvmMain/kotlin/mtmc/emulator/MTMCIO.kt
+++ b/src/commonMain/kotlin/mtmc/emulator/MTMCIO.kt
@@ -1,7 +1,5 @@
package mtmc.emulator
-import java.util.*
-
class MTMCIO {
var value: Int = 0
@@ -17,12 +15,12 @@ class MTMCIO {
}
fun keyPressed(key: String) {
- val button = Buttons.valueOf(key.uppercase(Locale.getDefault()))
+ val button = Buttons.valueOf(key.uppercase())
value = value or button.mask
}
fun keyReleased(key: String) {
- val button = Buttons.valueOf(key.uppercase(Locale.getDefault()))
+ val button = Buttons.valueOf(key.uppercase())
value = value and button.mask.inv()
}
}
diff --git a/src/jvmMain/kotlin/mtmc/emulator/MTMCObserver.kt b/src/commonMain/kotlin/mtmc/emulator/MTMCObserver.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/emulator/MTMCObserver.kt
rename to src/commonMain/kotlin/mtmc/emulator/MTMCObserver.kt
diff --git a/src/jvmMain/kotlin/mtmc/emulator/MonTanaMiniComputer.kt b/src/commonMain/kotlin/mtmc/emulator/MonTanaMiniComputer.kt
similarity index 93%
rename from src/jvmMain/kotlin/mtmc/emulator/MonTanaMiniComputer.kt
rename to src/commonMain/kotlin/mtmc/emulator/MonTanaMiniComputer.kt
index 015d4df..79a7b2d 100644
--- a/src/jvmMain/kotlin/mtmc/emulator/MonTanaMiniComputer.kt
+++ b/src/commonMain/kotlin/mtmc/emulator/MonTanaMiniComputer.kt
@@ -4,19 +4,7 @@ import mtmc.asm.instructions.Instruction
import mtmc.os.MTOS
import mtmc.os.fs.FileSystem
import mtmc.util.BinaryUtils.getBits
-import java.lang.Byte
-import java.util.*
-import java.util.function.Consumer
-import java.util.stream.IntStream
-import kotlin.Array
-import kotlin.Boolean
-import kotlin.ByteArray
-import kotlin.Int
-import kotlin.IntArray
-import kotlin.Long
-import kotlin.Short
-import kotlin.ShortArray
-import kotlin.String
+import mtmc.util.Runnable
import kotlin.experimental.and
import kotlin.experimental.inv
import kotlin.experimental.or
@@ -43,10 +31,10 @@ class MonTanaMiniComputer {
var display: MTMCDisplay = MTMCDisplay(this)
var clock: MTMCClock = MTMCClock(this)
var fileSystem: FileSystem = FileSystem(this)
- var rewindSteps: LinkedList? = LinkedList()
+ var rewindSteps = mutableListOf()
// listeners
- private val observers: MutableList = ArrayList()
+ private val observers = mutableListOf()
var debugInfo: DebugInfo? = null
private var currentRewindStep: RewindStep? = null
@@ -58,13 +46,15 @@ class MonTanaMiniComputer {
registerFile = ShortArray(Register.entries.size)
memory = ByteArray(MEMORY_SIZE)
breakpoints = ByteArray(MEMORY_SIZE)
- rewindSteps = null
+ rewindSteps.clear()
setRegisterValue(
Register.SP,
MEMORY_SIZE.toShort().toInt()
) // default the stack pointer to the top of memory
- rewindSteps = LinkedList()
- observers!!.forEach(Consumer { obj: MTMCObserver? -> obj!!.computerReset() })
+ rewindSteps.clear()
+ observers.forEach { obj ->
+ obj.computerReset()
+ }
}
fun load(code: ByteArray, data: ByteArray, debugInfo: DebugInfo?) {
@@ -79,11 +69,11 @@ class MonTanaMiniComputer {
val codeBoundary = code.size
- System.arraycopy(code, 0, memory, 0, codeBoundary)
+ code.copyInto(memory, 0, 0, codeBoundary)
setRegisterValue(Register.CB, codeBoundary - 1)
val dataBoundary = codeBoundary + data.size
- System.arraycopy(data, 0, memory, codeBoundary, data.size)
+ code.copyInto(memory, codeBoundary, 0, data.size)
setRegisterValue(Register.DB, dataBoundary - 1)
@@ -143,7 +133,9 @@ class MonTanaMiniComputer {
fun fetchAndExecute() {
currentRewindStep = RewindStep()
- rewindSteps!!.push(currentRewindStep)
+ currentRewindStep?.let {
+ rewindSteps.add(0, it)
+ }
fetchCurrentInstruction()
val instruction = getRegisterValue(Register.IR)
if (isDoubleWordInstruction(instruction)) {
@@ -158,7 +150,7 @@ class MonTanaMiniComputer {
}
fun execInstruction(instruction: Short) {
- observers!!.forEach(Consumer { o: MTMCObserver? -> o!!.beforeExecution(instruction) })
+ observers!!.forEach({ o: MTMCObserver? -> o!!.beforeExecution(instruction) })
val instructionType: Short = getBits(16, 4, instruction)
if (instructionType.toInt() == 0x0000) { // MISC
val topNibble: Int = getBits(12, 4, instruction).toInt()
@@ -710,7 +702,9 @@ class MonTanaMiniComputer {
} else {
badInstruction(instruction)
}
- observers.forEach(Consumer { o: MTMCObserver? -> o!!.afterExecution(instruction) })
+ observers.forEach { o: MTMCObserver? ->
+ o!!.afterExecution(instruction)
+ }
}
val isFlagTestBitSet: Boolean
@@ -733,7 +727,7 @@ class MonTanaMiniComputer {
private fun badInstruction(instruction: Short) {
setStatus(ComputerStatus.PERMANENT_ERROR)
// TODO implement flags
- console.println("BAD INSTRUCTION: 0x" + Integer.toHexString(instruction.toInt() and 0xFFFF))
+ console.println("BAD INSTRUCTION: 0x" + (instruction.toInt() and 0xFFFF).toHexString())
}
fun fetchCurrentInstruction() {
@@ -746,14 +740,16 @@ class MonTanaMiniComputer {
} else {
setRegisterValue(Register.DR, 0)
}
- observers!!.forEach(Consumer { o: MTMCObserver? -> o!!.instructionFetched(instruction) })
+ observers.forEach { o: MTMCObserver? ->
+ o!!.instructionFetched(instruction)
+ }
}
fun fetchWordFromMemory(address: Int): Short {
val upperByte = fetchByteFromMemory(address).toShort()
val lowerByte = fetchByteFromMemory(address + 1)
var value = (upperByte.toInt() shl 8).toShort()
- val i = value.toInt() or Byte.toUnsignedInt(lowerByte)
+ val i = value.toInt() or lowerByte.toInt()
value = i.toShort()
return value
}
@@ -762,9 +758,8 @@ class MonTanaMiniComputer {
if (address < 0 || address >= memory.size) {
setStatus(ComputerStatus.PERMANENT_ERROR)
console.println(
- "BAD MEMORY LOCATION ON READ: " + address + " (0x" + Integer.toHexString(
- address and 0xFFFF
- ) + ")"
+ "BAD MEMORY LOCATION ON READ: $address (0x" +
+ (address and 0xFFFF).toHexString() + ")"
)
return 0
} else {
@@ -782,23 +777,24 @@ class MonTanaMiniComputer {
if (address < 0 || address >= memory.size) {
setStatus(ComputerStatus.PERMANENT_ERROR)
console.println(
- "BAD MEMORY LOCATION ON WRITE: " + address + " (0x" + Integer.toHexString(
- address and 0xFFFF
- ) + ")"
+ "BAD MEMORY LOCATION ON WRITE: " + address + " (0x" +
+ (address and 0xFFFF).toHexString() + ")"
)
return
}
val currentValue = memory[address]
- addRewindStep(Runnable { memory[address] = currentValue })
+ addRewindStep { memory[address] = currentValue }
memory[address] = value
- observers!!.forEach(Consumer { o: MTMCObserver? -> o!!.memoryUpdated(address, value) })
+ observers!!.forEach { o: MTMCObserver? ->
+ o!!.memoryUpdated(address, value)
+ }
}
private fun addRewindStep(runnable: Runnable?) {
if (currentRewindStep != null && rewindSteps != null) {
currentRewindStep!!.addSubStep(runnable)
- if (rewindSteps!!.size > MAX_REWIND_STEPS) {
- rewindSteps!!.removeLast()
+ if (rewindSteps.size > MAX_REWIND_STEPS) {
+ rewindSteps.removeLast()
}
}
}
@@ -812,11 +808,13 @@ class MonTanaMiniComputer {
// TODO mark as overflow
}
val currentValue = registerFile[register]
- addRewindStep(Runnable {
+ addRewindStep {
registerFile[register] = currentValue
- })
+ }
registerFile[register] = value.toShort()
- observers!!.forEach(Consumer { o: MTMCObserver? -> o!!.registerUpdated(register, value) })
+ observers!!.forEach { o: MTMCObserver? ->
+ o!!.registerUpdated(register, value)
+ }
}
fun getRegisterValue(register: Register): Short {
@@ -850,7 +848,9 @@ class MonTanaMiniComputer {
}
fun getBytesFromMemory(address: Int, length: Int): ByteArray {
- return Arrays.copyOfRange(memory, address, address + length)
+ val result = ByteArray(length)
+ memory.copyInto(result, 0, address, address + length)
+ return result
}
val oS: MTOS
@@ -858,18 +858,15 @@ class MonTanaMiniComputer {
val memoryAddresses: Iterable
get() = Iterable {
- IntStream.range(
- 0,
- MEMORY_SIZE
- ).iterator()
+ (0..MEMORY_SIZE).iterator()
}
fun addObserver(observer: MTMCObserver?) {
- observers!!.add(observer!!)
+ observers.add(observer!!)
}
fun removeObserver(observer: MTMCObserver?) {
- observers!!.remove(observer!!)
+ observers.remove(observer!!)
}
fun pause() {
@@ -936,7 +933,7 @@ class MonTanaMiniComputer {
fun setArg(arg: String) {
if (!arg.isEmpty()) {
val start = getRegisterValue(Register.BP)
- val bytes = arg.toByteArray()
+ val bytes = arg.encodeToByteArray()
writeStringToMemory(start.toInt(), bytes)
setRegisterValue(Register.A0, start.toInt())
setRegisterValue(Register.BP, start + bytes.size + 1)
@@ -953,7 +950,7 @@ class MonTanaMiniComputer {
}
fun rewind() {
- val latestRewindStep = rewindSteps!!.pop()
+ val latestRewindStep = rewindSteps.removeFirst()
latestRewindStep.rewind()
}
@@ -1020,7 +1017,6 @@ class MonTanaMiniComputer {
return false
}
- @JvmStatic
fun main(args: Array) {
val computer = MonTanaMiniComputer()
computer.speed = 1 // default to 1hz
diff --git a/src/jvmMain/kotlin/mtmc/emulator/Register.kt b/src/commonMain/kotlin/mtmc/emulator/Register.kt
similarity index 99%
rename from src/jvmMain/kotlin/mtmc/emulator/Register.kt
rename to src/commonMain/kotlin/mtmc/emulator/Register.kt
index 20b8a0f..82ff429 100644
--- a/src/jvmMain/kotlin/mtmc/emulator/Register.kt
+++ b/src/commonMain/kotlin/mtmc/emulator/Register.kt
@@ -73,4 +73,4 @@ enum class Register {
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/jvmMain/kotlin/mtmc/emulator/RewindStep.kt b/src/commonMain/kotlin/mtmc/emulator/RewindStep.kt
similarity index 67%
rename from src/jvmMain/kotlin/mtmc/emulator/RewindStep.kt
rename to src/commonMain/kotlin/mtmc/emulator/RewindStep.kt
index bfa8b49..4de124f 100644
--- a/src/jvmMain/kotlin/mtmc/emulator/RewindStep.kt
+++ b/src/commonMain/kotlin/mtmc/emulator/RewindStep.kt
@@ -1,10 +1,12 @@
package mtmc.emulator
+import mtmc.util.Runnable
+
class RewindStep {
var subSteps: MutableList = ArrayList()
fun rewind() {
- subSteps.reversed().forEach({ obj: Runnable? -> obj!!.run() })
+ subSteps.reversed().forEach({ obj: Runnable? -> obj!!.invoke() })
}
fun addSubStep(subStep: Runnable?) {
diff --git a/src/jvmMain/kotlin/mtmc/os/MTOS.kt b/src/commonMain/kotlin/mtmc/os/MTOS.kt
similarity index 93%
rename from src/jvmMain/kotlin/mtmc/os/MTOS.kt
rename to src/commonMain/kotlin/mtmc/os/MTOS.kt
index 756bfa6..e77f145 100644
--- a/src/jvmMain/kotlin/mtmc/os/MTOS.kt
+++ b/src/commonMain/kotlin/mtmc/os/MTOS.kt
@@ -3,18 +3,17 @@ package mtmc.os
import mtmc.emulator.MonTanaMiniComputer
import mtmc.emulator.Register
import mtmc.os.SysCall.Companion.getValue
+import mtmc.os.fs.File
+import mtmc.os.fs.Files
import mtmc.os.shell.Shell
-import java.io.File
-import java.io.IOException
-import java.nio.file.Files
-import java.util.*
+import mtmc.util.currentTimeMillis
import kotlin.math.max
import kotlin.math.min
-import kotlin.text.Charsets.US_ASCII
+import kotlin.random.Random
class MTOS(private val computer: MonTanaMiniComputer) {
private var timer: Long = 0
- var random: Random = Random()
+ var random: Random = Random.Default
// Editor support
var currentFile: String? = null
@@ -98,7 +97,7 @@ class MTOS(private val computer: MonTanaMiniComputer) {
}
}
val string = computer.console.readString()
- val bytes = string!!.toByteArray(US_ASCII)
+ val bytes = string!!.encodeToByteArray()
val bytesToRead = min(bytes.size, maxLen.toInt())
for (i in 0..(str.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
+ val lines: List =
+ str.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
.filter { s: String? -> !s!!.startsWith("!") }
.toList()
@@ -251,7 +250,7 @@ class MTOS(private val computer: MonTanaMiniComputer) {
val cappedLines = min(linesTotal, maxSize2.toInt())
for (lineNum in 0.. 0) this.timer = System.currentTimeMillis() + value
+ if (value > 0) this.timer = currentTimeMillis() + value
computer.setRegisterValue(
Register.RV,
- max(0, this.timer - System.currentTimeMillis()).toInt()
+ max(0, this.timer - currentTimeMillis()).toInt()
)
} else if (syscallNumber == getValue("drawimg").toShort()) {
val image = computer.getRegisterValue(Register.A0)
@@ -401,10 +399,13 @@ class MTOS(private val computer: MonTanaMiniComputer) {
}
val file = list[offset.toInt()]
- val name = file.getName()
+ val name = file.name
val size = min(maxSizeOut - 1, name.length)
- computer.writeWordToMemory(destination.toInt(), if (file.isDirectory()) 1 else 0)
+ computer.writeWordToMemory(
+ destination.toInt(),
+ if (file.directory) 1 else 0
+ )
for (i in 0..")
+ /*
+ {
+ val fs = computer.fileSystem
+ val file = fs.getRealPath(path).toFile()
+ return file
+ }
+ */
}
diff --git a/src/jvmMain/kotlin/mtmc/os/SysCall.kt b/src/commonMain/kotlin/mtmc/os/SysCall.kt
similarity index 82%
rename from src/jvmMain/kotlin/mtmc/os/SysCall.kt
rename to src/commonMain/kotlin/mtmc/os/SysCall.kt
index fe21f90..a577728 100644
--- a/src/jvmMain/kotlin/mtmc/os/SysCall.kt
+++ b/src/commonMain/kotlin/mtmc/os/SysCall.kt
@@ -1,7 +1,5 @@
package mtmc.os
-import java.util.*
-
enum class SysCall(value: Int) {
EXIT(0x00),
RINT(0x01),
@@ -50,25 +48,24 @@ enum class SysCall(value: Int) {
companion object {
fun isSysCall(call: String): Boolean {
try {
- valueOf(call.uppercase(Locale.getDefault()))
+ valueOf(call.uppercase())
return true
} catch (e: IllegalArgumentException) {
return false
}
}
- @JvmStatic
fun getValue(call: String): Byte {
- return valueOf(call.uppercase(Locale.getDefault())).value
+ return valueOf(call.uppercase()).value
}
fun getString(syscallCode: Byte): String? {
for (o in entries) {
if (o.value == syscallCode) {
- return o.name.lowercase(Locale.getDefault())
+ return o.name.lowercase()
}
}
return null
}
}
-}
+}
\ No newline at end of file
diff --git a/src/commonMain/kotlin/mtmc/os/exec/Executable.kt b/src/commonMain/kotlin/mtmc/os/exec/Executable.kt
new file mode 100644
index 0000000..9342613
--- /dev/null
+++ b/src/commonMain/kotlin/mtmc/os/exec/Executable.kt
@@ -0,0 +1,58 @@
+package mtmc.os.exec
+
+import mtmc.emulator.DebugInfo
+import mtmc.os.fs.Path
+
+data class Executable(
+ val format: Format,
+ val code: ByteArray,
+ val data: ByteArray,
+ val graphics: Array,
+ val sourceName: String,
+ val debugInfo: DebugInfo?
+) {
+ enum class Format(val formatName: String) {
+ Orc1("orc1");
+ }
+
+ fun dump(): String? {
+ return null //Gson().toJson(this)
+ }
+
+ fun dump(path: Path) {
+ /*
+ FileWriter(path.toFile()).use { fw ->
+ dump(fw)
+ }
+ */
+ }
+
+ /*
+ fun dump(writer: Writer?) {
+ val gson = Gson()
+ gson.toJson(this, writer)
+ }
+ */
+
+ companion object {
+ fun load(exe: String?): Executable? {
+ return null //Gson().fromJson(exe, Executable::class.java)
+ }
+
+ fun load(path: Path): Executable? = null
+ /*
+ {
+ FileReader(path.toFile()).use { fw ->
+ return load(fw)
+ }
+ }
+ */
+
+ /*
+ fun load(reader: Reader): Executable? {
+ val gson = Gson()
+ return gson.fromJson(reader, Executable::class.java)
+ }
+ */
+ }
+}
diff --git a/src/commonMain/kotlin/mtmc/os/fs/Console.kt b/src/commonMain/kotlin/mtmc/os/fs/Console.kt
new file mode 100644
index 0000000..cd31fa7
--- /dev/null
+++ b/src/commonMain/kotlin/mtmc/os/fs/Console.kt
@@ -0,0 +1,11 @@
+package mtmc.os.fs
+
+object System {
+ val console: Console = Console()
+}
+
+class Console {
+ fun readLine(prompt: String? = ""): String {
+ TODO("Not yet implemented")
+ }
+}
\ No newline at end of file
diff --git a/src/jvmMain/kotlin/mtmc/os/fs/ExecutableFileTypeDetector.java b/src/commonMain/kotlin/mtmc/os/fs/ExecutableFileTypeDetector.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/os/fs/ExecutableFileTypeDetector.java
rename to src/commonMain/kotlin/mtmc/os/fs/ExecutableFileTypeDetector.java
diff --git a/src/commonMain/kotlin/mtmc/os/fs/File.kt b/src/commonMain/kotlin/mtmc/os/fs/File.kt
new file mode 100644
index 0000000..5791843
--- /dev/null
+++ b/src/commonMain/kotlin/mtmc/os/fs/File.kt
@@ -0,0 +1,47 @@
+package mtmc.os.fs
+
+object Files {
+ fun readString(toPath: Path): String {
+ TODO("Not yet implemented")
+ }
+
+ fun readAllBytes(toPath: Path): ByteArray {
+ TODO("Not yet implemented")
+ }
+
+}
+
+class File(
+ val parent: File? = null,
+ val name: String
+) {
+
+ var directory: Boolean = TODO("initialize me")
+
+ constructor(name: String) : this(null, name)
+
+ fun getParent(): File = parent ?: error("No parent")
+
+ fun getPath(): String = if (parent == null) {
+ name
+ } else {
+ "${parent.getPath()}/$name"
+ }
+
+ fun exists(): Boolean {
+ TODO("Not yet implemented")
+ }
+
+ fun getAbsolutePath(): String {
+ TODO("Not yet implemented")
+ }
+
+ fun toPath(): Path {
+ TODO("Not yet implemented")
+ }
+
+ fun listFiles(): Array {
+ TODO("Not yet implemented")
+ }
+
+}
\ No newline at end of file
diff --git a/src/commonMain/kotlin/mtmc/os/fs/FileSystem.kt b/src/commonMain/kotlin/mtmc/os/fs/FileSystem.kt
new file mode 100644
index 0000000..2f904ca
--- /dev/null
+++ b/src/commonMain/kotlin/mtmc/os/fs/FileSystem.kt
@@ -0,0 +1,213 @@
+package mtmc.os.fs
+
+import mtmc.emulator.MonTanaMiniComputer
+import kotlin.jvm.JvmField
+
+class FileSystem(
+ val computer: MonTanaMiniComputer
+) {
+ private var cwd = "/home"
+
+ init {
+ initFileSystem()
+ }
+
+ private fun initFileSystem() {
+ /*
+ if (DISK_PATH.toFile().exists()) return
+
+
+ // Make the disk/ directory
+ DISK_PATH.toFile().mkdirs()
+
+ try {
+ ZipInputStream(getClass().getResourceAsStream("/disk.zip")).use { `in` ->
+ var entry: ZipEntry?
+ var file: File?
+
+ val data = ByteArray(4096)
+ var count: Int
+ while ((`in`.getNextEntry().also { entry = it }) != null) {
+ file = File(entry.getName())
+
+ if (entry.isDirectory()) {
+ file.mkdirs()
+ } else {
+ file.getParentFile().mkdirs()
+
+ FileOutputStream(file).use { out ->
+ while ((`in`.read(data).also { count = it }) > 0) {
+ out.write(data, 0, count)
+ }
+ }
+ }
+ }
+ }
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+ */
+ }
+
+ private fun notifyOfFileSystemUpdate() {
+ if (this.computer != null) {
+ computer.notifyOfFileSystemUpdate()
+ }
+ }
+
+ var cWD: String
+ get() = this.cwd
+ set(cwd) {
+ this.cwd = resolve(cwd)
+ this.notifyOfFileSystemUpdate()
+ }
+
+ fun exists(path: String): Boolean {
+ return false //File(DISK_PATH.toFile(), resolve(path)).exists()
+ }
+
+ fun mkdir(path: String): Boolean {
+ /*
+ val success: Boolean = File(DISK_PATH.toFile(), resolve(path)).mkdir()
+
+ if (success) {
+ computer.notifyOfFileSystemUpdate()
+ }
+
+ return success
+ */
+ return true
+ }
+
+ fun delete(path: String): Boolean {
+ /*
+ val success: Boolean = File(DISK_PATH.toFile(), resolve(path)).delete()
+
+ if (success) {
+ computer.notifyOfFileSystemUpdate()
+ }
+
+ return success
+ */
+ return true
+ }
+
+ fun resolve(filename: String): String = filename
+ /*
+ {
+ val root: File = DISK_PATH.toFile()
+ var directory = if (filename.startsWith("/")) root else File(root, cwd)
+ val path: Array = filename.split("/")
+
+ for (name in path) {
+ if (name.equals(".")) {
+ continue
+ } else if (name.equals("..") && directory.equals(root)) {
+ continue
+ } else if (name.equals("..")) {
+ directory = directory.getParentFile()
+ } else {
+ directory = File(directory, name)
+ }
+ }
+
+ if (directory.equals(root)) {
+ return "/"
+ }
+
+ return directory.getAbsolutePath().substring(root.getAbsolutePath().length())
+ }
+ */
+
+ fun getRealPath(path: String): Path { // Resolves given path and returns /disk/ + path
+ val resolvedPath = resolve(path)
+ val slashGone: String = if (resolvedPath.length > 0) resolvedPath.substring(1) else ""
+ val file: File = DISK_PATH.resolve(slashGone).toFile()
+
+ if (file.getAbsolutePath().length < DISK_PATH.toFile().getAbsolutePath().length) {
+ return DISK_PATH
+ }
+
+ return file.toPath()
+ }
+
+ fun getFileList(path: String): Array {
+ val resolvedPath: File = getRealPath(path).toFile()
+
+ if (!resolvedPath.directory) return arrayOf(resolvedPath)
+
+ return resolvedPath.listFiles()
+ }
+
+ fun listFiles(path: String): Listing {
+ val resolvedPath: File = getRealPath(path).toFile()
+
+ return Listing(this, resolvedPath)
+ }
+
+ fun listCWD(): Listing {
+ return listFiles(cwd)
+ }
+
+ fun listRoot(): Listing {
+ return listFiles("/")
+ }
+
+ fun writeFile(path: String, contents: String?) {
+ val filePath: Path = getRealPath(path)
+ //Files.writeString(filePath, contents)
+ }
+
+ fun readFile(path: String): String? {
+ val filePath: Path = getRealPath(path)
+ val contents = "" //Files.readString(filePath)
+ return contents
+ }
+
+ fun getMimeType(path: String): String {
+ val file: Path = getRealPath(path)
+ val name = file.toFile().name.lowercase()
+ val probed = file.probeContentType()
+
+ if (name.endsWith(".asm")) return "text/x-asm"
+ if (name.endsWith(".c")) return "text/x-csrc"
+ if (name.endsWith(".sea")) return "text/x-csrc"
+ if (name.endsWith(".h")) return "text/x-csrc"
+ if (probed != null) return probed
+
+ return "application/octet-stream"
+ }
+
+ /*
+ fun openFile(path: String): InputStream? {
+ val file: Unit */
+ /* TODO: class org.jetbrains.kotlin.nj2k.types.JKJavaNullPrimitiveType *//*
+? =
+ getRealPath(path).toFile()
+
+ return FileInputStream(file)
+ }
+*/
+
+ /*
+ fun saveFile(path: String, contents: InputStream) {
+ val file: Unit */
+ /* TODO: class org.jetbrains.kotlin.nj2k.types.JKJavaNullPrimitiveType *//*
+? =
+ getRealPath(path).toFile()
+ val data = ByteArray(4096)
+ var count: Int
+
+ FileOutputStream(file).use { out ->
+ while ((contents.read(data).also { count = it }) > 0) {
+ out.write(data, 0, count)
+ }
+ }
+ }
+*/
+
+ companion object {
+ @JvmField
+ val DISK_PATH: Path = Path() //.of(System.getProperty("user.dir"), "disk").toAbsolutePath()
+ }
+}
\ No newline at end of file
diff --git a/src/commonMain/kotlin/mtmc/os/fs/Listing.kt b/src/commonMain/kotlin/mtmc/os/fs/Listing.kt
new file mode 100644
index 0000000..899a76e
--- /dev/null
+++ b/src/commonMain/kotlin/mtmc/os/fs/Listing.kt
@@ -0,0 +1,45 @@
+package mtmc.os.fs
+
+class Listing(
+ val fs: FileSystem,
+ val file: File
+) {
+ val path: String
+ val name: String
+ val directory: Boolean
+ val root: Boolean
+
+ init {
+ val root = FileSystem.DISK_PATH.toFile().getAbsolutePath().replace('\\', '/')
+ val path = file.getAbsolutePath().substring(root.length).replace('\\', '/')
+
+ this.path = if (path.length > 0) path else "/"
+ this.name = if (path.length > 0) file.name else "/"
+ this.directory = file.directory
+ this.root = this.path.equals("/")
+ }
+
+ val parent: Listing?
+ get() = if (file.parent != null) {
+ Listing(fs, file.parent)
+ } else {
+ null
+ }
+
+ fun list(): List {
+ if (!directory) {
+ return ArrayList()
+ }
+
+ val list = ArrayList()
+ val children = file.listFiles()
+
+ list.sortBy { it.name }
+
+ for (child in children) {
+ list.add(Listing(fs, child))
+ }
+
+ return list
+ }
+}
diff --git a/src/commonMain/kotlin/mtmc/os/fs/Path.kt b/src/commonMain/kotlin/mtmc/os/fs/Path.kt
new file mode 100644
index 0000000..d005d17
--- /dev/null
+++ b/src/commonMain/kotlin/mtmc/os/fs/Path.kt
@@ -0,0 +1,15 @@
+package mtmc.os.fs
+
+class Path {
+ fun toFile(): File {
+ TODO("Not yet implemented")
+ }
+
+ fun probeContentType(): String? {
+ TODO("Not yet implemented")
+ }
+
+ fun resolve(filename: String): Path {
+ TODO("Not yet implemented")
+ }
+}
\ No newline at end of file
diff --git a/src/jvmMain/kotlin/mtmc/os/fs/PlainTextFileTypeDetector.java b/src/commonMain/kotlin/mtmc/os/fs/PlainTextFileTypeDetector.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/os/fs/PlainTextFileTypeDetector.java
rename to src/commonMain/kotlin/mtmc/os/fs/PlainTextFileTypeDetector.java
diff --git a/src/commonMain/kotlin/mtmc/os/shell/Shell.kt b/src/commonMain/kotlin/mtmc/os/shell/Shell.kt
index 450e018..4d8b057 100644
--- a/src/commonMain/kotlin/mtmc/os/shell/Shell.kt
+++ b/src/commonMain/kotlin/mtmc/os/shell/Shell.kt
@@ -1,160 +1,163 @@
-package mtmc.os.shell;
+package mtmc.os.shell
-import mtmc.asm.Assembler;
-import mtmc.asm.AssemblyResult;
-import mtmc.asm.instructions.Instruction;
-import mtmc.emulator.DebugInfo;
-import mtmc.emulator.MonTanaMiniComputer;
-import mtmc.emulator.Register;
-import mtmc.os.exec.Executable;
-import mtmc.os.fs.FileSystem;
-import mtmc.os.shell.builtins.AssembleCommand;
-import mtmc.os.shell.builtins.DisplayCommand;
-import mtmc.os.shell.builtins.ExitCommand;
-import mtmc.os.shell.builtins.GetCommand;
-import mtmc.os.shell.builtins.HelpCommand;
-import mtmc.os.shell.builtins.LoadCommand;
-import mtmc.os.shell.builtins.PauseCommand;
-import mtmc.os.shell.builtins.RunCommand;
-import mtmc.os.shell.builtins.SeacCommand;
-import mtmc.os.shell.builtins.SetCommand;
-import mtmc.os.shell.builtins.SpeedCommand;
-import mtmc.os.shell.builtins.StepCommand;
-import mtmc.os.shell.builtins.WebCommand;
-import mtmc.tokenizer.MTMCToken;
-import mtmc.tokenizer.MTMCTokenizer;
+import mtmc.asm.Assembler
+import mtmc.asm.instructions.Instruction.Companion.isInstruction
+import mtmc.asm.peekFirst
+import mtmc.emulator.MonTanaMiniComputer
+import mtmc.emulator.Register
+import mtmc.os.fs.FileSystem
+import mtmc.os.shell.builtins.AssembleCommand
+import mtmc.os.shell.builtins.DisplayCommand
+import mtmc.os.shell.builtins.ExitCommand
+import mtmc.os.shell.builtins.GetCommand
+import mtmc.os.shell.builtins.HelpCommand
+import mtmc.os.shell.builtins.LoadCommand
+import mtmc.os.shell.builtins.PauseCommand
+import mtmc.os.shell.builtins.RunCommand
+import mtmc.os.shell.builtins.SeacCommand
+import mtmc.os.shell.builtins.SetCommand
+import mtmc.os.shell.builtins.SpeedCommand
+import mtmc.os.shell.builtins.StepCommand
+import mtmc.os.shell.builtins.WebCommand
+import mtmc.tokenizer.MTMCToken
+import mtmc.tokenizer.MTMCTokenizer
-import java.nio.file.NoSuchFileException;
-import java.nio.file.Path;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.Map;
+object Shell {
+ private val COMMANDS: MutableMap = LinkedHashMap()
-import static mtmc.tokenizer.MTMCToken.TokenType.IDENTIFIER;
-import static mtmc.tokenizer.MTMCToken.TokenType.QUESTION_MARK;
+ init {
+ COMMANDS.put("help", HelpCommand())
+ COMMANDS.put("exit", ExitCommand())
+ COMMANDS.put("set", SetCommand())
+ COMMANDS.put("get", GetCommand())
+ COMMANDS.put("web", WebCommand())
+ COMMANDS.put("disp", DisplayCommand())
+ COMMANDS.put("asm", AssembleCommand())
+ COMMANDS.put("load", LoadCommand())
+ COMMANDS.put("step", StepCommand())
+ COMMANDS.put("run", RunCommand())
+ COMMANDS.put("pause", PauseCommand())
+ COMMANDS.put("speed", SpeedCommand())
+ COMMANDS.put("sc", SeacCommand())
+ }
-public class Shell {
- private static final Map COMMANDS = new LinkedHashMap<>();
+ fun isCommand(cmd: String): Boolean {
+ return COMMANDS.containsKey(cmd.lowercase())
+ }
- static {
- COMMANDS.put("help", new HelpCommand());
- COMMANDS.put("exit", new ExitCommand());
- COMMANDS.put("set", new SetCommand());
- COMMANDS.put("get", new GetCommand());
- COMMANDS.put("web", new WebCommand());
- COMMANDS.put("disp", new DisplayCommand());
- COMMANDS.put("asm", new AssembleCommand());
- COMMANDS.put("load", new LoadCommand());
- COMMANDS.put("step", new StepCommand());
- COMMANDS.put("run", new RunCommand());
- COMMANDS.put("pause", new PauseCommand());
- COMMANDS.put("speed", new SpeedCommand());
- COMMANDS.put("sc", new SeacCommand());
- }
+ private fun findExecutable(path: String?, fs: FileSystem): Boolean {
+ if (path == null || path == "") return false
+ //if (fs.exists(path) && !fs.listFiles(path).directory) return true
+ //if (fs.exists("/bin/" + path) && !fs.listFiles("/bin/" + path).directory) return true
- public static boolean isCommand(String cmd) {
- return COMMANDS.containsKey(cmd.toLowerCase());
- }
-
- private static boolean findExecutable(String path, FileSystem fs) {
- if (path == null || path.equals("")) return false;
- if (fs.exists(path) && !fs.listFiles(path).directory) return true;
- if (fs.exists("/bin/" + path) && !fs.listFiles("/bin/" + path).directory) return true;
-
- return false;
- }
-
- private static void runExecutable(String file, String command, MTMCTokenizer tokens, MonTanaMiniComputer computer) throws Exception {
- FileSystem fs = computer.getFileSystem();
- Path srcPath = Path.of("disk/" + fs.resolve(file));
- if(!srcPath.toFile().exists()) {
- srcPath = Path.of("disk" + fs.resolve("/bin/" + file));
+ return false
+ }
+
+ @Throws(Exception::class)
+ private fun runExecutable(
+ file: String,
+ command: String,
+ tokens: MTMCTokenizer,
+ computer: MonTanaMiniComputer
+ ) {
+ val fs = computer.fileSystem
+ /*
+ var srcPath = Path.of("disk/" + fs.resolve(file))
+ if (!srcPath.toFile().exists()) {
+ srcPath = Path.of("disk" + fs.resolve("/bin/" + file))
}
- Executable exec = Executable.load(srcPath);
- computer.load(exec.code, exec.data, exec.graphics, exec.debugInfo);
- tokens.consume();
- String arg = command.substring(file.length()).strip();
- computer.getOS().applyBreakpoints();
- computer.setArg(arg);
- computer.run();
- }
-
- public static void execCommand(String command, MonTanaMiniComputer computer) {
- MTMCTokenizer tokens = new MTMCTokenizer(command, "#");
- try {
- MTMCToken identifier = tokens.matchAndConsume(IDENTIFIER);
- String cmd;
- if (identifier == null) {
- MTMCToken question = tokens.matchAndConsume(QUESTION_MARK);
- String executable = tokens.collapseTokensAsString();
-
- // alias ? to help
- if (question != null) {
- cmd = "help";
- } else if (findExecutable(executable, computer.getFileSystem())) {
- cmd = executable;
- } else {
- printShellHelp(computer);
- return;
- }
- } else {
- cmd = identifier.stringValue();
+ val exec = load(srcPath)
+ computer.load(exec!!.code, exec.data, exec.graphics, exec.debugInfo)
+ tokens.consume()
+ val arg = command.substring(file.length).trim()
+ computer.oS.applyBreakpoints()
+ computer.setArg(arg)
+ computer.run()
+ */
+ }
+
+ fun execCommand(command: String, computer: MonTanaMiniComputer) {
+ val tokens = MTMCTokenizer(command, "#")
+ try {
+ val identifier = tokens.matchAndConsume(MTMCToken.TokenType.IDENTIFIER)
+ val cmd: String?
+ if (identifier == null) {
+ val question = tokens.matchAndConsume(MTMCToken.TokenType.QUESTION_MARK)
+ val executable = tokens.collapseTokensAsString()
+
+
+ // alias ? to help
+ if (question != null) {
+ cmd = "help"
+ } else if (findExecutable(executable, computer.fileSystem)) {
+ cmd = executable
+ } else {
+ printShellHelp(computer)
+ return
+ }
+ } else {
+ cmd = identifier.stringValue()
+ }
+ if (isCommand(cmd)) {
+ COMMANDS[cmd.lowercase()]!!.exec(tokens, computer)
+ } else {
+ tokens.reset()
+ val asm = mutableListOf()
+ asm.addAll(tokens.tokens)
+ val updatedAsm = Assembler.transformSyntheticInstructions(asm)
+ val firstToken = updatedAsm.peekFirst()
+ val firstTokenStr = firstToken?.stringValue() ?: error("Unexpected null token")
+ if (!updatedAsm.isEmpty() && isInstruction(firstTokenStr)) {
+ val assembler = Assembler()
+ val result = assembler.assemble(command)
+ if (result.errors.isEmpty()) {
+ val code = result.code
+ if (code.size == 4) {
+ val data = (code[2].toInt() shl 8) or code[3].toInt()
+ computer.setRegisterValue(Register.DR, data)
}
- if (isCommand(cmd)) {
- COMMANDS.get(cmd.toLowerCase()).exec(tokens, computer);
- } else {
- tokens.reset();
- LinkedList asm = new LinkedList<>(tokens.stream().toList());
- LinkedList updatedAsm = Assembler.Companion.transformSyntheticInstructions(asm);
- MTMCToken firstToken = updatedAsm.peekFirst();
- String firstTokenStr = firstToken.stringValue();
- if (!updatedAsm.isEmpty() && Instruction.isInstruction(firstTokenStr)) {
- Assembler assembler = new Assembler();
- AssemblyResult result = assembler.assemble(command);
- if (result.errors.isEmpty()) {
- byte[] code = result.code;
- if (code.length == 4) {
- int data = (code[2] << 8) | code[3];
- computer.setRegisterValue(Register.DR, data);
- }
- int lower = code[1] & 0xFF;
- int higher = code[0] & 0xFF;
- int inst = (higher << 8) | lower;
- DebugInfo originalDebugInfo = computer.getDebugInfo();
- computer.setDebugInfo(result.debugInfo);
- computer.execInstruction((short) inst);
- computer.setDebugInfo(originalDebugInfo);
- } else {
- computer.getConsole().println(result.printErrors());
- }
- } else {
- if (findExecutable(cmd, computer.getFileSystem())) {
- runExecutable(cmd, command, tokens, computer);
- } else {
- printShellHelp(computer);
- }
- }
- }
- } catch (NoSuchFileException e) {
- computer.getConsole().println("No such file: " + e.getFile());
- } catch (Exception e) {
- computer.getConsole().println(e.getMessage());
- e.printStackTrace();
+ val lower = code[1].toInt() and 0xFF
+ val higher = code[0].toInt() and 0xFF
+ val inst = (higher shl 8) or lower
+ val originalDebugInfo = computer.debugInfo
+ computer.debugInfo = result.debugInfo
+ computer.execInstruction(inst.toShort())
+ computer.debugInfo = originalDebugInfo
+ } else {
+ computer.console.println(result.printErrors())
+ }
+ } else {
+ if (findExecutable(cmd, computer.fileSystem)) {
+ runExecutable(cmd, command, tokens, computer)
+ } else {
+ printShellHelp(computer)
+ }
}
+ }
+ /*
+ } catch (e: NoSuchFileException) {
+ computer.console.println("No such file: " + e.getFile())
+ */
+ } catch (e: Exception) {
+ computer.console.println(e.message!!)
+ e.printStackTrace()
}
+ }
- public static void printShellHelp(MonTanaMiniComputer computer) {
- computer.getConsole().println("Shell BuiltIns: \n");
- for (ShellCommand value : COMMANDS.values()) {
- computer.getConsole().println(value.help);
- }
- computer.getConsole().println("Also: ");
- computer.getConsole().println(" ");
- computer.getConsole().println("or \n" +
- " \n\n");
+ fun printShellHelp(computer: MonTanaMiniComputer) {
+ computer.console.println("Shell BuiltIns: \n")
+ for (value in COMMANDS.values) {
+ computer.console.println(value.help!!)
}
+ computer.console.println("Also: ")
+ computer.console.println(" ")
+ computer.console.println(
+ "or \n" +
+ " \n\n"
+ )
+ }
- public static void printShellWelcome(MonTanaMiniComputer computer) {
- computer.getConsole().println("Welcome to MtOS! Type ? for help");
- }
+ fun printShellWelcome(computer: MonTanaMiniComputer) {
+ computer.console.println("Welcome to MtOS! Type ? for help")
+ }
}
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/ShellCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/ShellCommand.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/os/shell/ShellCommand.kt
rename to src/commonMain/kotlin/mtmc/os/shell/ShellCommand.kt
diff --git a/src/commonMain/kotlin/mtmc/os/shell/UsageException.kt b/src/commonMain/kotlin/mtmc/os/shell/UsageException.kt
index 69e1bb2..deb9af5 100644
--- a/src/commonMain/kotlin/mtmc/os/shell/UsageException.kt
+++ b/src/commonMain/kotlin/mtmc/os/shell/UsageException.kt
@@ -1,12 +1,7 @@
-package mtmc.os.shell;
+package mtmc.os.shell
-public class UsageException extends RuntimeException {
- private final ShellCommand cmd;
- public UsageException(ShellCommand shellCommand) {
- super("Usage:\n\n" + shellCommand.help);
- this.cmd = shellCommand;
- }
- public ShellCommand getCmd() {
- return cmd;
- }
-}
+class UsageException(
+ cmd: ShellCommand
+) : RuntimeException(
+ "Usage:\n\n" + cmd.help
+)
diff --git a/src/commonMain/kotlin/mtmc/os/shell/builtins/AssembleCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/builtins/AssembleCommand.kt
new file mode 100644
index 0000000..4a3f2bd
--- /dev/null
+++ b/src/commonMain/kotlin/mtmc/os/shell/builtins/AssembleCommand.kt
@@ -0,0 +1,45 @@
+package mtmc.os.shell.builtins
+
+import mtmc.emulator.MonTanaMiniComputer
+import mtmc.os.shell.ShellCommand
+import mtmc.tokenizer.MTMCTokenizer
+
+class AssembleCommand : ShellCommand() {
+ @Throws(Exception::class)
+ public override fun exec(tokens: MTMCTokenizer, computer: MonTanaMiniComputer) {
+ val fs = computer.fileSystem
+ val src = tokens.collapseTokensAsString()
+ require(!(src == null || src.isBlank())) { "missing or required argument 'src'" }
+ /*
+ val srcPath: Path = getDiskPath(src, fs)
+
+ val dst = tokens.collapseTokensAsString()
+ require(!(dst == null || dst.isBlank())) { "missing required argument 'dst'" }
+ val dstPath: Path = getDiskPath(dst, fs)
+
+ val contents = Files.readString(srcPath)
+ val assembler = Assembler()
+ val file_name =
+ fs.resolve(src) // srcPath.toString().substring(DISK_PATH.toString().length()).replaceAll("\\\\", "/");
+ val executable = assembler.assembleExecutable(file_name, contents)
+ executable.dump(dstPath)
+ computer.notifyOfFileSystemUpdate()
+ */
+ }
+
+ override val help: String
+ get() = """
+ asm
+ - src : path to a .asm file
+ - dst : path to a target output binary
+ """.trimIndent()
+
+ companion object {
+ /*
+ fun getDiskPath(pathString: String, fs: FileSystem): Path {
+ val path = Path.of("disk" + fs.resolve(pathString))
+ return path.toAbsolutePath()
+ }
+ */
+ }
+}
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/builtins/DisplayCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/builtins/DisplayCommand.kt
similarity index 83%
rename from src/jvmMain/kotlin/mtmc/os/shell/builtins/DisplayCommand.kt
rename to src/commonMain/kotlin/mtmc/os/shell/builtins/DisplayCommand.kt
index 7b7512d..1260872 100644
--- a/src/jvmMain/kotlin/mtmc/os/shell/builtins/DisplayCommand.kt
+++ b/src/commonMain/kotlin/mtmc/os/shell/builtins/DisplayCommand.kt
@@ -2,15 +2,14 @@ package mtmc.os.shell.builtins
import mtmc.emulator.MTMCDisplay
import mtmc.emulator.MonTanaMiniComputer
+import mtmc.os.fs.File
import mtmc.os.shell.ShellCommand
import mtmc.tokenizer.MTMCToken
import mtmc.tokenizer.MTMCTokenizer
-import java.io.File
-import java.util.*
-import javax.imageio.ImageIO
+import kotlin.random.Random
class DisplayCommand : ShellCommand() {
- var random: Random = Random()
+ var random: Random = Random.Default
@Throws(Exception::class)
public override fun exec(tokens: MTMCTokenizer, computer: MonTanaMiniComputer) {
@@ -42,8 +41,8 @@ class DisplayCommand : ShellCommand() {
if (tokens.more()) {
val imagePath = tokens.collapseTokensAsString()
val file = computer.oS.loadFile(imagePath)
- val img = ImageIO.read(file)
- computer.display.loadScaledImage(img)
+ //val img = ImageIO.read(file)
+ //computer.display.loadScaledImage(img)
} else {
usageException()
}
@@ -54,11 +53,15 @@ class DisplayCommand : ShellCommand() {
} else if (tokens.match(MTMCToken.TokenType.INTEGER)) {
val row = tokens.consumeAsInteger()
val col = tokens.require(
- mtmc.tokenizer.MTMCToken.TokenType.INTEGER,
- java.lang.Runnable { this.usageException() })!!.intValue()
+ mtmc.tokenizer.MTMCToken.TokenType.INTEGER
+ ) {
+ this.usageException()
+ }!!.intValue()
val color = tokens.require(
- mtmc.tokenizer.MTMCToken.TokenType.INTEGER,
- java.lang.Runnable { this.usageException() })!!.intValue()
+ mtmc.tokenizer.MTMCToken.TokenType.INTEGER
+ ) {
+ this.usageException()
+ }!!.intValue()
computer.display.setPixel(row, col, color)
} else {
usageException()
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/builtins/ExitCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/builtins/ExitCommand.kt
similarity index 94%
rename from src/jvmMain/kotlin/mtmc/os/shell/builtins/ExitCommand.kt
rename to src/commonMain/kotlin/mtmc/os/shell/builtins/ExitCommand.kt
index 7ad6b06..fee12fc 100644
--- a/src/jvmMain/kotlin/mtmc/os/shell/builtins/ExitCommand.kt
+++ b/src/commonMain/kotlin/mtmc/os/shell/builtins/ExitCommand.kt
@@ -7,7 +7,7 @@ import mtmc.tokenizer.MTMCTokenizer
class ExitCommand : ShellCommand() {
public override fun exec(tokens: MTMCTokenizer, computer: MonTanaMiniComputer) {
computer.console.println("Goodbye!")
- System.exit(1)
+ //System.exit(1)
}
override val help: String
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/builtins/GetCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/builtins/GetCommand.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/os/shell/builtins/GetCommand.kt
rename to src/commonMain/kotlin/mtmc/os/shell/builtins/GetCommand.kt
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/builtins/HelpCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/builtins/HelpCommand.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/os/shell/builtins/HelpCommand.kt
rename to src/commonMain/kotlin/mtmc/os/shell/builtins/HelpCommand.kt
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/builtins/LoadCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/builtins/LoadCommand.kt
similarity index 92%
rename from src/jvmMain/kotlin/mtmc/os/shell/builtins/LoadCommand.kt
rename to src/commonMain/kotlin/mtmc/os/shell/builtins/LoadCommand.kt
index 789fe95..96387be 100644
--- a/src/jvmMain/kotlin/mtmc/os/shell/builtins/LoadCommand.kt
+++ b/src/commonMain/kotlin/mtmc/os/shell/builtins/LoadCommand.kt
@@ -3,13 +3,13 @@ package mtmc.os.shell.builtins
import mtmc.emulator.MonTanaMiniComputer
import mtmc.os.exec.Executable.Companion.load
import mtmc.os.fs.FileSystem
+import mtmc.os.fs.Path
import mtmc.os.shell.ShellCommand
import mtmc.tokenizer.MTMCTokenizer
-import java.nio.file.Path
class LoadCommand : ShellCommand() {
@Throws(Exception::class)
- public override fun exec(tokens: MTMCTokenizer, computer: MonTanaMiniComputer) {
+ override fun exec(tokens: MTMCTokenizer, computer: MonTanaMiniComputer) {
val fs = computer.fileSystem
val program = tokens.collapseTokensAsString()
require(!(program == null || program.isBlank())) { "missing or required argument 'src'" }
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/builtins/PauseCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/builtins/PauseCommand.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/os/shell/builtins/PauseCommand.kt
rename to src/commonMain/kotlin/mtmc/os/shell/builtins/PauseCommand.kt
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/builtins/RunCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/builtins/RunCommand.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/os/shell/builtins/RunCommand.kt
rename to src/commonMain/kotlin/mtmc/os/shell/builtins/RunCommand.kt
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/builtins/SeacCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/builtins/SeacCommand.kt
similarity index 66%
rename from src/jvmMain/kotlin/mtmc/os/shell/builtins/SeacCommand.kt
rename to src/commonMain/kotlin/mtmc/os/shell/builtins/SeacCommand.kt
index fc6bd34..2b053e2 100644
--- a/src/jvmMain/kotlin/mtmc/os/shell/builtins/SeacCommand.kt
+++ b/src/commonMain/kotlin/mtmc/os/shell/builtins/SeacCommand.kt
@@ -1,10 +1,8 @@
package mtmc.os.shell.builtins
import mtmc.emulator.MonTanaMiniComputer
-import mtmc.lang.sea.SeaLanguage
import mtmc.os.shell.ShellCommand
import mtmc.tokenizer.MTMCTokenizer
-import mtmc.util.StringEscapeUtils.escapeString
class SeacCommand : ShellCommand() {
@Throws(Exception::class)
@@ -24,15 +22,18 @@ class SeacCommand : ShellCommand() {
requireNotNull(filename) { "expected source file" }
- require(fs.exists(filename)) { "file " + escapeString(filename) + " does not exist" }
+ require(fs.exists(filename)) { "file " + filename + " does not exist" }
println(fs.resolve(filename))
- val lang = SeaLanguage()
- val content = fs.readFile(filename)
- val exec = lang.compileExecutable(fs.resolve(filename), content)
- val bin = exec.dump()
- computer.fileSystem.writeFile(output, bin)
- computer.notifyOfFileSystemUpdate()
+ /*
+ val lang = SeaLanguage()
+ val content = fs.readFile(filename)
+ val exec = lang.compileExecutable(fs.resolve(filename), content)
+
+ val bin = exec.dump()
+ computer.fileSystem.writeFile(output, bin)
+ computer.notifyOfFileSystemUpdate()
+ */
}
override val help: String
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/builtins/SetCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/builtins/SetCommand.kt
similarity index 93%
rename from src/jvmMain/kotlin/mtmc/os/shell/builtins/SetCommand.kt
rename to src/commonMain/kotlin/mtmc/os/shell/builtins/SetCommand.kt
index bb93b3b..6dfffe8 100644
--- a/src/jvmMain/kotlin/mtmc/os/shell/builtins/SetCommand.kt
+++ b/src/commonMain/kotlin/mtmc/os/shell/builtins/SetCommand.kt
@@ -40,7 +40,10 @@ class SetCommand : ShellCommand() {
if (value?.type === MTMCToken.TokenType.INTEGER || value?.type === MTMCToken.TokenType.BINARY || value?.type === MTMCToken.TokenType.HEX) {
computer.writeWordToMemory(memLocation.intValue(), value.intValue())
} else {
- computer.writeStringToMemory(memLocation.intValue(), value!!.stringValue().toByteArray())
+ computer.writeStringToMemory(
+ memLocation.intValue(),
+ value!!.stringValue().encodeToByteArray()
+ )
}
}
}
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/builtins/SpeedCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/builtins/SpeedCommand.kt
similarity index 90%
rename from src/jvmMain/kotlin/mtmc/os/shell/builtins/SpeedCommand.kt
rename to src/commonMain/kotlin/mtmc/os/shell/builtins/SpeedCommand.kt
index 210dff7..625af06 100644
--- a/src/jvmMain/kotlin/mtmc/os/shell/builtins/SpeedCommand.kt
+++ b/src/commonMain/kotlin/mtmc/os/shell/builtins/SpeedCommand.kt
@@ -4,13 +4,10 @@ import mtmc.emulator.MonTanaMiniComputer
import mtmc.os.shell.ShellCommand
import mtmc.tokenizer.MTMCToken
import mtmc.tokenizer.MTMCTokenizer
-import java.util.*
class SpeedCommand : ShellCommand() {
- private val speeds: MutableList = Arrays.asList(
- *arrayOf(
+ private val speeds = listOf(
1, 10, 100, 1000, 10000, 100000, 1000000
- )
)
@Throws(Exception::class)
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/builtins/StepCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/builtins/StepCommand.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/os/shell/builtins/StepCommand.kt
rename to src/commonMain/kotlin/mtmc/os/shell/builtins/StepCommand.kt
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/builtins/WebCommand.kt b/src/commonMain/kotlin/mtmc/os/shell/builtins/WebCommand.kt
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/os/shell/builtins/WebCommand.kt
rename to src/commonMain/kotlin/mtmc/os/shell/builtins/WebCommand.kt
diff --git a/src/jvmMain/kotlin/mtmc/tokenizer/MTMCScanner.kt b/src/commonMain/kotlin/mtmc/tokenizer/MTMCScanner.kt
similarity index 97%
rename from src/jvmMain/kotlin/mtmc/tokenizer/MTMCScanner.kt
rename to src/commonMain/kotlin/mtmc/tokenizer/MTMCScanner.kt
index 27c4fae..171f2d1 100644
--- a/src/jvmMain/kotlin/mtmc/tokenizer/MTMCScanner.kt
+++ b/src/commonMain/kotlin/mtmc/tokenizer/MTMCScanner.kt
@@ -1,14 +1,16 @@
package mtmc.tokenizer
-import java.util.*
+fun Char.isHexDigit(): Boolean {
+ return this in '0'..'9' || this in 'a'..'f' || this in 'A'..'F'
+}
class MTMCScanner(private val src: String, private val lineCommentStart: String) {
var position: Int = 0
var line: Int = 1
var lineOffset: Int = 0
- var tokens: LinkedList = LinkedList()
+ var tokens = mutableListOf()
- fun tokenize(): LinkedList {
+ fun tokenize(): MutableList {
consumeWhitespace()
while (!scanEnd()) {
scanToken()
@@ -38,7 +40,7 @@ class MTMCScanner(private val src: String, private val lineCommentStart: String)
}
private fun scanLineComment(): Boolean {
- val bytes = lineCommentStart.toByteArray()
+ val bytes = lineCommentStart.encodeToByteArray()
for (i in bytes.indices) {
val aChar = bytes[i]
if (peek(i).code.toByte() != aChar) {
@@ -188,7 +190,7 @@ class MTMCScanner(private val src: String, private val lineCommentStart: String)
private fun scanHex(start: Int): Boolean {
takeChar() // take leading zero
takeChar() // take 'x'
- while (HexFormat.isHexDigit(peek().code)) {
+ while (peek().isHexDigit()) {
takeChar()
}
tokens.add(makeToken(MTMCToken.TokenType.HEX, strValueFrom(start), start))
diff --git a/src/jvmMain/kotlin/mtmc/tokenizer/MTMCToken.kt b/src/commonMain/kotlin/mtmc/tokenizer/MTMCToken.kt
similarity index 92%
rename from src/jvmMain/kotlin/mtmc/tokenizer/MTMCToken.kt
rename to src/commonMain/kotlin/mtmc/tokenizer/MTMCToken.kt
index 35efb74..e3f4f2f 100644
--- a/src/jvmMain/kotlin/mtmc/tokenizer/MTMCToken.kt
+++ b/src/commonMain/kotlin/mtmc/tokenizer/MTMCToken.kt
@@ -1,13 +1,12 @@
package mtmc.tokenizer
-@JvmRecord
data class MTMCToken(
- @JvmField val start: Int,
- @JvmField val end: Int,
+ val start: Int,
+ val end: Int,
val line: Int,
val lineOffset: Int,
- @JvmField val stringValue: String,
- @JvmField val type: TokenType?
+ val stringValue: String,
+ val type: TokenType?
) {
override fun toString(): String {
return stringValue
diff --git a/src/jvmMain/kotlin/mtmc/tokenizer/MTMCTokenizer.kt b/src/commonMain/kotlin/mtmc/tokenizer/MTMCTokenizer.kt
similarity index 90%
rename from src/jvmMain/kotlin/mtmc/tokenizer/MTMCTokenizer.kt
rename to src/commonMain/kotlin/mtmc/tokenizer/MTMCTokenizer.kt
index 575a7cc..0911056 100644
--- a/src/jvmMain/kotlin/mtmc/tokenizer/MTMCTokenizer.kt
+++ b/src/commonMain/kotlin/mtmc/tokenizer/MTMCTokenizer.kt
@@ -1,11 +1,10 @@
package mtmc.tokenizer
-import java.util.*
-import java.util.stream.Stream
+import mtmc.util.Runnable
import kotlin.math.max
class MTMCTokenizer(var source: String, lineCommentStart: String) {
- var tokens: LinkedList = MTMCScanner(source, lineCommentStart).tokenize()
+ var tokens: MutableList = MTMCScanner(source, lineCommentStart).tokenize()
var currentToken: Int = 0
fun currentToken(): MTMCToken {
@@ -59,10 +58,6 @@ class MTMCTokenizer(var source: String, lineCommentStart: String) {
return tokens.get(max(0, currentToken - 1))
}
- fun stream(): Stream {
- return tokens.stream()
- }
-
override fun toString(): String {
val sb = StringBuilder()
for (i in tokens.indices) {
@@ -104,7 +99,7 @@ class MTMCTokenizer(var source: String, lineCommentStart: String) {
if (match(tokenType)) {
return consume()
} else {
- notFound.run()
+ notFound.invoke()
return null
}
}
diff --git a/src/jvmMain/kotlin/mtmc/util/BinaryUtils.kt b/src/commonMain/kotlin/mtmc/util/BinaryUtils.kt
similarity index 71%
rename from src/jvmMain/kotlin/mtmc/util/BinaryUtils.kt
rename to src/commonMain/kotlin/mtmc/util/BinaryUtils.kt
index 01745ee..abb18dd 100644
--- a/src/jvmMain/kotlin/mtmc/util/BinaryUtils.kt
+++ b/src/commonMain/kotlin/mtmc/util/BinaryUtils.kt
@@ -22,27 +22,21 @@ object BinaryUtils {
}
fun toBinary(aByte: Byte): String {
- val binaryString = Integer.toBinaryString(aByte.toInt())
- val formatted = String.format("%8s", binaryString)
- val zeroed = formatted.replace(" ".toRegex(), "0")
+ val zeroed = aByte.toInt().toString(2).padStart(8, '0')
val underScored = zeroed.replace("....".toRegex(), "$0_")
val noTrailingUnderscore = underScored.substring(0, underScored.length - 1)
return "0b" + noTrailingUnderscore
}
fun toBinary(aShort: Short): String {
- val binaryString = Integer.toBinaryString(aShort.toInt())
- val formatted = String.format("%16s", binaryString)
- val zeroed = formatted.replace(" ".toRegex(), "0")
+ val zeroed = aShort.toInt().toString(2).padStart(16, '0')
val underScored = zeroed.replace("....".toRegex(), "$0_")
val noTrailingUnderscore = underScored.substring(0, underScored.length - 1)
return "0b" + noTrailingUnderscore
}
fun toBinary(anInt: Int): String {
- val binaryString = Integer.toBinaryString(anInt)
- val formatted = String.format("%32s", binaryString)
- val zeroed = formatted.replace(" ".toRegex(), "0")
+ val zeroed = anInt.toString(2).padStart(32, '0')
val underScored = zeroed.replace("....".toRegex(), "$0_")
val noTrailingUnderscore = underScored.substring(0, underScored.length - 1)
return "0b" + noTrailingUnderscore
diff --git a/src/commonMain/kotlin/mtmc/util/PlatformSpecific.kt b/src/commonMain/kotlin/mtmc/util/PlatformSpecific.kt
new file mode 100644
index 0000000..eb0a634
--- /dev/null
+++ b/src/commonMain/kotlin/mtmc/util/PlatformSpecific.kt
@@ -0,0 +1,3 @@
+package mtmc.util
+
+expect fun currentTimeMillis(): Long
\ No newline at end of file
diff --git a/src/commonMain/kotlin/mtmc/util/Runnable.kt b/src/commonMain/kotlin/mtmc/util/Runnable.kt
new file mode 100644
index 0000000..4a7ff90
--- /dev/null
+++ b/src/commonMain/kotlin/mtmc/util/Runnable.kt
@@ -0,0 +1,3 @@
+package mtmc.util
+
+typealias Runnable = () -> Unit
\ No newline at end of file
diff --git a/src/jsMain/kotlin/mtmc/util/PlatformSpecific.js.kt b/src/jsMain/kotlin/mtmc/util/PlatformSpecific.js.kt
new file mode 100644
index 0000000..8d0587b
--- /dev/null
+++ b/src/jsMain/kotlin/mtmc/util/PlatformSpecific.js.kt
@@ -0,0 +1,5 @@
+package mtmc.util
+
+import kotlin.js.Date
+
+actual fun currentTimeMillis(): Long = Date().getTime().toLong()
diff --git a/src/jvmMain/kotlin/mtmc/lang/CompilationException.java b/src/jvmMain/java/mtmc/lang/CompilationException.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/CompilationException.java
rename to src/jvmMain/java/mtmc/lang/CompilationException.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/Language.java b/src/jvmMain/java/mtmc/lang/Language.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/Language.java
rename to src/jvmMain/java/mtmc/lang/Language.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/Location.java b/src/jvmMain/java/mtmc/lang/Location.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/Location.java
rename to src/jvmMain/java/mtmc/lang/Location.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/ParseException.java b/src/jvmMain/java/mtmc/lang/ParseException.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/ParseException.java
rename to src/jvmMain/java/mtmc/lang/ParseException.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/Span.java b/src/jvmMain/java/mtmc/lang/Span.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/Span.java
rename to src/jvmMain/java/mtmc/lang/Span.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/Token.java b/src/jvmMain/java/mtmc/lang/Token.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/Token.java
rename to src/jvmMain/java/mtmc/lang/Token.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/SeaCompiler.java b/src/jvmMain/java/mtmc/lang/sea/SeaCompiler.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/SeaCompiler.java
rename to src/jvmMain/java/mtmc/lang/sea/SeaCompiler.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/SeaLanguage.java b/src/jvmMain/java/mtmc/lang/sea/SeaLanguage.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/SeaLanguage.java
rename to src/jvmMain/java/mtmc/lang/sea/SeaLanguage.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/SeaParser.java b/src/jvmMain/java/mtmc/lang/sea/SeaParser.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/SeaParser.java
rename to src/jvmMain/java/mtmc/lang/sea/SeaParser.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/SeaType.java b/src/jvmMain/java/mtmc/lang/sea/SeaType.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/SeaType.java
rename to src/jvmMain/java/mtmc/lang/sea/SeaType.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/Symbol.java b/src/jvmMain/java/mtmc/lang/sea/Symbol.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/Symbol.java
rename to src/jvmMain/java/mtmc/lang/sea/Symbol.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/Token.java b/src/jvmMain/java/mtmc/lang/sea/Token.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/Token.java
rename to src/jvmMain/java/mtmc/lang/sea/Token.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/Ast.java b/src/jvmMain/java/mtmc/lang/sea/ast/Ast.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/Ast.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/Ast.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/Declaration.java b/src/jvmMain/java/mtmc/lang/sea/ast/Declaration.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/Declaration.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/Declaration.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/DeclarationFunc.java b/src/jvmMain/java/mtmc/lang/sea/ast/DeclarationFunc.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/DeclarationFunc.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/DeclarationFunc.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/DeclarationStruct.java b/src/jvmMain/java/mtmc/lang/sea/ast/DeclarationStruct.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/DeclarationStruct.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/DeclarationStruct.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/DeclarationSyntaxError.java b/src/jvmMain/java/mtmc/lang/sea/ast/DeclarationSyntaxError.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/DeclarationSyntaxError.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/DeclarationSyntaxError.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/DeclarationTypedef.java b/src/jvmMain/java/mtmc/lang/sea/ast/DeclarationTypedef.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/DeclarationTypedef.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/DeclarationTypedef.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/DeclarationVar.java b/src/jvmMain/java/mtmc/lang/sea/ast/DeclarationVar.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/DeclarationVar.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/DeclarationVar.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/Error.java b/src/jvmMain/java/mtmc/lang/sea/ast/Error.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/Error.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/Error.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/Expression.java b/src/jvmMain/java/mtmc/lang/sea/ast/Expression.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/Expression.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/Expression.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionAccess.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionAccess.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionAccess.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionAccess.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionBin.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionBin.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionBin.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionBin.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionCall.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionCall.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionCall.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionCall.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionCast.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionCast.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionCast.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionCast.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionChar.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionChar.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionChar.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionChar.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionIdent.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionIdent.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionIdent.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionIdent.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionIndex.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionIndex.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionIndex.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionIndex.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionInitializer.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionInitializer.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionInitializer.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionInitializer.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionInteger.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionInteger.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionInteger.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionInteger.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionParens.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionParens.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionParens.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionParens.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionPostfix.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionPostfix.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionPostfix.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionPostfix.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionPrefix.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionPrefix.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionPrefix.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionPrefix.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionString.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionString.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionString.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionString.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionSyntaxError.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionSyntaxError.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionSyntaxError.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionSyntaxError.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionTernary.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionTernary.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionTernary.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionTernary.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionTypeError.java b/src/jvmMain/java/mtmc/lang/sea/ast/ExpressionTypeError.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/ExpressionTypeError.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/ExpressionTypeError.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/Statement.java b/src/jvmMain/java/mtmc/lang/sea/ast/Statement.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/Statement.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/Statement.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementBlock.java b/src/jvmMain/java/mtmc/lang/sea/ast/StatementBlock.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementBlock.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/StatementBlock.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementBreak.java b/src/jvmMain/java/mtmc/lang/sea/ast/StatementBreak.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementBreak.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/StatementBreak.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementContinue.java b/src/jvmMain/java/mtmc/lang/sea/ast/StatementContinue.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementContinue.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/StatementContinue.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementDoWhile.java b/src/jvmMain/java/mtmc/lang/sea/ast/StatementDoWhile.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementDoWhile.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/StatementDoWhile.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementExpression.java b/src/jvmMain/java/mtmc/lang/sea/ast/StatementExpression.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementExpression.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/StatementExpression.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementFor.java b/src/jvmMain/java/mtmc/lang/sea/ast/StatementFor.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementFor.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/StatementFor.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementGoto.java b/src/jvmMain/java/mtmc/lang/sea/ast/StatementGoto.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementGoto.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/StatementGoto.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementIf.java b/src/jvmMain/java/mtmc/lang/sea/ast/StatementIf.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementIf.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/StatementIf.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementReturn.java b/src/jvmMain/java/mtmc/lang/sea/ast/StatementReturn.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementReturn.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/StatementReturn.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementSyntaxError.java b/src/jvmMain/java/mtmc/lang/sea/ast/StatementSyntaxError.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementSyntaxError.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/StatementSyntaxError.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementVar.java b/src/jvmMain/java/mtmc/lang/sea/ast/StatementVar.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementVar.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/StatementVar.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementWhile.java b/src/jvmMain/java/mtmc/lang/sea/ast/StatementWhile.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/StatementWhile.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/StatementWhile.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/SyntaxError.java b/src/jvmMain/java/mtmc/lang/sea/ast/SyntaxError.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/SyntaxError.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/SyntaxError.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeDeclaration.java b/src/jvmMain/java/mtmc/lang/sea/ast/TypeDeclaration.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeDeclaration.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/TypeDeclaration.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeExpr.java b/src/jvmMain/java/mtmc/lang/sea/ast/TypeExpr.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeExpr.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/TypeExpr.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeExprArray.java b/src/jvmMain/java/mtmc/lang/sea/ast/TypeExprArray.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeExprArray.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/TypeExprArray.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeExprChar.java b/src/jvmMain/java/mtmc/lang/sea/ast/TypeExprChar.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeExprChar.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/TypeExprChar.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeExprInt.java b/src/jvmMain/java/mtmc/lang/sea/ast/TypeExprInt.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeExprInt.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/TypeExprInt.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeExprRef.java b/src/jvmMain/java/mtmc/lang/sea/ast/TypeExprRef.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeExprRef.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/TypeExprRef.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeExprVoid.java b/src/jvmMain/java/mtmc/lang/sea/ast/TypeExprVoid.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/TypeExprVoid.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/TypeExprVoid.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/TypePointer.java b/src/jvmMain/java/mtmc/lang/sea/ast/TypePointer.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/TypePointer.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/TypePointer.java
diff --git a/src/jvmMain/kotlin/mtmc/lang/sea/ast/Unit.java b/src/jvmMain/java/mtmc/lang/sea/ast/Unit.java
similarity index 100%
rename from src/jvmMain/kotlin/mtmc/lang/sea/ast/Unit.java
rename to src/jvmMain/java/mtmc/lang/sea/ast/Unit.java
diff --git a/src/jvmMain/kotlin/mtmc/asm/graphics/Graphic.kt b/src/jvmMain/kotlin/mtmc/asm/graphics/Graphic.kt
deleted file mode 100644
index 34adc22..0000000
--- a/src/jvmMain/kotlin/mtmc/asm/graphics/Graphic.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-package mtmc.asm.graphics
-
-import mtmc.asm.ASMElement
-import mtmc.emulator.MTMCDisplay.Companion.convertImage
-import mtmc.tokenizer.MTMCToken
-import java.io.ByteArrayOutputStream
-import java.io.File
-import java.io.FileNotFoundException
-import java.io.IOException
-import javax.imageio.ImageIO
-
-/**
- *
- * @author jbanes
- */
-class Graphic(labels: MutableList, lineNumber: Int) : ASMElement(labels, lineNumber) {
- private var filename: String? = null
- var imageData: ByteArray = ByteArray(0)
-
- fun setImage(filename: String) {
- try {
- var image = ImageIO.read(File(filename))
- val buffer = ByteArrayOutputStream()
-
- if (image.getWidth() > 1024 || image.getHeight() > 1024) {
- addError(filename + " is too large. Maximum image size is 1024x1024")
- }
-
- image = convertImage(image)
-
- ImageIO.write(image, "png", buffer)
-
- this.filename = filename
- this.imageData = buffer.toByteArray()
- } catch (e: FileNotFoundException) {
- e.printStackTrace()
- addError("$filename not found")
- } catch (e: IOException) {
- e.printStackTrace()
- addError(e.message ?: "error in Graphic") // TODO: Verify these messages are meaningful
- }
- }
-
- override fun addError(err: String) {
- addError(labels.last(), err)
- }
-
- override var sizeInBytes: Int
- get() = 2
- set(value) {}
-}
diff --git a/src/jvmMain/kotlin/mtmc/emulator/DebugInfo.kt b/src/jvmMain/kotlin/mtmc/emulator/DebugInfo.kt
deleted file mode 100644
index e40ec01..0000000
--- a/src/jvmMain/kotlin/mtmc/emulator/DebugInfo.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package mtmc.emulator
-
-import java.util.*
-import java.util.regex.Pattern
-
-@JvmRecord
-data class DebugInfo(
- val debugStrings: MutableList,
- val assemblyFile: String?,
- val assemblySource: String,
- val assemblyLineNumbers: IntArray,
- val originalFile: String,
- val originalLineNumbers: IntArray,
- val globals: Array,
- val locals: Array>
-) {
- fun handleDebugString(debugIndex: Short, monTanaMiniComputer: MonTanaMiniComputer) {
- val debugString = debugStrings!!.get(debugIndex.toInt())
- val compile = Pattern.compile("(\\$[a-zA-Z][a-zA-Z0-9])")
- val matcher = compile.matcher(debugString)
- val formattedString = StringBuilder()
- var start = 0
- var end: Int
- while (matcher.find()) {
- val match = matcher.group().substring(1)
- try {
- end = matcher.start()
- formattedString.append(debugString, start, end)
- val register = Register.valueOf(match.uppercase(Locale.getDefault()))
- formattedString.append(monTanaMiniComputer.getRegisterValue(register).toInt())
- start = matcher.end()
- } catch (e: Exception) {
- formattedString.append(match)
- }
- }
- formattedString.append(debugString.substring(start))
- println("DEBUG[" + System.nanoTime() + "] : " + formattedString)
- }
-
- @JvmRecord
- data class GlobalInfo(val name: String?, val location: Int, val type: String?)
-
- @JvmRecord
- data class LocalInfo(val name: String?, val offset: Int, val type: String?)
-}
\ No newline at end of file
diff --git a/src/jvmMain/kotlin/mtmc/os/exec/Executable.kt b/src/jvmMain/kotlin/mtmc/os/exec/Executable.kt
deleted file mode 100644
index 61b370e..0000000
--- a/src/jvmMain/kotlin/mtmc/os/exec/Executable.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-package mtmc.os.exec
-
-import com.google.gson.Gson
-import mtmc.emulator.DebugInfo
-import java.io.FileReader
-import java.io.FileWriter
-import java.io.IOException
-import java.io.Reader
-import java.io.Writer
-import java.nio.file.Path
-
-@JvmRecord
-data class Executable(
- val format: Format,
- @JvmField val code: ByteArray,
- @JvmField val data: ByteArray,
- @JvmField val graphics: Array,
- val sourceName: String,
- @JvmField val debugInfo: DebugInfo?
-) {
- enum class Format(val formatName: String) {
- Orc1("orc1");
- }
-
- fun dump(): String? {
- return Gson().toJson(this)
- }
-
- @Throws(IOException::class)
- fun dump(path: Path) {
- FileWriter(path.toFile()).use { fw ->
- dump(fw)
- }
- }
-
- fun dump(writer: Writer?) {
- val gson = Gson()
- gson.toJson(this, writer)
- }
-
- companion object {
- fun load(exe: String?): Executable? {
- return Gson().fromJson(exe, Executable::class.java)
- }
-
- @JvmStatic
- @Throws(IOException::class)
- fun load(path: Path): Executable? {
- FileReader(path.toFile()).use { fw ->
- return load(fw)
- }
- }
-
- @Throws(IOException::class)
- fun load(reader: Reader): Executable? {
- val gson = Gson()
- return gson.fromJson(reader, Executable::class.java)
- }
- }
-}
diff --git a/src/jvmMain/kotlin/mtmc/os/fs/FileSystem.java b/src/jvmMain/kotlin/mtmc/os/fs/FileSystem.java
deleted file mode 100644
index 27a0c54..0000000
--- a/src/jvmMain/kotlin/mtmc/os/fs/FileSystem.java
+++ /dev/null
@@ -1,199 +0,0 @@
-package mtmc.os.fs;
-
-import mtmc.emulator.MonTanaMiniComputer;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-public class FileSystem {
- private String cwd = "/home";
- private MonTanaMiniComputer computer;
- static final Path DISK_PATH = Path.of(System.getProperty("user.dir"), "disk").toAbsolutePath();
-
- public FileSystem(MonTanaMiniComputer computer) {
- this.computer = computer;
-
- initFileSystem();
- }
-
- private void initFileSystem() {
- if (DISK_PATH.toFile().exists()) return;
-
- // Make the disk/ directory
- DISK_PATH.toFile().mkdirs();
-
- try (var in = new ZipInputStream(getClass().getResourceAsStream("/disk.zip"))) {
- ZipEntry entry;
- File file;
-
- byte[] data = new byte[4096];
- int count;
-
- while ((entry = in.getNextEntry()) != null) {
- file = new File(entry.getName());
-
- if (entry.isDirectory()) {
- file.mkdirs();
- } else {
- file.getParentFile().mkdirs();
-
- try (var out = new FileOutputStream(file)) {
- while((count = in.read(data)) > 0) {
- out.write(data, 0, count);
- }
- }
- }
- }
- } catch(IOException e) {
- e.printStackTrace();
- }
- }
-
- private void notifyOfFileSystemUpdate() {
- if (this.computer != null) {
- computer.notifyOfFileSystemUpdate();
- }
- }
-
- public String getCWD() {
- return this.cwd;
- }
-
- public void setCWD(String cwd) {
- this.cwd = resolve(cwd);
- this.notifyOfFileSystemUpdate();
- }
-
- public boolean exists(String path) {
- return new File(DISK_PATH.toFile(), resolve(path)).exists();
- }
-
- public boolean mkdir(String path) {
- boolean success = new File(DISK_PATH.toFile(), resolve(path)).mkdir();
-
- if (success) {
- computer.notifyOfFileSystemUpdate();
- }
-
- return success;
- }
-
- public boolean delete(String path) {
- boolean success = new File(DISK_PATH.toFile(), resolve(path)).delete();
-
- if (success) {
- computer.notifyOfFileSystemUpdate();
- }
-
- return success;
- }
-
- public String resolve(String filename) {
- File root = DISK_PATH.toFile();
- File directory = filename.startsWith("/") ? root : new File(root, cwd);
- String[] path = filename.split("/");
-
- for (String name : path) {
- if (name.equals(".")) {
- continue;
- } else if (name.equals("..") && directory.equals(root)) {
- continue;
- } else if (name.equals("..")) {
- directory = directory.getParentFile();
- } else {
- directory = new File(directory, name);
- }
- }
-
- if(directory.equals(root)) {
- return "/";
- }
-
- return directory.getAbsolutePath().substring(root.getAbsolutePath().length());
- }
-
- public Path getRealPath(String path) { // Resolves given path and returns /disk/ + path
- String resolvedPath = resolve(path);
- String slashGone = resolvedPath.length() > 0 ? resolvedPath.substring(1) : "";
- File file = DISK_PATH.resolve(slashGone).toFile();
-
- if (file.getAbsolutePath().length() < DISK_PATH.toFile().getAbsolutePath().length()) {
- return DISK_PATH;
- }
-
- return file.toPath();
- }
-
- public File[] getFileList(String path) {
- File resolvedPath = getRealPath(path).toFile();
-
- if (!resolvedPath.isDirectory()) return new File[]{ resolvedPath };
-
- return resolvedPath.listFiles();
- }
-
- public Listing listFiles(String path) {
- File resolvedPath = getRealPath(path).toFile();
-
- return new Listing(this, resolvedPath);
- }
-
- public Listing listCWD() {
- return listFiles(cwd);
- }
-
- public Listing listRoot() {
- return listFiles("/");
- }
-
- public void writeFile(String path, String contents) throws IOException {
- Path filePath = getRealPath(path);
- Files.writeString(filePath, contents);
- }
-
- public String readFile(String path) throws FileNotFoundException, IOException {
- Path filePath = getRealPath(path);
- var contents = Files.readString(filePath);
- return contents;
- }
-
- public String getMimeType(String path) throws IOException {
- var file = getRealPath(path);
- var name = file.toFile().getName().toLowerCase();
- var probed = Files.probeContentType(file);
-
- if(name.endsWith(".asm")) return "text/x-asm";
- if(name.endsWith(".c")) return "text/x-csrc";
- if(name.endsWith(".sea")) return "text/x-csrc";
- if(name.endsWith(".h")) return "text/x-csrc";
- if(probed != null) return probed;
-
- return "application/octet-stream";
- }
-
- public InputStream openFile(String path) throws IOException {
- var file = getRealPath(path).toFile();
-
- return new FileInputStream(file);
- }
-
- public void saveFile(String path, InputStream contents) throws IOException {
- var file = getRealPath(path).toFile();
- byte[] data = new byte[4096];
- int count;
-
- try(var out = new FileOutputStream(file)) {
- while((count = contents.read(data)) > 0) {
- out.write(data, 0, count);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/jvmMain/kotlin/mtmc/os/fs/Listing.java b/src/jvmMain/kotlin/mtmc/os/fs/Listing.java
deleted file mode 100644
index c2af8c5..0000000
--- a/src/jvmMain/kotlin/mtmc/os/fs/Listing.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package mtmc.os.fs;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public class Listing {
- public final String path;
- public final String name;
- public final boolean directory;
- public final boolean root;
-
- private FileSystem fs;
- private File file;
-
- public Listing(FileSystem fs, File file) {
- String root = FileSystem.DISK_PATH.toFile().getAbsolutePath().replace('\\', '/');
- String path = file.getAbsolutePath().substring(root.length()).replace('\\', '/');
-
- this.fs = fs;
- this.file = file;
-
- this.path = path.length() > 0 ? path : "/";
- this.name = path.length() > 0 ? file.getName() : "/";
- this.directory = file.isDirectory();
- this.root = this.path.equals("/");
- }
-
- public Listing getParent() {
- return new Listing(fs, file.getParentFile());
- }
-
- public List list() {
- if (!directory) {
- return new ArrayList<>();
- }
-
- var list = new ArrayList();
- var children = file.listFiles();
-
- Arrays.sort(children, (a, b) -> {
- return a.getName().compareTo(b.getName());
- });
-
- for (File child : children) {
- list.add(new Listing(fs, child));
- }
-
- return list;
- }
-}
diff --git a/src/jvmMain/kotlin/mtmc/os/shell/builtins/AssembleCommand.kt b/src/jvmMain/kotlin/mtmc/os/shell/builtins/AssembleCommand.kt
deleted file mode 100644
index 007cdd4..0000000
--- a/src/jvmMain/kotlin/mtmc/os/shell/builtins/AssembleCommand.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package mtmc.os.shell.builtins
-
-import mtmc.asm.Assembler
-import mtmc.emulator.MonTanaMiniComputer
-import mtmc.os.fs.FileSystem
-import mtmc.os.shell.ShellCommand
-import mtmc.tokenizer.MTMCTokenizer
-import java.nio.file.Files
-import java.nio.file.Path
-
-class AssembleCommand : ShellCommand() {
- @Throws(Exception::class)
- public override fun exec(tokens: MTMCTokenizer, computer: MonTanaMiniComputer) {
- val fs = computer.fileSystem
- val src = tokens.collapseTokensAsString()
- require(!(src == null || src.isBlank())) { "missing or required argument 'src'" }
- val srcPath: Path = getDiskPath(src, fs)
-
- val dst = tokens.collapseTokensAsString()
- require(!(dst == null || dst.isBlank())) { "missing required argument 'dst'" }
- val dstPath: Path = getDiskPath(dst, fs)
-
- val contents = Files.readString(srcPath)
- val assembler = Assembler()
- val file_name =
- fs.resolve(src) // srcPath.toString().substring(DISK_PATH.toString().length()).replaceAll("\\\\", "/");
- val executable = assembler.assembleExecutable(file_name, contents)
- executable.dump(dstPath)
- computer.notifyOfFileSystemUpdate()
- }
-
- override val help: String
- get() = """
- asm
- - src : path to a .asm file
- - dst : path to a target output binary
- """.trimIndent()
-
- companion object {
- fun getDiskPath(pathString: String, fs: FileSystem): Path {
- val path = Path.of("disk" + fs.resolve(pathString))
- return path.toAbsolutePath()
- }
- }
-}
diff --git a/src/jvmMain/kotlin/mtmc/util/PlatformSpecific.jvm.kt b/src/jvmMain/kotlin/mtmc/util/PlatformSpecific.jvm.kt
new file mode 100644
index 0000000..841f842
--- /dev/null
+++ b/src/jvmMain/kotlin/mtmc/util/PlatformSpecific.jvm.kt
@@ -0,0 +1,3 @@
+package mtmc.util
+
+actual fun currentTimeMillis(): Long = System.currentTimeMillis()
\ No newline at end of file
diff --git a/src/jvmMain/kotlin/mtmc/util/SafeClosable.kt b/src/jvmMain/kotlin/mtmc/util/SafeClosable.kt
index d5aa578..34dfad4 100644
--- a/src/jvmMain/kotlin/mtmc/util/SafeClosable.kt
+++ b/src/jvmMain/kotlin/mtmc/util/SafeClosable.kt
@@ -4,4 +4,4 @@ import java.io.Closeable
interface SafeClosable : Closeable {
override fun close()
-}
+}
\ No newline at end of file
diff --git a/src/jvmMain/kotlin/mtmc/util/StringEscapeUtils.kt b/src/jvmMain/kotlin/mtmc/util/StringEscapeUtils.kt
index 8413e79..6e43908 100644
--- a/src/jvmMain/kotlin/mtmc/util/StringEscapeUtils.kt
+++ b/src/jvmMain/kotlin/mtmc/util/StringEscapeUtils.kt
@@ -28,4 +28,4 @@ object StringEscapeUtils {
out.append('"')
return out.toString()
}
-}
+}
\ No newline at end of file