diff --git a/src/main/kotlin/me/camdenorrb/crescentvm/Main.kt b/src/main/kotlin/me/camdenorrb/crescentvm/Main.kt index 88272a9..057dd04 100644 --- a/src/main/kotlin/me/camdenorrb/crescentvm/Main.kt +++ b/src/main/kotlin/me/camdenorrb/crescentvm/Main.kt @@ -20,9 +20,16 @@ object Main { val code = """ - fun main { - println("Me" + "ow") - } +fun main() { +println(" /\") +println(" /__\") +println(" /\ /\") +println(" /__\/__\") +println(" /\ /\") +println(" /__\ /__\") +println(" /\ /\ /\ /\") +println("/__\/__\/__\/__\") +} """ /* """ diff --git a/src/main/kotlin/me/camdenorrb/crescentvm/parsers/CrescentParser.kt b/src/main/kotlin/me/camdenorrb/crescentvm/parsers/CrescentParser.kt index 49cff5d..e20f202 100644 --- a/src/main/kotlin/me/camdenorrb/crescentvm/parsers/CrescentParser.kt +++ b/src/main/kotlin/me/camdenorrb/crescentvm/parsers/CrescentParser.kt @@ -681,7 +681,8 @@ object CrescentParser { arguments += readExpression(tokenIterator) - if (tokenIterator.peekNext() != CrescentToken.Parenthesis.CLOSE) { + println(arguments) + if (tokenIterator.peekNext().also { println(it) } != CrescentToken.Parenthesis.CLOSE) { checkEquals(CrescentToken.Operator.COMMA, tokenIterator.next()) } } diff --git a/src/main/kotlin/me/camdenorrb/crescentvm/vm/CrescentVM.kt b/src/main/kotlin/me/camdenorrb/crescentvm/vm/CrescentVM.kt index 81761c4..38a6261 100644 --- a/src/main/kotlin/me/camdenorrb/crescentvm/vm/CrescentVM.kt +++ b/src/main/kotlin/me/camdenorrb/crescentvm/vm/CrescentVM.kt @@ -7,6 +7,7 @@ import me.camdenorrb.crescentvm.vm.CrescentAST.Node.Primitive import me.camdenorrb.crescentvm.vm.CrescentAST.Node.Type import java.util.* import kotlin.math.pow +import kotlin.math.round import kotlin.math.sqrt // TODO: Add a way to add external functions @@ -120,6 +121,25 @@ class CrescentVM(val files: List, val mainFile: Node.File) { } } + is Node.Statement.For -> { + + val forContext = context.copy() + + val ranges = node.ranges.map { + (it.start as Primitive.Number).data.toInt()..(it.end as Primitive.Number).data.toInt() + } + + node.identifiers.forEachIndexed { index, identifier -> + forContext.variableValues[identifier.name] = Primitive.Number((ranges.getOrNull(index) ?: ranges[0]).first) + } + + /* + while ((runNode(node.predicate, context) as Primitive.Boolean).data) { + runBlock(node.block, context) + } + */ + } + is Node.Variable.Basic -> { context.variableValues[node.name] = runNode(node.value, context) } @@ -395,6 +415,11 @@ class CrescentVM(val files: List, val mainFile: Node.File) { return Primitive.Number(sqrt((runNode(node.arguments[0], context) as Primitive.Number).data.toDouble())) } + "round" -> { + checkEquals(1, node.arguments.size) + return Primitive.Number(round((runNode(node.arguments[0], context) as Primitive.Number).data.toDouble())) + } + "print" -> { checkEquals(1, node.arguments.size) print(runNode(node.arguments[0], context).asString()) @@ -501,7 +526,7 @@ class CrescentVM(val files: List, val mainFile: Node.File) { * @constructor */ data class BlockContext( - val holder: Node, + val self: Node, val parameters: MutableMap, //val variables: MutableMap = mutableMapOf(), val variableValues: MutableMap = mutableMapOf(), diff --git a/src/test/kotlin/me/camdenorrb/crescentvm/manual/Bench.kt b/src/test/kotlin/me/camdenorrb/crescentvm/manual/Bench.kt index c6aff4e..447c6b4 100644 --- a/src/test/kotlin/me/camdenorrb/crescentvm/manual/Bench.kt +++ b/src/test/kotlin/me/camdenorrb/crescentvm/manual/Bench.kt @@ -3,6 +3,9 @@ package me.camdenorrb.crescentvm.manual import me.camdenorrb.crescentvm.data.TestCode import me.camdenorrb.crescentvm.lexers.CrescentLexer import me.camdenorrb.crescentvm.parsers.CrescentParser +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.PrintStream import java.nio.file.Path import kotlin.system.measureNanoTime @@ -16,9 +19,33 @@ internal object Bench { val parserBenchmark = Benchmark("Parser") + val originalSystemOut = System.out + + val originalSystemIn = System.`in` + + + private inline fun collectSystemOut(block: () -> Unit): String { + + val byteArrayOutputStream = ByteArrayOutputStream() + val printStream = PrintStream(byteArrayOutputStream) + + System.setOut(printStream) + block() + System.setOut(originalSystemOut) + + return byteArrayOutputStream.toString() + } + + private inline fun fakeUserInput(input: String, block: () -> Unit) { + System.setIn(ByteArrayInputStream(input.toByteArray())) + block() + System.setIn(originalSystemIn) + } + @JvmStatic fun main(args: Array) { + benchCode("Hello World", TestCode.helloWorlds) benchCode("If Statement", TestCode.ifStatement) benchCode("If Input Statement", TestCode.ifInputStatement) @@ -30,6 +57,8 @@ internal object Bench { benchCode("Enum", TestCode.enum) benchCode("Comments", TestCode.comments) benchCode("Imports", TestCode.imports) + + Benchmark("") } fun benchCode(name: String, code: String) {