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
|
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" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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!
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user