mirror of
https://github.com/irmen/prog8.git
synced 2024-08-11 21:29:03 +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:
|
if self.constant:
|
||||||
return False, "cannot assign to a constant"
|
return False, "cannot assign to a constant"
|
||||||
if isinstance(other, IndirectValue):
|
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 self.datatype == DataType.BYTE:
|
||||||
if isinstance(other, (IntegerValue, RegisterValue, MemMappedValue)):
|
if isinstance(other, (IntegerValue, RegisterValue, MemMappedValue)):
|
||||||
if other.datatype == DataType.BYTE:
|
if other.datatype == DataType.BYTE:
|
||||||
|
@ -395,13 +395,9 @@ class CodeGenerator:
|
|||||||
self.previous_stmt_was_assignment = isinstance(stmt, AssignmentStmt)
|
self.previous_stmt_was_assignment = isinstance(stmt, AssignmentStmt)
|
||||||
|
|
||||||
def generate_incr_or_decr(self, stmt: Union[InplaceIncrStmt, InplaceDecrStmt]) -> None:
|
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
|
assert stmt.howmuch > 0
|
||||||
if stmt.howmuch > 0xff:
|
if stmt.what.datatype != DataType.FLOAT and stmt.howmuch > 0xff:
|
||||||
raise CodeError("only supports incr/decr by up to 255 for now") # XXX
|
raise CodeError("only supports integer incr/decr by up to 255 for now") # XXX
|
||||||
is_incr = isinstance(stmt, InplaceIncrStmt)
|
is_incr = isinstance(stmt, InplaceIncrStmt)
|
||||||
if isinstance(stmt.what, RegisterValue):
|
if isinstance(stmt.what, RegisterValue):
|
||||||
reg = stmt.what.register
|
reg = stmt.what.register
|
||||||
@ -564,8 +560,20 @@ class CodeGenerator:
|
|||||||
self.p("\t\tbcs +")
|
self.p("\t\tbcs +")
|
||||||
self.p("\t\tdec {:s}+1".format(r_str))
|
self.p("\t\tdec {:s}+1".format(r_str))
|
||||||
self.p("+\t\tpla")
|
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:
|
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:
|
else:
|
||||||
raise CodeError("cannot in/decrement " + str(stmt.what))
|
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:
|
if datatype in (DataType.BYTE, DataType.WORD, DataType.MATRIX) and type(value) is float:
|
||||||
frac = math.modf(value) # type:ignore
|
frac = math.modf(value) # type:ignore
|
||||||
if frac != 0:
|
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 True, int(value)
|
||||||
return False, value
|
return False, value
|
||||||
|
|
||||||
@ -1333,7 +1333,8 @@ class Optimizer:
|
|||||||
def remove_unused_subroutines(self, block: Block) -> None:
|
def remove_unused_subroutines(self, block: Block) -> None:
|
||||||
# some symbols are used by the emitted assembly code from the code generator,
|
# some symbols are used by the emitted assembly code from the code generator,
|
||||||
# and should never be removed or the assembler will fail
|
# 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 = []
|
discarded = []
|
||||||
for sub in list(block.symbols.iter_subroutines()):
|
for sub in list(block.symbols.iter_subroutines()):
|
||||||
usages = self.parsed.subroutine_usage[(sub.blockname, sub.name)]
|
usages = self.parsed.subroutine_usage[(sub.blockname, sub.name)]
|
||||||
|
@ -121,4 +121,35 @@ copy_mflt stx SCRATCH_ZP1
|
|||||||
ldy SCRATCH_ZPWORD1+1
|
ldy SCRATCH_ZPWORD1+1
|
||||||
rts
|
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"
|
import "c64lib"
|
||||||
|
|
||||||
~ main {
|
~ main {
|
||||||
|
|
||||||
|
var .float float1 = 123.456
|
||||||
start
|
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
|
A = $11
|
||||||
X = $22
|
X = $22
|
||||||
Y = $33
|
Y = $33
|
||||||
|
Loading…
Reference in New Issue
Block a user