From 9ec62eb045ebf5a18948b3c47f47a37ec278f9b7 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 21 Aug 2020 16:26:40 +0200 Subject: [PATCH] fixed lsb(), fixed const value type mismatch, fixed and() const evaluation. --- .../src/prog8/ast/processing/AstChecker.kt | 4 +++- .../ast/processing/AstVariousTransforms.kt | 12 ------------ .../c64/codegen/BuiltinFunctionsAsmGen.kt | 18 +++++++++++++++++- .../src/prog8/optimizer/ConstExprEvaluator.kt | 4 ++-- .../optimizer/ConstantFoldingOptimizer.kt | 19 ++++++++++++++----- 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/compiler/src/prog8/ast/processing/AstChecker.kt b/compiler/src/prog8/ast/processing/AstChecker.kt index 5800f01be..8add048d6 100644 --- a/compiler/src/prog8/ast/processing/AstChecker.kt +++ b/compiler/src/prog8/ast/processing/AstChecker.kt @@ -438,7 +438,9 @@ internal class AstChecker(private val program: Program, if(variable==null) errors.err("pointer-of operand must be the name of a heap variable", addressOf.position) else { - if(variable.datatype !in ArrayDatatypes && variable.datatype != DataType.STR && variable.datatype!=DataType.STRUCT) + if(variable.datatype !in ArrayDatatypes + && variable.type!=VarDeclType.MEMORY + && variable.datatype != DataType.STR && variable.datatype!=DataType.STRUCT) errors.err("invalid pointer-of operand type", addressOf.position) } super.visit(addressOf) diff --git a/compiler/src/prog8/ast/processing/AstVariousTransforms.kt b/compiler/src/prog8/ast/processing/AstVariousTransforms.kt index 999fd4c6f..3fbba6291 100644 --- a/compiler/src/prog8/ast/processing/AstVariousTransforms.kt +++ b/compiler/src/prog8/ast/processing/AstVariousTransforms.kt @@ -47,18 +47,6 @@ internal class AstVariousTransforms(private val program: Program) : AstWalker() return noModifications } - override fun before(functionCall: FunctionCall, parent: Node): Iterable { - if(functionCall.target.nameInSource.size==1 && functionCall.target.nameInSource[0]=="lsb") { - // lsb(...) is just an alias for type cast to ubyte, so replace with "... as ubyte" - val typecast = TypecastExpression(functionCall.args.single(), DataType.UBYTE, false, functionCall.position) - return listOf(IAstModification.ReplaceNode( - functionCall, typecast, parent - )) - } - - return noModifications - } - override fun before(decl: VarDecl, parent: Node): Iterable { // is it a struct variable? then define all its struct members as mangled names, // and include the original decl as well. diff --git a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt index 3734d8cf3..b9f22663b 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt @@ -35,6 +35,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val when (functionName) { "msb" -> funcMsb(fcall) + "lsb" -> funcLsb(fcall) "mkword" -> funcMkword(fcall, func) "abs" -> funcAbs(fcall, func) "swap" -> funcSwap(fcall) @@ -584,7 +585,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val if (arg.inferType(program).typeOrElse(DataType.STRUCT) !in WordDatatypes) throw AssemblyError("msb required word argument") if (arg is NumericLiteralValue) - throw AssemblyError("should have been const-folded") + throw AssemblyError("msb(const) should have been const-folded away") if (arg is IdentifierReference) { val sourceName = asmgen.asmIdentifierName(arg) asmgen.out(" lda $sourceName+1 | sta $ESTACK_LO_HEX,x | dex") @@ -594,6 +595,21 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } } + private fun funcLsb(fcall: IFunctionCall) { + val arg = fcall.args.single() + if (arg.inferType(program).typeOrElse(DataType.STRUCT) !in WordDatatypes) + throw AssemblyError("lsb required word argument") + if (arg is NumericLiteralValue) + throw AssemblyError("lsb(const) should have been const-folded away") + if (arg is IdentifierReference) { + val sourceName = asmgen.asmIdentifierName(arg) + asmgen.out(" lda $sourceName | sta $ESTACK_LO_HEX,x | dex") + } else { + asmgen.translateExpression(arg) + // just ignore any high-byte + } + } + private fun outputPushAddressAndLenghtOfArray(arg: Expression) { arg as IdentifierReference val identifierName = asmgen.asmIdentifierName(arg) diff --git a/compiler/src/prog8/optimizer/ConstExprEvaluator.kt b/compiler/src/prog8/optimizer/ConstExprEvaluator.kt index 42c980259..c9d43b776 100644 --- a/compiler/src/prog8/optimizer/ConstExprEvaluator.kt +++ b/compiler/src/prog8/optimizer/ConstExprEvaluator.kt @@ -132,11 +132,11 @@ class ConstExprEvaluator { private fun bitwiseand(left: NumericLiteralValue, right: NumericLiteralValue): NumericLiteralValue { if(left.type== DataType.UBYTE) { if(right.type in IntegerDatatypes) { - return NumericLiteralValue(DataType.UBYTE, (left.number.toInt() or (right.number.toInt() and 255)).toShort(), left.position) + return NumericLiteralValue(DataType.UBYTE, (left.number.toInt() and (right.number.toInt() and 255)).toShort(), left.position) } } else if(left.type== DataType.UWORD) { if(right.type in IntegerDatatypes) { - return NumericLiteralValue(DataType.UWORD, left.number.toInt() or right.number.toInt(), left.position) + return NumericLiteralValue(DataType.UWORD, left.number.toInt() and right.number.toInt(), left.position) } } throw ExpressionError("cannot calculate $left & $right", left.position) diff --git a/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt b/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt index cebb0aed9..2ec8005a5 100644 --- a/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt +++ b/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt @@ -273,11 +273,8 @@ internal class ConstantFoldingOptimizer(private val program: Program) : AstWalke // const fold when both operands are a const if(leftconst != null && rightconst != null) { val evaluator = ConstExprEvaluator() - return listOf(IAstModification.ReplaceNode( - expr, - evaluator.evaluate(leftconst, expr.operator, rightconst), - parent - )) + val result = evaluator.evaluate(leftconst, expr.operator, rightconst) + return listOf(IAstModification.ReplaceNode(expr, result, parent)) } return noModifications @@ -379,6 +376,18 @@ internal class ConstantFoldingOptimizer(private val program: Program) : AstWalke return noModifications } + override fun after(decl: VarDecl, parent: Node): Iterable { + val numval = decl.value as? NumericLiteralValue + if(decl.type== VarDeclType.CONST && numval!=null) { + val valueDt = numval.inferType(program) + if(!valueDt.istype(decl.datatype)) { + val adjustedVal = numval.castNoCheck(decl.datatype) + return listOf(IAstModification.ReplaceNode(numval, adjustedVal, decl)) + } + } + return noModifications + } + private class ShuffleOperands(val expr: BinaryExpression, val exprOperator: String?, val subExpr: BinaryExpression,