diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/ExecutableBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/ExecutableBlock.kt new file mode 100644 index 0000000..a937c70 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/program/ExecutableBlock.kt @@ -0,0 +1,12 @@ +package net.shadowfacts.asmr.program + +/** + * @author shadowfacts + */ +abstract class ExecutableBlock: ProgramBlock { + + var nextExecutableBlock: ExecutableBlock? = null + + abstract fun execute() + +} \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/Program.kt b/src/main/kotlin/net/shadowfacts/asmr/program/Program.kt new file mode 100644 index 0000000..2ebfd59 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/program/Program.kt @@ -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() + + fun execute() { + var currentBlock: ExecutableBlock? = startBlock.nextExecutableBlock + while (currentBlock != null) { + currentBlock.execute() + + currentBlock = currentBlock.nextExecutableBlock + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlock.kt new file mode 100644 index 0000000..466f191 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlock.kt @@ -0,0 +1,11 @@ +package net.shadowfacts.asmr.program + +/** + * @author shadowfacts + */ +interface ProgramBlock { + + val inputs: Array> + val outputs: Array> + +} \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockInput.kt b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockInput.kt new file mode 100644 index 0000000..06c417f --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockInput.kt @@ -0,0 +1,14 @@ +package net.shadowfacts.asmr.program + +/** + * @author shadowfacts + */ +class ProgramBlockInput( + val type: ProgramType, + var source: ProgramBlockOutput? = null +) { + + val value: Type? + get() = source?.value + +} diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockOutput.kt b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockOutput.kt new file mode 100644 index 0000000..f7dc9da --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlockOutput.kt @@ -0,0 +1,12 @@ +package net.shadowfacts.asmr.program + +/** + * @author shadowfacts + */ +class ProgramBlockOutput( + val type: ProgramType +) { + + lateinit var value: Type + +} \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/ProgramType.kt b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramType.kt new file mode 100644 index 0000000..9a8075b --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramType.kt @@ -0,0 +1,12 @@ +package net.shadowfacts.asmr.program + +/** + * @author shadowfacts + */ +class ProgramType { + companion object { + val int = ProgramType() + val float = ProgramType() + val string = ProgramType() + } +} \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/ConstantBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/ConstantBlock.kt new file mode 100644 index 0000000..a6b633c --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/ConstantBlock.kt @@ -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( + val type: ProgramType, + val value: Type +): ProgramBlock { + + val output = ProgramBlockOutput(type).apply { + value = this@ConstantBlock.value + } + + override val inputs: Array> = arrayOf() + override val outputs: Array> = arrayOf(output) + +} \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/PrintBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/PrintBlock.kt new file mode 100644 index 0000000..190dc4e --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/PrintBlock.kt @@ -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( + val type: ProgramType +): ExecutableBlock() { + + val input = ProgramBlockInput(type, null) + + override val inputs: Array> = arrayOf(input) + override val outputs: Array> = arrayOf() + + override fun execute() { + println(input.value) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/StartBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/StartBlock.kt new file mode 100644 index 0000000..076f768 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/StartBlock.kt @@ -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> = arrayOf() + override val outputs: Array> = arrayOf() + + var nextExecutableBlock: ExecutableBlock? = null + +} \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/math/BinaryOperatorBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/math/BinaryOperatorBlock.kt new file mode 100644 index 0000000..84c8d24 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/math/BinaryOperatorBlock.kt @@ -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( + val type: ProgramType, + 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> = arrayOf(left, right) + override val outputs: Array> = 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 + } + +} \ No newline at end of file diff --git a/src/test/kotlin/net/shadowfacts/asmr/program/ProgramTests.kt b/src/test/kotlin/net/shadowfacts/asmr/program/ProgramTests.kt new file mode 100644 index 0000000..cdfd993 --- /dev/null +++ b/src/test/kotlin/net/shadowfacts/asmr/program/ProgramTests.kt @@ -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) + } + +} \ No newline at end of file