mirror of
https://github.com/irmen/prog8.git
synced 2025-02-19 11:31:07 +00:00
fixes
This commit is contained in:
parent
4dc214199f
commit
890fcffdfa
@ -58,6 +58,9 @@ def generate_aug_assignment(ctx: Context) -> None:
|
|||||||
raise CodeError("cannot assign a combined 16-bit register to a single 8-bit register", rvalue)
|
raise CodeError("cannot assign a combined 16-bit register to a single 8-bit register", rvalue)
|
||||||
_generate_aug_reg_reg(out, lvalue, stmt.operator, rvalue, ctx.scope)
|
_generate_aug_reg_reg(out, lvalue, stmt.operator, rvalue, ctx.scope)
|
||||||
elif isinstance(rvalue, Dereference):
|
elif isinstance(rvalue, Dereference):
|
||||||
|
print("warning: {}: using indirect/dereferece is very costly".format(rvalue.sourceref))
|
||||||
|
if rvalue.datatype != DataType.BYTE:
|
||||||
|
raise CodeError("aug. assignment value must be a byte, 0..255", rvalue)
|
||||||
if isinstance(rvalue.operand, (LiteralValue, SymbolName)):
|
if isinstance(rvalue.operand, (LiteralValue, SymbolName)):
|
||||||
if isinstance(rvalue.operand, LiteralValue):
|
if isinstance(rvalue.operand, LiteralValue):
|
||||||
what = to_hex(rvalue.operand.value)
|
what = to_hex(rvalue.operand.value)
|
||||||
@ -75,14 +78,22 @@ def generate_aug_assignment(ctx: Context) -> None:
|
|||||||
out("\vldy #0")
|
out("\vldy #0")
|
||||||
out("\vlda (il65_lib.SCRATCH_ZPWORD1), y")
|
out("\vlda (il65_lib.SCRATCH_ZPWORD1), y")
|
||||||
a_reg = Register(name="A", sourceref=stmt.sourceref) # type: ignore
|
a_reg = Register(name="A", sourceref=stmt.sourceref) # type: ignore
|
||||||
|
if 'A' in lvalue.name:
|
||||||
|
raise CodeError("can't yet use register A in this aug assign lhs", lvalue.sourceref) # @todo
|
||||||
_generate_aug_reg_reg(out, lvalue, stmt.operator, a_reg, ctx.scope)
|
_generate_aug_reg_reg(out, lvalue, stmt.operator, a_reg, ctx.scope)
|
||||||
out("\vst{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
if lvalue.name in REGISTER_BYTES:
|
||||||
|
out("\vst{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
||||||
|
else:
|
||||||
|
out("\vst{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name[0].lower()))
|
||||||
|
out("\vst{:s} il65_lib.SCRATCH_ZP2".format(lvalue.name[1].lower()))
|
||||||
out("\vpla\n\vtay\n\vpla") # restore A, Y from stack
|
out("\vpla\n\vtay\n\vpla") # restore A, Y from stack
|
||||||
out("\vld{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
if lvalue.name in REGISTER_BYTES:
|
||||||
|
out("\vld{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
||||||
|
else:
|
||||||
|
out("\vld{:s} il65_lib.SCRATCH_ZP2".format(lvalue.name[0].lower()))
|
||||||
|
out("\vld{:s} il65_lib.SCRATCH_ZP2".format(lvalue.name[1].lower()))
|
||||||
elif isinstance(rvalue.operand, Register):
|
elif isinstance(rvalue.operand, Register):
|
||||||
assert rvalue.operand.datatype == DataType.WORD
|
assert rvalue.operand.datatype == DataType.WORD
|
||||||
if rvalue.datatype != DataType.BYTE:
|
|
||||||
raise CodeError("aug. assignment value must be a byte, 0..255", rvalue)
|
|
||||||
reg = rvalue.operand.name
|
reg = rvalue.operand.name
|
||||||
out("\vst{:s} il65_lib.SCRATCH_ZPWORD1".format(reg[0].lower()))
|
out("\vst{:s} il65_lib.SCRATCH_ZPWORD1".format(reg[0].lower()))
|
||||||
out("\vst{:s} il65_lib.SCRATCH_ZPWORD1+1".format(reg[1].lower()))
|
out("\vst{:s} il65_lib.SCRATCH_ZPWORD1+1".format(reg[1].lower()))
|
||||||
@ -90,12 +101,22 @@ def generate_aug_assignment(ctx: Context) -> None:
|
|||||||
out("\vldy #0")
|
out("\vldy #0")
|
||||||
out("\vlda (il65_lib.SCRATCH_ZPWORD1), y")
|
out("\vlda (il65_lib.SCRATCH_ZPWORD1), y")
|
||||||
a_reg = Register(name="A", sourceref=stmt.sourceref) # type: ignore
|
a_reg = Register(name="A", sourceref=stmt.sourceref) # type: ignore
|
||||||
|
if 'A' in lvalue.name:
|
||||||
|
raise CodeError("can't yet use register A in this aug assign lhs", lvalue.sourceref) # @todo
|
||||||
_generate_aug_reg_reg(out, lvalue, stmt.operator, a_reg, ctx.scope)
|
_generate_aug_reg_reg(out, lvalue, stmt.operator, a_reg, ctx.scope)
|
||||||
if lvalue.name != 'X':
|
if lvalue.name != 'X':
|
||||||
out("\vst{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
if lvalue.name in REGISTER_BYTES:
|
||||||
|
out("\vst{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
||||||
|
else:
|
||||||
|
out("\vst{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name[0].lower()))
|
||||||
|
out("\vst{:s} il65_lib.SCRATCH_ZP2".format(lvalue.name[1].lower()))
|
||||||
out("\vpla\n\vtay\n\vpla") # restore A, Y from stack
|
out("\vpla\n\vtay\n\vpla") # restore A, Y from stack
|
||||||
if lvalue.name != 'X':
|
if lvalue.name != 'X':
|
||||||
out("\vld{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
if lvalue.name in REGISTER_BYTES:
|
||||||
|
out("\vld{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
||||||
|
else:
|
||||||
|
out("\vld{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name[0].lower()))
|
||||||
|
out("\vld{:s} il65_lib.SCRATCH_ZP2".format(lvalue.name[1].lower()))
|
||||||
else:
|
else:
|
||||||
raise CodeError("invalid dereference operand type", rvalue)
|
raise CodeError("invalid dereference operand type", rvalue)
|
||||||
else:
|
else:
|
||||||
@ -109,7 +130,7 @@ def _generate_aug_reg_int(out: Callable, lvalue: Register, operator: str, rvalue
|
|||||||
right_str = rname
|
right_str = rname
|
||||||
else:
|
else:
|
||||||
# an immediate value is provided in rvalue
|
# an immediate value is provided in rvalue
|
||||||
right_str = "#" + to_hex(rvalue)
|
right_str = "#" + str(rvalue)
|
||||||
if operator == "+=":
|
if operator == "+=":
|
||||||
_gen_aug_plus_reg_int(lvalue, out, right_str, scope)
|
_gen_aug_plus_reg_int(lvalue, out, right_str, scope)
|
||||||
elif operator == "-=":
|
elif operator == "-=":
|
||||||
@ -125,7 +146,8 @@ def _generate_aug_reg_int(out: Callable, lvalue: Register, operator: str, rvalue
|
|||||||
elif operator == "<<=":
|
elif operator == "<<=":
|
||||||
_gen_aug_shiftleft_reg_int(lvalue, out, rname, rvalue, scope)
|
_gen_aug_shiftleft_reg_int(lvalue, out, rname, rvalue, scope)
|
||||||
else:
|
else:
|
||||||
raise ValueError("invalid operator", operator)
|
# @todo implement more operators such as *= /=
|
||||||
|
raise ValueError("invalid operator: " + operator, str(lvalue.sourceref))
|
||||||
|
|
||||||
|
|
||||||
def _generate_aug_reg_reg(out: Callable, lvalue: Register, operator: str, rvalue: Register, scope: Scope) -> None:
|
def _generate_aug_reg_reg(out: Callable, lvalue: Register, operator: str, rvalue: Register, scope: Scope) -> None:
|
||||||
@ -144,7 +166,8 @@ def _generate_aug_reg_reg(out: Callable, lvalue: Register, operator: str, rvalue
|
|||||||
elif operator == "<<=":
|
elif operator == "<<=":
|
||||||
_gen_aug_shiftleft_reg_reg(lvalue, out, rvalue, scope)
|
_gen_aug_shiftleft_reg_reg(lvalue, out, rvalue, scope)
|
||||||
else:
|
else:
|
||||||
raise ValueError("invalid operator", operator)
|
# @todo implement more operators such as *= /=
|
||||||
|
raise ValueError("invalid operator: " + operator, str(lvalue.sourceref))
|
||||||
|
|
||||||
|
|
||||||
def _gen_aug_shiftleft_reg_int(lvalue: Register, out: Callable, rname: str, rvalue: int, scope: Scope) -> None:
|
def _gen_aug_shiftleft_reg_int(lvalue: Register, out: Callable, rname: str, rvalue: int, scope: Scope) -> None:
|
||||||
@ -304,8 +327,29 @@ def _gen_aug_minus_reg_int(lvalue: Register, out: Callable, right_str: str, scop
|
|||||||
out("\vsec")
|
out("\vsec")
|
||||||
out("\vsbc " + right_str)
|
out("\vsbc " + right_str)
|
||||||
out("\vtay")
|
out("\vtay")
|
||||||
|
elif lvalue.name == "AX":
|
||||||
|
out("\vsec")
|
||||||
|
out("\vsbc " + right_str)
|
||||||
|
out("\vbcs +")
|
||||||
|
out("\vdex")
|
||||||
|
out("+")
|
||||||
|
elif lvalue.name == "AY":
|
||||||
|
out("\vsec")
|
||||||
|
out("\vsbc " + right_str)
|
||||||
|
out("\vbcs +")
|
||||||
|
out("\vdey")
|
||||||
|
out("+")
|
||||||
|
elif lvalue.name == "XY":
|
||||||
|
with preserving_registers({'A'}, scope, out):
|
||||||
|
out("\vtxa")
|
||||||
|
out("\vsec")
|
||||||
|
out("\vsbc " + right_str)
|
||||||
|
out("\vtax")
|
||||||
|
out("\vbcs +")
|
||||||
|
out("\vdey")
|
||||||
|
out("+")
|
||||||
else:
|
else:
|
||||||
raise CodeError("unsupported register for aug assign", str(lvalue)) # @todo -=.word
|
raise ValueError("invalid register", str(lvalue))
|
||||||
|
|
||||||
|
|
||||||
def _gen_aug_plus_reg_int(lvalue: Register, out: Callable, right_str: str, scope: Scope) -> None:
|
def _gen_aug_plus_reg_int(lvalue: Register, out: Callable, right_str: str, scope: Scope) -> None:
|
||||||
@ -324,8 +368,29 @@ def _gen_aug_plus_reg_int(lvalue: Register, out: Callable, right_str: str, scope
|
|||||||
out("\vclc")
|
out("\vclc")
|
||||||
out("\vadc " + right_str)
|
out("\vadc " + right_str)
|
||||||
out("\vtay")
|
out("\vtay")
|
||||||
|
elif lvalue.name == "AX":
|
||||||
|
out("\vclc")
|
||||||
|
out("\vadc " + right_str)
|
||||||
|
out("\vbcc +")
|
||||||
|
out("\vinx")
|
||||||
|
out("+")
|
||||||
|
elif lvalue.name == "AY":
|
||||||
|
out("\vclc")
|
||||||
|
out("\vadc " + right_str)
|
||||||
|
out("\vbcc +")
|
||||||
|
out("\viny")
|
||||||
|
out("+")
|
||||||
|
elif lvalue.name == "XY":
|
||||||
|
with preserving_registers({'A'}, scope, out):
|
||||||
|
out("\vtxa")
|
||||||
|
out("\vclc")
|
||||||
|
out("\vadc " + right_str)
|
||||||
|
out("\vtax")
|
||||||
|
out("\vbcc +")
|
||||||
|
out("\viny")
|
||||||
|
out("+")
|
||||||
else:
|
else:
|
||||||
raise CodeError("unsupported register for aug assign", str(lvalue)) # @todo +=.word
|
raise ValueError("invalid register", str(lvalue))
|
||||||
|
|
||||||
|
|
||||||
def _gen_aug_shiftleft_reg_reg(lvalue: Register, out: Callable, rvalue: Register, scope: Scope) -> None:
|
def _gen_aug_shiftleft_reg_reg(lvalue: Register, out: Callable, rvalue: Register, scope: Scope) -> None:
|
||||||
@ -466,23 +531,42 @@ def _gen_aug_minus_reg_reg(lvalue: Register, out: Callable, rvalue: Register, sc
|
|||||||
def _gen_aug_plus_reg_reg(lvalue: Register, out: Callable, rvalue: Register, scope: Scope) -> None:
|
def _gen_aug_plus_reg_reg(lvalue: Register, out: Callable, rvalue: Register, scope: Scope) -> None:
|
||||||
if rvalue.name not in REGISTER_BYTES:
|
if rvalue.name not in REGISTER_BYTES:
|
||||||
raise CodeError("unsupported rvalue register for aug assign", str(rvalue)) # @todo +=.word
|
raise CodeError("unsupported rvalue register for aug assign", str(rvalue)) # @todo +=.word
|
||||||
|
out("\vst{:s} {:s}".format(rvalue.name.lower(), to_hex(Zeropage.SCRATCH_B1)))
|
||||||
if lvalue.name == "A":
|
if lvalue.name == "A":
|
||||||
out("\vst{:s} {:s}".format(rvalue.name.lower(), to_hex(Zeropage.SCRATCH_B1)))
|
|
||||||
out("\vclc")
|
out("\vclc")
|
||||||
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
||||||
elif lvalue.name == "X":
|
elif lvalue.name == "X":
|
||||||
out("\vst{:s} {:s}".format(rvalue.name.lower(), to_hex(Zeropage.SCRATCH_B1)))
|
|
||||||
with preserving_registers({'A'}, scope, out):
|
with preserving_registers({'A'}, scope, out):
|
||||||
out("\vtxa")
|
out("\vtxa")
|
||||||
out("\vclc")
|
out("\vclc")
|
||||||
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
||||||
out("\vtax")
|
out("\vtax")
|
||||||
elif lvalue.name == "Y":
|
elif lvalue.name == "Y":
|
||||||
out("\vst{:s} {:s}".format(rvalue.name.lower(), to_hex(Zeropage.SCRATCH_B1)))
|
|
||||||
with preserving_registers({'A'}, scope, out):
|
with preserving_registers({'A'}, scope, out):
|
||||||
out("\vtya")
|
out("\vtya")
|
||||||
out("\vclc")
|
out("\vclc")
|
||||||
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
||||||
out("\vtay")
|
out("\vtay")
|
||||||
|
elif lvalue.name == "AX":
|
||||||
|
out("\vclc")
|
||||||
|
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
||||||
|
out("\vbcc +")
|
||||||
|
out("\vinx")
|
||||||
|
out("+")
|
||||||
|
elif lvalue.name == "AY":
|
||||||
|
out("\vclc")
|
||||||
|
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
||||||
|
out("\vbcc +")
|
||||||
|
out("\viny")
|
||||||
|
out("+")
|
||||||
|
elif lvalue.name == "XY":
|
||||||
|
with preserving_registers({'A'}, scope, out):
|
||||||
|
out("\vtxa")
|
||||||
|
out("\vclc")
|
||||||
|
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
||||||
|
out("\vtax")
|
||||||
|
out("\vbcc +")
|
||||||
|
out("\viny")
|
||||||
|
out("+")
|
||||||
else:
|
else:
|
||||||
raise CodeError("unsupported lvalue register for aug assign", str(lvalue)) # @todo +=.word
|
raise ValueError("invalid register", str(lvalue))
|
||||||
|
9
todo.ill
9
todo.ill
@ -3,11 +3,10 @@
|
|||||||
|
|
||||||
~ main {
|
~ main {
|
||||||
|
|
||||||
;var .float flt
|
var .float flt
|
||||||
; var bytevar = 22 + 23 ; @todo constant-fold before semantic check
|
var bytevar = 22 + 23 ; @todo bytevar in source should show its initial value in a comment
|
||||||
; var .float initfloat1 = -1.234e-14 ; @todo constant-fold before semantic check / fix float parse?
|
var .text guess1 = "?X" * 40 ; @todo constant-fold before semantic check
|
||||||
; var .float initfloat2 = -555.666 ; @todo constant-fold before semantic check / fix float parse?
|
var .text guess2 = "?" * 40 ; @todo string result instead of int!
|
||||||
; var .text guess = '?' * 80 ; @todo constant-fold before semantic check
|
|
||||||
const .word border = $d020
|
const .word border = $d020
|
||||||
var .word border2 = $d020
|
var .word border2 = $d020
|
||||||
memory screenm = $d021
|
memory screenm = $d021
|
||||||
|
50
todo2.ill
50
todo2.ill
@ -39,11 +39,11 @@ start:
|
|||||||
|
|
||||||
X += border
|
X += border
|
||||||
XY += border ; @todo .word augassign register
|
XY += border ; @todo .word augassign register
|
||||||
XY -= 1234+333 ; @todo .word augassign register
|
XY -= 234+3 ; @todo .word augassign register
|
||||||
|
|
||||||
A += [c2f]
|
X += [c2f]
|
||||||
AY += [c2f]
|
XY += [c2f]
|
||||||
AY += [XY]
|
Y += [XY]
|
||||||
|
|
||||||
XY+=255
|
XY+=255
|
||||||
XY+=254
|
XY+=254
|
||||||
@ -53,21 +53,21 @@ start:
|
|||||||
XY-=253
|
XY-=253
|
||||||
|
|
||||||
v3t++
|
v3t++
|
||||||
v3t+=1
|
;v3t+=1 ; @todo non-reg augassign
|
||||||
v3t+=1 ; @todo? (optimize) join with previous
|
;v3t+=1 ; @todo? (optimize) join with previous
|
||||||
v3t+=0 ; is removed.
|
;v3t+=0 ; is removed by optimizer
|
||||||
v3t+=1 ; @todo? (optimize) join with previous
|
;v3t+=1 ; @todo? (optimize) join with previous
|
||||||
v3t+=1 ; @todo? (optimize) join with previous
|
;v3t+=1 ; @todo? (optimize) join with previous
|
||||||
v3t=2.23424 ; @todo store as constant float with generated name, replace value node
|
;v3t=2.23424 ; @todo store as constant float with generated name, replace value node
|
||||||
v3t=2.23411 ; @todo store as constant float with generated name, replace value node
|
;v3t=2.23411 ; @todo store as constant float with generated name, replace value node
|
||||||
v3t=1.23411 + 1; @todo store as constant float with generated name, replace value node
|
;v3t=1.23411 + 1; @todo store as constant float with generated name, replace value node
|
||||||
v3t+=2.23424 ; @todo store as constant float with generated name, replace value node
|
;v3t+=2.23424 ; @todo store as constant float with generated name, replace value node
|
||||||
v3t+=2.23424 ; @todo store as constant float with generated name, replace value node
|
;v3t+=2.23424 ; @todo store as constant float with generated name, replace value node
|
||||||
v3t+=2.23411 ; @todo store as constant float with generated name, replace value node
|
;v3t+=2.23411 ; @todo store as constant float with generated name, replace value node
|
||||||
v3t+=2.23411 ; @todo store as constant float with generated name, replace value node
|
;v3t+=2.23411 ; @todo store as constant float with generated name, replace value node
|
||||||
v3t=2.23424 * v3t ; @todo store as constant float with generated name, replace value node
|
;v3t=2.23424 * v3t ; @todo store as constant float with generated name, replace value node
|
||||||
XY*=2
|
;XY*=2 ; @todo operator
|
||||||
XY*=3
|
;XY*=3 ; @todo operator
|
||||||
X=3 ; @todo optimize consecutive assignments
|
X=3 ; @todo optimize consecutive assignments
|
||||||
X=4
|
X=4
|
||||||
X=5
|
X=5
|
||||||
@ -83,11 +83,11 @@ start:
|
|||||||
border = 1
|
border = 1
|
||||||
border = 2
|
border = 2
|
||||||
|
|
||||||
XY=XY/0 ; @todo zerodiv (during expression to code generation)
|
;XY=XY/0 ; @todo zerodiv (during expression to code generation) @todo operator
|
||||||
XY=XY//0 ; @todo zerodiv (during expression to code generation)
|
;XY=XY//0 ; @todo zerodiv (during expression to code generation) @todo operator
|
||||||
XY*=2.23424 ; @todo store as constant float with generated name, replace value node
|
;XY*=2.23424 ; @todo store as constant float with generated name, replace value node @todo operator
|
||||||
XY*=2.23424 * v3t ; @todo store as constant float with generated name, replace value node
|
;XY*=2.23424 * v3t ; @todo store as constant float with generated name, replace value node @todo operator
|
||||||
v3t*=2.23424 * v3t ; @todo store as constant float with generated name, replace value node
|
;v3t*=2.23424 * v3t ; @todo store as constant float with generated name, replace value node @todo operator, non-register
|
||||||
A++
|
A++
|
||||||
X--
|
X--
|
||||||
A+=1
|
A+=1
|
||||||
@ -104,7 +104,7 @@ start:
|
|||||||
A+=3
|
A+=3
|
||||||
XY+=6
|
XY+=6
|
||||||
XY+=222
|
XY+=222
|
||||||
XY+=666
|
XY+=11
|
||||||
|
|
||||||
return 44
|
return 44
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user