mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +00:00
character literals (strings of len 1) are no longer automatically converted to byte integers
This commit is contained in:
parent
780443ddab
commit
fb1a4aa4ea
@ -146,8 +146,7 @@ def _generate_aug_reg_int(out: Callable, lvalue: Register, operator: str, rvalue
|
||||
elif operator == "<<=":
|
||||
_gen_aug_shiftleft_reg_int(lvalue, out, rname, rvalue, scope)
|
||||
else:
|
||||
# @todo implement more operators such as *= /=
|
||||
raise ValueError("invalid operator: " + operator, str(lvalue.sourceref))
|
||||
raise ValueError("invalid operator: " + operator, str(lvalue.sourceref)) # @todo implement more operators such as *=, /=
|
||||
|
||||
|
||||
def _generate_aug_reg_reg(out: Callable, lvalue: Register, operator: str, rvalue: Register, scope: Scope) -> None:
|
||||
@ -166,8 +165,7 @@ def _generate_aug_reg_reg(out: Callable, lvalue: Register, operator: str, rvalue
|
||||
elif operator == "<<=":
|
||||
_gen_aug_shiftleft_reg_reg(lvalue, out, rvalue, scope)
|
||||
else:
|
||||
# @todo implement more operators such as *= /=
|
||||
raise ValueError("invalid operator: " + operator, str(lvalue.sourceref))
|
||||
raise ValueError("invalid operator: " + operator, str(lvalue.sourceref)) # @todo implement more operators such as *=, /=
|
||||
|
||||
|
||||
def _gen_aug_shiftleft_reg_int(lvalue: Register, out: Callable, rname: str, rvalue: int, scope: Scope) -> None:
|
||||
|
@ -111,8 +111,8 @@ class Optimizer:
|
||||
incrdecrs.append(node)
|
||||
target = node.target
|
||||
|
||||
def _same_target(self, node1: Union[TargetRegisters, Register, SymbolName, Dereference],
|
||||
node2: Union[TargetRegisters, Register, SymbolName, Dereference]) -> bool:
|
||||
def _same_target(self, node1: Union[Register, SymbolName, Dereference],
|
||||
node2: Union[Register, SymbolName, Dereference]) -> bool:
|
||||
if isinstance(node1, Register) and isinstance(node2, Register) and node1.name == node2.name:
|
||||
return True
|
||||
if isinstance(node1, SymbolName) and isinstance(node2, SymbolName) and node1.name == node2.name:
|
||||
@ -240,9 +240,9 @@ class Optimizer:
|
||||
return new_assignment
|
||||
|
||||
@no_type_check
|
||||
def _make_aug_assign(self, old_assign: Assignment, target: Union[TargetRegisters, Register, SymbolName, Dereference],
|
||||
def _make_aug_assign(self, old_assign: Assignment, target: Union[Register, SymbolName, Dereference],
|
||||
value: Union[int, float], operator: str) -> AugAssignment:
|
||||
assert isinstance(target, (TargetRegisters, Register, SymbolName, Dereference))
|
||||
assert isinstance(target, (Register, SymbolName, Dereference))
|
||||
a = AugAssignment(operator=operator, sourceref=old_assign.sourceref)
|
||||
a.nodes.append(target)
|
||||
target.parent = a
|
||||
@ -253,9 +253,9 @@ class Optimizer:
|
||||
return a
|
||||
|
||||
@no_type_check
|
||||
def _make_incrdecr(self, old_stmt: AstNode, target: Union[TargetRegisters, Register, SymbolName, Dereference],
|
||||
def _make_incrdecr(self, old_stmt: AstNode, target: Union[Register, SymbolName, Dereference],
|
||||
howmuch: Union[int, float], operator: str) -> IncrDecr:
|
||||
assert isinstance(target, (TargetRegisters, Register, SymbolName, Dereference))
|
||||
assert isinstance(target, (Register, SymbolName, Dereference))
|
||||
a = IncrDecr(operator=operator, howmuch=howmuch, sourceref=old_stmt.sourceref)
|
||||
a.nodes.append(target)
|
||||
target.parent = a
|
||||
|
@ -22,7 +22,7 @@ __all__ = ["ProgramFormat", "ZpOptions", "math_functions", "builtin_functions",
|
||||
"UndefinedSymbolError", "AstNode", "Directive", "Scope", "Block", "Module", "Label", "Expression",
|
||||
"Register", "Subroutine", "LiteralValue", "AddressOf", "SymbolName", "Dereference", "IncrDecr",
|
||||
"ExpressionWithOperator", "Goto", "SubCall", "VarDef", "Return", "Assignment", "AugAssignment",
|
||||
"InlineAssembly", "TargetRegisters", "AssignmentTargets",
|
||||
"InlineAssembly", "AssignmentTargets",
|
||||
"parse_file", "coerce_constant_value", "datatype_of", "check_symbol_definition"]
|
||||
|
||||
|
||||
@ -390,15 +390,6 @@ class PreserveRegs(AstNode):
|
||||
# no subnodes.
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class TargetRegisters(AstNode):
|
||||
# subnodes is is a list of 1 or more registers.
|
||||
# In it's multiple-register form it is only used to be able to parse
|
||||
# the result of a subroutine call such as A,X = sub().
|
||||
# It will be replaced by a regular Register node if it contains just one register.
|
||||
pass
|
||||
|
||||
|
||||
@attr.s(cmp=False, repr=False)
|
||||
class InlineAssembly(AstNode):
|
||||
# no subnodes.
|
||||
@ -545,21 +536,19 @@ class Dereference(Expression):
|
||||
@attr.s(cmp=False)
|
||||
class IncrDecr(AstNode):
|
||||
# increment or decrement something by a CONSTANT value (1 or more)
|
||||
# one subnode: target (TargetRegisters, Register, SymbolName, or Dereference).
|
||||
# one subnode: target (Register, SymbolName, or Dereference).
|
||||
operator = attr.ib(type=str, validator=attr.validators.in_(["++", "--"]))
|
||||
howmuch = attr.ib(default=1)
|
||||
|
||||
@property
|
||||
def target(self) -> Union[TargetRegisters, Register, SymbolName, Dereference]:
|
||||
def target(self) -> Union[Register, SymbolName, Dereference]:
|
||||
return self.nodes[0] # type: ignore
|
||||
|
||||
@target.setter
|
||||
def target(self, target: Union[TargetRegisters, Register, SymbolName, Dereference]) -> None:
|
||||
def target(self, target: Union[Register, SymbolName, Dereference]) -> None:
|
||||
if isinstance(target, Register):
|
||||
if target.name not in REGISTER_BYTES | REGISTER_WORDS:
|
||||
raise ParseError("cannot incr/decr that register", self.sourceref)
|
||||
if isinstance(target, TargetRegisters):
|
||||
raise ParseError("cannot incr/decr multiple registers at once", self.sourceref)
|
||||
assert isinstance(target, (Register, SymbolName, Dereference))
|
||||
self.nodes.clear()
|
||||
self.nodes.append(target)
|
||||
@ -842,7 +831,7 @@ class Return(AstNode):
|
||||
|
||||
@attr.s(cmp=False, slots=True, repr=False)
|
||||
class AssignmentTargets(AstNode):
|
||||
# a list of one or more assignment targets (TargetRegisters, Register, SymbolName, or Dereference).
|
||||
# a list of one or more assignment targets (Register, SymbolName, or Dereference).
|
||||
nodes = attr.ib(type=list, init=True) # requires nodes in __init__
|
||||
|
||||
def has_memvalue(self) -> bool:
|
||||
@ -862,9 +851,7 @@ class AssignmentTargets(AstNode):
|
||||
for t1, t2 in zip(self.nodes, other.nodes):
|
||||
if type(t1) is not type(t2):
|
||||
return False
|
||||
if isinstance(t1, TargetRegisters):
|
||||
pass
|
||||
elif isinstance(t1, Register):
|
||||
if isinstance(t1, Register):
|
||||
if t1 != t2: # __eq__ is defined
|
||||
return False
|
||||
elif isinstance(t1, SymbolName):
|
||||
@ -909,11 +896,11 @@ class Assignment(AstNode):
|
||||
|
||||
@attr.s(cmp=False, slots=True, repr=False)
|
||||
class AugAssignment(AstNode):
|
||||
# has two subnodes: left (=TargetRegisters, Register, SymbolName, or Dereference) and right (=Expression)
|
||||
# has two subnodes: left (=Register, SymbolName, or Dereference) and right (=Expression)
|
||||
operator = attr.ib(type=str)
|
||||
|
||||
@property
|
||||
def left(self) -> Union[TargetRegisters, Register, SymbolName, Dereference]:
|
||||
def left(self) -> Union[Register, SymbolName, Dereference]:
|
||||
return self.nodes[0] # type: ignore
|
||||
|
||||
@property
|
||||
@ -936,9 +923,6 @@ def datatype_of(targetnode: AstNode, scope: Scope) -> DataType:
|
||||
symdef = scope.lookup(targetnode.name)
|
||||
if isinstance(symdef, VarDef):
|
||||
return symdef.datatype
|
||||
elif isinstance(targetnode, TargetRegisters):
|
||||
if len(targetnode.nodes) == 1:
|
||||
return datatype_of(targetnode.nodes[0], scope)
|
||||
raise TypeError("cannot determine datatype", targetnode)
|
||||
|
||||
|
||||
@ -1625,38 +1609,19 @@ def p_expression_value(p):
|
||||
|
||||
def p_assignment_target(p):
|
||||
"""
|
||||
assignment_target : target_registers
|
||||
assignment_target : register
|
||||
| symbolname
|
||||
| dereference
|
||||
"""
|
||||
if isinstance(p[1], TargetRegisters):
|
||||
# if the target registers is just a single register, use that instead
|
||||
if len(p[1].nodes) == 1:
|
||||
assert isinstance(p[1].nodes[0], Register)
|
||||
p[1] = p[1].nodes[0]
|
||||
p[0] = p[1]
|
||||
|
||||
|
||||
def p_target_registers(p):
|
||||
"""
|
||||
target_registers : register
|
||||
| target_registers ',' register
|
||||
"""
|
||||
if len(p) == 2:
|
||||
p[0] = TargetRegisters(sourceref=_token_sref(p, 1))
|
||||
p[0].nodes.append(p[1])
|
||||
else:
|
||||
p[1].nodes.append(p[3])
|
||||
p[0] = p[1]
|
||||
|
||||
|
||||
def p_empty(p):
|
||||
"""empty :"""
|
||||
pass
|
||||
|
||||
|
||||
def p_error(p):
|
||||
stack_state_str = ' '.join([symbol.type for symbol in parser.symstack][1:])
|
||||
if p:
|
||||
sref = SourceRef(p.lexer.source_filename, p.lineno, find_tok_column(p))
|
||||
if p.value in ("", "\n"):
|
||||
@ -1665,6 +1630,7 @@ def p_error(p):
|
||||
p.lexer.error_function(sref, "syntax error before or at '{:.20s}'", str(p.value).rstrip())
|
||||
else:
|
||||
lexer.error_function(None, "syntax error at end of input", lexer.source_filename)
|
||||
# stack_state_str = ' '.join([symbol.type for symbol in parser.symstack][1:])
|
||||
# print('\n[ERROR DEBUG: parser state={:d} stack: {} . {} ]'.format(parser.state, stack_state_str, p))
|
||||
|
||||
|
||||
|
46
todo.ill
46
todo.ill
@ -1,40 +1,28 @@
|
||||
~ main {
|
||||
|
||||
var .float flt = -9.87e-21
|
||||
var bytevar = 22 + 23
|
||||
const .word border = $d020
|
||||
var .word border2 = $d020
|
||||
memory screenm = $d021
|
||||
const .word border = $0099
|
||||
|
||||
start:
|
||||
; @todo float incrdecr/augassign
|
||||
; flt += 0.1
|
||||
; flt += 1.1
|
||||
; flt += 10.1
|
||||
; flt += 100.1
|
||||
; flt += 1000.1
|
||||
; flt *= 2.34
|
||||
; @todo float augassign
|
||||
flt += 1000.1
|
||||
flt *= 2.34
|
||||
flt *= flt
|
||||
|
||||
screenm ++
|
||||
screenm ++
|
||||
border2 ++
|
||||
border2 ++
|
||||
screenm --
|
||||
border2 --
|
||||
;[border] &= 2 ; @todo augassign on dereference
|
||||
|
||||
[$55 .float] ++
|
||||
[screenm .float]--
|
||||
XY*=3 ; @todo operator
|
||||
XY=XY/0 ; @todo zerodiv (during expression to code generation) @todo operator
|
||||
XY=XY//0 ; @todo zerodiv (during expression to code generation) @todo operator
|
||||
|
||||
; @todo incr by more than 1
|
||||
[AX]++
|
||||
[AX]++
|
||||
A=0
|
||||
; @todo decr by more than 1
|
||||
[AX]--
|
||||
[AX]--
|
||||
|
||||
[border] ++
|
||||
[border] ++
|
||||
[border] --
|
||||
[$d020] ++
|
||||
[$d020] ++
|
||||
[$d020] --
|
||||
[border2 .word] ++
|
||||
[border2 .float] ++
|
||||
[border2] --
|
||||
[XY] ++
|
||||
|
||||
return 44.123
|
||||
}
|
||||
|
111
todo2.ill
111
todo2.ill
@ -1,111 +0,0 @@
|
||||
%output basic
|
||||
%import c64lib
|
||||
|
||||
|
||||
~ main {
|
||||
var .byte v1t = true
|
||||
var .byte v1f = false
|
||||
var .word v2t = true
|
||||
var .word v2f = false
|
||||
var .float v3t = true
|
||||
var .float v3f = false
|
||||
var .text v4t = true
|
||||
var .text v4f = false
|
||||
var .array(3) v5t = true
|
||||
var .array(3) v5f = false
|
||||
var .array(10) v6t = true
|
||||
var .array(10) v6f = false
|
||||
var .wordarray(3) v7t = true
|
||||
var .wordarray(3) v7f = false
|
||||
var .wordarray(10) v8t = true
|
||||
var .wordarray(10) v8f = false
|
||||
var .matrix(2,2) v9t = true
|
||||
var .matrix(2,2) v9f = false
|
||||
var .matrix(5,5) v10t = true
|
||||
var .matrix(5,5) v10f = false
|
||||
|
||||
const .byte c1t=true
|
||||
const .byte c1f=false
|
||||
const .word c2t=true
|
||||
const .word c2f=false
|
||||
const .float c3t=true
|
||||
const .float c3f=false
|
||||
|
||||
memory border = $d020
|
||||
|
||||
|
||||
start:
|
||||
%breakpoint abc,def
|
||||
|
||||
X += border
|
||||
XY += border ; @todo .word augassign register
|
||||
XY -= 234+3 ; @todo .word augassign register
|
||||
|
||||
X += [c2f]
|
||||
XY += [c2f]
|
||||
Y += [XY]
|
||||
|
||||
XY+=255
|
||||
XY+=254
|
||||
XY+=253
|
||||
XY-=255
|
||||
XY-=254
|
||||
XY-=253
|
||||
|
||||
v3t++
|
||||
;v3t+=1 ; @todo non-reg augassign
|
||||
;v3t+=1 ; @todo? (optimize) join with previous
|
||||
;v3t+=0 ; is removed by optimizer
|
||||
;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.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+=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.23424 * v3t ; @todo store as constant float with generated name, replace value node
|
||||
;XY*=2 ; @todo operator
|
||||
;XY*=3 ; @todo operator
|
||||
X=3 ; @todo optimize consecutive assignments
|
||||
X=4
|
||||
X=5
|
||||
X=A=6
|
||||
A=X=6
|
||||
X=A=6
|
||||
X=A=9
|
||||
X=A=10
|
||||
v3t=1 ; @todo optimize consecutive assignments
|
||||
v3t=2
|
||||
v3t=3
|
||||
border = 0 ; @todo do not optimize consecucutive assignments to a memory var
|
||||
border = 1
|
||||
border = 2
|
||||
|
||||
;XY=XY/0 ; @todo zerodiv (during expression to code generation) @todo operator
|
||||
;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 @todo operator
|
||||
;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 @todo operator, non-register
|
||||
A++
|
||||
X--
|
||||
A+=1
|
||||
X-=2
|
||||
[AX]++
|
||||
[AX .byte]++
|
||||
[AX .word]++
|
||||
[AX .float]++
|
||||
[$ccc0]++
|
||||
[$ccc0 .byte]++
|
||||
[$ccc0 .word]++
|
||||
[$ccc0 .float]++
|
||||
A+=2
|
||||
A+=3
|
||||
XY+=6
|
||||
XY+=222
|
||||
XY+=11
|
||||
|
||||
return 44
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user