mirror of
https://github.com/irmen/prog8.git
synced 2024-08-17 02:28:56 +00:00
got rid of multi-assignments
This commit is contained in:
parent
de3bca0763
commit
920b6ca51e
@ -37,7 +37,6 @@ class PlyParser:
|
|||||||
module.scope.define_builtin_functions()
|
module.scope.define_builtin_functions()
|
||||||
self.process_imports(module)
|
self.process_imports(module)
|
||||||
self.check_and_merge_zeropages(module)
|
self.check_and_merge_zeropages(module)
|
||||||
self.create_multiassigns(module)
|
|
||||||
if not self.imported_module:
|
if not self.imported_module:
|
||||||
# the following shall only be done on the main module after all imports have been done:
|
# the following shall only be done on the main module after all imports have been done:
|
||||||
self.check_all_symbolnames(module)
|
self.check_all_symbolnames(module)
|
||||||
@ -249,24 +248,6 @@ class PlyParser:
|
|||||||
for node in module.all_nodes(SymbolName):
|
for node in module.all_nodes(SymbolName):
|
||||||
check_symbol_definition(node.name, node.my_scope(), node.sourceref) # type: ignore
|
check_symbol_definition(node.name, node.my_scope(), node.sourceref) # type: ignore
|
||||||
|
|
||||||
@no_type_check
|
|
||||||
def create_multiassigns(self, module: Module) -> None:
|
|
||||||
# create multi-assign statements from nested assignments (A=B=C=5),
|
|
||||||
def reduce_right(assign: Assignment) -> Assignment:
|
|
||||||
if isinstance(assign.right, Assignment):
|
|
||||||
right = reduce_right(assign.right)
|
|
||||||
for rn in right.left.nodes:
|
|
||||||
rn.parent = assign.left
|
|
||||||
assign.left.nodes.extend(right.left.nodes)
|
|
||||||
assign.right = right.right
|
|
||||||
assign.right.parent = assign
|
|
||||||
return assign
|
|
||||||
|
|
||||||
for node in module.all_nodes(Assignment):
|
|
||||||
if isinstance(node.right, Assignment):
|
|
||||||
multi = reduce_right(node)
|
|
||||||
assert multi is node and len(multi.left.nodes) > 1 and not isinstance(multi.right, Assignment)
|
|
||||||
|
|
||||||
@no_type_check
|
@no_type_check
|
||||||
def apply_directive_options(self, module: Module) -> None:
|
def apply_directive_options(self, module: Module) -> None:
|
||||||
def set_save_registers(scope: Scope, save_dir: Directive) -> None:
|
def set_save_registers(scope: Scope, save_dir: Directive) -> None:
|
||||||
|
@ -40,7 +40,6 @@ class Optimizer:
|
|||||||
self.optimize_assignments()
|
self.optimize_assignments()
|
||||||
self.remove_superfluous_assignments()
|
self.remove_superfluous_assignments()
|
||||||
self.combine_assignments_into_multi()
|
self.combine_assignments_into_multi()
|
||||||
self.optimize_multiassigns()
|
|
||||||
# @todo optimize addition with self into shift 1 (A+=A -> A<<=1)
|
# @todo optimize addition with self into shift 1 (A+=A -> A<<=1)
|
||||||
self.optimize_goto_compare_with_zero()
|
self.optimize_goto_compare_with_zero()
|
||||||
self.join_incrdecrs()
|
self.join_incrdecrs()
|
||||||
@ -301,19 +300,6 @@ class Optimizer:
|
|||||||
rvalue = None
|
rvalue = None
|
||||||
assignments.clear()
|
assignments.clear()
|
||||||
|
|
||||||
@no_type_check
|
|
||||||
def optimize_multiassigns(self) -> None:
|
|
||||||
# optimize multi-assign statements (remove duplicate targets, optimize order)
|
|
||||||
for assignment in self.module.all_nodes(Assignment):
|
|
||||||
if len(assignment.left.nodes) > 1:
|
|
||||||
# remove duplicates
|
|
||||||
lvalues = set(assignment.left.nodes)
|
|
||||||
if len(lvalues) != len(assignment.left.nodes):
|
|
||||||
print("{}: removed duplicate assignment targets".format(assignment.sourceref))
|
|
||||||
# @todo change order: first registers, then zp addresses, then non-zp addresses, then the rest (if any)
|
|
||||||
assignment.left.nodes = list(lvalues)
|
|
||||||
self.optimizations_performed = True
|
|
||||||
|
|
||||||
@no_type_check
|
@no_type_check
|
||||||
def remove_unused_subroutines(self) -> None:
|
def remove_unused_subroutines(self) -> 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,
|
||||||
|
@ -846,10 +846,7 @@ class Return(AstNode):
|
|||||||
|
|
||||||
@attr.s(cmp=False, slots=True, repr=False)
|
@attr.s(cmp=False, slots=True, repr=False)
|
||||||
class Assignment(AstNode):
|
class Assignment(AstNode):
|
||||||
# can be single- or multi-assignment
|
# has two subnodes: left (=Register/SymbolName/Dereference ) and right (=Expression)
|
||||||
# has two subnodes: left (=Register/SymbolName/Dereference ) and right (=Expression,
|
|
||||||
# or another Assignment but those will be converted into multi assign)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def left(self) -> Union[Register, SymbolName, Dereference]:
|
def left(self) -> Union[Register, SymbolName, Dereference]:
|
||||||
return self.nodes[0] # type: ignore
|
return self.nodes[0] # type: ignore
|
||||||
@ -1475,7 +1472,6 @@ def p_symbolname(p):
|
|||||||
def p_assignment(p):
|
def p_assignment(p):
|
||||||
"""
|
"""
|
||||||
assignment : assignment_target IS expression
|
assignment : assignment_target IS expression
|
||||||
| assignment_target IS assignment
|
|
||||||
"""
|
"""
|
||||||
p[0] = Assignment(sourceref=_token_sref(p, 2))
|
p[0] = Assignment(sourceref=_token_sref(p, 2))
|
||||||
p[0].nodes.append(p[1])
|
p[0].nodes.append(p[1])
|
||||||
|
@ -288,13 +288,9 @@ want to work on later, because the contents of the ignored block are not fully p
|
|||||||
|
|
||||||
### Assignments
|
### Assignments
|
||||||
|
|
||||||
Assignment statements assign a single value to one or more variables or memory locations.
|
Assignment statements assign a single value to a target variable or memory location.
|
||||||
If you know that you have to assign the same value to more than one thing at once, it is more
|
|
||||||
efficient to write it as a multi-assign instead of several separate assignments. The compiler
|
|
||||||
tries to detect this situation however and optimize it itself if it finds the case.
|
|
||||||
|
|
||||||
target = value-expression
|
target = value-expression
|
||||||
target1 = target2 = target3 [,...] = value-expression
|
|
||||||
|
|
||||||
|
|
||||||
### Augmented Assignments
|
### Augmented Assignments
|
||||||
|
@ -153,8 +153,6 @@ start:
|
|||||||
A = 0
|
A = 0
|
||||||
A = '@'
|
A = '@'
|
||||||
A = 1.2345
|
A = 1.2345
|
||||||
A=X=Y= true
|
|
||||||
A=XY= true
|
|
||||||
A = false
|
A = false
|
||||||
A = 255
|
A = 255
|
||||||
A = X
|
A = X
|
||||||
@ -180,8 +178,6 @@ start:
|
|||||||
XY = uninitbyte1
|
XY = uninitbyte1
|
||||||
XY = "text-immediate"
|
XY = "text-immediate"
|
||||||
AY = "text-immediate"
|
AY = "text-immediate"
|
||||||
; AX = &"text-immediate" ; equivalent to simply assigning the string directly
|
|
||||||
; AX = & "text-immediate" ; equivalent to simply assigning the string directly
|
|
||||||
AX = ctext3
|
AX = ctext3
|
||||||
AX = ""
|
AX = ""
|
||||||
AX = XY
|
AX = XY
|
||||||
@ -190,7 +186,7 @@ start:
|
|||||||
XY = membyte2
|
XY = membyte2
|
||||||
XY = memword1
|
XY = memword1
|
||||||
XY = sin
|
XY = sin
|
||||||
; XY = &sin ; @todo not yet implemented
|
XY = &sin ; @todo not yet implemented
|
||||||
|
|
||||||
|
|
||||||
[$c000] = A
|
[$c000] = A
|
||||||
@ -214,7 +210,7 @@ start:
|
|||||||
[$c000.word] = ""
|
[$c000.word] = ""
|
||||||
[$c000.word] = uninitbyte1
|
[$c000.word] = uninitbyte1
|
||||||
[$c000.word] = membyte2
|
[$c000.word] = membyte2
|
||||||
; [$c000.word] = &membyte2 ; @todo not yet implemented
|
[$c000.word] = &membyte2 ; @todo not yet implemented
|
||||||
[$c000.word] = [cword2]
|
[$c000.word] = [cword2]
|
||||||
[$c000.word] = memword1
|
[$c000.word] = memword1
|
||||||
[$c000.float] = 65535
|
[$c000.float] = 65535
|
||||||
@ -228,7 +224,7 @@ start:
|
|||||||
[$c112.word] = [$c223.byte]
|
[$c112.word] = [$c223.byte]
|
||||||
[$c222.word] = [$c333.word]
|
[$c222.word] = [$c333.word]
|
||||||
[$c333.word] = sin
|
[$c333.word] = sin
|
||||||
; [$c333.word] = &sin ; @todo not yet implemented
|
[$c333.word] = &sin ; @todo not yet implemented
|
||||||
|
|
||||||
|
|
||||||
SC = 0
|
SC = 0
|
||||||
@ -264,7 +260,7 @@ start:
|
|||||||
uninitfloat = 9.8765
|
uninitfloat = 9.8765
|
||||||
uninitfloat = '@'
|
uninitfloat = '@'
|
||||||
initword1 = sin
|
initword1 = sin
|
||||||
; initword1 = &sin ; @todo not yet implemented
|
initword1 = &sin ; @todo not yet implemented
|
||||||
|
|
||||||
|
|
||||||
membyte1 = A
|
membyte1 = A
|
||||||
@ -280,7 +276,7 @@ start:
|
|||||||
memword1 = 2233
|
memword1 = 2233
|
||||||
memfloat = 3.4567
|
memfloat = 3.4567
|
||||||
memword1 = sin
|
memword1 = sin
|
||||||
; memword1 = &sin ; @todo not yet implemented
|
memword1 = &sin ; @todo not yet implemented
|
||||||
|
|
||||||
membyte1 = A
|
membyte1 = A
|
||||||
memword1 = A
|
memword1 = A
|
||||||
|
@ -15,7 +15,7 @@ start:
|
|||||||
A = c64.VMCSB
|
A = c64.VMCSB
|
||||||
A |= 2
|
A |= 2
|
||||||
c64.VMCSB = A
|
c64.VMCSB = A
|
||||||
;c64.VMCSB |= 2 ; @todo when this works it replaces the three lines above
|
c64.VMCSB |= 2 ; @todo when this works it replaces the three lines above
|
||||||
|
|
||||||
; greeting
|
; greeting
|
||||||
c64scr.print_string("Enter your name: ")
|
c64scr.print_string("Enter your name: ")
|
||||||
|
@ -33,7 +33,19 @@ start: ;foo
|
|||||||
Y = X
|
Y = X
|
||||||
X = 66
|
X = 66
|
||||||
screen = 0
|
screen = 0
|
||||||
screen = border = cursor = X = Y = A = X = Y = A = border = cursor = border = cursor = 66 ; multi-assign!
|
screen = 66
|
||||||
|
border = 66
|
||||||
|
cursor = 66
|
||||||
|
X = 66
|
||||||
|
Y = 66
|
||||||
|
A = 66
|
||||||
|
X = 66
|
||||||
|
Y = 66
|
||||||
|
A = 66
|
||||||
|
border = 66
|
||||||
|
cursor = 66
|
||||||
|
border = 66
|
||||||
|
cursor = 66
|
||||||
border = false
|
border = false
|
||||||
border = true
|
border = true
|
||||||
border = 0
|
border = 0
|
||||||
@ -58,7 +70,9 @@ start: ;foo
|
|||||||
Y = 2
|
Y = 2
|
||||||
Y = true
|
Y = true
|
||||||
Y = false
|
Y = false
|
||||||
A = Y = X = 0 ; multi assign!
|
A = 0
|
||||||
|
Y = 0
|
||||||
|
X = 0
|
||||||
|
|
||||||
; [646,Y] = [$d020,X]
|
; [646,Y] = [$d020,X]
|
||||||
|
|
||||||
@ -130,8 +144,19 @@ somelabel1:
|
|||||||
|
|
||||||
goto somelabel1
|
goto somelabel1
|
||||||
goto block2.somelabel1222
|
goto block2.somelabel1222
|
||||||
A=X=Y=A=X=Y=A=X=Y=99
|
A=99
|
||||||
[$d020]=[$d021]=[$d020]=[$d021]=55
|
X=99
|
||||||
|
Y=99
|
||||||
|
A=99
|
||||||
|
X=99
|
||||||
|
Y=99
|
||||||
|
A=99
|
||||||
|
X=99
|
||||||
|
Y=99
|
||||||
|
[$d020]=55
|
||||||
|
[$d021]=55
|
||||||
|
[$d020]=55
|
||||||
|
[$d021]=55
|
||||||
|
|
||||||
A=1
|
A=1
|
||||||
X=1
|
X=1
|
||||||
|
@ -67,7 +67,8 @@ start:
|
|||||||
~ global2 {
|
~ global2 {
|
||||||
|
|
||||||
make_screen_black:
|
make_screen_black:
|
||||||
c64.EXTCOL = c64.BGCOL0 = 0
|
c64.EXTCOL = 0
|
||||||
|
c64.BGCOL0 = 0
|
||||||
c64.COLOR = 3
|
c64.COLOR = 3
|
||||||
Y = true
|
Y = true
|
||||||
return
|
return
|
||||||
|
@ -53,7 +53,8 @@ start2:
|
|||||||
~ global2 {
|
~ global2 {
|
||||||
|
|
||||||
make_screen_black:
|
make_screen_black:
|
||||||
c64.EXTCOL = c64.BGCOL0 = 0
|
c64.EXTCOL = 0
|
||||||
|
c64.BGCOL0 = 0
|
||||||
c64.COLOR = 3
|
c64.COLOR = 3
|
||||||
return
|
return
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user