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)
|
val rightCv = expr.right.constValue(program)
|
||||||
|
|
||||||
if(leftDt.isKnown && rightDt.isKnown) {
|
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) {
|
if(expr.operator in LogicalOperators && leftDt.isInteger && rightDt.isInteger) {
|
||||||
// see if any of the operands needs conversion to bool
|
// see if any of the operands needs conversion to bool
|
||||||
val modifications = mutableListOf<IAstModification>()
|
val modifications = mutableListOf<IAstModification>()
|
||||||
|
@ -3,13 +3,19 @@ package prog8tests.ast
|
|||||||
import io.kotest.core.spec.style.FunSpec
|
import io.kotest.core.spec.style.FunSpec
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import io.kotest.matchers.shouldNotBe
|
import io.kotest.matchers.shouldNotBe
|
||||||
|
import io.kotest.matchers.types.instanceOf
|
||||||
import prog8.ast.IFunctionCall
|
import prog8.ast.IFunctionCall
|
||||||
|
import prog8.ast.expressions.BinaryExpression
|
||||||
import prog8.ast.expressions.IdentifierReference
|
import prog8.ast.expressions.IdentifierReference
|
||||||
|
import prog8.ast.expressions.NumericLiteral
|
||||||
import prog8.ast.expressions.StringLiteral
|
import prog8.ast.expressions.StringLiteral
|
||||||
|
import prog8.ast.statements.Assignment
|
||||||
import prog8.ast.statements.InlineAssembly
|
import prog8.ast.statements.InlineAssembly
|
||||||
import prog8.ast.statements.VarDecl
|
import prog8.ast.statements.VarDecl
|
||||||
|
import prog8.code.core.DataType
|
||||||
import prog8.code.core.Position
|
import prog8.code.core.Position
|
||||||
import prog8.code.target.C64Target
|
import prog8.code.target.C64Target
|
||||||
|
import prog8.compiler.printProgram
|
||||||
import prog8tests.helpers.compileText
|
import prog8tests.helpers.compileText
|
||||||
|
|
||||||
class TestVarious: FunSpec({
|
class TestVarious: FunSpec({
|
||||||
@ -129,5 +135,31 @@ main {
|
|||||||
}"""
|
}"""
|
||||||
compileText(C64Target(), optimize=false, src, writeAssembly=false) shouldNotBe null
|
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
|
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
|
- ir/vm: allow label in block scope
|
||||||
- regression test the various projects
|
- 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)
|
- 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() {
|
sub start() {
|
||||||
|
|
||||||
internalstart:
|
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.print_uwhex(start, true)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
txt.print_uwhex(alsostart, true)
|
txt.print_uwhex(alsostart, true)
|
||||||
|
Loading…
Reference in New Issue
Block a user