mirror of
https://github.com/irmen/prog8.git
synced 2024-11-19 11:32:17 +00:00
attr
This commit is contained in:
parent
18526469ed
commit
9b68722df3
@ -6,170 +6,187 @@ Written by Irmen de Jong (irmen@razorvine.net)
|
||||
License: GNU GPL 3.0, see LICENSE
|
||||
"""
|
||||
|
||||
from typing import List, Set
|
||||
import attr
|
||||
from ply.yacc import yacc
|
||||
from .symbols import SourceRef, AstNode
|
||||
from typing import Union
|
||||
from .symbols import SourceRef
|
||||
from .lexer import tokens, lexer, find_tok_column # get the lexer tokens. required.
|
||||
|
||||
|
||||
start = "start"
|
||||
|
||||
|
||||
@attr.s(cmp=False, slots=True, frozen=False)
|
||||
class AstNode:
|
||||
sourceref = attr.ib(type=SourceRef)
|
||||
|
||||
@property
|
||||
def lineref(self) -> str:
|
||||
return "src l. " + str(self.sourceref.line)
|
||||
|
||||
def print_tree(self) -> None:
|
||||
def tostr(node: AstNode, level: int) -> None:
|
||||
if not isinstance(node, AstNode):
|
||||
return
|
||||
indent = " " * level
|
||||
name = getattr(node, "name", "")
|
||||
print(indent, node.__class__.__name__, repr(name))
|
||||
try:
|
||||
variables = vars(node).items()
|
||||
except TypeError:
|
||||
return
|
||||
for name, value in variables:
|
||||
if isinstance(value, AstNode):
|
||||
tostr(value, level + 1)
|
||||
if isinstance(value, (list, tuple, set)):
|
||||
if len(value) > 0:
|
||||
elt = list(value)[0]
|
||||
if isinstance(elt, AstNode) or name == "nodes":
|
||||
print(indent, " >", name, "=")
|
||||
for elt in value:
|
||||
tostr(elt, level + 2)
|
||||
tostr(self, 0)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class Module(AstNode):
|
||||
def __init__(self, nodes: List[AstNode], sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.nodes = nodes or []
|
||||
nodes = attr.ib(type=list)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class Directive(AstNode):
|
||||
def __init__(self, name: str, args, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.name = name
|
||||
self.args = args or []
|
||||
|
||||
|
||||
class Block(AstNode):
|
||||
def __init__(self, name: str, address, scope, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.name = name
|
||||
self.address = address
|
||||
self.scope = scope
|
||||
name = attr.ib(type=str)
|
||||
args = attr.ib(type=list, default=attr.Factory(list))
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class Scope(AstNode):
|
||||
def __init__(self, nodes: List[AstNode], sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.nodes = nodes
|
||||
nodes = attr.ib(type=list)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class Block(AstNode):
|
||||
scope = attr.ib(type=Scope)
|
||||
name = attr.ib(type=str, default=None)
|
||||
address = attr.ib(type=int, default=None)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class Label(AstNode):
|
||||
def __init__(self, name: str, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.name = name
|
||||
name = attr.ib(type=str)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class Register(AstNode):
|
||||
def __init__(self, name: str, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.name = name
|
||||
name = attr.ib(type=str)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class PreserveRegs(AstNode):
|
||||
def __init__(self, registers, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.registers = registers
|
||||
registers = attr.ib(type=str)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class Assignment(AstNode):
|
||||
def __init__(self, lhs, rhs, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.lhs = lhs
|
||||
self.rhs = rhs
|
||||
left = attr.ib() # type: Union[str, TargetRegisters, Dereference]
|
||||
right = attr.ib()
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class AugAssignment(Assignment):
|
||||
def __init__(self, lhs, operator: str, rhs, sourceref: SourceRef) -> None:
|
||||
super().__init__(lhs, rhs, sourceref)
|
||||
self.operator = operator
|
||||
operator = attr.ib(type=str)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class SubCall(AstNode):
|
||||
def __init__(self, target, preserveregs, arguments, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.target = target
|
||||
self.preserveregs = preserveregs
|
||||
self.arguments = arguments
|
||||
target = attr.ib()
|
||||
preserve_regs = attr.ib()
|
||||
arguments = attr.ib()
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class Return(AstNode):
|
||||
def __init__(self, valueA, valueX, valueY, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.valueA = valueA
|
||||
self.valueX = valueX
|
||||
self.valueY = valueY
|
||||
value_A = attr.ib(default=None)
|
||||
value_X = attr.ib(default=None)
|
||||
value_Y = attr.ib(default=None)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class TargetRegisters(AstNode):
|
||||
def __init__(self, registers: List[str], sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.registers = registers
|
||||
registers = attr.ib(type=list)
|
||||
|
||||
def add_register(self, register) -> None:
|
||||
def add(self, register: str) -> None:
|
||||
self.registers.append(register)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class InlineAssembly(AstNode):
|
||||
def __init__(self, assembly: str, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.assembly = assembly
|
||||
assembly = attr.ib(type=str)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class VarDef(AstNode):
|
||||
def __init__(self, name: str, vartype, datatype, value, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.name = name
|
||||
self.vartype = vartype
|
||||
self.datatype = datatype
|
||||
self.value = value
|
||||
name = attr.ib(type=str)
|
||||
vartype = attr.ib()
|
||||
datatype = attr.ib()
|
||||
value = attr.ib(default=None)
|
||||
|
||||
|
||||
@attr.s(cmp=False, slots=True)
|
||||
class Datatype(AstNode):
|
||||
def __init__(self, name: str, dimension, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.name = name
|
||||
self.dimension = dimension
|
||||
name = attr.ib(type=str)
|
||||
dimension = attr.ib(type=list, default=None)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class Subroutine(AstNode):
|
||||
def __init__(self, name: str, paramspec, resultspec, code, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.name = name
|
||||
self.paramspec = paramspec
|
||||
self.resultspec = resultspec
|
||||
self.code = code
|
||||
name = attr.ib(type=str)
|
||||
param_spec = attr.ib()
|
||||
result_spec = attr.ib()
|
||||
scope = attr.ib(type=Scope, default=None)
|
||||
address = attr.ib(type=int, default=None)
|
||||
|
||||
def __attrs_post_init__(self):
|
||||
if self.scope is not None and self.address is not None:
|
||||
raise ValueError("subroutine must have either a scope or an address, not both")
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class Goto(AstNode):
|
||||
def __init__(self, target, ifstmt, condition, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.target = target
|
||||
self.ifstmt = ifstmt
|
||||
self.condition = condition
|
||||
target = attr.ib()
|
||||
if_stmt = attr.ib(default=None)
|
||||
condition = attr.ib(default=None)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class Dereference(AstNode):
|
||||
def __init__(self, location, datatype, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.location = location
|
||||
self.datatype = datatype
|
||||
location = attr.ib()
|
||||
datatype = attr.ib()
|
||||
|
||||
|
||||
@attr.s(cmp=False, slots=True)
|
||||
class CallTarget(AstNode):
|
||||
def __init__(self, target, address_of: bool, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.target = target
|
||||
self.address_of = address_of
|
||||
target = attr.ib()
|
||||
address_of = attr.ib(type=bool)
|
||||
|
||||
|
||||
@attr.s(cmp=False, slots=True)
|
||||
class CallArgument(AstNode):
|
||||
def __init__(self, name: str, value, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.name = name
|
||||
self.value = value
|
||||
value = attr.ib()
|
||||
name = attr.ib(type=str, default=None)
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class UnaryOp(AstNode):
|
||||
def __init__(self, operator, operand, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.operator = operator
|
||||
self.operand = operand
|
||||
operator = attr.ib(type=str)
|
||||
operand = attr.ib()
|
||||
|
||||
|
||||
@attr.s(cmp=False, slots=True)
|
||||
class Expression(AstNode):
|
||||
def __init__(self, lhs, operator, rhs, sourceref: SourceRef) -> None:
|
||||
super().__init__(sourceref)
|
||||
self.lhs = lhs
|
||||
self.operator = operator
|
||||
self.rhs = rhs
|
||||
left = attr.ib()
|
||||
operator = attr.ib(type=str)
|
||||
right = attr.ib()
|
||||
|
||||
|
||||
def p_start(p):
|
||||
@ -178,7 +195,7 @@ def p_start(p):
|
||||
| module_elements
|
||||
"""
|
||||
if p[1]:
|
||||
p[0] = Module(p[1], _token_sref(p, 1))
|
||||
p[0] = Module(nodes=p[1], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_module(p):
|
||||
@ -207,9 +224,9 @@ def p_directive(p):
|
||||
| DIRECTIVE directive_args ENDL
|
||||
"""
|
||||
if len(p) == 2:
|
||||
p[0] = Directive(p[1], None, _token_sref(p, 1))
|
||||
p[0] = Directive(name=p[1], sourceref=_token_sref(p, 1))
|
||||
else:
|
||||
p[0] = Directive(p[1], p[2], _token_sref(p, 1))
|
||||
p[0] = Directive(name=p[1], args=p[2], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_directive_args(p):
|
||||
@ -236,21 +253,21 @@ def p_block_name_addr(p):
|
||||
"""
|
||||
block : BITINVERT NAME INTEGER endl_opt scope
|
||||
"""
|
||||
p[0] = Block(p[2], p[3], p[5], _token_sref(p, 1))
|
||||
p[0] = Block(name=p[2], address=p[3], scope=p[5], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_block_name(p):
|
||||
"""
|
||||
block : BITINVERT NAME endl_opt scope
|
||||
"""
|
||||
p[0] = Block(p[2], None, p[4], _token_sref(p, 1))
|
||||
p[0] = Block(name=p[2], scope=p[4], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_block(p):
|
||||
"""
|
||||
block : BITINVERT endl_opt scope
|
||||
"""
|
||||
p[0] = Block(None, None, p[3], _token_sref(p, 1))
|
||||
p[0] = Block(scope=p[3], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_endl_opt(p):
|
||||
@ -265,7 +282,7 @@ def p_scope(p):
|
||||
"""
|
||||
scope : '{' scope_elements_opt '}'
|
||||
"""
|
||||
p[0] = Scope(p[2], _token_sref(p, 1))
|
||||
p[0] = Scope(nodes=p[2], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_scope_elements_opt(p):
|
||||
@ -304,28 +321,28 @@ def p_label(p):
|
||||
"""
|
||||
label : LABEL
|
||||
"""
|
||||
p[0] = Label(p[1], _token_sref(p, 1))
|
||||
p[0] = Label(name=p[1], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_inlineasm(p):
|
||||
"""
|
||||
inlineasm : INLINEASM ENDL
|
||||
"""
|
||||
p[0] = InlineAssembly(p[1], _token_sref(p, 1))
|
||||
p[0] = InlineAssembly(assembly=p[1], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_vardef(p):
|
||||
"""
|
||||
vardef : VARTYPE type_opt NAME ENDL
|
||||
"""
|
||||
p[0] = VarDef(p[3], p[1], p[2], None, _token_sref(p, 1))
|
||||
p[0] = VarDef(name=p[3], vartype=p[1], datatype=p[2], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_vardef_value(p):
|
||||
"""
|
||||
vardef : VARTYPE type_opt NAME IS expression
|
||||
"""
|
||||
p[0] = VarDef(p[3], p[1], p[2], p[5], _token_sref(p, 1))
|
||||
p[0] = VarDef(name=p[3], vartype=p[1], datatype=p[2], value=p[5], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_type_opt(p):
|
||||
@ -335,9 +352,9 @@ def p_type_opt(p):
|
||||
| empty
|
||||
"""
|
||||
if len(p) == 5:
|
||||
p[0] = Datatype(p[1], p[3], _token_sref(p, 1))
|
||||
p[0] = Datatype(name=p[1], dimension=p[3], sourceref=_token_sref(p, 1))
|
||||
elif len(p) == 2:
|
||||
p[0] = Datatype(p[1], None, _token_sref(p, 1))
|
||||
p[0] = Datatype(name=p[1], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_dimensions(p):
|
||||
@ -364,7 +381,13 @@ def p_subroutine(p):
|
||||
"""
|
||||
subroutine : SUB NAME '(' sub_param_spec ')' RARROW '(' sub_result_spec ')' subroutine_body ENDL
|
||||
"""
|
||||
p[0] = Subroutine(p[1], p[3], p[7], p[9], _token_sref(p, 1))
|
||||
body = p[10]
|
||||
if isinstance(body, Scope):
|
||||
p[0] = Subroutine(name=p[2], param_spec=p[4], result_spec=p[8], scope=body, sourceref=_token_sref(p, 1))
|
||||
elif isinstance(body, int):
|
||||
p[0] = Subroutine(name=p[2], param_spec=p[4], result_spec=p[8], address=body, sourceref=_token_sref(p, 1))
|
||||
else:
|
||||
raise TypeError("subroutine_body", p.slice)
|
||||
|
||||
|
||||
def p_sub_param_spec(p):
|
||||
@ -457,14 +480,14 @@ def p_incrdecr(p):
|
||||
incrdecr : assignment_target INCR
|
||||
| assignment_target DECR
|
||||
"""
|
||||
p[0] = UnaryOp(p[2], p[1], _token_sref(p, 1))
|
||||
p[0] = UnaryOp(operator=p[2], operand=p[1], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_call_subroutine(p):
|
||||
"""
|
||||
subroutine_call : calltarget preserveregs_opt '(' call_arguments_opt ')'
|
||||
"""
|
||||
p[0] = SubCall(p[1], p[2], p[4], _token_sref(p, 1))
|
||||
p[0] = SubCall(target=p[1], preserve_regs=p[2], arguments=p[4], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_preserveregs_opt(p):
|
||||
@ -479,7 +502,7 @@ def p_preserveregs(p):
|
||||
"""
|
||||
preserveregs : PRESERVEREGS
|
||||
"""
|
||||
p[0] = PreserveRegs(p[1], _token_sref(p, 1))
|
||||
p[0] = PreserveRegs(registers=p[1], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_call_arguments_opt(p):
|
||||
@ -508,9 +531,9 @@ def p_call_argument(p):
|
||||
| NAME IS expression
|
||||
"""
|
||||
if len(p) == 2:
|
||||
p[0] = CallArgument(None, p[1], _token_sref(p, 1))
|
||||
p[0] = CallArgument(value=p[1], sourceref=_token_sref(p, 1))
|
||||
elif len(p) == 4:
|
||||
p[0] = CallArgument(p[1], p[3], _token_sref(p, 1))
|
||||
p[0] = CallArgument(name=p[1], value=p[3], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_return(p):
|
||||
@ -521,41 +544,41 @@ def p_return(p):
|
||||
| RETURN expression ',' expression ',' expression
|
||||
"""
|
||||
if len(p) == 2:
|
||||
p[0] = Return(None, None, None, _token_sref(p, 1))
|
||||
p[0] = Return(sourceref=_token_sref(p, 1))
|
||||
elif len(p) == 3:
|
||||
p[0] = Return(p[2], None, None, _token_sref(p, 1))
|
||||
p[0] = Return(value_A=p[2], sourceref=_token_sref(p, 1))
|
||||
elif len(p) == 5:
|
||||
p[0] = Return(p[2], p[4], None, _token_sref(p, 1))
|
||||
p[0] = Return(value_A=p[2], value_X=p[4], sourceref=_token_sref(p, 1))
|
||||
elif len(p) == 7:
|
||||
p[0] = Return(p[2], p[4], p[6], _token_sref(p, 1))
|
||||
p[0] = Return(value_A=p[2], value_X=p[4], value_Y=p[6], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_register(p):
|
||||
"""
|
||||
register : REGISTER
|
||||
"""
|
||||
p[0] = Register(p[1], _token_sref(p, 1))
|
||||
p[0] = Register(name=p[1], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_goto(p):
|
||||
"""
|
||||
goto : GOTO calltarget
|
||||
"""
|
||||
p[0] = Goto(p[2], None, None, _token_sref(p, 1))
|
||||
p[0] = Goto(target=p[2], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_conditional_goto_plain(p):
|
||||
"""
|
||||
conditional_goto : IF GOTO calltarget
|
||||
"""
|
||||
p[0] = Goto(p[3], p[1], None, _token_sref(p, 1))
|
||||
p[0] = Goto(target=p[3], if_stmt=p[1], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_conditional_goto_expr(p):
|
||||
"""
|
||||
conditional_goto : IF expression GOTO calltarget
|
||||
"""
|
||||
p[0] = Goto(p[4], p[1], p[2], _token_sref(p, 1))
|
||||
p[0] = Goto(target=p[4], if_stmt=p[1], condition=p[2], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_calltarget(p):
|
||||
@ -566,16 +589,16 @@ def p_calltarget(p):
|
||||
| dereference
|
||||
"""
|
||||
if len(p) == 2:
|
||||
p[0] = CallTarget(p[1], False, _token_sref(p, 1))
|
||||
p[0] = CallTarget(target=p[1], address_of=False, sourceref=_token_sref(p, 1))
|
||||
elif len(p) == 3:
|
||||
p[0] = CallTarget(p[2], True, _token_sref(p, 1))
|
||||
p[0] = CallTarget(target=p[2], address_of=True, sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_dereference(p):
|
||||
"""
|
||||
dereference : '[' dereference_operand ']'
|
||||
"""
|
||||
p[0] = Dereference(p[2][0], p[2][1], _token_sref(p, 1))
|
||||
p[0] = Dereference(location=p[2][0], datatype=p[2][1], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_dereference_operand(p):
|
||||
@ -600,14 +623,14 @@ def p_assignment(p):
|
||||
assignment : assignment_target IS expression
|
||||
| assignment_target IS assignment
|
||||
"""
|
||||
p[0] = Assignment(p[1], p[3], _token_sref(p, 1))
|
||||
p[0] = Assignment(left=p[1], right=p[3], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_aug_assignment(p):
|
||||
"""
|
||||
aug_assignment : assignment_target AUGASSIGN expression
|
||||
"""
|
||||
p[0] = AugAssignment(p[1], p[2], p[3], _token_sref(p, 1))
|
||||
p[0] = AugAssignment(left=p[1], operator=p[2], right=p[3], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
precedence = (
|
||||
@ -632,28 +655,28 @@ def p_expression(p):
|
||||
| expression EQUALS expression
|
||||
| expression NOTEQUALS expression
|
||||
"""
|
||||
p[0] = Expression(p[1], p[2], p[3], _token_sref(p, 1))
|
||||
p[0] = Expression(left=p[1], operator=p[2], right=p[3], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_expression_uminus(p):
|
||||
"""
|
||||
expression : '-' expression %prec UNARY_MINUS
|
||||
"""
|
||||
p[0] = UnaryOp(p[1], p[2], _token_sref(p, 1))
|
||||
p[0] = UnaryOp(operator=p[1], operand=p[2], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_expression_addressof(p):
|
||||
"""
|
||||
expression : BITAND symbolname %prec UNARY_ADDRESSOF
|
||||
"""
|
||||
p[0] = UnaryOp(p[1], p[2], _token_sref(p, 1))
|
||||
p[0] = UnaryOp(operator=p[1], operand=p[2], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_unary_expression_bitinvert(p):
|
||||
"""
|
||||
expression : BITINVERT expression
|
||||
"""
|
||||
p[0] = UnaryOp(p[1], p[2], _token_sref(p, 1))
|
||||
p[0] = UnaryOp(operator=p[1], operand=p[2], sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_expression_group(p):
|
||||
@ -663,7 +686,7 @@ def p_expression_group(p):
|
||||
p[0] = p[2]
|
||||
|
||||
|
||||
def p_expression_ass_rhs(p):
|
||||
def p_expression_expr_value(p):
|
||||
"""expression : expression_value"""
|
||||
p[0] = p[1]
|
||||
|
||||
@ -694,13 +717,12 @@ def p_target_registers(p):
|
||||
| target_registers ',' register
|
||||
"""
|
||||
if len(p) == 2:
|
||||
p[0] = TargetRegisters([p[1]], _token_sref(p, 1))
|
||||
p[0] = TargetRegisters(registers=[p[1]], sourceref=_token_sref(p, 1))
|
||||
else:
|
||||
p[1].add_register(p[3])
|
||||
p[1].add(p[3])
|
||||
p[0] = p[1]
|
||||
|
||||
|
||||
|
||||
def p_empty(p):
|
||||
"""empty :"""
|
||||
pass
|
||||
|
Loading…
Reference in New Issue
Block a user