From 7ea7e63f44a6c969d3e9b913dae9d96cef4a230b Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 27 Sep 2022 18:27:55 +0200 Subject: [PATCH] use require() more often --- codeCore/src/prog8/code/ast/AstExpressions.kt | 3 +- .../codegen/intermediate/ExpressionGen.kt | 3 +- docs/source/todo.rst | 2 - .../src/prog8/intermediate/IRInstructions.kt | 69 +++++++------------ .../src/prog8/intermediate/IRProgram.kt | 21 ++---- intermediate/test/TestInstructions.kt | 2 +- virtualmachine/src/prog8/vm/VirtualMachine.kt | 3 +- 7 files changed, 37 insertions(+), 66 deletions(-) diff --git a/codeCore/src/prog8/code/ast/AstExpressions.kt b/codeCore/src/prog8/code/ast/AstExpressions.kt index 0a10473bb..11d92603d 100644 --- a/codeCore/src/prog8/code/ast/AstExpressions.kt +++ b/codeCore/src/prog8/code/ast/AstExpressions.kt @@ -173,8 +173,7 @@ class PtPrefix(val operator: String, type: DataType, position: Position): PtExpr init { // note: the "not" operator may no longer occur in the ast; not x should have been replaced with x==0 - if(operator !in setOf("+", "-", "~")) - throw IllegalArgumentException("invalid prefix operator: $operator") + require(operator in setOf("+", "-", "~")) { "invalid prefix operator: $operator" } } override fun printProperties() { diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt index bf132980f..3b9cd7c1c 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt @@ -544,8 +544,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } private fun operatorModulo(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): IRCodeChunk { - if(vmDt==VmDataType.FLOAT) - throw IllegalArgumentException("floating-point modulo not supported") + require(vmDt!=VmDataType.FLOAT) {"floating-point modulo not supported"} val code = IRCodeChunk(binExpr.position) val rightResultReg = codeGen.vmRegisters.nextFree() if(binExpr.right is PtNumber) { diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 92cfd4aaa..94a2f1f08 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- replace throw IllegalArgumentException() by require()? - ... diff --git a/intermediate/src/prog8/intermediate/IRInstructions.kt b/intermediate/src/prog8/intermediate/IRInstructions.kt index 5f60f951f..e31d92977 100644 --- a/intermediate/src/prog8/intermediate/IRInstructions.kt +++ b/intermediate/src/prog8/intermediate/IRInstructions.kt @@ -434,59 +434,41 @@ data class IRInstruction( val fpReg1direction: OperandDirection init { - if(labelSymbol?.startsWith('_')==true) { - throw IllegalArgumentException("label/symbol should not start with underscore $labelSymbol") - } - if(reg1!=null && (reg1<0 || reg1>65536)) - throw IllegalArgumentException("reg1 out of bounds") - if(reg2!=null && (reg2<0 || reg2>65536)) - throw IllegalArgumentException("reg2 out of bounds") - if(fpReg1!=null && (fpReg1<0 || fpReg1>65536)) - throw IllegalArgumentException("fpReg1 out of bounds") - if(fpReg2!=null && (fpReg2<0 || fpReg2>65536)) - throw IllegalArgumentException("fpReg2 out of bounds") + require(labelSymbol?.first()!='_') {"label/symbol should not start with underscore $labelSymbol"} + require(reg1==null || reg1 in 0..65536) {"reg1 out of bounds"} + require(reg2==null || reg2 in 0..65536) {"reg2 out of bounds"} + require(fpReg1==null || fpReg1 in 0..65536) {"fpReg1 out of bounds"} + require(fpReg2==null || fpReg2 in 0..65536) {"fpReg2 out of bounds"} if(value!=null && opcode !in OpcodesWithAddress) { when (type) { - VmDataType.BYTE -> { - if (value < -128 || value > 255) - throw IllegalArgumentException("value out of range for byte: $value") - } - VmDataType.WORD -> { - if (value < -32768 || value > 65535) - throw IllegalArgumentException("value out of range for word: $value") - } + VmDataType.BYTE -> require(value in -128..255) {"value out of range for byte: $value"} + VmDataType.WORD -> require(value in -32768..65535) {"value out of range for word: $value"} VmDataType.FLOAT, null -> {} } } - if(opcode==Opcode.BINARYDATA && binaryData==null || binaryData!=null && opcode!=Opcode.BINARYDATA) - throw IllegalArgumentException("binarydata inconsistency") + require((opcode==Opcode.BINARYDATA && binaryData!=null) || (opcode!=Opcode.BINARYDATA && binaryData==null)) { + "binarydata inconsistency" + } val formats = instructionFormats.getValue(opcode) - if(type==null && !formats.containsKey(null)) - throw IllegalArgumentException("missing type") + require (type != null || formats.containsKey(null)) { "missing type" } val format = formats.getValue(type) - if(format.reg1 && reg1==null || format.reg2 && reg2==null) - throw IllegalArgumentException("missing a register (int)") - - if(format.fpReg1 && fpReg1==null || format.fpReg2 && fpReg2==null) - throw IllegalArgumentException("missing a register (float)") - - if(!format.reg1 && reg1!=null || !format.reg2 && reg2!=null) - throw IllegalArgumentException("too many registers (int)") - - if(!format.fpReg1 && fpReg1!=null || !format.fpReg2 && fpReg2!=null) - throw IllegalArgumentException("too many registers (float)") + if(format.reg1) require(reg1!=null) { "missing reg1" } + if(format.reg2) require(reg2!=null) { "missing reg2" } + if(format.fpReg1) require(fpReg1!=null) { "missing fpReg1" } + if(format.fpReg2) require(fpReg2!=null) { "missing fpReg2" } + if(!format.reg1) require(reg1==null) { "invalid reg1" } + if(!format.reg2) require(reg2==null) { "invalid reg2" } + if(!format.fpReg1) require(fpReg1==null) { "invalid fpReg1" } + if(!format.fpReg2) require(fpReg2==null) { "invalid fpReg2" } if (type==VmDataType.FLOAT) { - if(format.fpValue && (fpValue==null && labelSymbol==null)) - throw IllegalArgumentException("missing a fp-value or labelsymbol") + if(format.fpValue) require(fpValue!=null || labelSymbol!=null) {"missing a fp-value or labelsymbol"} } else { - if(format.value && (value==null && labelSymbol==null)) - throw IllegalArgumentException("missing a value or labelsymbol") - if (fpReg1 != null || fpReg2 != null) - throw IllegalArgumentException("integer point instruction can't use floating point registers") + if(format.value) require(value!=null || labelSymbol!=null) {"missing a value or labelsymbol"} + require(fpReg1==null && fpReg2==null) {"integer point instruction can't use floating point registers"} } reg1direction = format.reg1direction @@ -498,9 +480,10 @@ data class IRInstruction( Opcode.SEQ, Opcode.SNE, Opcode.SLT, Opcode.SLTS, Opcode.SGT, Opcode.SGTS, Opcode.SLE, Opcode.SLES, Opcode.SGE, Opcode.SGES)) { - if((type==VmDataType.FLOAT && fpReg1==fpReg2) || reg1==reg2) { - throw IllegalArgumentException("$opcode: reg1 and reg2 should be different") - } + if(type==VmDataType.FLOAT) + require(fpReg1!=fpReg2) {"$opcode: fpReg1 and fpReg2 should be different"} + else + require(reg1!=reg2) {"$opcode: reg1 and reg2 should be different"} } } diff --git a/intermediate/src/prog8/intermediate/IRProgram.kt b/intermediate/src/prog8/intermediate/IRProgram.kt index 83d53ad32..5023c372a 100644 --- a/intermediate/src/prog8/intermediate/IRProgram.kt +++ b/intermediate/src/prog8/intermediate/IRProgram.kt @@ -55,8 +55,7 @@ class IRProgram(val name: String, fun addGlobalInits(chunk: IRCodeChunk) = globalInits.addAll(chunk.lines) fun addBlock(block: IRBlock) { - if(blocks.any { it.name==block.name }) - throw IllegalArgumentException("duplicate block ${block.name} ${block.position}") + require(blocks.all { it.name != block.name}) { "duplicate block ${block.name} ${block.position}" } blocks.add(block) } } @@ -94,16 +93,12 @@ class IRSubroutine(val name: String, val chunks = mutableListOf() init { - if(!name.contains('.')) - throw IllegalArgumentException("subroutine name is not scoped: $name") - if(name.startsWith("main.main.")) - throw IllegalArgumentException("subroutine name invalid main prefix: $name") + require('.' in name) {"subroutine name is not scoped: $name"} + require(!name.startsWith("main.main.")) {"subroutine name invalid main prefix: $name"} // params and return value should not be str - if(parameters.any{ it.dt !in NumericDatatypes }) - throw IllegalArgumentException("non-numeric parameter") - if(returnType!=null && returnType !in NumericDatatypes) - throw IllegalArgumentException("non-numeric returntype $returnType") + require(parameters.all{ it.dt in NumericDatatypes }) {"non-numeric parameter"} + require(returnType==null || returnType in NumericDatatypes) {"non-numeric returntype $returnType"} } operator fun plusAssign(chunk: IRCodeChunkBase) { chunks+= chunk } @@ -117,10 +112,8 @@ class IRAsmSubroutine(val name: String, val returns: List>, val assembly: String) { init { - if(!name.contains('.')) - throw IllegalArgumentException("subroutine name is not scoped: $name") - if(name.startsWith("main.main.")) - throw IllegalArgumentException("subroutine name invalid main prefix: $name") + require('.' in name) { "subroutine name is not scoped: $name" } + require(!name.startsWith("main.main.")) { "subroutine name invalid main prefix: $name" } } } diff --git a/intermediate/test/TestInstructions.kt b/intermediate/test/TestInstructions.kt index 0fe156cb0..d0f960985 100644 --- a/intermediate/test/TestInstructions.kt +++ b/intermediate/test/TestInstructions.kt @@ -79,7 +79,7 @@ class TestInstructions: FunSpec({ } test("missing registers should fail") { - shouldThrowWithMessage("missing a register (int)") { + shouldThrowWithMessage("missing reg1") { IRInstruction(Opcode.BZ, VmDataType.BYTE, value=99) } } diff --git a/virtualmachine/src/prog8/vm/VirtualMachine.kt b/virtualmachine/src/prog8/vm/VirtualMachine.kt index 1ea991521..e37290000 100644 --- a/virtualmachine/src/prog8/vm/VirtualMachine.kt +++ b/virtualmachine/src/prog8/vm/VirtualMachine.kt @@ -45,8 +45,7 @@ class VirtualMachine(irProgram: IRProgram) { init { program = VmProgramLoader().load(irProgram, memory).toTypedArray() - if(program.size>65536) - throw IllegalArgumentException("program cannot contain more than 65536 instructions") + require(program.size<=65536) {"program cannot contain more than 65536 instructions"} cx16virtualregsBaseAddress = (irProgram.st.lookup("cx16.r0") as? StMemVar)?.address?.toInt() ?: 0xff02 }