mirror of
https://github.com/irmen/prog8.git
synced 2024-07-13 12:29:05 +00:00
float incr/decr by 1
This commit is contained in:
parent
3b0d6e969b
commit
3dcfa42574
@ -307,7 +307,9 @@ class MemMappedValue(Value):
|
||||
if self.constant:
|
||||
return False, "cannot assign to a constant"
|
||||
if isinstance(other, IndirectValue):
|
||||
return False, "can not yet assign memory mapped value from indirect value" # @todo indirect v assign
|
||||
if self.datatype == other.datatype:
|
||||
return True, ""
|
||||
return False, "data type of value and target are not the same"
|
||||
if self.datatype == DataType.BYTE:
|
||||
if isinstance(other, (IntegerValue, RegisterValue, MemMappedValue)):
|
||||
if other.datatype == DataType.BYTE:
|
||||
|
@ -395,13 +395,9 @@ class CodeGenerator:
|
||||
self.previous_stmt_was_assignment = isinstance(stmt, AssignmentStmt)
|
||||
|
||||
def generate_incr_or_decr(self, stmt: Union[InplaceIncrStmt, InplaceDecrStmt]) -> None:
|
||||
if stmt.what.datatype == DataType.FLOAT:
|
||||
raise CodeError("incr/decr on float not yet supported") # @todo support incr/decr on float
|
||||
else:
|
||||
assert type(stmt.howmuch) is int
|
||||
assert stmt.howmuch > 0
|
||||
if stmt.howmuch > 0xff:
|
||||
raise CodeError("only supports incr/decr by up to 255 for now") # XXX
|
||||
if stmt.what.datatype != DataType.FLOAT and stmt.howmuch > 0xff:
|
||||
raise CodeError("only supports integer incr/decr by up to 255 for now") # XXX
|
||||
is_incr = isinstance(stmt, InplaceIncrStmt)
|
||||
if isinstance(stmt.what, RegisterValue):
|
||||
reg = stmt.what.register
|
||||
@ -564,8 +560,20 @@ class CodeGenerator:
|
||||
self.p("\t\tbcs +")
|
||||
self.p("\t\tdec {:s}+1".format(r_str))
|
||||
self.p("+\t\tpla")
|
||||
elif what.datatype == DataType.FLOAT:
|
||||
if stmt.howmuch == 1.0:
|
||||
t_str = stmt.what.name or Parser.to_hex(stmt.what.address)
|
||||
with self.preserving_registers({'A', 'X', 'Y'}, loads_a_within=True):
|
||||
self.p("\t\t ldx #<" + t_str)
|
||||
self.p("\t\t ldy #>" + t_str)
|
||||
if is_incr:
|
||||
self.p("\t\t jsr il65_lib.float_add_one")
|
||||
else:
|
||||
self.p("\t\t jsr il65_lib.float_sub_one")
|
||||
else:
|
||||
raise CodeError("cannot incr/decr float by other than 1 at this time", stmt.howmuch) # XXX
|
||||
else:
|
||||
raise CodeError("cannot in/decrement memory of type " + str(what.datatype))
|
||||
raise CodeError("cannot in/decrement memory of type " + str(what.datatype), stmt.howmuch)
|
||||
else:
|
||||
raise CodeError("cannot in/decrement " + str(stmt.what))
|
||||
|
||||
|
@ -1163,7 +1163,7 @@ class Parser:
|
||||
if datatype in (DataType.BYTE, DataType.WORD, DataType.MATRIX) and type(value) is float:
|
||||
frac = math.modf(value) # type:ignore
|
||||
if frac != 0:
|
||||
self.print_warning("float value truncated")
|
||||
self.print_warning("float value truncated ({} to datatype {})".format(value, datatype.name))
|
||||
return True, int(value)
|
||||
return False, value
|
||||
|
||||
@ -1333,7 +1333,8 @@ class Optimizer:
|
||||
def remove_unused_subroutines(self, block: Block) -> None:
|
||||
# some symbols are used by the emitted assembly code from the code generator,
|
||||
# and should never be removed or the assembler will fail
|
||||
never_remove = {"c64.GIVUAYF", "c64.FREADUY", "c64.FTOMEMXY"}
|
||||
# @todo make this dynamic
|
||||
never_remove = {"c64.GIVUAYF", "c64.FREADUY", "c64.FTOMEMXY", "c64.FADD", "c64.FSUB"}
|
||||
discarded = []
|
||||
for sub in list(block.symbols.iter_subroutines()):
|
||||
usages = self.parsed.subroutine_usage[(sub.blockname, sub.name)]
|
||||
|
@ -121,4 +121,35 @@ copy_mflt stx SCRATCH_ZP1
|
||||
ldy SCRATCH_ZPWORD1+1
|
||||
rts
|
||||
}
|
||||
|
||||
asm {
|
||||
|
||||
; ---- add 1 to the MFLT pointed to by X/Y. Clobbers A, X, Y
|
||||
float_add_one
|
||||
stx SCRATCH_ZP1
|
||||
sty SCRATCH_ZP2
|
||||
txa
|
||||
jsr c64.MOVFM ; fac1 = float XY
|
||||
lda #<c64.FL_FONE
|
||||
ldy #>c64.FL_FONE
|
||||
jsr c64.FADD ; fac1 += 1
|
||||
ldx SCRATCH_ZP1
|
||||
ldy SCRATCH_ZP2
|
||||
jmp c64.FTOMEMXY ; float XY = fac1
|
||||
|
||||
; ---- subtract 1 from the MFLT pointed to by X/Y. Clobbers A, X, Y
|
||||
float_sub_one
|
||||
stx SCRATCH_ZP1
|
||||
sty SCRATCH_ZP2
|
||||
lda #<c64.FL_FONE
|
||||
ldy #>c64.FL_FONE
|
||||
jsr c64.MOVFM ; fac1 = 1
|
||||
txa
|
||||
ldy SCRATCH_ZP2
|
||||
jsr c64.FSUB ; fac1 = float XY - 1
|
||||
ldx SCRATCH_ZP1
|
||||
ldy SCRATCH_ZP2
|
||||
jmp c64.FTOMEMXY ; float XY = fac1
|
||||
|
||||
}
|
||||
}
|
||||
|
28
todo.ill
28
todo.ill
@ -5,7 +5,35 @@ output prg,basic
|
||||
import "c64lib"
|
||||
|
||||
~ main {
|
||||
|
||||
var .float float1 = 123.456
|
||||
start
|
||||
c64.MOVFM(#float1)
|
||||
c64.FPRINTLN()
|
||||
float1++
|
||||
c64.MOVFM(#float1)
|
||||
c64.FPRINTLN()
|
||||
float1-=1
|
||||
c64.MOVFM(#float1)
|
||||
c64.FPRINTLN()
|
||||
float1--
|
||||
c64.MOVFM(#float1)
|
||||
c64.FPRINTLN()
|
||||
;float1+=0.5
|
||||
;c64.MOVFM(#float1)
|
||||
;c64.FPRINTLN()
|
||||
;float1+=2235.55
|
||||
;c64.MOVFM(#float1)
|
||||
;c64.FPRINTLN()
|
||||
;float1-=999.55
|
||||
;c64.MOVFM(#float1)
|
||||
;c64.FPRINTLN()
|
||||
;float1-=33333.456
|
||||
;c64.MOVFM(#float1)
|
||||
;c64.FPRINTLN()
|
||||
|
||||
return
|
||||
|
||||
A = $11
|
||||
X = $22
|
||||
Y = $33
|
||||
|
Loading…
Reference in New Issue
Block a user