Initial program implementation
This commit is contained in:
parent
7cbcb267dd
commit
b6982e04e4
|
@ -0,0 +1,12 @@
|
|||
package net.shadowfacts.asmr.program
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
abstract class ExecutableBlock: ProgramBlock {
|
||||
|
||||
var nextExecutableBlock: ExecutableBlock? = null
|
||||
|
||||
abstract fun execute()
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package net.shadowfacts.asmr.program
|
||||
|
||||
import net.shadowfacts.asmr.program.blocks.StartBlock
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class Program {
|
||||
|
||||
var startBlock = StartBlock()
|
||||
val blocks = mutableListOf<ProgramBlock>()
|
||||
|
||||
fun execute() {
|
||||
var currentBlock: ExecutableBlock? = startBlock.nextExecutableBlock
|
||||
while (currentBlock != null) {
|
||||
currentBlock.execute()
|
||||
|
||||
currentBlock = currentBlock.nextExecutableBlock
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package net.shadowfacts.asmr.program
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
interface ProgramBlock {
|
||||
|
||||
val inputs: Array<ProgramBlockInput<*>>
|
||||
val outputs: Array<ProgramBlockOutput<*>>
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package net.shadowfacts.asmr.program
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class ProgramBlockInput<Type: Any>(
|
||||
val type: ProgramType<Type>,
|
||||
var source: ProgramBlockOutput<Type>? = null
|
||||
) {
|
||||
|
||||
val value: Type?
|
||||
get() = source?.value
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package net.shadowfacts.asmr.program
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class ProgramBlockOutput<Type: Any>(
|
||||
val type: ProgramType<Type>
|
||||
) {
|
||||
|
||||
lateinit var value: Type
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package net.shadowfacts.asmr.program
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class ProgramType<Type> {
|
||||
companion object {
|
||||
val int = ProgramType<Int>()
|
||||
val float = ProgramType<Float>()
|
||||
val string = ProgramType<String>()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package net.shadowfacts.asmr.program.blocks
|
||||
|
||||
import net.shadowfacts.asmr.program.ProgramBlock
|
||||
import net.shadowfacts.asmr.program.ProgramBlockInput
|
||||
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
||||
import net.shadowfacts.asmr.program.ProgramType
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class ConstantBlock<Type: Any>(
|
||||
val type: ProgramType<Type>,
|
||||
val value: Type
|
||||
): ProgramBlock {
|
||||
|
||||
val output = ProgramBlockOutput(type).apply {
|
||||
value = this@ConstantBlock.value
|
||||
}
|
||||
|
||||
override val inputs: Array<ProgramBlockInput<*>> = arrayOf()
|
||||
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf(output)
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package net.shadowfacts.asmr.program.blocks
|
||||
|
||||
import net.shadowfacts.asmr.program.ExecutableBlock
|
||||
import net.shadowfacts.asmr.program.ProgramBlockInput
|
||||
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
||||
import net.shadowfacts.asmr.program.ProgramType
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class PrintBlock<Type: Any>(
|
||||
val type: ProgramType<Type>
|
||||
): ExecutableBlock() {
|
||||
|
||||
val input = ProgramBlockInput(type, null)
|
||||
|
||||
override val inputs: Array<ProgramBlockInput<*>> = arrayOf(input)
|
||||
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf()
|
||||
|
||||
override fun execute() {
|
||||
println(input.value)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package net.shadowfacts.asmr.program.blocks
|
||||
|
||||
import net.shadowfacts.asmr.program.ExecutableBlock
|
||||
import net.shadowfacts.asmr.program.ProgramBlock
|
||||
import net.shadowfacts.asmr.program.ProgramBlockInput
|
||||
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class StartBlock: ProgramBlock {
|
||||
|
||||
override val inputs: Array<ProgramBlockInput<*>> = arrayOf()
|
||||
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf()
|
||||
|
||||
var nextExecutableBlock: ExecutableBlock? = null
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package net.shadowfacts.asmr.program.blocks.math
|
||||
|
||||
import net.shadowfacts.asmr.program.ExecutableBlock
|
||||
import net.shadowfacts.asmr.program.ProgramBlockInput
|
||||
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
||||
import net.shadowfacts.asmr.program.ProgramType
|
||||
import java.lang.RuntimeException
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class BinaryOperatorBlock<Type: Any>(
|
||||
val type: ProgramType<Type>,
|
||||
val operation: Operation
|
||||
): ExecutableBlock() {
|
||||
|
||||
init {
|
||||
if (type != ProgramType.int && type != ProgramType.float) {
|
||||
throw RuntimeException("BinaryOperatorBlock type must be int or float")
|
||||
}
|
||||
}
|
||||
|
||||
val left = ProgramBlockInput(type)
|
||||
val right = ProgramBlockInput(type)
|
||||
|
||||
val output = ProgramBlockOutput(type)
|
||||
|
||||
override val inputs: Array<ProgramBlockInput<*>> = arrayOf(left, right)
|
||||
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf(output)
|
||||
|
||||
override fun execute() {
|
||||
if (type == ProgramType.int) {
|
||||
val left = left.value as Int
|
||||
val right = right.value as Int
|
||||
output.value = when (operation) {
|
||||
Operation.add -> left + right
|
||||
Operation.subtract -> left - right
|
||||
Operation.multiply -> left * right
|
||||
Operation.divide -> left / right
|
||||
} as Type
|
||||
} else if (type == ProgramType.float) {
|
||||
val left = left.value as Float
|
||||
val right = right.value as Float
|
||||
output.value = when (operation) {
|
||||
Operation.add -> left + right
|
||||
Operation.subtract -> left - right
|
||||
Operation.multiply -> left * right
|
||||
Operation.divide -> left / right
|
||||
} as Type
|
||||
}
|
||||
}
|
||||
|
||||
enum class Operation {
|
||||
add, subtract, multiply, divide
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package net.shadowfacts.asmr.program
|
||||
|
||||
import net.shadowfacts.asmr.program.blocks.ConstantBlock
|
||||
import net.shadowfacts.asmr.program.blocks.math.BinaryOperatorBlock
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class ProgramTests {
|
||||
|
||||
@Test
|
||||
fun testExecutionFlow() {
|
||||
val program = Program()
|
||||
val one = ConstantBlock(ProgramType.int, 3)
|
||||
program.blocks.add(one)
|
||||
val two = ConstantBlock(ProgramType.int, 7)
|
||||
program.blocks.add(two)
|
||||
val multiply = BinaryOperatorBlock(ProgramType.int, BinaryOperatorBlock.Operation.multiply)
|
||||
multiply.left.source = one.output
|
||||
multiply.right.source = two.output
|
||||
program.blocks.add(multiply)
|
||||
|
||||
program.startBlock.nextExecutableBlock = multiply
|
||||
|
||||
program.execute()
|
||||
|
||||
assertEquals(21, multiply.output.value)
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue