mirror of
https://github.com/irmen/prog8.git
synced 2024-11-25 19:31:36 +00:00
fixed ast parent pointers
This commit is contained in:
parent
4d70e3d42f
commit
d299742ddf
@ -40,6 +40,7 @@ class PlyParser:
|
||||
# the following shall only be done on the main module after all imports have been done:
|
||||
self.apply_directive_options(module)
|
||||
self.determine_subroutine_usage(module)
|
||||
self.all_parents_connected(module)
|
||||
self.semantic_check(module)
|
||||
self.allocate_zeropage_vars(module)
|
||||
except ParseError as x:
|
||||
@ -68,6 +69,18 @@ class PlyParser:
|
||||
raise ParseError("last statement in a block/subroutine must be a return or goto, "
|
||||
"(or %noreturn directive to silence this error)", last_stmt.sourceref)
|
||||
|
||||
def all_parents_connected(self, module: Module) -> None:
|
||||
# check that all parents are connected in all nodes
|
||||
def check(node: AstNode, expected_parent: AstNode) -> None:
|
||||
if node.parent is not expected_parent:
|
||||
raise CompileError("parent node invalid", node, node.parent, expected_parent, node.sourceref, expected_parent.sourceref)
|
||||
for child_node in node.nodes:
|
||||
if isinstance(child_node, AstNode):
|
||||
check(child_node, node)
|
||||
else:
|
||||
raise TypeError("invalid child node type", child_node, " in ", node, " sref", node.sourceref)
|
||||
check(module, None)
|
||||
|
||||
def semantic_check(self, module: Module) -> None:
|
||||
# perform semantic analysis / checks on the syntactic parse tree we have so far
|
||||
# (note: symbol names have already been checked to exist when we start this)
|
||||
@ -203,12 +216,15 @@ class PlyParser:
|
||||
@no_type_check
|
||||
def create_multiassigns(self, module: Module) -> None:
|
||||
# create multi-assign statements from nested assignments (A=B=C=5),
|
||||
# and optimize TargetRegisters down to single Register if it's just one register.
|
||||
# @todo optimize TargetRegisters down to single Register if it's just one register.
|
||||
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):
|
||||
@ -325,12 +341,10 @@ class PlyParser:
|
||||
elif isinstance(expr, ExpressionWithOperator):
|
||||
self._get_subroutine_usages_from_expression(usages, expr.left, parent_scope)
|
||||
self._get_subroutine_usages_from_expression(usages, expr.right, parent_scope)
|
||||
elif isinstance(expr, LiteralValue):
|
||||
elif isinstance(expr, (LiteralValue, AddressOf)):
|
||||
return
|
||||
elif isinstance(expr, Dereference):
|
||||
return self._get_subroutine_usages_from_expression(usages, expr.operand, parent_scope)
|
||||
elif isinstance(expr, AddressOf):
|
||||
return self._get_subroutine_usages_from_expression(usages, expr.name, parent_scope)
|
||||
elif isinstance(expr, SymbolName):
|
||||
try:
|
||||
symbol = parent_scope.lookup(expr.name)
|
||||
|
@ -7,7 +7,7 @@ Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
||||
|
||||
from collections import defaultdict
|
||||
from typing import Dict, List, Callable, Any, no_type_check
|
||||
from ..plyparse import Block, VarType, VarDef, LiteralValue
|
||||
from ..plyparse import Block, VarType, VarDef, LiteralValue, AddressOf
|
||||
from ..datatypes import DataType, STRING_DATATYPES
|
||||
from . import to_hex, to_mflpt5, CodeError
|
||||
|
||||
@ -66,6 +66,8 @@ def generate_block_init(out: Callable, block: Block) -> None:
|
||||
prev_value_a = bytevar.value.value
|
||||
out("\vsta {:s}".format(bytevar.name))
|
||||
for wordvar in sorted(vars_by_datatype[DataType.WORD], key=lambda vd: vd.value):
|
||||
if isinstance(wordvar.value, AddressOf):
|
||||
raise CodeError("can't yet use addressof here", wordvar.sourceref) # XXX
|
||||
assert isinstance(wordvar.value, LiteralValue) and type(wordvar.value.value) is int
|
||||
v_hi, v_lo = divmod(wordvar.value.value, 256)
|
||||
if v_hi != prev_value_a:
|
||||
|
@ -64,7 +64,8 @@ class Optimizer:
|
||||
evaluated = process_expression(expression) # type: ignore
|
||||
if evaluated is not expression:
|
||||
# replace the node with the newly evaluated result
|
||||
expression.parent.replace_node(expression, evaluated)
|
||||
parent = expression.parent
|
||||
parent.replace_node(expression, evaluated)
|
||||
self.optimizations_performed = True
|
||||
except ParseError:
|
||||
raise
|
||||
@ -389,15 +390,18 @@ class Optimizer:
|
||||
node.my_scope().nodes.remove(node)
|
||||
|
||||
|
||||
def process_expression(expr: Expression) -> Any:
|
||||
def process_expression(expr: Expression) -> Expression:
|
||||
# process/simplify all expressions (constant folding etc)
|
||||
result = None # type: Expression
|
||||
if expr.is_compile_constant() or isinstance(expr, ExpressionWithOperator) and expr.must_be_constant:
|
||||
return process_constant_expression(expr, expr.sourceref)
|
||||
result = _process_constant_expression(expr, expr.sourceref)
|
||||
else:
|
||||
return process_dynamic_expression(expr, expr.sourceref)
|
||||
result = _process_dynamic_expression(expr, expr.sourceref)
|
||||
result.parent = expr.parent
|
||||
return result
|
||||
|
||||
|
||||
def process_constant_expression(expr: Expression, sourceref: SourceRef) -> LiteralValue:
|
||||
def _process_constant_expression(expr: Expression, sourceref: SourceRef) -> LiteralValue:
|
||||
# the expression must result in a single (constant) value (int, float, whatever) wrapped as LiteralValue.
|
||||
if isinstance(expr, LiteralValue):
|
||||
return expr
|
||||
@ -418,8 +422,8 @@ def process_constant_expression(expr: Expression, sourceref: SourceRef) -> Liter
|
||||
else:
|
||||
raise ExpressionEvaluationError("constant symbol required, not {}".format(value.__class__.__name__), expr.sourceref)
|
||||
elif isinstance(expr, AddressOf):
|
||||
assert isinstance(expr.name, SymbolName)
|
||||
value = check_symbol_definition(expr.name.name, expr.my_scope(), expr.sourceref)
|
||||
assert isinstance(expr.name, str)
|
||||
value = check_symbol_definition(expr.name, expr.my_scope(), expr.sourceref)
|
||||
if isinstance(value, VarDef):
|
||||
if value.vartype == VarType.MEMORY:
|
||||
if isinstance(value.value, LiteralValue):
|
||||
@ -427,18 +431,18 @@ def process_constant_expression(expr: Expression, sourceref: SourceRef) -> Liter
|
||||
else:
|
||||
raise ExpressionEvaluationError("constant literal value required", value.sourceref)
|
||||
if value.vartype == VarType.CONST:
|
||||
raise ExpressionEvaluationError("can't take the address of a constant", expr.name.sourceref)
|
||||
raise ExpressionEvaluationError("can't take the address of a constant", expr.sourceref)
|
||||
raise ExpressionEvaluationError("address-of this {} isn't a compile-time constant"
|
||||
.format(value.__class__.__name__), expr.name.sourceref)
|
||||
.format(value.__class__.__name__), expr.sourceref)
|
||||
else:
|
||||
raise ExpressionEvaluationError("constant address required, not {}"
|
||||
.format(value.__class__.__name__), expr.name.sourceref)
|
||||
.format(value.__class__.__name__), expr.sourceref)
|
||||
elif isinstance(expr, SubCall):
|
||||
if isinstance(expr.target, SymbolName): # 'function(1,2,3)'
|
||||
funcname = expr.target.name
|
||||
if funcname in math_functions or funcname in builtin_functions:
|
||||
func_args = []
|
||||
for a in (process_constant_expression(callarg.value, sourceref) for callarg in expr.arguments.nodes):
|
||||
for a in (_process_constant_expression(callarg.value, sourceref) for callarg in list(expr.arguments.nodes)):
|
||||
if isinstance(a, LiteralValue):
|
||||
func_args.append(a.value)
|
||||
else:
|
||||
@ -459,7 +463,8 @@ def process_constant_expression(expr: Expression, sourceref: SourceRef) -> Liter
|
||||
elif isinstance(expr, ExpressionWithOperator):
|
||||
if expr.unary:
|
||||
left_sourceref = expr.left.sourceref if isinstance(expr.left, AstNode) else sourceref
|
||||
expr.left = process_constant_expression(expr.left, left_sourceref)
|
||||
expr.left = _process_constant_expression(expr.left, left_sourceref)
|
||||
expr.left.parent = expr
|
||||
if isinstance(expr.left, LiteralValue) and type(expr.left.value) in (int, float):
|
||||
try:
|
||||
if expr.operator == '-':
|
||||
@ -474,9 +479,11 @@ def process_constant_expression(expr: Expression, sourceref: SourceRef) -> Liter
|
||||
raise ValueError("invalid operand type for unary operator", expr.left, expr.operator)
|
||||
else:
|
||||
left_sourceref = expr.left.sourceref if isinstance(expr.left, AstNode) else sourceref
|
||||
expr.left = process_constant_expression(expr.left, left_sourceref)
|
||||
expr.left = _process_constant_expression(expr.left, left_sourceref)
|
||||
expr.left.parent = expr
|
||||
right_sourceref = expr.right.sourceref if isinstance(expr.right, AstNode) else sourceref
|
||||
expr.right = process_constant_expression(expr.right, right_sourceref)
|
||||
expr.right = _process_constant_expression(expr.right, right_sourceref)
|
||||
expr.right.parent = expr
|
||||
if isinstance(expr.left, LiteralValue):
|
||||
if isinstance(expr.right, LiteralValue):
|
||||
return expr.evaluate_primitive_constants(expr.right.sourceref)
|
||||
@ -490,7 +497,7 @@ def process_constant_expression(expr: Expression, sourceref: SourceRef) -> Liter
|
||||
raise ExpressionEvaluationError("constant value required, not {}".format(expr.__class__.__name__), expr.sourceref)
|
||||
|
||||
|
||||
def process_dynamic_expression(expr: Expression, sourceref: SourceRef) -> Any:
|
||||
def _process_dynamic_expression(expr: Expression, sourceref: SourceRef) -> Expression:
|
||||
# constant-fold a dynamic expression
|
||||
if isinstance(expr, LiteralValue):
|
||||
return expr
|
||||
@ -498,17 +505,17 @@ def process_dynamic_expression(expr: Expression, sourceref: SourceRef) -> Any:
|
||||
return LiteralValue(value=expr.const_value(), sourceref=sourceref) # type: ignore
|
||||
elif isinstance(expr, SymbolName):
|
||||
try:
|
||||
return process_constant_expression(expr, sourceref)
|
||||
return _process_constant_expression(expr, sourceref)
|
||||
except ExpressionEvaluationError:
|
||||
return expr
|
||||
elif isinstance(expr, AddressOf):
|
||||
try:
|
||||
return process_constant_expression(expr, sourceref)
|
||||
return _process_constant_expression(expr, sourceref)
|
||||
except ExpressionEvaluationError:
|
||||
return expr
|
||||
elif isinstance(expr, SubCall):
|
||||
try:
|
||||
return process_constant_expression(expr, sourceref)
|
||||
return _process_constant_expression(expr, sourceref)
|
||||
except ExpressionEvaluationError:
|
||||
if isinstance(expr.target, SymbolName):
|
||||
check_symbol_definition(expr.target.name, expr.my_scope(), expr.target.sourceref)
|
||||
@ -522,18 +529,21 @@ def process_dynamic_expression(expr: Expression, sourceref: SourceRef) -> Any:
|
||||
elif isinstance(expr, ExpressionWithOperator):
|
||||
if expr.unary:
|
||||
left_sourceref = expr.left.sourceref if isinstance(expr.left, AstNode) else sourceref
|
||||
expr.left = process_dynamic_expression(expr.left, left_sourceref)
|
||||
expr.left = _process_dynamic_expression(expr.left, left_sourceref)
|
||||
expr.left.parent = expr
|
||||
try:
|
||||
return process_constant_expression(expr, sourceref)
|
||||
return _process_constant_expression(expr, sourceref)
|
||||
except ExpressionEvaluationError:
|
||||
return expr
|
||||
else:
|
||||
left_sourceref = expr.left.sourceref if isinstance(expr.left, AstNode) else sourceref
|
||||
expr.left = process_dynamic_expression(expr.left, left_sourceref)
|
||||
expr.left = _process_dynamic_expression(expr.left, left_sourceref)
|
||||
expr.left.parent = expr
|
||||
right_sourceref = expr.right.sourceref if isinstance(expr.right, AstNode) else sourceref
|
||||
expr.right = process_dynamic_expression(expr.right, right_sourceref)
|
||||
expr.right = _process_dynamic_expression(expr.right, right_sourceref)
|
||||
expr.right.parent = expr
|
||||
try:
|
||||
return process_constant_expression(expr, sourceref)
|
||||
return _process_constant_expression(expr, sourceref)
|
||||
except ExpressionEvaluationError:
|
||||
return expr
|
||||
else:
|
||||
|
@ -86,12 +86,17 @@ class AstNode:
|
||||
yield from node.all_nodes(*nodetypes)
|
||||
|
||||
def remove_node(self, node: 'AstNode') -> None:
|
||||
assert node.parent is self
|
||||
self.nodes.remove(node)
|
||||
node.parent = None
|
||||
|
||||
def replace_node(self, oldnode: 'AstNode', newnode: 'AstNode') -> None:
|
||||
assert oldnode.parent is self
|
||||
assert isinstance(newnode, AstNode)
|
||||
idx = self.nodes.index(oldnode)
|
||||
self.nodes[idx] = newnode
|
||||
newnode.parent = self
|
||||
oldnode.parent = None
|
||||
|
||||
def add_node(self, newnode: 'AstNode', index: int = None) -> None:
|
||||
assert isinstance(newnode, AstNode)
|
||||
@ -99,6 +104,7 @@ class AstNode:
|
||||
self.nodes.append(newnode)
|
||||
else:
|
||||
self.nodes.insert(index, newnode)
|
||||
newnode.parent = self
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
@ -421,7 +427,7 @@ class LiteralValue(Expression):
|
||||
@attr.s(cmp=False)
|
||||
class AddressOf(Expression):
|
||||
# no subnodes.
|
||||
name = attr.ib(type=str)
|
||||
name = attr.ib(type=str, validator=attr.validators._InstanceOfValidator(type=str))
|
||||
|
||||
def is_compile_constant(self) -> bool:
|
||||
return False
|
||||
@ -455,12 +461,12 @@ class SymbolName(Expression):
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class Dereference(Expression):
|
||||
# one subnode: operand (SymbolName, int or register name)
|
||||
# one subnode: operand (SymbolName, integer LiteralValue or Register)
|
||||
datatype = attr.ib()
|
||||
size = attr.ib(type=int, default=None)
|
||||
|
||||
@property
|
||||
def operand(self) -> Union[SymbolName, int, str]:
|
||||
def operand(self) -> Union[SymbolName, LiteralValue, Register]:
|
||||
return self.nodes[0] # type: ignore
|
||||
|
||||
def __attrs_post_init__(self):
|
||||
@ -475,6 +481,8 @@ class Dereference(Expression):
|
||||
if not self.datatype.to_enum().isnumeric():
|
||||
raise ParseError("dereference target value must be byte, word, float", self.datatype.sourceref)
|
||||
self.datatype = self.datatype.to_enum()
|
||||
if self.nodes and not isinstance(self.nodes[0], (SymbolName, LiteralValue, Register)):
|
||||
raise TypeError("operand of dereference invalid type", self.nodes[0], self.sourceref)
|
||||
|
||||
def is_compile_constant(self) -> bool:
|
||||
return False
|
||||
@ -514,13 +522,34 @@ class IncrDecr(AstNode):
|
||||
|
||||
@attr.s(cmp=False, slots=True, repr=False)
|
||||
class ExpressionWithOperator(Expression):
|
||||
left = attr.ib() # type: Expression
|
||||
# 2 nodes: left (Expression), right (not present if unary, Expression if not unary)
|
||||
operator = attr.ib(type=str)
|
||||
right = attr.ib() # type: Expression
|
||||
unary = attr.ib(type=bool, default=False)
|
||||
# when evaluating the expression, does it have to be a compile-time constant value?
|
||||
must_be_constant = attr.ib(type=bool, init=False, default=False)
|
||||
|
||||
@property
|
||||
def unary(self) -> bool:
|
||||
return len(self.nodes) == 1
|
||||
|
||||
@property
|
||||
def left(self) -> Expression:
|
||||
return self.nodes[0] # type: ignore
|
||||
|
||||
@left.setter
|
||||
def left(self, newleft: Expression) -> None:
|
||||
if self.nodes:
|
||||
self.nodes[0] = newleft
|
||||
else:
|
||||
self.nodes.append(newleft)
|
||||
|
||||
@property
|
||||
def right(self) -> Optional[Expression]:
|
||||
return self.nodes[1] if len(self.nodes) == 2 else None # type: ignore
|
||||
|
||||
@right.setter
|
||||
def right(self, newright: Expression) -> None:
|
||||
self.nodes[1] = newright
|
||||
|
||||
def __attrs_post_init__(self):
|
||||
assert self.operator not in ("++", "--"), "incr/decr should not be an expression"
|
||||
if self.operator == "mod":
|
||||
@ -540,7 +569,9 @@ class ExpressionWithOperator(Expression):
|
||||
raise ValueError("operator", self.operator)
|
||||
estr = "{} {} {}".format(repr(self.left.value), self.operator, repr(self.right.value))
|
||||
try:
|
||||
return LiteralValue(value=eval(estr, {}, {}), sourceref=sourceref) # type: ignore # safe because of checks above
|
||||
lv = LiteralValue(value=eval(estr, {}, {}), sourceref=sourceref) # type: ignore # safe because of checks above
|
||||
lv.parent = self.parent
|
||||
return lv
|
||||
except ZeroDivisionError:
|
||||
raise ParseError("division by zero", sourceref)
|
||||
except Exception as x:
|
||||
@ -580,12 +611,12 @@ class CallArguments(AstNode):
|
||||
@attr.s(cmp=False, repr=False)
|
||||
class SubCall(Expression):
|
||||
# has three subnodes:
|
||||
# 0: target (Symbolname, int, or Dereference),
|
||||
# 0: target (Symbolname, integer LiteralValue, or Dereference),
|
||||
# 1: preserve_regs (PreserveRegs)
|
||||
# 2: arguments (CallArguments).
|
||||
|
||||
@property
|
||||
def target(self) -> Union[SymbolName, int, Dereference]:
|
||||
def target(self) -> Union[SymbolName, LiteralValue, Dereference]:
|
||||
return self.nodes[0] # type: ignore
|
||||
|
||||
@property
|
||||
@ -659,6 +690,7 @@ class VarDef(AstNode):
|
||||
print("warning: {}: array/matrix with size 1, use normal byte/word instead".format(self.sourceref))
|
||||
if self.value is None and (self.datatype.isnumeric() or self.datatype.isarray()):
|
||||
self.value = LiteralValue(value=0, sourceref=self.sourceref)
|
||||
self.value.parent = self
|
||||
# if it's a matrix with interleave, it must be memory mapped
|
||||
if self.datatype == DataType.MATRIX and len(self.size) == 3:
|
||||
if self.vartype != VarType.MEMORY:
|
||||
@ -795,7 +827,9 @@ def coerce_constant_value(datatype: DataType, value: AstNode,
|
||||
if isinstance(value, LiteralValue):
|
||||
if type(value.value) is str and len(value.value) == 1 and (datatype.isnumeric() or datatype.isarray()):
|
||||
# convert a string of length 1 to its numeric character value
|
||||
return True, LiteralValue(value=char_to_bytevalue(value.value), sourceref=value.sourceref) # type: ignore
|
||||
lv = LiteralValue(value=char_to_bytevalue(value.value), sourceref=value.sourceref) # type: ignore
|
||||
lv.parent = value.parent
|
||||
return True, lv
|
||||
# if we're an integer value and the passed value is float, truncate it (and give a warning)
|
||||
if datatype in (DataType.BYTE, DataType.WORD, DataType.MATRIX) and isinstance(value.value, float):
|
||||
frac = math.modf(value.value)
|
||||
@ -803,7 +837,9 @@ def coerce_constant_value(datatype: DataType, value: AstNode,
|
||||
print_warning("float value truncated ({} to datatype {})".format(value.value, datatype.name), sourceref=sourceref)
|
||||
v2 = int(value.value)
|
||||
verify_bounds(v2)
|
||||
return True, LiteralValue(value=v2, sourceref=value.sourceref) # type: ignore
|
||||
lv = LiteralValue(value=v2, sourceref=value.sourceref) # type: ignore
|
||||
lv.parent = value.parent
|
||||
return True, lv
|
||||
if type(value.value) in (int, float):
|
||||
verify_bounds(value.value)
|
||||
if datatype == DataType.WORD:
|
||||
@ -821,7 +857,9 @@ def coerce_constant_value(datatype: DataType, value: AstNode,
|
||||
elif isinstance(value, AddressOf):
|
||||
try:
|
||||
address = value.const_value()
|
||||
return True, LiteralValue(value=address, sourceref=value.sourceref) # type: ignore
|
||||
lv = LiteralValue(value=address, sourceref=value.sourceref) # type: ignore
|
||||
lv.parent = value.parent
|
||||
return True, lv
|
||||
except TypeError:
|
||||
return False, value
|
||||
if datatype == DataType.WORD and not isinstance(value, (LiteralValue, Dereference, Register, SymbolName, AddressOf)):
|
||||
@ -1174,8 +1212,11 @@ def p_call_subroutine(p):
|
||||
"""
|
||||
sref = _token_sref(p, 3)
|
||||
p[0] = SubCall(sourceref=sref)
|
||||
p[0].nodes.append(p[1])
|
||||
p[0].nodes.append(p[2])
|
||||
target = p[1]
|
||||
if isinstance(target, int):
|
||||
target = LiteralValue(value=target, sourceref=sref)
|
||||
p[0].nodes.append(target)
|
||||
p[0].nodes.append(p[2] or PreserveRegs(registers="", sourceref=sref))
|
||||
p[0].nodes.append(CallArguments(nodes=p[4] or [], sourceref=sref))
|
||||
|
||||
|
||||
@ -1300,7 +1341,14 @@ def p_dereference(p):
|
||||
dereference : '[' dereference_operand ']'
|
||||
"""
|
||||
p[0] = Dereference(datatype=p[2][1], sourceref=_token_sref(p, 1))
|
||||
p[0].nodes.append(p[2][0])
|
||||
operand = p[2][0]
|
||||
if isinstance(operand, int):
|
||||
p[0].nodes.append(LiteralValue(value=operand, sourceref=p[0].sourceref))
|
||||
elif isinstance(operand, str):
|
||||
p[0].nodes.append(Register(name=operand, sourceref=p[0].sourceref))
|
||||
elif isinstance(operand, SymbolName):
|
||||
p[0].nodes.append(operand)
|
||||
attr.validate(p[0])
|
||||
|
||||
|
||||
def p_dereference_operand(p):
|
||||
@ -1380,35 +1428,40 @@ def p_expression(p):
|
||||
| expression EQUALS expression
|
||||
| expression NOTEQUALS expression
|
||||
"""
|
||||
p[0] = ExpressionWithOperator(left=p[1], operator=p[2], right=p[3], sourceref=_token_sref(p, 2))
|
||||
p[0] = ExpressionWithOperator(operator=p[2], sourceref=_token_sref(p, 2))
|
||||
p[0].nodes.append(p[1])
|
||||
p[0].nodes.append(p[3])
|
||||
|
||||
|
||||
def p_expression_uminus(p):
|
||||
"""
|
||||
expression : '-' expression %prec UNARY_MINUS
|
||||
"""
|
||||
p[0] = ExpressionWithOperator(left=p[2], operator=p[1], right=None, unary=True, sourceref=_token_sref(p, 1))
|
||||
p[0] = ExpressionWithOperator(operator=p[1], sourceref=_token_sref(p, 1))
|
||||
p[0].nodes.append(p[2])
|
||||
|
||||
|
||||
def p_expression_addressof(p):
|
||||
"""
|
||||
expression : BITAND symbolname %prec UNARY_ADDRESSOF
|
||||
"""
|
||||
p[0] = AddressOf(name=p[2], sourceref=_token_sref(p, 1))
|
||||
p[0] = AddressOf(name=p[2].name, sourceref=_token_sref(p, 1))
|
||||
|
||||
|
||||
def p_unary_expression_bitinvert(p):
|
||||
"""
|
||||
expression : BITINVERT expression
|
||||
"""
|
||||
p[0] = ExpressionWithOperator(left=p[2], operator=p[1], right=None, unary=True, sourceref=_token_sref(p, 1))
|
||||
p[0] = ExpressionWithOperator(operator=p[1], sourceref=_token_sref(p, 1))
|
||||
p[0].nodes.append(p[2])
|
||||
|
||||
|
||||
def p_unary_expression_logicnot(p):
|
||||
"""
|
||||
expression : LOGICNOT expression
|
||||
"""
|
||||
p[0] = ExpressionWithOperator(left=p[2], operator=p[1], right=None, unary=True, sourceref=_token_sref(p, 1))
|
||||
p[0] = ExpressionWithOperator(operator=p[1], sourceref=_token_sref(p, 1))
|
||||
p[0].nodes.append(p[2])
|
||||
|
||||
|
||||
def p_expression_group(p):
|
||||
|
@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
from il65.plylex import lexer, tokens, find_tok_column, literals, reserved, SourceRef
|
||||
from il65.plyparse import parser, connect_parents, TokenFilter, Module, Subroutine, Block, IncrDecr, Scope, \
|
||||
VarDef, Expression, ExpressionWithOperator, LiteralValue, Label, SubCall, Dereference
|
||||
VarDef, Register, ExpressionWithOperator, LiteralValue, Label, SubCall, Dereference
|
||||
from il65.datatypes import DataType
|
||||
|
||||
|
||||
@ -137,7 +137,7 @@ def test_parser():
|
||||
assert sub2 is sub
|
||||
assert sub2.lineref == "src l. 19"
|
||||
all_nodes = list(result.all_nodes())
|
||||
assert len(all_nodes) == 12
|
||||
assert len(all_nodes) == 14
|
||||
all_nodes = list(result.all_nodes(Subroutine))
|
||||
assert len(all_nodes) == 1
|
||||
assert isinstance(all_nodes[0], Subroutine)
|
||||
@ -176,8 +176,8 @@ def test_parser_2():
|
||||
call = block.scope.nodes[0]
|
||||
assert isinstance(call, SubCall)
|
||||
assert len(call.arguments.nodes) == 2
|
||||
assert isinstance(call.target, int)
|
||||
assert call.target == 999
|
||||
assert isinstance(call.target, LiteralValue)
|
||||
assert call.target.value == 999
|
||||
call = block.scope.nodes[1]
|
||||
assert isinstance(call, SubCall)
|
||||
assert len(call.arguments.nodes) == 0
|
||||
@ -219,10 +219,14 @@ def test_typespec():
|
||||
assert isinstance(t2, Dereference)
|
||||
assert isinstance(t3, Dereference)
|
||||
assert isinstance(t4, Dereference)
|
||||
assert t1.operand == 0xc000
|
||||
assert t2.operand == 0xc000
|
||||
assert t3.operand == "AX"
|
||||
assert t4.operand == "AX"
|
||||
assert isinstance(t1.operand, LiteralValue)
|
||||
assert isinstance(t2.operand, LiteralValue)
|
||||
assert isinstance(t3.operand, Register)
|
||||
assert isinstance(t4.operand, Register)
|
||||
assert t1.operand.value == 0xc000
|
||||
assert t2.operand.value == 0xc000
|
||||
assert t3.operand.name == "AX"
|
||||
assert t4.operand.name == "AX"
|
||||
assert t1.datatype == DataType.WORD
|
||||
assert t2.datatype == DataType.BYTE
|
||||
assert t3.datatype == DataType.WORD
|
||||
|
@ -61,7 +61,8 @@ def test_set_value():
|
||||
assert v.value is None
|
||||
v.value = LiteralValue(value="hello", sourceref=sref)
|
||||
assert v.value.value == "hello"
|
||||
e = ExpressionWithOperator(left=LiteralValue(value=42, sourceref=sref), operator="-", unary=True, right=None, sourceref=sref)
|
||||
e = ExpressionWithOperator(operator="-", sourceref=sref)
|
||||
e.left = LiteralValue(value=42, sourceref=sref)
|
||||
assert not e.must_be_constant
|
||||
v.value = e
|
||||
assert v.value is e
|
||||
@ -94,7 +95,8 @@ def test_const_value():
|
||||
assert v.const_value() == 0
|
||||
v.value = LiteralValue(value=42.9988, sourceref=sref)
|
||||
assert v.const_value() == 42.9988
|
||||
e = ExpressionWithOperator(left=LiteralValue(value=42, sourceref=sref), operator="-", unary=True, right=None, sourceref=sref)
|
||||
e = ExpressionWithOperator(operator="-", sourceref=sref)
|
||||
e.left = LiteralValue(value=42, sourceref=sref)
|
||||
v.value = e
|
||||
with pytest.raises(TypeError):
|
||||
v.const_value()
|
||||
|
@ -313,7 +313,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -321,7 +321,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -353,7 +353,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -378,7 +378,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -667,7 +667,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -675,7 +675,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -707,7 +707,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -732,7 +732,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -1021,7 +1021,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -1029,7 +1029,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -1061,7 +1061,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -1086,7 +1086,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -1375,7 +1375,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -1383,7 +1383,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -1415,7 +1415,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -1440,7 +1440,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -1729,7 +1729,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -1737,7 +1737,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -1769,7 +1769,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -1794,7 +1794,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -2083,7 +2083,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -2091,7 +2091,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -2123,7 +2123,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -2148,7 +2148,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -2437,7 +2437,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -2445,7 +2445,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -2477,7 +2477,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -2502,7 +2502,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -2791,7 +2791,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -2799,7 +2799,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -2831,7 +2831,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -2856,7 +2856,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -3145,7 +3145,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -3153,7 +3153,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -3185,7 +3185,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -3210,7 +3210,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -3499,7 +3499,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -3507,7 +3507,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -3539,7 +3539,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -3564,7 +3564,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -3853,7 +3853,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -3861,7 +3861,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -3893,7 +3893,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -3918,7 +3918,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -4207,7 +4207,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -4215,7 +4215,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -4247,7 +4247,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -4272,7 +4272,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -4561,7 +4561,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -4569,7 +4569,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -4601,7 +4601,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -4626,7 +4626,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -4915,7 +4915,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -4923,7 +4923,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -4955,7 +4955,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -4980,7 +4980,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -5269,7 +5269,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -5277,7 +5277,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -5309,7 +5309,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -5334,7 +5334,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -5623,7 +5623,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -5631,7 +5631,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -5663,7 +5663,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -5688,7 +5688,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -5977,7 +5977,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -5985,7 +5985,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -6017,7 +6017,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -6042,7 +6042,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -6331,7 +6331,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -6339,7 +6339,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -6371,7 +6371,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -6396,7 +6396,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -6685,7 +6685,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -6693,7 +6693,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -6725,7 +6725,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -6750,7 +6750,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
@ -7039,7 +7039,7 @@ max:
|
||||
|
||||
sub sub1 () -> (X?) = $ffdd
|
||||
sub sub2 (A) -> (Y?) = $eecc
|
||||
sub sub3 (XY) -> (Y?) = $ddaa
|
||||
sub sub3 (thing: XY) -> (Y?) = $ddaa
|
||||
sub sub4 (string: XY, other : A) -> (Y?) = $dd22
|
||||
|
||||
|
||||
@ -7047,7 +7047,7 @@ bar:
|
||||
goto sub1
|
||||
return sub2 (1 )
|
||||
return sub3 (3)
|
||||
return sub3 (XY="hello")
|
||||
return sub3 (thing="hello")
|
||||
return sub3 ("hello, there")
|
||||
return sub4 (string="hello, there", other = 42)
|
||||
return sub4 ("hello", 42)
|
||||
@ -7079,7 +7079,7 @@ bar:
|
||||
sub1!()
|
||||
sub2!(11)
|
||||
sub3 !(3)
|
||||
sub3! (XY="hello")
|
||||
sub3! (thing="hello")
|
||||
sub3! ("hello, there")
|
||||
sub4! ("hello", 42)
|
||||
sub4! ("hello", other=42)
|
||||
@ -7104,7 +7104,7 @@ bar:
|
||||
sub1()
|
||||
sub2(11)
|
||||
sub3 (3)
|
||||
sub3 (XY="hello")
|
||||
sub3 (thing="hello")
|
||||
sub3 ("hello, there")
|
||||
sub4 ("hello", 42)
|
||||
sub4 ("hello", other= 42)
|
||||
|
Loading…
Reference in New Issue
Block a user