mirror of
https://github.com/irmen/prog8.git
synced 2024-11-28 10:51:14 +00:00
added unary ^ and << operators (experimental) (gets bank and address of a long integer)
This commit is contained in:
parent
d77b1944fb
commit
cb86206698
@ -318,7 +318,7 @@ class PtPrefix(val operator: String, type: DataType, position: Position): PtExpr
|
||||
get() = children.single() as PtExpression
|
||||
|
||||
init {
|
||||
require(operator in setOf("+", "-", "~", "not")) { "invalid prefix operator: $operator" }
|
||||
require(operator in setOf("+", "-", "~", "^", "<<", "not")) { "invalid prefix operator: $operator" }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
val sscope = fcall.definingISub()
|
||||
|
||||
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)
|
||||
"lsb" -> funcLsb(fcall, resultRegister)
|
||||
"mkword" -> funcMkword(fcall, resultRegister)
|
||||
|
@ -536,6 +536,10 @@ internal class AssignmentAsmGen(
|
||||
}
|
||||
}
|
||||
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.source.datatype isAssignableTo assign.target.datatype || (assign.source.datatype==DataType.BOOL && assign.target.datatype in ByteDatatypes)) {
|
||||
if(assign.source.datatype in IntegerDatatypesWithBoolean) {
|
||||
|
@ -19,7 +19,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
"callfar" -> funcCallfar(call)
|
||||
"callfar2" -> funcCallfar2(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)
|
||||
"lsb" -> funcLsb(call)
|
||||
"memory" -> funcMemory(call)
|
||||
|
@ -373,6 +373,8 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
"not" -> {
|
||||
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")
|
||||
}
|
||||
return ExpressionCodeResult(result, vmDt, tr.resultReg, tr.resultFpReg)
|
||||
|
@ -148,6 +148,22 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ import prog8.code.target.encodings.JapaneseCharacterConverter
|
||||
import java.io.CharConversionException
|
||||
import java.util.Objects
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.exp
|
||||
import kotlin.math.floor
|
||||
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 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 converted = when(operator) {
|
||||
"+" -> 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)
|
||||
}
|
||||
"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")
|
||||
}
|
||||
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 inferred
|
||||
}
|
||||
"^" -> InferredTypes.knownFor(DataType.UBYTE)
|
||||
"<<" -> InferredTypes.knownFor(DataType.UWORD)
|
||||
else -> throw FatalAstException("weird prefix expression operator")
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
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?
|
||||
|
||||
-> added unary ^ operator as alternative to bankof()
|
||||
-> added unary << operator as alternative to addr() / lsb(x>>16) / lsw()
|
||||
-> TODO document whatever remains of those!
|
||||
|
||||
...
|
||||
|
||||
|
@ -4,6 +4,20 @@
|
||||
main {
|
||||
sub start() {
|
||||
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.spc()
|
||||
txt.print_uwhex(foo2 &$ffff, false)
|
||||
|
@ -192,7 +192,7 @@ postincrdecr : assign_target operator = ('++' | '--') ;
|
||||
expression :
|
||||
'(' expression ')'
|
||||
| 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
|
||||
|
Loading…
Reference in New Issue
Block a user