From 2d768c3f286272cc083f62984983637a76ccb327 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 22 Aug 2019 22:06:21 +0200 Subject: [PATCH] code cleanups --- compiler/src/prog8/ast/AstToplevel.kt | 4 +- .../prog8/ast/expressions/InferredTypes.kt | 6 ++- .../src/prog8/ast/processing/AstChecker.kt | 15 ++++---- .../ast/processing/AstIdentifiersChecker.kt | 37 ++++++++----------- .../ast/processing/IAstModifyingVisitor.kt | 6 +-- compiler/src/prog8/compiler/Compiler.kt | 3 -- .../compiler/target/c64/codegen/AsmGen.kt | 3 +- .../target/c64/codegen/PostIncrDecrAsmGen.kt | 3 +- .../src/prog8/functions/BuiltinFunctions.kt | 3 +- .../src/prog8/optimizer/StatementOptimizer.kt | 8 ++-- compiler/src/prog8/vm/RuntimeValue.kt | 12 ++---- compiler/src/prog8/vm/astvm/AstVm.kt | 2 - 12 files changed, 43 insertions(+), 59 deletions(-) diff --git a/compiler/src/prog8/ast/AstToplevel.kt b/compiler/src/prog8/ast/AstToplevel.kt index bc525e637..a26b4c0a7 100644 --- a/compiler/src/prog8/ast/AstToplevel.kt +++ b/compiler/src/prog8/ast/AstToplevel.kt @@ -160,7 +160,9 @@ interface INameScope { } } -interface IAssignable {} +interface IAssignable { + // just a tag for now +} /*********** Everything starts from here, the Program; zero or more modules *************/ diff --git a/compiler/src/prog8/ast/expressions/InferredTypes.kt b/compiler/src/prog8/ast/expressions/InferredTypes.kt index d7111e1a5..a18c578a5 100644 --- a/compiler/src/prog8/ast/expressions/InferredTypes.kt +++ b/compiler/src/prog8/ast/expressions/InferredTypes.kt @@ -1,12 +1,12 @@ package prog8.ast.expressions import prog8.ast.base.DataType +import java.util.* object InferredTypes { class InferredType private constructor(val isUnknown: Boolean, val isVoid: Boolean, private var datatype: DataType?) { init { - if(datatype!=null && (isUnknown || isVoid)) - throw IllegalArgumentException("invalid combination of args") + require(!(datatype!=null && (isUnknown || isVoid))) { "invalid combination of args" } } val isKnown = datatype!=null @@ -32,6 +32,8 @@ object InferredTypes { else -> "" } } + + override fun hashCode(): Int = Objects.hash(isVoid, datatype) } private val unknownInstance = InferredType.unknown() diff --git a/compiler/src/prog8/ast/processing/AstChecker.kt b/compiler/src/prog8/ast/processing/AstChecker.kt index 8bea2b1fe..d58ec0da4 100644 --- a/compiler/src/prog8/ast/processing/AstChecker.kt +++ b/compiler/src/prog8/ast/processing/AstChecker.kt @@ -1,3 +1,5 @@ +@file:Suppress("DuplicatedCode") + package prog8.ast.processing import prog8.ast.IFunctionCall @@ -945,9 +947,8 @@ internal class AstChecker(private val program: Program, if(dt !in NumericDatatypes && dt !in ArrayDatatypes) checkResult.add(SyntaxError("can only increment or decrement a byte/float/word", postIncrDecr.position)) } - } else if(postIncrDecr.target.memoryAddress != null) { - // a memory location can always be ++/-- } + // else if(postIncrDecr.target.memoryAddress != null) { } // a memory location can always be ++/-- super.visit(postIncrDecr) } @@ -1231,11 +1232,11 @@ internal class AstChecker(private val program: Program, } val array = value.value.map { - if(it is NumericLiteralValue) - it.number.toInt() - else if(it is AddressOf) - it.identifier.heapId(program.namespace) - else -9999999 + when (it) { + is NumericLiteralValue -> it.number.toInt() + is AddressOf -> it.identifier.heapId(program.namespace) + else -> -9999999 + } } val correct: Boolean when (type) { diff --git a/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt b/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt index cd1ca6a13..033ff82a1 100644 --- a/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt +++ b/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt @@ -219,15 +219,8 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi val subroutine = returnStmt.definingSubroutine()!! if(subroutine.returntypes.size!=1) return returnStmt // mismatch in number of return values, error will be printed later. - val newValue: Expression val lval = returnStmt.value as? NumericLiteralValue - if(lval!=null) { - newValue = lval.cast(subroutine.returntypes.single()) - } else { - newValue = returnStmt.value!! - } - - returnStmt.value = newValue + returnStmt.value = lval?.cast(subroutine.returntypes.single()) ?: returnStmt.value!! } return super.visit(returnStmt) } @@ -236,18 +229,19 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi val array = super.visit(arrayLiteral) if(array is ArrayLiteralValue) { val vardecl = array.parent as? VarDecl - return if (vardecl!=null) { - fixupArrayDatatype(array, vardecl, program) - } else if(array.heapId!=null) { - // fix the datatype of the array (also on the heap) to the 'biggest' datatype in the array - // (we don't know the desired datatype here exactly so we guess) - val datatype = determineArrayDt(array.value) - val litval2 = array.cast(datatype)!! - litval2.parent = array.parent - // finally, replace the literal array by a identifier reference. - makeIdentifierFromRefLv(litval2) - } else - array + return when { + vardecl!=null -> fixupArrayDatatype(array, vardecl, program) + array.heapId!=null -> { + // fix the datatype of the array (also on the heap) to the 'biggest' datatype in the array + // (we don't know the desired datatype here exactly so we guess) + val datatype = determineArrayDt(array.value) + val litval2 = array.cast(datatype)!! + litval2.parent = array.parent + // finally, replace the literal array by a identifier reference. + makeIdentifierFromRefLv(litval2) + } + else -> array + } } return array } @@ -272,8 +266,7 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi private fun determineArrayDt(array: Array): DataType { val datatypesInArray = array.map { it.inferType(program) } - if(datatypesInArray.isEmpty() || datatypesInArray.any { !it.isKnown }) - throw IllegalArgumentException("can't determine type of empty array") + require(datatypesInArray.isNotEmpty() && datatypesInArray.all { it.isKnown }) { "can't determine type of empty array" } val dts = datatypesInArray.map { it.typeOrElse(DataType.STRUCT) } return when { DataType.FLOAT in dts -> DataType.ARRAY_F diff --git a/compiler/src/prog8/ast/processing/IAstModifyingVisitor.kt b/compiler/src/prog8/ast/processing/IAstModifyingVisitor.kt index 6c7e55049..6c8043929 100644 --- a/compiler/src/prog8/ast/processing/IAstModifyingVisitor.kt +++ b/compiler/src/prog8/ast/processing/IAstModifyingVisitor.kt @@ -142,8 +142,7 @@ interface IAstModifyingVisitor { } fun visit(forLoop: ForLoop): Statement { - val newloopvar = forLoop.loopVar?.accept(this) - when(newloopvar) { + when(val newloopvar = forLoop.loopVar?.accept(this)) { is IdentifierReference -> forLoop.loopVar = newloopvar null -> forLoop.loopVar = null else -> throw FatalAstException("can't change class of loopvar") @@ -179,8 +178,7 @@ interface IAstModifyingVisitor { } fun visit(assignTarget: AssignTarget): AssignTarget { - val ident = assignTarget.identifier?.accept(this) - when (ident) { + when (val ident = assignTarget.identifier?.accept(this)) { is IdentifierReference -> assignTarget.identifier = ident null -> assignTarget.identifier = null else -> throw FatalAstException("can't change class of assign target identifier") diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 6aaf7cf45..b95a194a3 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -1,6 +1,5 @@ package prog8.compiler -import prog8.ast.expressions.AddressOf import java.io.File import java.io.InputStream import java.nio.file.Path @@ -24,8 +23,6 @@ enum class ZeropageType { DONTUSE } -data class IntegerOrAddressOf(val integer: Int?, val addressOf: AddressOf?) - data class CompilationOptions(val output: OutputType, val launcher: LauncherType, val zeropage: ZeropageType, diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt index a7649cbe7..a95130c90 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt @@ -820,8 +820,7 @@ internal class AsmGen(val program: Program, } internal fun translateArrayIndexIntoA(expr: ArrayIndexedExpression) { - val index = expr.arrayspec.index - when (index) { + when (val index = expr.arrayspec.index) { is NumericLiteralValue -> throw AssemblyError("this should be optimized directly") is RegisterExpr -> { when (index.register) { diff --git a/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt index 6089bb173..d9e73e520 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt @@ -57,8 +57,7 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg } } targetMemory!=null -> { - val addressExpr = targetMemory.addressExpression - when (addressExpr) { + when (val addressExpr = targetMemory.addressExpression) { is NumericLiteralValue -> { val what = addressExpr.number.toHex() asmgen.out(if(incr) " inc $what" else " dec $what") diff --git a/compiler/src/prog8/functions/BuiltinFunctions.kt b/compiler/src/prog8/functions/BuiltinFunctions.kt index 368567fff..0ae593431 100644 --- a/compiler/src/prog8/functions/BuiltinFunctions.kt +++ b/compiler/src/prog8/functions/BuiltinFunctions.kt @@ -120,8 +120,7 @@ fun builtinFunctionReturnType(function: String, args: List, program: val idt = arglist.inferType(program) if(!idt.isKnown) throw FatalAstException("couldn't determine type of iterable $arglist") - val dt = idt.typeOrElse(DataType.STRUCT) - return when(dt) { + return when(val dt = idt.typeOrElse(DataType.STRUCT)) { in NumericDatatypes -> dt in StringDatatypes -> dt in ArrayDatatypes -> ArrayElementTypes.getValue(dt) diff --git a/compiler/src/prog8/optimizer/StatementOptimizer.kt b/compiler/src/prog8/optimizer/StatementOptimizer.kt index ccc1cea76..22c6690bd 100644 --- a/compiler/src/prog8/optimizer/StatementOptimizer.kt +++ b/compiler/src/prog8/optimizer/StatementOptimizer.kt @@ -136,7 +136,7 @@ internal class StatementOptimizer(private val program: Program) : IAstModifyingV // removes 'duplicate' assignments that assign the isSameAs target val linesToRemove = mutableListOf() var previousAssignmentLine: Int? = null - for (i in 0 until statements.size) { + for (i in statements.indices) { val stmt = statements[i] as? Assignment if (stmt != null && stmt.value is NumericLiteralValue) { if (previousAssignmentLine == null) { @@ -172,10 +172,10 @@ internal class StatementOptimizer(private val program: Program) : IAstModifyingV // printing a literal string of just 2 or 1 characters is replaced by directly outputting those characters val arg = functionCallStatement.arglist.single() val stringVar: IdentifierReference? - if(arg is AddressOf) { - stringVar = arg.identifier + stringVar = if(arg is AddressOf) { + arg.identifier } else { - stringVar = arg as? IdentifierReference + arg as? IdentifierReference } if(stringVar!=null) { val vardecl = stringVar.targetVarDecl(program.namespace)!! diff --git a/compiler/src/prog8/vm/RuntimeValue.kt b/compiler/src/prog8/vm/RuntimeValue.kt index defc70e69..73a5cef22 100644 --- a/compiler/src/prog8/vm/RuntimeValue.kt +++ b/compiler/src/prog8/vm/RuntimeValue.kt @@ -42,8 +42,7 @@ class RuntimeValueNumeric(type: DataType, num: Number): RuntimeValueBase(type) { when (type) { DataType.UBYTE -> { val inum = num.toInt() - if (inum !in 0..255) - throw IllegalArgumentException("invalid value for ubyte: $inum") + require(inum in 0..255) { "invalid value for ubyte: $inum" } byteval = inum.toShort() wordval = null floatval = null @@ -51,8 +50,7 @@ class RuntimeValueNumeric(type: DataType, num: Number): RuntimeValueBase(type) { } DataType.BYTE -> { val inum = num.toInt() - if (inum !in -128..127) - throw IllegalArgumentException("invalid value for byte: $inum") + require(inum in -128..127) { "invalid value for byte: $inum" } byteval = inum.toShort() wordval = null floatval = null @@ -60,8 +58,7 @@ class RuntimeValueNumeric(type: DataType, num: Number): RuntimeValueBase(type) { } DataType.UWORD -> { val inum = num.toInt() - if (inum !in 0..65535) - throw IllegalArgumentException("invalid value for uword: $inum") + require(inum in 0..65535) { "invalid value for uword: $inum" } wordval = inum byteval = null floatval = null @@ -69,8 +66,7 @@ class RuntimeValueNumeric(type: DataType, num: Number): RuntimeValueBase(type) { } DataType.WORD -> { val inum = num.toInt() - if (inum !in -32768..32767) - throw IllegalArgumentException("invalid value for word: $inum") + require(inum in -32768..32767) { "invalid value for word: $inum" } wordval = inum byteval = null floatval = null diff --git a/compiler/src/prog8/vm/astvm/AstVm.kt b/compiler/src/prog8/vm/astvm/AstVm.kt index 565346879..20586baf2 100644 --- a/compiler/src/prog8/vm/astvm/AstVm.kt +++ b/compiler/src/prog8/vm/astvm/AstVm.kt @@ -116,8 +116,6 @@ class RuntimeVariables { return where[name] ?: throw NoSuchElementException("no such runtime memory-variable: ${scope.name}.$name") } - fun swap(a1: VarDecl, a2: VarDecl) = swap(a1.definingScope(), a1.name, a2.definingScope(), a2.name) - fun swap(scope1: INameScope, name1: String, scope2: INameScope, name2: String) { val v1 = get(scope1, name1) val v2 = get(scope2, name2)