fixed lsb(), fixed const value type mismatch, fixed and() const evaluation.

This commit is contained in:
Irmen de Jong 2020-08-21 16:26:40 +02:00
parent 12f841e30d
commit 9ec62eb045
5 changed files with 36 additions and 21 deletions

View File

@ -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)

View File

@ -47,18 +47,6 @@ internal class AstVariousTransforms(private val program: Program) : AstWalker()
return noModifications
}
override fun before(functionCall: FunctionCall, parent: Node): Iterable<IAstModification> {
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<IAstModification> {
// is it a struct variable? then define all its struct members as mangled names,
// and include the original decl as well.

View File

@ -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)

View File

@ -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)

View File

@ -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<IAstModification> {
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,