added unary ^ and << operators (experimental) (gets bank and address of a long integer)

This commit is contained in:
Irmen de Jong 2024-11-24 03:07:18 +01:00
parent d77b1944fb
commit cb86206698
10 changed files with 54 additions and 6 deletions

View File

@ -318,7 +318,7 @@ class PtPrefix(val operator: String, type: DataType, position: Position): PtExpr
get() = children.single() as PtExpression get() = children.single() as PtExpression
init { init {
require(operator in setOf("+", "-", "~", "not")) { "invalid prefix operator: $operator" } require(operator in setOf("+", "-", "~", "^", "<<", "not")) { "invalid prefix operator: $operator" }
} }
} }

View File

@ -24,7 +24,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
val sscope = fcall.definingISub() val sscope = fcall.definingISub()
when (fcall.name) { when (fcall.name) {
"bankof" -> throw AssemblyError("bankof() should have been replaced by a const value at all times (either the bank number of a long const, or zero for any other smaller value)") "bankof" -> throw AssemblyError("bankof() should have been replaced by a const value (either the bank number of a long const, or zero for any other smaller value)")
"msb" -> funcMsb(fcall, resultRegister) "msb" -> funcMsb(fcall, resultRegister)
"lsb" -> funcLsb(fcall, resultRegister) "lsb" -> funcLsb(fcall, resultRegister)
"mkword" -> funcMkword(fcall, resultRegister) "mkword" -> funcMkword(fcall, resultRegister)

View File

@ -536,6 +536,10 @@ internal class AssignmentAsmGen(
} }
} }
is PtPrefix -> { is PtPrefix -> {
if(value.operator=="^")
throw AssemblyError("unary ^ should have been replaced by a const value (either the bank number of a long const, or zero for any other smaller value)")
if(value.operator=="<<")
throw AssemblyError("unary << should have been replaced by a const uword")
if(assign.target.array==null) { if(assign.target.array==null) {
if(assign.source.datatype isAssignableTo assign.target.datatype || (assign.source.datatype==DataType.BOOL && assign.target.datatype in ByteDatatypes)) { if(assign.source.datatype isAssignableTo assign.target.datatype || (assign.source.datatype==DataType.BOOL && assign.target.datatype in ByteDatatypes)) {
if(assign.source.datatype in IntegerDatatypesWithBoolean) { if(assign.source.datatype in IntegerDatatypesWithBoolean) {

View File

@ -19,7 +19,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
"callfar" -> funcCallfar(call) "callfar" -> funcCallfar(call)
"callfar2" -> funcCallfar2(call) "callfar2" -> funcCallfar2(call)
"call" -> funcCall(call) "call" -> funcCall(call)
"bankof" -> throw AssemblyError("bankof() should have been replaced by a const value at all times (either the bank number of a long const, or zero for any other smaller value)") "bankof" -> throw AssemblyError("bankof() should have been replaced by a const value (either the bank number of a long const, or zero for any other smaller value)")
"msb" -> funcMsb(call) "msb" -> funcMsb(call)
"lsb" -> funcLsb(call) "lsb" -> funcLsb(call)
"memory" -> funcMemory(call) "memory" -> funcMemory(call)

View File

@ -373,6 +373,8 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
"not" -> { "not" -> {
addInstr(result, IRInstruction(Opcode.XOR, vmDt, reg1 = tr.resultReg, immediate = 1), null) addInstr(result, IRInstruction(Opcode.XOR, vmDt, reg1 = tr.resultReg, immediate = 1), null)
} }
"^" -> throw AssemblyError("unary ^ should have been replaced by a const value (either the bank number of a long const, or zero for any other smaller value)")
"<<" -> throw AssemblyError("unary << should have been replaced by a const uword")
else -> throw AssemblyError("weird prefix operator") else -> throw AssemblyError("weird prefix operator")
} }
return ExpressionCodeResult(result, vmDt, tr.resultReg, tr.resultFpReg) return ExpressionCodeResult(result, vmDt, tr.resultReg, tr.resultFpReg)

View File

@ -148,6 +148,22 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
return listOf(IAstModification.ReplaceNode(expr, expr.expression, parent)) return listOf(IAstModification.ReplaceNode(expr, expr.expression, parent))
} }
if(expr.operator=="<<") {
// << X --> X (X is word or byte)
val valueDt = expr.expression.inferType(program)
if(valueDt.isBytes || valueDt.isWords) {
return listOf(IAstModification.ReplaceNode(expr, expr.expression, parent))
}
}
if(expr.operator=="^") {
// ^ X --> 0 (X is word or byte)
val valueDt = expr.expression.inferType(program)
if(valueDt.isBytes || valueDt.isWords) {
val zero = NumericLiteral(DataType.UBYTE, 0.0, expr.expression.position)
return listOf(IAstModification.ReplaceNode(expr, zero, parent))
}
}
return noModifications return noModifications
} }

View File

@ -13,6 +13,7 @@ import prog8.code.target.encodings.JapaneseCharacterConverter
import java.io.CharConversionException import java.io.CharConversionException
import java.util.Objects import java.util.Objects
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.exp
import kotlin.math.floor import kotlin.math.floor
import kotlin.math.truncate import kotlin.math.truncate
@ -98,6 +99,11 @@ class PrefixExpression(val operator: String, var expression: Expression, overrid
override fun copy() = PrefixExpression(operator, expression.copy(), position) override fun copy() = PrefixExpression(operator, expression.copy(), position)
override fun constValue(program: Program): NumericLiteral? { override fun constValue(program: Program): NumericLiteral? {
if(operator=="^") {
val valueDt = expression.inferType(program)
if(valueDt.isBytes || valueDt.isWords)
return NumericLiteral(DataType.UBYTE, 0.0, expression.position)
}
val constval = expression.constValue(program) ?: return null val constval = expression.constValue(program) ?: return null
val converted = when(operator) { val converted = when(operator) {
"+" -> constval "+" -> constval
@ -114,6 +120,8 @@ class PrefixExpression(val operator: String, var expression: Expression, overrid
else -> throw ExpressionError("can only take bitwise inversion of int", constval.position) else -> throw ExpressionError("can only take bitwise inversion of int", constval.position)
} }
"not" -> NumericLiteral.fromBoolean(constval.number==0.0, constval.position) "not" -> NumericLiteral.fromBoolean(constval.number==0.0, constval.position)
"^" -> NumericLiteral(DataType.UBYTE, (constval.number.toInt() ushr 16 and 255).toDouble(), constval.position) // bank
"<<" -> NumericLiteral(DataType.UWORD, (constval.number.toInt() and 65535).toDouble(), constval.position) // address
else -> throw FatalAstException("invalid operator") else -> throw FatalAstException("invalid operator")
} }
converted.linkParents(this.parent) converted.linkParents(this.parent)
@ -138,6 +146,8 @@ class PrefixExpression(val operator: String, var expression: Expression, overrid
else if(inferred.isWords) InferredTypes.knownFor(DataType.WORD) else if(inferred.isWords) InferredTypes.knownFor(DataType.WORD)
else inferred else inferred
} }
"^" -> InferredTypes.knownFor(DataType.UBYTE)
"<<" -> InferredTypes.knownFor(DataType.UWORD)
else -> throw FatalAstException("weird prefix expression operator") else -> throw FatalAstException("weird prefix expression operator")
} }
} }

