mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
make uword xx = 1<<shift into a word shifting
This commit is contained in:
parent
922033c1b2
commit
d8e87bd881
@ -47,6 +47,36 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
||||
val rightCv = expr.right.constValue(program)
|
||||
|
||||
if(leftDt.isKnown && rightDt.isKnown) {
|
||||
|
||||
if(expr.operator=="<<" && leftDt.isBytes) {
|
||||
// uword ww = 1 << shift --> make the '1' a word constant
|
||||
val leftConst = expr.left.constValue(program)
|
||||
if(leftConst!=null) {
|
||||
val leftConstAsWord =
|
||||
if(leftDt.istype(DataType.UBYTE))
|
||||
NumericLiteral(DataType.UWORD, leftConst.number, leftConst.position)
|
||||
else
|
||||
NumericLiteral(DataType.WORD, leftConst.number, leftConst.position)
|
||||
val modifications = mutableListOf<IAstModification>()
|
||||
if (parent is Assignment) {
|
||||
if (parent.target.inferType(program).isWords) {
|
||||
modifications += IAstModification.ReplaceNode(expr.left, leftConstAsWord, expr)
|
||||
if(rightDt.isBytes)
|
||||
modifications += IAstModification.ReplaceNode(expr.right, TypecastExpression(expr.right, leftConstAsWord.type, true, expr.right.position), expr)
|
||||
}
|
||||
} else if (parent is TypecastExpression && parent.type == DataType.UWORD && parent.parent is Assignment) {
|
||||
val assign = parent.parent as Assignment
|
||||
if (assign.target.inferType(program).isWords) {
|
||||
modifications += IAstModification.ReplaceNode(expr.left, leftConstAsWord, expr)
|
||||
if(rightDt.isBytes)
|
||||
modifications += IAstModification.ReplaceNode(expr.right, TypecastExpression(expr.right, leftConstAsWord.type, true, expr.right.position), expr)
|
||||
}
|
||||
}
|
||||
if(modifications.isNotEmpty())
|
||||
return modifications
|
||||
}
|
||||
}
|
||||
|
||||
if(expr.operator in LogicalOperators && leftDt.isInteger && rightDt.isInteger) {
|
||||
// see if any of the operands needs conversion to bool
|
||||
val modifications = mutableListOf<IAstModification>()
|
||||
|
@ -3,13 +3,19 @@ package prog8tests.ast
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.shouldNotBe
|
||||
import io.kotest.matchers.types.instanceOf
|
||||
import prog8.ast.IFunctionCall
|
||||
import prog8.ast.expressions.BinaryExpression
|
||||
import prog8.ast.expressions.IdentifierReference
|
||||
import prog8.ast.expressions.NumericLiteral
|
||||
import prog8.ast.expressions.StringLiteral
|
||||
import prog8.ast.statements.Assignment
|
||||
import prog8.ast.statements.InlineAssembly
|
||||
import prog8.ast.statements.VarDecl
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.Position
|
||||
import prog8.code.target.C64Target
|
||||
import prog8.compiler.printProgram
|
||||
import prog8tests.helpers.compileText
|
||||
|
||||
class TestVarious: FunSpec({
|
||||
@ -129,5 +135,31 @@ main {
|
||||
}"""
|
||||
compileText(C64Target(), optimize=false, src, writeAssembly=false) shouldNotBe null
|
||||
}
|
||||
|
||||
test("bitshift left of const byte converted to word") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
ubyte shift = 10
|
||||
uword value = 1<<shift
|
||||
value++
|
||||
value = 1<<shift
|
||||
value++
|
||||
}
|
||||
}"""
|
||||
val result = compileText(C64Target(), optimize=false, src, writeAssembly=false)!!
|
||||
printProgram(result.program)
|
||||
val stmts = result.program.entrypoint.statements
|
||||
stmts.size shouldBe 7
|
||||
val assign1expr = (stmts[3] as Assignment).value as BinaryExpression
|
||||
val assign2expr = (stmts[5] as Assignment).value as BinaryExpression
|
||||
assign1expr.operator shouldBe "<<"
|
||||
val leftval1 = assign1expr.left.constValue(result.program)!!
|
||||
leftval1.type shouldBe DataType.UWORD
|
||||
leftval1.number shouldBe 1.0
|
||||
val leftval2 = assign2expr.left.constValue(result.program)!!
|
||||
leftval2.type shouldBe DataType.UWORD
|
||||
leftval2.number shouldBe 1.0
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -3,7 +3,6 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- make it so that uword xx = <byte constant> <op> expr is treated as <word constant> <op> <expr> instead (or inverse order)
|
||||
- ir/vm: allow label in block scope
|
||||
- regression test the various projects
|
||||
- 6502 codegen: make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``p8v_``? Or not worth it (most 3 letter opcodes as variables are nonsensical anyway)
|
||||
|
@ -7,6 +7,16 @@ alsostart:
|
||||
sub start() {
|
||||
|
||||
internalstart:
|
||||
ubyte fact = 10
|
||||
uword ww = 1<<fact
|
||||
txt.print_uw(ww)
|
||||
txt.nl()
|
||||
ww++
|
||||
ww = 1<<fact
|
||||
txt.print_uw(ww)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
|
||||
txt.print_uwhex(start, true)
|
||||
txt.nl()
|
||||
txt.print_uwhex(alsostart, true)
|
||||
|
Loading…
Reference in New Issue
Block a user