it all works - some output problems
This commit is contained in:
6
.idea/cssdialects.xml
generated
Normal file
6
.idea/cssdialects.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CssDialectMappings">
|
||||||
|
<file url="file://$PROJECT_DIR$/ide/src/main/resources/befide/ide/style.css" dialect="CLASSIC" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -46,5 +46,14 @@
|
|||||||
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-common:1.3.0" level="project" />
|
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-common:1.3.0" level="project" />
|
||||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||||
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.3.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib-common:1.3.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-junit:1.3.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-annotations-common:1.3.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test:1.3.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-common:1.3.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
@@ -10,4 +10,5 @@ data class Vec(val x: Int, val y: Int) {
|
|||||||
operator fun times(c: Int) = Vec(x * c, y * c)
|
operator fun times(c: Int) = Vec(x * c, y * c)
|
||||||
|
|
||||||
infix fun mod(other: Vec) = Vec(x mod other.x, y mod other.y)
|
infix fun mod(other: Vec) = Vec(x mod other.x, y mod other.y)
|
||||||
|
operator fun unaryMinus() = Vec(-x, -y)
|
||||||
}
|
}
|
||||||
15
ide/ide.iml
15
ide/ide.iml
@@ -47,6 +47,21 @@
|
|||||||
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-common:1.3.0" level="project" />
|
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-common:1.3.0" level="project" />
|
||||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||||
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: no.tornado:tornadofx:1.7.17" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.glassfish:javax.json:1.1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.json:javax.json-api:1.1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.60" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.60" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-reflect:1.2.60" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.3.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib-common:1.3.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-junit:1.3.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-annotations-common:1.3.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test:1.3.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-common:1.3.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||||
<orderEntry type="module" module-name="befunge" />
|
<orderEntry type="module" module-name="befunge" />
|
||||||
<orderEntry type="library" name="Maven: no.tornado:tornadofx:1.7.17" level="project" />
|
<orderEntry type="library" name="Maven: no.tornado:tornadofx:1.7.17" level="project" />
|
||||||
<orderEntry type="library" name="Maven: org.glassfish:javax.json:1.1.2" level="project" />
|
<orderEntry type="library" name="Maven: org.glassfish:javax.json:1.1.2" level="project" />
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import javafx.animation.Timeline
|
|||||||
import javafx.util.Duration
|
import javafx.util.Duration
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
|
||||||
class ActionView(val interp: Interpreter, val ioView: IOView) : View() {
|
class ActionView(val interp: Interpreter, val codeView: CodeView, val ioView: IOView) : View() {
|
||||||
var runTimeline: Timeline = timeline(false) {
|
var runTimeline: Timeline = timeline(false) {
|
||||||
keyframe(Duration.seconds(0.0)) {
|
keyframe(Duration.seconds(0.0)) {
|
||||||
setOnFinished {
|
setOnFinished {
|
||||||
@@ -21,25 +21,36 @@ class ActionView(val interp: Interpreter, val ioView: IOView) : View() {
|
|||||||
|
|
||||||
override val root = hbox {
|
override val root = hbox {
|
||||||
button("step") {
|
button("step") {
|
||||||
setOnAction { interp.step() }
|
setOnAction {
|
||||||
|
interp.funge.setString(codeView.src)
|
||||||
|
interp.step()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button("reset") {
|
button("reset") {
|
||||||
|
enableWhen(codeView.lockedProperty)
|
||||||
|
|
||||||
setOnAction {
|
setOnAction {
|
||||||
interp.reset()
|
interp.reset()
|
||||||
ioView.reset()
|
ioView.reset()
|
||||||
|
codeView.src = interp.funge.toString()
|
||||||
|
codeView.locked = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button("run") {
|
button("run") {
|
||||||
setOnAction {
|
setOnAction {
|
||||||
runTimeline.rate = 10000000.0
|
interp.funge.setString(codeView.src)
|
||||||
|
codeView.locked = true
|
||||||
|
runTimeline.rate = 10000.0
|
||||||
runTimeline.playFromStart()
|
runTimeline.playFromStart()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button("walk") {
|
button("walk") {
|
||||||
setOnAction {
|
setOnAction {
|
||||||
|
interp.funge.setString(codeView.src)
|
||||||
|
codeView.locked = true
|
||||||
runTimeline.rate = 50.0
|
runTimeline.rate = 50.0
|
||||||
runTimeline.playFromStart()
|
runTimeline.playFromStart()
|
||||||
}
|
}
|
||||||
@@ -47,6 +58,8 @@ class ActionView(val interp: Interpreter, val ioView: IOView) : View() {
|
|||||||
|
|
||||||
button("crawl") {
|
button("crawl") {
|
||||||
setOnAction {
|
setOnAction {
|
||||||
|
interp.funge.setString(codeView.src)
|
||||||
|
codeView.locked = true
|
||||||
runTimeline.rate = 4.0
|
runTimeline.rate = 4.0
|
||||||
runTimeline.playFromStart()
|
runTimeline.playFromStart()
|
||||||
}
|
}
|
||||||
|
|||||||
37
ide/src/main/kotlin/befide/ide/CodeLabel.kt
Normal file
37
ide/src/main/kotlin/befide/ide/CodeLabel.kt
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package befide.ide
|
||||||
|
|
||||||
|
import befide.befunge.core.Interpreter
|
||||||
|
import befide.befunge.state.Vec
|
||||||
|
import javafx.beans.property.ObjectProperty
|
||||||
|
import javafx.beans.property.SimpleObjectProperty
|
||||||
|
import javafx.scene.control.Label
|
||||||
|
import tornadofx.*
|
||||||
|
|
||||||
|
class CodeLabel(val pos: Vec, val cursorPos: ObjectProperty<Vec>, val interp: Interpreter) : Label() {
|
||||||
|
val charProperty = SimpleObjectProperty<Char>('\u0000')
|
||||||
|
var char: Char by charProperty
|
||||||
|
|
||||||
|
fun restyle() {
|
||||||
|
styleClass.setAll("code")
|
||||||
|
|
||||||
|
if (char in "0123456789") styleClass.add("code-num")
|
||||||
|
if (char in "gp") styleClass.add("code-funge")
|
||||||
|
if (char in "<>^v?#") styleClass.add("code-dir")
|
||||||
|
|
||||||
|
if (pos == cursorPos.value) styleClass.add("code-cursor")
|
||||||
|
if (pos == interp.ip.pos) styleClass.add("code-cursor-ip")
|
||||||
|
if (char == '\u2022') styleClass.add("unknown")
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
textProperty().bind(charProperty.stringBinding { it?.toString() ?: " " })
|
||||||
|
|
||||||
|
setOnMouseClicked {
|
||||||
|
cursorPos.value = pos
|
||||||
|
}
|
||||||
|
|
||||||
|
charProperty.addListener { _, _, _ -> restyle() }
|
||||||
|
|
||||||
|
char = ' '
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,131 @@
|
|||||||
package befide.ide
|
package befide.ide
|
||||||
|
|
||||||
import befide.befunge.core.Interpreter
|
import befide.befunge.core.Interpreter
|
||||||
import javafx.beans.property.SimpleStringProperty
|
import befide.befunge.state.Vec
|
||||||
|
import javafx.beans.property.ObjectProperty
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty
|
||||||
|
import javafx.beans.property.SimpleObjectProperty
|
||||||
|
import javafx.scene.input.KeyCode
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
import tornadofx.getValue
|
||||||
|
import tornadofx.setValue
|
||||||
|
|
||||||
|
operator fun <T> List<List<T>>.get(v: Vec): T = this[v.y][v.x]
|
||||||
|
|
||||||
class CodeView(val interp: Interpreter) : View() {
|
class CodeView(val interp: Interpreter) : View() {
|
||||||
val srcProperty = SimpleStringProperty("")
|
val cursorPosProperty: ObjectProperty<Vec> = SimpleObjectProperty<Vec>(Vec(0, 0))
|
||||||
var src by srcProperty
|
var cursorPos by cursorPosProperty
|
||||||
|
|
||||||
|
val cursorDeltaProperty = SimpleObjectProperty<Vec>(Vec(1, 0))
|
||||||
|
var cursorDelta by cursorDeltaProperty
|
||||||
|
|
||||||
|
val lockedProperty = SimpleBooleanProperty(false)
|
||||||
|
var locked by lockedProperty
|
||||||
|
|
||||||
|
var labels: List<List<CodeLabel>> = List(25) { y -> List(80) { x -> CodeLabel(Vec(x, y), cursorPosProperty, interp) } }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
interp.fungeChanged += { src = interp.funge.toString() }
|
cursorPosProperty.addListener { _, old, new ->
|
||||||
srcProperty.addListener { _, _, newValue -> interp.funge.setString(newValue) }
|
labels[old].restyle()
|
||||||
|
labels[new].restyle()
|
||||||
|
}
|
||||||
|
|
||||||
|
interp.ipChanged += {
|
||||||
|
labels[it.from.pos].restyle()
|
||||||
|
labels[it.to.pos].restyle()
|
||||||
|
}
|
||||||
|
|
||||||
|
interp.fungeChanged += {
|
||||||
|
for (change in it.changes) {
|
||||||
|
labels[change.vec].char = change.to.asChar ?: '\u2022'
|
||||||
|
labels[change.vec].restyle()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val root = textarea(srcProperty) {
|
fun move(delta: Vec? = null) {
|
||||||
prefRowCount = 25
|
cursorPos = interp.funge.nextVec(cursorPos, delta ?: cursorDelta)
|
||||||
prefColumnCount = 80
|
}
|
||||||
|
|
||||||
|
var src: String
|
||||||
|
get() = labels.joinToString("\n") { row ->
|
||||||
|
row.dropLastWhile { lbl ->
|
||||||
|
lbl.char.isWhitespace()
|
||||||
|
}.joinToString("") { lbl ->
|
||||||
|
lbl.char.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
val lines = value.lines()
|
||||||
|
|
||||||
|
for (row in labels) {
|
||||||
|
for (lbl in row) {
|
||||||
|
lbl.char = lines.getOrNull(lbl.pos.y)?.getOrNull(lbl.pos.x) ?: ' '
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val root = hbox {
|
||||||
|
isFocusTraversable = true
|
||||||
|
|
||||||
|
addClass("code-view")
|
||||||
|
|
||||||
|
vbox {
|
||||||
|
children.setAll(labels.map { row -> hbox { children.setAll(row) } })
|
||||||
|
}
|
||||||
|
|
||||||
|
setOnMouseClicked {
|
||||||
|
requestFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
setOnKeyPressed {
|
||||||
|
when (it.code) {
|
||||||
|
KeyCode.RIGHT -> move(Vec(1, 0))
|
||||||
|
KeyCode.LEFT -> move(Vec(-1, 0))
|
||||||
|
KeyCode.DOWN -> move(Vec(0, 1))
|
||||||
|
KeyCode.UP -> move(Vec(0, -1))
|
||||||
|
else -> return@setOnKeyPressed
|
||||||
|
}
|
||||||
|
if (it.isAltDown) when (it.code) {
|
||||||
|
KeyCode.RIGHT -> cursorDelta = Vec(1, 0)
|
||||||
|
KeyCode.LEFT -> cursorDelta = Vec(-1, 0)
|
||||||
|
KeyCode.DOWN -> cursorDelta = Vec(0, 1)
|
||||||
|
KeyCode.UP -> cursorDelta = Vec(0, -1)
|
||||||
|
else -> Unit
|
||||||
|
}
|
||||||
|
it.consume()
|
||||||
|
}
|
||||||
|
|
||||||
|
setOnKeyTyped {
|
||||||
|
if (locked) return@setOnKeyTyped
|
||||||
|
|
||||||
|
for (ch in it.character) {
|
||||||
|
when {
|
||||||
|
!ch.isISOControl() -> {
|
||||||
|
cursorDelta = when (ch) {
|
||||||
|
'>' -> Vec(1, 0)
|
||||||
|
'<' -> Vec(-1, 0)
|
||||||
|
'v' -> Vec(0, 1)
|
||||||
|
'^' -> Vec(0, -1)
|
||||||
|
else -> cursorDelta
|
||||||
|
}
|
||||||
|
|
||||||
|
labels[cursorPos].char = ch
|
||||||
|
|
||||||
|
move()
|
||||||
|
}
|
||||||
|
|
||||||
|
ch == '\u0008' -> { // backspace
|
||||||
|
move(-cursorDelta)
|
||||||
|
|
||||||
|
labels[cursorPos].char = ' '
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
println("'$ch' (${ch.toInt()})")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,18 +10,14 @@ class EditorView : View("Befide") {
|
|||||||
private val codeView = CodeView(interp)
|
private val codeView = CodeView(interp)
|
||||||
private val stackView = StackView(interp)
|
private val stackView = StackView(interp)
|
||||||
private val ioView = IOView(interp)
|
private val ioView = IOView(interp)
|
||||||
private val actionView = ActionView(interp, ioView)
|
private val actionView = ActionView(interp, codeView, ioView)
|
||||||
|
|
||||||
override val root = borderpane {
|
override val root = borderpane {
|
||||||
top { add(actionView) }
|
top { add(actionView) }
|
||||||
|
|
||||||
center {
|
center { add(codeView) }
|
||||||
add(codeView)
|
|
||||||
}
|
|
||||||
|
|
||||||
right {
|
right { add(stackView) }
|
||||||
add(stackView)
|
|
||||||
}
|
|
||||||
|
|
||||||
bottom { add(ioView) }
|
bottom { add(ioView) }
|
||||||
}
|
}
|
||||||
@@ -31,31 +27,13 @@ class EditorView : View("Befide") {
|
|||||||
^ 0 v +1\ _^#-+*< >22g02g*"_@"*-!1- #v_v>
|
^ 0 v +1\ _^#-+*< >22g02g*"_@"*-!1- #v_v>
|
||||||
>:>::3g: ,\188 ^^ -1\g21\g22<p3\"_":<
|
>:>::3g: ,\188 ^^ -1\g21\g22<p3\"_":<
|
||||||
________________________________@_________________________________^ p3\"@":<"""
|
________________________________@_________________________________^ p3\"@":<"""
|
||||||
// codeView.src = """--------------------------------------------------------------------------------
|
|
||||||
// |-
|
// codeView.src = """"hello world",,,,,,,,,,@"""
|
||||||
// |-
|
}
|
||||||
// |-
|
|
||||||
// |-
|
override fun onDock() {
|
||||||
// |-
|
super.onDock()
|
||||||
// |-
|
|
||||||
// |-
|
codeView.root.requestFocus()
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// |-
|
|
||||||
// """.trimMargin()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,45 @@
|
|||||||
-fx-font-fill: black;
|
-fx-font-fill: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-area {
|
.code, .text-area {
|
||||||
-fx-font-family: monospace;
|
-fx-font-family: Consolas, monospace;
|
||||||
|
-fx-text-fill: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-view, .text-area {
|
||||||
|
-fx-border-color: #aaa;
|
||||||
|
-fx-border-radius: 2px;
|
||||||
|
-fx-border-width: 1px;
|
||||||
|
-fx-background-color: #fff;
|
||||||
|
-fx-graphic: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-num {
|
||||||
|
-fx-text-fill: #2d6a9c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-funge {
|
||||||
|
-fx-text-fill: #258135;
|
||||||
|
-fx-font-style: italic;
|
||||||
|
-fx-font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-dir {
|
||||||
|
-fx-text-fill: #b82893;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-str {
|
||||||
|
-fx-text-fill: #0a5158;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-cursor-ip {
|
||||||
|
-fx-background-color: rgba(39, 186, 235, 0.51);
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-unknown {
|
||||||
|
-fx-background-color: rgba(216, 194, 155, 0.56);
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-cursor {
|
||||||
|
-fx-background-color: rgba(0, 0, 0, 0.16);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user