View File

@ -1,9 +1,11 @@
TODO TODO
==== ====
what to do with bnk(): it's an awkward name but bank() is too general a name and will forbid you to use 'bank' as a variable... what to do with bankof(): keep it? add another syntax like \`value or ^value to get the bank byte?
add a function like addr() or lsw() to complement bnk() in getting easy access to the lower 16 bits of a long integer? add a function like addr() or lsw() to complement bnk() in getting easy access to the lower 16 bits of a long integer?
-> added unary ^ operator as alternative to bankof()
-> added unary << operator as alternative to addr() / lsb(x>>16) / lsw()
-> TODO document whatever remains of those!
... ...

View File

@ -4,6 +4,20 @@
main { main {
sub start() { sub start() {
const long foo2 = $123456 const long foo2 = $123456
cx16.r0 = $ffff
cx16.r1 = $ea31
txt.print_uwbin(cx16.r1 << 7, true)
txt.nl()
txt.print_uwhex(cx16.r0 ^ cx16.r1, true)
txt.nl()
txt.print_ubhex(^cx16.r0, true)
txt.spc()
txt.print_uwhex(<<cx16.r0, false)
txt.nl()
txt.print_ubhex(^foo2, true)
txt.spc()
txt.print_uwhex(<<foo2, false)
txt.nl()
txt.print_ubhex(bankof(foo2), true) txt.print_ubhex(bankof(foo2), true)
txt.spc() txt.spc()
txt.print_uwhex(foo2 &$ffff, false) txt.print_uwhex(foo2 &$ffff, false)

View File

@ -192,7 +192,7 @@ postincrdecr : assign_target operator = ('++' | '--') ;
expression : expression :
'(' expression ')' '(' expression ')'
| functioncall | functioncall
| <assoc=right> prefix = ('+'|'-'|'~') expression | <assoc=right> prefix = ('+'|'-'|'~'|'^'|'<<') expression
| left = expression EOL? bop = ('*' | '/' | '%' ) EOL? right = expression | left = expression EOL? bop = ('*' | '/' | '%' ) EOL? right = expression
| left = expression EOL? bop = ('+' | '-' ) EOL? right = expression | left = expression EOL? bop = ('+' | '-' ) EOL? right = expression
| left = expression EOL? bop = ('<<' | '>>' ) EOL? right = expression | left = expression EOL? bop = ('<<' | '>>' ) EOL? right = expression