mirror of
https://github.com/irmen/prog8.git
synced 2024-08-11 05:29:18 +00:00
fixed lsb(), fixed const value type mismatch, fixed and() const evaluation.
This commit is contained in:
parent
12f841e30d
commit
9ec62eb045
@ -438,7 +438,9 @@ internal class AstChecker(private val program: Program,
|
|||||||
if(variable==null)
|
if(variable==null)
|
||||||
errors.err("pointer-of operand must be the name of a heap variable", addressOf.position)
|
errors.err("pointer-of operand must be the name of a heap variable", addressOf.position)
|
||||||
else {
|
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)
|
errors.err("invalid pointer-of operand type", addressOf.position)
|
||||||
}
|
}
|
||||||
super.visit(addressOf)
|
super.visit(addressOf)
|
||||||
|
@ -47,18 +47,6 @@ internal class AstVariousTransforms(private val program: Program) : AstWalker()
|
|||||||
return noModifications
|
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> {
|
override fun before(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
||||||
// is it a struct variable? then define all its struct members as mangled names,
|
// is it a struct variable? then define all its struct members as mangled names,
|
||||||
// and include the original decl as well.
|
// and include the original decl as well.
|
||||||
|
@ -35,6 +35,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
|
|
||||||
when (functionName) {
|
when (functionName) {
|
||||||
"msb" -> funcMsb(fcall)
|
"msb" -> funcMsb(fcall)
|
||||||
|
"lsb" -> funcLsb(fcall)
|
||||||
"mkword" -> funcMkword(fcall, func)
|
"mkword" -> funcMkword(fcall, func)
|
||||||
"abs" -> funcAbs(fcall, func)
|
"abs" -> funcAbs(fcall, func)
|
||||||
"swap" -> funcSwap(fcall)
|
"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)
|
if (arg.inferType(program).typeOrElse(DataType.STRUCT) !in WordDatatypes)
|
||||||
throw AssemblyError("msb required word argument")
|
throw AssemblyError("msb required word argument")
|
||||||
if (arg is NumericLiteralValue)
|
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) {
|
if (arg is IdentifierReference) {
|
||||||
val sourceName = asmgen.asmIdentifierName(arg)
|
val sourceName = asmgen.asmIdentifierName(arg)
|
||||||
asmgen.out(" lda $sourceName+1 | sta $ESTACK_LO_HEX,x | dex")
|
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) {
|
private fun outputPushAddressAndLenghtOfArray(arg: Expression) {
|
||||||
arg as IdentifierReference
|
arg as IdentifierReference
|
||||||
val identifierName = asmgen.asmIdentifierName(arg)
|
val identifierName = asmgen.asmIdentifierName(arg)
|
||||||
|
@ -132,11 +132,11 @@ class ConstExprEvaluator {
|
|||||||
private fun bitwiseand(left: NumericLiteralValue, right: NumericLiteralValue): NumericLiteralValue {
|
private fun bitwiseand(left: NumericLiteralValue, right: NumericLiteralValue): NumericLiteralValue {
|
||||||
if(left.type== DataType.UBYTE) {
|
if(left.type== DataType.UBYTE) {
|
||||||
if(right.type in IntegerDatatypes) {
|
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) {
|
} else if(left.type== DataType.UWORD) {
|
||||||
if(right.type in IntegerDatatypes) {
|
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)
|
throw ExpressionError("cannot calculate $left & $right", left.position)
|
||||||
|
@ -273,11 +273,8 @@ internal class ConstantFoldingOptimizer(private val program: Program) : AstWalke
|
|||||||
// const fold when both operands are a const
|
// const fold when both operands are a const
|
||||||
if(leftconst != null && rightconst != null) {
|
if(leftconst != null && rightconst != null) {
|
||||||
val evaluator = ConstExprEvaluator()
|
val evaluator = ConstExprEvaluator()
|
||||||
return listOf(IAstModification.ReplaceNode(
|
val result = evaluator.evaluate(leftconst, expr.operator, rightconst)
|
||||||
expr,
|
return listOf(IAstModification.ReplaceNode(expr, result, parent))
|
||||||
evaluator.evaluate(leftconst, expr.operator, rightconst),
|
|
||||||
parent
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return noModifications
|
return noModifications
|
||||||
@ -379,6 +376,18 @@ internal class ConstantFoldingOptimizer(private val program: Program) : AstWalke
|
|||||||
return noModifications
|
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,
|
private class ShuffleOperands(val expr: BinaryExpression,
|
||||||
val exprOperator: String?,
|
val exprOperator: String?,
|
||||||
val subExpr: BinaryExpression,
|
val subExpr: BinaryExpression,
|
||||||
|
Loading…
Reference in New Issue
Block a user