From d299742ddf059bf78bceb4fa3071865d910dc8dc Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 30 Jan 2018 01:38:37 +0100 Subject: [PATCH] fixed ast parent pointers --- il65/compile.py | 22 ++++-- il65/emit/variables.py | 4 +- il65/optimize.py | 56 +++++++++------ il65/plyparse.py | 93 ++++++++++++++++++------ tests/test_parser.py | 20 +++--- tests/test_vardef.py | 6 +- testsource/large.ill | 160 ++++++++++++++++++++--------------------- todo.ill | 1 + 8 files changed, 224 insertions(+), 138 deletions(-) diff --git a/il65/compile.py b/il65/compile.py index d64384732..d360008f6 100644 --- a/il65/compile.py +++ b/il65/compile.py @@ -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) diff --git a/il65/emit/variables.py b/il65/emit/variables.py index 02b4d799a..7efc63d45 100644 --- a/il65/emit/variables.py +++ b/il65/emit/variables.py @@ -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: diff --git a/il65/optimize.py b/il65/optimize.py index 3088874ab..3bfd201e1 100644 --- a/il65/optimize.py +++ b/il65/optimize.py @@ -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: diff --git a/il65/plyparse.py b/il65/plyparse.py index f4437428d..d8a71e86c 100644 --- a/il65/plyparse.py +++ b/il65/plyparse.py @@ -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): diff --git a/tests/test_parser.py b/tests/test_parser.py index ca54b0e21..fcb6aa2db 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -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 diff --git a/tests/test_vardef.py b/tests/test_vardef.py index 512399219..eaf171f2e 100644 --- a/tests/test_vardef.py +++ b/tests/test_vardef.py @@ -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() diff --git a/testsource/large.ill b/testsource/large.ill index 8da55ad23..84953b191 100644 --- a/testsource/large.ill +++ b/testsource/large.ill @@ -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) diff --git a/todo.ill b/todo.ill index 01e152d33..5eb8b2ec1 100644 --- a/todo.ill +++ b/todo.ill @@ -2,6 +2,7 @@ ~ main { var .float flt + var .word vmemaddr1 = &flt start: