From 1794f704e735c9570328051040c7f56d1dbdb9d1 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 8 Jul 2019 14:09:25 +0200 Subject: [PATCH] restructuring more things --- compiler/build.gradle | 2 +- compiler/src/prog8/CompilerMain.kt | 181 ++---------------- .../prog8/ast/expressions/AstExpressions.kt | 12 +- .../ast/processing/AstIdentifiersChecker.kt | 2 +- .../VarInitValueAndAddressOfCreator.kt | 2 +- compiler/src/prog8/compiler/Compiler.kt | 1 + compiler/src/prog8/compiler/Main.kt | 175 +++++++++++++++++ .../compiler/intermediate/Instruction.kt | 2 +- .../intermediate/IntermediateProgram.kt | 2 +- .../src/prog8/compiler/target/c64/AsmGen.kt | 2 +- .../src/prog8/optimizer/ConstExprEvaluator.kt | 3 - .../src/prog8/optimizer/ConstantFolding.kt | 8 +- .../prog8/{compiler => vm}/RuntimeValue.kt | 3 +- compiler/src/prog8/vm/astvm/AstVm.kt | 4 +- .../src/prog8/vm/astvm/BuiltinFunctions.kt | 2 +- compiler/src/prog8/vm/astvm/Expressions.kt | 8 +- .../src/prog8/vm/astvm/VariablesCreator.kt | 2 +- compiler/src/prog8/vm/stackvm/Program.kt | 2 +- compiler/src/prog8/vm/stackvm/StackVm.kt | 2 +- compiler/test/RuntimeValueTests.kt | 2 +- compiler/test/StackVMOpcodeTests.kt | 2 +- compiler/test/UnitTests.kt | 2 +- 22 files changed, 220 insertions(+), 201 deletions(-) create mode 100644 compiler/src/prog8/compiler/Main.kt rename compiler/src/prog8/{compiler => vm}/RuntimeValue.kt (99%) diff --git a/compiler/build.gradle b/compiler/build.gradle index 13f07fea4..1457e3419 100644 --- a/compiler/build.gradle +++ b/compiler/build.gradle @@ -30,7 +30,7 @@ compileKotlin { kotlinOptions { jvmTarget = "1.8" verbose = true - freeCompilerArgs += "-XXLanguage:+NewInference -verbose" + // freeCompilerArgs += "-XXLanguage:+NewInference" } } diff --git a/compiler/src/prog8/CompilerMain.kt b/compiler/src/prog8/CompilerMain.kt index 6ebd82678..e5b272f8b 100644 --- a/compiler/src/prog8/CompilerMain.kt +++ b/compiler/src/prog8/CompilerMain.kt @@ -1,30 +1,10 @@ package prog8 -import prog8.ast.* -import prog8.ast.base.* -import prog8.ast.base.checkIdentifiers -import prog8.ast.base.checkRecursion -import prog8.ast.base.checkValid -import prog8.ast.base.reorderStatements -import prog8.ast.statements.Directive import prog8.vm.astvm.AstVm -import prog8.compiler.* -import prog8.compiler.target.c64.AsmGen -import prog8.compiler.target.c64.C64Zeropage -import prog8.optimizer.constantFold -import prog8.optimizer.optimizeStatements -import prog8.optimizer.simplifyExpressions -import prog8.parser.ParsingFailedError -import prog8.parser.importLibraryModule -import prog8.parser.importModule -import prog8.parser.moduleName import prog8.vm.stackvm.stackVmMain -import java.io.File -import java.io.PrintStream -import java.lang.Exception +import prog8.compiler.* import java.nio.file.Paths import kotlin.system.exitProcess -import kotlin.system.measureTimeMillis fun main(args: Array) { @@ -82,115 +62,8 @@ private fun compileMain(args: Array) { usage() val filepath = Paths.get(moduleFile).normalize() - var programname = "?" - lateinit var programAst: Program - try { - val totalTime = measureTimeMillis { - // import main module and everything it needs - println("Parsing...") - programAst = Program(moduleName(filepath.fileName), mutableListOf()) - importModule(programAst, filepath) - - val compilerOptions = determineCompilationOptions(programAst) - if (compilerOptions.launcher == LauncherType.BASIC && compilerOptions.output != OutputType.PRG) - throw ParsingFailedError("${programAst.modules.first().position} BASIC launcher requires output type PRG.") - - // if we're producing a PRG or BASIC program, include the c64utils and c64lib libraries - if(compilerOptions.launcher==LauncherType.BASIC || compilerOptions.output==OutputType.PRG) { - importLibraryModule(programAst, "c64lib") - importLibraryModule(programAst, "c64utils") - } - - // always import prog8lib and math - importLibraryModule(programAst, "math") - importLibraryModule(programAst, "prog8lib") - - - // perform initial syntax checks and constant folding - println("Syntax check...") - val time1= measureTimeMillis { - programAst.checkIdentifiers() - } - //println(" time1: $time1") - val time2 = measureTimeMillis { - programAst.constantFold() - } - //println(" time2: $time2") - val time3 = measureTimeMillis { - programAst.reorderStatements() // reorder statements and add type casts, to please the compiler later - } - //println(" time3: $time3") - val time4 = measureTimeMillis { - programAst.checkValid(compilerOptions) // check if tree is valid - } - //println(" time4: $time4") - - programAst.checkIdentifiers() - if(optimize) { - // optimize the parse tree - println("Optimizing...") - while (true) { - // keep optimizing expressions and statements until no more steps remain - val optsDone1 = programAst.simplifyExpressions() - val optsDone2 = programAst.optimizeStatements(optimizeInlining) - if (optsDone1 + optsDone2 == 0) - break - } - } - - programAst.checkValid(compilerOptions) // check if final tree is valid - programAst.checkRecursion() // check if there are recursive subroutine calls - - // namespace.debugPrint() - - // compile the syntax tree into stackvmProg form, and optimize that - val compiler = Compiler(programAst) - val intermediate = compiler.compile(compilerOptions) - if(optimize) - intermediate.optimize() - - if(writeVmCode) { - val stackVmFilename = intermediate.name + ".vm.txt" - val stackvmFile = PrintStream(File(stackVmFilename), "utf-8") - intermediate.writeCode(stackvmFile) - stackvmFile.close() - println("StackVM program code written to '$stackVmFilename'") - } - - if(writeAssembly) { - val zeropage = C64Zeropage(compilerOptions) - intermediate.allocateZeropage(zeropage) - val assembly = AsmGen(compilerOptions, intermediate, programAst.heap, zeropage).compileToAssembly(optimize) - assembly.assemble(compilerOptions) - programname = assembly.name - } - } - println("\nTotal compilation+assemble time: ${totalTime / 1000.0} sec.") - - } catch (px: ParsingFailedError) { - System.err.print("\u001b[91m") // bright red - System.err.println(px.message) - System.err.print("\u001b[0m") // reset - exitProcess(1) - } catch (ax: AstException) { - System.err.print("\u001b[91m") // bright red - System.err.println(ax.toString()) - System.err.print("\u001b[0m") // reset - exitProcess(1) - } catch (x: Exception) { - print("\u001b[91m") // bright red - println("\n* internal error *") - print("\u001b[0m") // reset - System.out.flush() - throw x - } catch (x: NotImplementedError) { - print("\u001b[91m") // bright red - println("\n* internal error: missing feature/code *") - print("\u001b[0m") // reset - System.out.flush() - throw x - } + val (programAst, programName) = compileProgram(filepath, optimize, optimizeInlining, writeVmCode, writeAssembly) if(launchAstVm) { println("\nLaunching AST-based vm...") @@ -199,51 +72,19 @@ private fun compileMain(args: Array) { } if(emulatorToStart.isNotEmpty()) { - println("\nStarting C-64 emulator $emulatorToStart...") - val cmdline = listOf(emulatorToStart, "-silent", "-moncommands", "$programname.vice-mon-list", - "-autostartprgmode", "1", "-autostart-warp", "-autostart", programname+".prg") - val process = ProcessBuilder(cmdline).inheritIO().start() - process.waitFor() + if(programName==null) + println("\nCan't start emulator because no program was assembled.") + else { + println("\nStarting C-64 emulator $emulatorToStart...") + val cmdline = listOf(emulatorToStart, "-silent", "-moncommands", "$programName.vice-mon-list", + "-autostartprgmode", "1", "-autostart-warp", "-autostart", programName + ".prg") + val process = ProcessBuilder(cmdline).inheritIO().start() + process.waitFor() + } } } -private fun determineCompilationOptions(program: Program): CompilationOptions { - val mainModule = program.modules.first() - val outputType = (mainModule.statements.singleOrNull { it is Directive && it.directive == "%output" } - as? Directive)?.args?.single()?.name?.toUpperCase() - val launcherType = (mainModule.statements.singleOrNull { it is Directive && it.directive == "%launcher" } - as? Directive)?.args?.single()?.name?.toUpperCase() - mainModule.loadAddress = (mainModule.statements.singleOrNull { it is Directive && it.directive == "%address" } - as? Directive)?.args?.single()?.int ?: 0 - val zpoption: String? = (mainModule.statements.singleOrNull { it is Directive && it.directive == "%zeropage" } - as? Directive)?.args?.single()?.name?.toUpperCase() - val allOptions = program.modules.flatMap { it.statements }.filter { it is Directive && it.directive == "%option" }.flatMap { (it as Directive).args }.toSet() - val floatsEnabled = allOptions.any { it.name == "enable_floats" } - val zpType: ZeropageType = - if (zpoption == null) - if(floatsEnabled) ZeropageType.FLOATSAFE else ZeropageType.KERNALSAFE - else - try { - ZeropageType.valueOf(zpoption) - } catch (x: IllegalArgumentException) { - ZeropageType.KERNALSAFE - // error will be printed by the astchecker - } - val zpReserved = mainModule.statements - .asSequence() - .filter { it is Directive && it.directive == "%zpreserved" } - .map { (it as Directive).args } - .map { it[0].int!!..it[1].int!! } - .toList() - - return CompilationOptions( - if (outputType == null) OutputType.PRG else OutputType.valueOf(outputType), - if (launcherType == null) LauncherType.BASIC else LauncherType.valueOf(launcherType), - zpType, zpReserved, floatsEnabled - ) -} - private fun usage() { System.err.println("Missing argument(s):") System.err.println(" [-emu] auto-start the 'x64' C-64 emulator after successful compilation") diff --git a/compiler/src/prog8/ast/expressions/AstExpressions.kt b/compiler/src/prog8/ast/expressions/AstExpressions.kt index a4553b367..6aa92bb42 100644 --- a/compiler/src/prog8/ast/expressions/AstExpressions.kt +++ b/compiler/src/prog8/ast/expressions/AstExpressions.kt @@ -6,7 +6,6 @@ import prog8.ast.processing.IAstProcessor import prog8.ast.statements.* import prog8.compiler.HeapValues import prog8.compiler.IntegerOrAddressOf -import prog8.compiler.RuntimeValue import prog8.compiler.target.c64.Petscii import prog8.functions.BuiltinFunctions import prog8.functions.NotConstArgumentException @@ -14,6 +13,10 @@ import prog8.functions.builtinFunctionReturnType import kotlin.math.abs import kotlin.math.floor + +val associativeOperators = setOf("+", "*", "&", "|", "^", "or", "and", "xor", "==", "!=") + + class PrefixExpression(val operator: String, var expression: IExpression, override val position: Position) : IExpression { override lateinit var parent: Node @@ -253,8 +256,9 @@ class TypecastExpression(var expression: IExpression, var type: DataType, val im override fun inferType(program: Program): DataType? = type override fun constValue(program: Program): LiteralValue? { val cv = expression.constValue(program) ?: return null - val value = RuntimeValue(cv.type, cv.asNumericValue!!).cast(type) - return LiteralValue.fromNumber(value.numericValue(), value.type, position) + return cv.cast(type) + // val value = RuntimeValue(cv.type, cv.asNumericValue!!).cast(type) + // return LiteralValue.fromNumber(value.numericValue(), value.type, position).cast(type) } override fun toString(): String { @@ -481,7 +485,7 @@ open class LiteralValue(val type: DataType, throw ExpressionError("cannot order compare type $type with ${other.type}", other.position) } - fun intoDatatype(targettype: DataType): LiteralValue? { + fun cast(targettype: DataType): LiteralValue? { if(type==targettype) return this when(type) { diff --git a/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt b/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt index 183cb8ae2..58e0898ca 100644 --- a/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt +++ b/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt @@ -177,7 +177,7 @@ internal class AstIdentifiersChecker(private val namespace: INameScope) : IAstPr for(returnvalue in returnStmt.values.zip(subroutine.returntypes)) { val lval = returnvalue.first as? LiteralValue if(lval!=null) { - val adjusted = lval.intoDatatype(returnvalue.second) + val adjusted = lval.cast(returnvalue.second) if(adjusted!=null && adjusted !== lval) newValues.add(adjusted) else diff --git a/compiler/src/prog8/ast/processing/VarInitValueAndAddressOfCreator.kt b/compiler/src/prog8/ast/processing/VarInitValueAndAddressOfCreator.kt index 12d6c88a8..a95a0aefc 100644 --- a/compiler/src/prog8/ast/processing/VarInitValueAndAddressOfCreator.kt +++ b/compiler/src/prog8/ast/processing/VarInitValueAndAddressOfCreator.kt @@ -46,7 +46,7 @@ internal class VarInitValueAndAddressOfCreator(private val namespace: INameScope val declvalue = decl.value!! val value = if(declvalue is LiteralValue) { - val converted = declvalue.intoDatatype(decl.datatype) + val converted = declvalue.cast(decl.datatype) converted ?: declvalue } else diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 473d4a2f6..d43071fad 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -11,6 +11,7 @@ import prog8.compiler.intermediate.Opcode import prog8.compiler.intermediate.branchOpcodes import prog8.functions.BuiltinFunctions import prog8.parser.tryGetEmbeddedResource +import prog8.vm.RuntimeValue import prog8.vm.stackvm.Syscall import java.io.File import java.nio.file.Path diff --git a/compiler/src/prog8/compiler/Main.kt b/compiler/src/prog8/compiler/Main.kt new file mode 100644 index 000000000..90d7826d1 --- /dev/null +++ b/compiler/src/prog8/compiler/Main.kt @@ -0,0 +1,175 @@ +package prog8.compiler + +import prog8.ast.Program +import prog8.ast.base.* +import prog8.ast.base.checkIdentifiers +import prog8.ast.base.checkValid +import prog8.ast.base.reorderStatements +import prog8.ast.statements.Directive +import prog8.compiler.target.c64.AsmGen +import prog8.compiler.target.c64.C64Zeropage +import prog8.optimizer.constantFold +import prog8.optimizer.optimizeStatements +import prog8.optimizer.simplifyExpressions +import prog8.parser.ParsingFailedError +import prog8.parser.importLibraryModule +import prog8.parser.importModule +import prog8.parser.moduleName +import java.io.File +import java.io.PrintStream +import java.lang.Exception +import java.nio.file.Path +import kotlin.system.exitProcess +import kotlin.system.measureTimeMillis + +fun compileProgram(filepath: Path, + optimize: Boolean, optimizeInlining: Boolean, + writeVmCode: Boolean, writeAssembly: Boolean): Pair { + lateinit var programAst: Program + var programName: String? = null + + try { + val totalTime = measureTimeMillis { + // import main module and everything it needs + println("Parsing...") + programAst = Program(moduleName(filepath.fileName), mutableListOf()) + importModule(programAst, filepath) + + val compilerOptions = determineCompilationOptions(programAst) + if (compilerOptions.launcher == LauncherType.BASIC && compilerOptions.output != OutputType.PRG) + throw ParsingFailedError("${programAst.modules.first().position} BASIC launcher requires output type PRG.") + + // if we're producing a PRG or BASIC program, include the c64utils and c64lib libraries + if (compilerOptions.launcher == LauncherType.BASIC || compilerOptions.output == OutputType.PRG) { + importLibraryModule(programAst, "c64lib") + importLibraryModule(programAst, "c64utils") + } + + // always import prog8lib and math + importLibraryModule(programAst, "math") + importLibraryModule(programAst, "prog8lib") + + + // perform initial syntax checks and constant folding + println("Syntax check...") + val time1 = measureTimeMillis { + programAst.checkIdentifiers() + } + //println(" time1: $time1") + val time2 = measureTimeMillis { + programAst.constantFold() + } + //println(" time2: $time2") + val time3 = measureTimeMillis { + programAst.reorderStatements() // reorder statements and add type casts, to please the compiler later + } + //println(" time3: $time3") + val time4 = measureTimeMillis { + programAst.checkValid(compilerOptions) // check if tree is valid + } + //println(" time4: $time4") + + programAst.checkIdentifiers() + if (optimize) { + // optimize the parse tree + println("Optimizing...") + while (true) { + // keep optimizing expressions and statements until no more steps remain + val optsDone1 = programAst.simplifyExpressions() + val optsDone2 = programAst.optimizeStatements(optimizeInlining) + if (optsDone1 + optsDone2 == 0) + break + } + } + + programAst.checkValid(compilerOptions) // check if final tree is valid + programAst.checkRecursion() // check if there are recursive subroutine calls + + // namespace.debugPrint() + + // compile the syntax tree into stackvmProg form, and optimize that + val compiler = Compiler(programAst) + val intermediate = compiler.compile(compilerOptions) + if (optimize) + intermediate.optimize() + + if (writeVmCode) { + val stackVmFilename = intermediate.name + ".vm.txt" + val stackvmFile = PrintStream(File(stackVmFilename), "utf-8") + intermediate.writeCode(stackvmFile) + stackvmFile.close() + println("StackVM program code written to '$stackVmFilename'") + } + + if (writeAssembly) { + val zeropage = C64Zeropage(compilerOptions) + intermediate.allocateZeropage(zeropage) + val assembly = AsmGen(compilerOptions, intermediate, programAst.heap, zeropage).compileToAssembly(optimize) + assembly.assemble(compilerOptions) + programName = assembly.name + } + } + println("\nTotal compilation+assemble time: ${totalTime / 1000.0} sec.") + + } catch (px: ParsingFailedError) { + System.err.print("\u001b[91m") // bright red + System.err.println(px.message) + System.err.print("\u001b[0m") // reset + exitProcess(1) + } catch (ax: AstException) { + System.err.print("\u001b[91m") // bright red + System.err.println(ax.toString()) + System.err.print("\u001b[0m") // reset + exitProcess(1) + } catch (x: Exception) { + print("\u001b[91m") // bright red + println("\n* internal error *") + print("\u001b[0m") // reset + System.out.flush() + throw x + } catch (x: NotImplementedError) { + print("\u001b[91m") // bright red + println("\n* internal error: missing feature/code *") + print("\u001b[0m") // reset + System.out.flush() + throw x + } + return Pair(programAst, programName) +} + + +private fun determineCompilationOptions(program: Program): CompilationOptions { + val mainModule = program.modules.first() + val outputType = (mainModule.statements.singleOrNull { it is Directive && it.directive == "%output" } + as? Directive)?.args?.single()?.name?.toUpperCase() + val launcherType = (mainModule.statements.singleOrNull { it is Directive && it.directive == "%launcher" } + as? Directive)?.args?.single()?.name?.toUpperCase() + mainModule.loadAddress = (mainModule.statements.singleOrNull { it is Directive && it.directive == "%address" } + as? Directive)?.args?.single()?.int ?: 0 + val zpoption: String? = (mainModule.statements.singleOrNull { it is Directive && it.directive == "%zeropage" } + as? Directive)?.args?.single()?.name?.toUpperCase() + val allOptions = program.modules.flatMap { it.statements }.filter { it is Directive && it.directive == "%option" }.flatMap { (it as Directive).args }.toSet() + val floatsEnabled = allOptions.any { it.name == "enable_floats" } + val zpType: ZeropageType = + if (zpoption == null) + if(floatsEnabled) ZeropageType.FLOATSAFE else ZeropageType.KERNALSAFE + else + try { + ZeropageType.valueOf(zpoption) + } catch (x: IllegalArgumentException) { + ZeropageType.KERNALSAFE + // error will be printed by the astchecker + } + val zpReserved = mainModule.statements + .asSequence() + .filter { it is Directive && it.directive == "%zpreserved" } + .map { (it as Directive).args } + .map { it[0].int!!..it[1].int!! } + .toList() + + return CompilationOptions( + if (outputType == null) OutputType.PRG else OutputType.valueOf(outputType), + if (launcherType == null) LauncherType.BASIC else LauncherType.valueOf(launcherType), + zpType, zpReserved, floatsEnabled + ) +} diff --git a/compiler/src/prog8/compiler/intermediate/Instruction.kt b/compiler/src/prog8/compiler/intermediate/Instruction.kt index a18acc175..0af5dba85 100644 --- a/compiler/src/prog8/compiler/intermediate/Instruction.kt +++ b/compiler/src/prog8/compiler/intermediate/Instruction.kt @@ -1,6 +1,6 @@ package prog8.compiler.intermediate -import prog8.compiler.RuntimeValue +import prog8.vm.RuntimeValue import prog8.vm.stackvm.Syscall open class Instruction(val opcode: Opcode, diff --git a/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt b/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt index e7f7d2f3f..953e288fd 100644 --- a/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt +++ b/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt @@ -5,7 +5,7 @@ import prog8.ast.base.* import prog8.ast.base.printWarning import prog8.ast.expressions.LiteralValue import prog8.ast.statements.VarDecl -import prog8.compiler.RuntimeValue +import prog8.vm.RuntimeValue import prog8.compiler.CompilerException import prog8.compiler.HeapValues import prog8.compiler.Zeropage diff --git a/compiler/src/prog8/compiler/target/c64/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/AsmGen.kt index 260487aef..fb4dc3283 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmGen.kt @@ -7,7 +7,7 @@ import prog8.ast.antlr.escape import prog8.ast.base.DataType import prog8.ast.base.initvarsSubName import prog8.ast.base.printWarning -import prog8.compiler.RuntimeValue +import prog8.vm.RuntimeValue import prog8.compiler.* import prog8.compiler.intermediate.* import prog8.vm.stackvm.Syscall diff --git a/compiler/src/prog8/optimizer/ConstExprEvaluator.kt b/compiler/src/prog8/optimizer/ConstExprEvaluator.kt index 435ba9fdb..ce1b174c6 100644 --- a/compiler/src/prog8/optimizer/ConstExprEvaluator.kt +++ b/compiler/src/prog8/optimizer/ConstExprEvaluator.kt @@ -9,9 +9,6 @@ import prog8.ast.expressions.LiteralValue import kotlin.math.pow -val associativeOperators = setOf("+", "*", "&", "|", "^", "or", "and", "xor", "==", "!=") - - class ConstExprEvaluator { fun evaluate(left: LiteralValue, operator: String, right: LiteralValue): IExpression { diff --git a/compiler/src/prog8/optimizer/ConstantFolding.kt b/compiler/src/prog8/optimizer/ConstantFolding.kt index 8070fff8f..fe632cec6 100644 --- a/compiler/src/prog8/optimizer/ConstantFolding.kt +++ b/compiler/src/prog8/optimizer/ConstantFolding.kt @@ -222,7 +222,7 @@ class ConstantFolding(private val program: Program) : IAstProcessor { val expectedDt = arg.second.type val argConst = arg.first.value.constValue(program) if(argConst!=null && argConst.type!=expectedDt) { - val convertedValue = argConst.intoDatatype(expectedDt) + val convertedValue = argConst.cast(expectedDt) if(convertedValue!=null) { functionCall.arglist[arg.first.index] = convertedValue optimizationsDone++ @@ -550,11 +550,11 @@ class ConstantFolding(private val program: Program) : IAstProcessor { override fun process(forLoop: ForLoop): IStatement { fun adjustRangeDt(rangeFrom: LiteralValue, targetDt: DataType, rangeTo: LiteralValue, stepLiteral: LiteralValue?, range: RangeExpr): RangeExpr { - val newFrom = rangeFrom.intoDatatype(targetDt) - val newTo = rangeTo.intoDatatype(targetDt) + val newFrom = rangeFrom.cast(targetDt) + val newTo = rangeTo.cast(targetDt) if (newFrom != null && newTo != null) { val newStep: IExpression = - if (stepLiteral != null) (stepLiteral.intoDatatype(targetDt) ?: stepLiteral) else range.step + if (stepLiteral != null) (stepLiteral.cast(targetDt) ?: stepLiteral) else range.step return RangeExpr(newFrom, newTo, newStep, range.position) } return range diff --git a/compiler/src/prog8/compiler/RuntimeValue.kt b/compiler/src/prog8/vm/RuntimeValue.kt similarity index 99% rename from compiler/src/prog8/compiler/RuntimeValue.kt rename to compiler/src/prog8/vm/RuntimeValue.kt index 51bf1a165..5cc39e23f 100644 --- a/compiler/src/prog8/compiler/RuntimeValue.kt +++ b/compiler/src/prog8/vm/RuntimeValue.kt @@ -1,7 +1,8 @@ -package prog8.compiler +package prog8.vm import prog8.ast.base.* import prog8.ast.expressions.LiteralValue +import prog8.compiler.HeapValues import prog8.compiler.target.c64.Petscii import kotlin.math.abs import kotlin.math.pow diff --git a/compiler/src/prog8/vm/astvm/AstVm.kt b/compiler/src/prog8/vm/astvm/AstVm.kt index 6e3f64f70..f9c58ffd3 100644 --- a/compiler/src/prog8/vm/astvm/AstVm.kt +++ b/compiler/src/prog8/vm/astvm/AstVm.kt @@ -6,8 +6,8 @@ import prog8.ast.base.initvarsSubName import prog8.ast.expressions.IdentifierReference import prog8.ast.expressions.LiteralValue import prog8.ast.statements.* -import prog8.compiler.RuntimeValue -import prog8.compiler.RuntimeValueRange +import prog8.vm.RuntimeValue +import prog8.vm.RuntimeValueRange import prog8.compiler.target.c64.Petscii import java.awt.EventQueue import kotlin.NoSuchElementException diff --git a/compiler/src/prog8/vm/astvm/BuiltinFunctions.kt b/compiler/src/prog8/vm/astvm/BuiltinFunctions.kt index e9376cefd..2060252a5 100644 --- a/compiler/src/prog8/vm/astvm/BuiltinFunctions.kt +++ b/compiler/src/prog8/vm/astvm/BuiltinFunctions.kt @@ -1,7 +1,7 @@ package prog8.vm.astvm import prog8.ast.base.DataType -import prog8.compiler.RuntimeValue +import prog8.vm.RuntimeValue import java.lang.Math.toDegrees import java.lang.Math.toRadians import java.util.* diff --git a/compiler/src/prog8/vm/astvm/Expressions.kt b/compiler/src/prog8/vm/astvm/Expressions.kt index b8a320d8b..639deb20b 100644 --- a/compiler/src/prog8/vm/astvm/Expressions.kt +++ b/compiler/src/prog8/vm/astvm/Expressions.kt @@ -9,8 +9,8 @@ import prog8.ast.statements.BuiltinFunctionStatementPlaceholder import prog8.ast.statements.Label import prog8.ast.statements.Subroutine import prog8.ast.statements.VarDecl -import prog8.compiler.RuntimeValue -import prog8.compiler.RuntimeValueRange +import prog8.vm.RuntimeValue +import prog8.vm.RuntimeValueRange import kotlin.math.abs class EvalContext(val program: Program, val mem: Memory, val statusflags: StatusFlags, @@ -106,8 +106,8 @@ fun evaluate(expr: IExpression, ctx: EvalContext): RuntimeValue { DataType.UWORD -> RuntimeValue(DataType.UWORD, ctx.mem.getUWord(address)) DataType.WORD -> RuntimeValue(DataType.WORD, ctx.mem.getSWord(address)) DataType.FLOAT -> RuntimeValue(DataType.FLOAT, ctx.mem.getFloat(address)) - DataType.STR -> RuntimeValue(DataType.STR, str=ctx.mem.getString(address)) - DataType.STR_S -> RuntimeValue(DataType.STR_S, str=ctx.mem.getScreencodeString(address)) + DataType.STR -> RuntimeValue(DataType.STR, str = ctx.mem.getString(address)) + DataType.STR_S -> RuntimeValue(DataType.STR_S, str = ctx.mem.getScreencodeString(address)) else -> TODO("memvar $variable") } } diff --git a/compiler/src/prog8/vm/astvm/VariablesCreator.kt b/compiler/src/prog8/vm/astvm/VariablesCreator.kt index 2e0caccd7..848fc9314 100644 --- a/compiler/src/prog8/vm/astvm/VariablesCreator.kt +++ b/compiler/src/prog8/vm/astvm/VariablesCreator.kt @@ -6,7 +6,7 @@ import prog8.ast.expressions.LiteralValue import prog8.ast.processing.IAstProcessor import prog8.ast.statements.VarDecl import prog8.compiler.HeapValues -import prog8.compiler.RuntimeValue +import prog8.vm.RuntimeValue class VariablesCreator(private val runtimeVariables: RuntimeVariables, private val heap: HeapValues) : IAstProcessor { diff --git a/compiler/src/prog8/vm/stackvm/Program.kt b/compiler/src/prog8/vm/stackvm/Program.kt index 084bda8cf..ea99db949 100644 --- a/compiler/src/prog8/vm/stackvm/Program.kt +++ b/compiler/src/prog8/vm/stackvm/Program.kt @@ -4,7 +4,7 @@ import prog8.ast.antlr.unescape import prog8.ast.base.* import prog8.ast.expressions.AddressOf import prog8.ast.expressions.IdentifierReference -import prog8.compiler.RuntimeValue +import prog8.vm.RuntimeValue import prog8.compiler.HeapValues import prog8.compiler.IntegerOrAddressOf import prog8.compiler.intermediate.* diff --git a/compiler/src/prog8/vm/stackvm/StackVm.kt b/compiler/src/prog8/vm/stackvm/StackVm.kt index a8f5c2843..b51794460 100644 --- a/compiler/src/prog8/vm/stackvm/StackVm.kt +++ b/compiler/src/prog8/vm/stackvm/StackVm.kt @@ -7,7 +7,7 @@ import prog8.ast.base.Register import prog8.ast.base.initvarsSubName import prog8.vm.astvm.BitmapScreenPanel import prog8.vm.astvm.Memory -import prog8.compiler.RuntimeValue +import prog8.vm.RuntimeValue import prog8.compiler.HeapValues import prog8.compiler.IntegerOrAddressOf import prog8.compiler.intermediate.Instruction diff --git a/compiler/test/RuntimeValueTests.kt b/compiler/test/RuntimeValueTests.kt index 0aed3a1c7..ffbd84db3 100644 --- a/compiler/test/RuntimeValueTests.kt +++ b/compiler/test/RuntimeValueTests.kt @@ -3,7 +3,7 @@ package prog8tests import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import prog8.ast.base.DataType -import prog8.compiler.RuntimeValue +import prog8.vm.RuntimeValue import kotlin.test.* diff --git a/compiler/test/StackVMOpcodeTests.kt b/compiler/test/StackVMOpcodeTests.kt index b79af12d9..f4ba615ba 100644 --- a/compiler/test/StackVMOpcodeTests.kt +++ b/compiler/test/StackVMOpcodeTests.kt @@ -8,7 +8,7 @@ import prog8.ast.base.ByteDatatypes import prog8.ast.base.DataType import prog8.ast.base.IterableDatatypes import prog8.ast.base.WordDatatypes -import prog8.compiler.RuntimeValue +import prog8.vm.RuntimeValue import prog8.compiler.HeapValues import prog8.compiler.intermediate.Instruction import prog8.compiler.intermediate.Opcode diff --git a/compiler/test/UnitTests.kt b/compiler/test/UnitTests.kt index 4c1479a33..cfa28ef06 100644 --- a/compiler/test/UnitTests.kt +++ b/compiler/test/UnitTests.kt @@ -8,7 +8,7 @@ import org.junit.jupiter.api.TestInstance import prog8.ast.base.DataType import prog8.ast.base.Position import prog8.ast.expressions.LiteralValue -import prog8.compiler.RuntimeValue +import prog8.vm.RuntimeValue import prog8.compiler.* import prog8.compiler.target.c64.* import java.io.CharConversionException