From: Philippe Proulx Date: Mon, 2 Oct 2023 03:33:09 +0000 (-0400) Subject: Add the directive form of a repetition (`!repeat`) X-Git-Tag: v0.8.0 X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=e57a18e1620dc01979402c7dda30c2a44c64792f;p=normand.git Add the directive form of a repetition (`!repeat`) This patch introduces the first directive amongst other ones I'd like to add later. `!repeat` is equivalent to what's now called the post-item repetition form: aa (bb cc dd) * 3 ee ff aa !repeat 3 bb cc dd !end ff `!repeat` (or the shorter `!r` alias) accepts exactly what's accepted after a `*`: a constant integer, an expression, and (new) a name. Obviously, the `!` symbol isn't considered a comment anymore. See `README.adoc` and the new tests to learn more. This patch also: * Makes it legal to refer to the special `ICITTE` name within a repetition count expression. It's less natural for the post-item form, but it works nevertheless. * Decouples the variables and labels dictionary types as `VariablesT` and `LabelsT`. Indeed, a variable value is (for the moment) an `int` or `float` instance, while a label value is always an integer (because it's an offset snapshot). Change-Id: I77cd4c9f29639082612534940c48964a61e51392 Signed-off-by: Philippe Proulx --- diff --git a/README.adoc b/README.adoc index 40eafc2..f0852d1 100644 --- a/README.adoc +++ b/README.adoc @@ -29,7 +29,7 @@ _**Normand**_ is a text-to-binary processor with its own language. This package offers both a portable {py3} module and a command-line tool. -WARNING: This version of Normand is 0.7, meaning both the Normand +WARNING: This version of Normand is 0.8, meaning both the Normand language and the module/CLI interface aren't stable. ifdef::env-github[] @@ -178,6 +178,10 @@ Input: + ---- aa bb * 5 cc "yeah\0" * {zoom * 3} + +!repeat 3 + ff ee "juice" +!end ---- + Output: @@ -190,6 +194,8 @@ aa bb bb bb bb bb cc 79 65 61 68 00 79 65 61 68 ┆ •••••••yeah 61 68 00 79 65 61 68 00 79 65 61 68 00 79 65 61 ┆ ah•yeah•yeah•yea 68 00 79 65 61 68 00 79 65 61 68 00 79 65 61 68 ┆ h•yeah•yeah•yeah 00 79 65 61 68 00 79 65 61 68 00 79 65 61 68 00 ┆ •yeah•yeah•yeah• +ff ee 6a 75 69 63 65 ff ee 6a 75 69 63 65 ff ee ┆ ••juice••juice•• +6a 75 69 63 65 ┆ juice ---- Alignment:: @@ -363,18 +369,22 @@ This is similar to an assembly label. * A <>, that is, a scoped sequence of items. -Moreover, you can <> any item above, except an offset -or a label, a given fixed or variable number of times. This is called a -repetition. +* A <>. + +Moreover, you can repeat many items above a constant or variable number +of times with the ``pass:[*]`` operator _after_ the item to repeat. This +is called a <>. A Normand comment may exist: * Between items, possibly within a group. * Between the nibbles of a constant hexadecimal byte. * Between the bits of a constant binary byte. -* Between the last item and the ``pass:[*]`` character of a repetition, - and between that ``pass:[*]`` character and the following number - or expression. +* Between the last item and the ``pass:[*]`` character of a post-item + repetition, and between that ``pass:[*]`` character and the following + number or expression. +* Between the ``!repeat``/``!r`` prefix and the following constant + integer, name, or expression of a repetition block. A comment is anything between two ``pass:[#]`` characters on the same line, or from ``pass:[#]`` until the end of the line. Whitespaces and @@ -382,7 +392,7 @@ the following symbol characters are also considered comments where a comment may exist: ---- -! / \ ? & : ; . , + [ ] _ = | - +/ \ ? & : ; . , + [ ] _ = | - ---- The latter serve to improve readability so that you may write, for @@ -953,8 +963,8 @@ A _group_ is a scoped sequence of items. The <> within a group aren't visible outside of it. -The main purpose of a group is to <> more than a -single item. +The main purpose of a group is to <> more +than a single item and to isolate labels. A group is: @@ -1020,22 +1030,14 @@ Output: ---- ==== -=== Repetition - -A _repetition_ represents the bytes of an item repeated a given number -of times. +=== Repetition block -A repetition is: - -. Any item except: +A _repetition block_ represents the bytes of one or more items repeated +a given number of times. -** A <>. -** A <>. -** A <>. -** A <>. -** A <>. +A repetition block is: -. The ``pass:[*]`` character. +. The `!repeat` or `!r` prefix. . One of: @@ -1049,21 +1051,38 @@ For a repetition at some source location{nbsp}__**L**__, this expression may contain: + -- -* The name of any <> defined before{nbsp}__**L**__ and - which isn't part of its repeated item. +* The name of any <> defined before{nbsp}__**L**__. * The name of any <> known - at{nbsp}__**L**__, which isn't part of its repeated item, and which - doesn't, directly or indirectly, refer to a label defined - after{nbsp}__**L**__. + at{nbsp}__**L**__ which doesn't, directly or indirectly, refer to a + label defined after{nbsp}__**L**__. -- + -This expression must not contain the special name `ICITTE`. +The value of the special name `ICITTE` (`int` type) in this expression +is the <> (before handling the items to +repeat). + +** A valid {py3} name. ++ +For the name `__NAME__`, this is equivalent to the +`pass:[{]__NAME__pass:[}]` form above. + +. Zero or more items. + +. The `!end` suffix. + +You may also use a <> after +some items. The form ``!repeat{nbsp}__X__{nbsp}__ITEMS__{nbsp}!end`` +is equivalent to ``(__ITEMS__){nbsp}pass:[*]{nbsp}__X__``. ==== Input: ---- -{end - ICITTE - 1 : 8} * 0x100 +!repeat 0x100 + {end - ICITTE - 1 : 8} +!end + + ---- Output: @@ -1093,13 +1112,21 @@ Input: ---- {times = 1} + aa bb cc dd -( + +!repeat 3 - (ee ff) * {here + 1} - 11 22 33 * {times} + + !repeat {here + 1} + ee ff + !end + + 11 22 !repeat times 33 !end + {times = times + 1} -) * 3 +!end + "coucou!" ---- @@ -1122,14 +1149,18 @@ ff ee ff ee ff ee ff ee ff ee ff ee ff 11 22 33 ┆ •••••••• ==== ==== -This example shows how to use a repetition as a conditional section -depending on some predefined variable. +This example shows how to use a repetition block as a conditional +section depending on some predefined variable. Input: ---- aa bb cc dd -(ee ff "meow mix" 00) * {cond} + +!repeat cond + ee ff "meow mix" 00 +!end + {be} {-1993:16} ---- @@ -1147,6 +1178,119 @@ aa bb cc dd ee ff 6d 65 6f 77 20 6d 69 78 00 f8 ┆ ••••••meow mix ---- ==== +=== Post-item repetition + +A _post-item repetition_ represents the bytes of an item repeated a +given number of times. + +A post-item repetition is: + +. Any item except: + +** A <>. +** A <>. +** A <>. +** A <>. +** A <>. +** A <>. + +. The ``pass:[*]`` character. + +. One of: + +** A positive integer (hexadecimal starting with `0x` or `0X` accepted) + which is the number of times to repeat the previous item. + +** The ``pass:[{]`` prefix, a valid {py3} expression, and the + ``pass:[}]`` suffix. ++ +For a repetition at some source location{nbsp}__**L**__, this expression +may contain: ++ +-- +* The name of any <> defined before{nbsp}__**L**__ and + which isn't part of its repeated item. +* The name of any <> known + at{nbsp}__**L**__, which isn't part of its repeated item, and which + doesn't, directly or indirectly, refer to a label defined + after{nbsp}__**L**__. +-- ++ +The value of the special name `ICITTE` (`int` type) in this expression +is the <> (before handling the items to +repeat). + +** A valid {py3} name. ++ +For the name `__NAME__`, this is equivalent to the +`pass:[{]__NAME__pass:[}]` form above. + +You may also use a <>. The form +``__ITEM__{nbsp}pass:[*]{nbsp}__X__`` is equivalent to +``!repeat{nbsp}__X__{nbsp}__ITEM__{nbsp}!end``. + +==== +Input: + +---- +{end - ICITTE - 1 : 8} * 0x100 +---- + +Output: + +---- +ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ┆ •••••••••••••••• +ef ee ed ec eb ea e9 e8 e7 e6 e5 e4 e3 e2 e1 e0 ┆ •••••••••••••••• +df de dd dc db da d9 d8 d7 d6 d5 d4 d3 d2 d1 d0 ┆ •••••••••••••••• +cf ce cd cc cb ca c9 c8 c7 c6 c5 c4 c3 c2 c1 c0 ┆ •••••••••••••••• +bf be bd bc bb ba b9 b8 b7 b6 b5 b4 b3 b2 b1 b0 ┆ •••••••••••••••• +af ae ad ac ab aa a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 ┆ •••••••••••••••• +9f 9e 9d 9c 9b 9a 99 98 97 96 95 94 93 92 91 90 ┆ •••••••••••••••• +8f 8e 8d 8c 8b 8a 89 88 87 86 85 84 83 82 81 80 ┆ •••••••••••••••• +7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70 ┆ •~}|{zyxwvutsrqp +6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60 ┆ onmlkjihgfedcba` +5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50 ┆ _^]\[ZYXWVUTSRQP +4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40 ┆ ONMLKJIHGFEDCBA@ +3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 ┆ ?>=<;:9876543210 +2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 ┆ /.-,+*)('&%$#"! +1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 ┆ •••••••••••••••• +0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 ┆ •••••••••••••••• +---- +==== + +==== +Input: + +---- +{times = 1} +aa bb cc dd +( + + (ee ff) * {here + 1} + 11 22 33 * {times} + {times = times + 1} +) * 3 +"coucou!" +---- + +Output: + +---- +aa bb cc dd ee ff ee ff ee ff ee ff ee ff 11 22 ┆ •••••••••••••••" +33 ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee ┆ 3••••••••••••••• +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee ┆ •••••••••••••••• +ff ee ff ee ff 11 22 33 33 ee ff ee ff ee ff ee ┆ ••••••"33••••••• +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee ┆ •••••••••••••••• +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee ┆ •••••••••••••••• +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee ┆ •••••••••••••••• +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee ┆ •••••••••••••••• +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee ┆ •••••••••••••••• +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee ┆ •••••••••••••••• +ff ee ff ee ff ee ff ee ff ee ff ee ff 11 22 33 ┆ ••••••••••••••"3 +33 33 63 6f 75 63 6f 75 21 ┆ 33coucou! +---- +==== + == Command-line tool If you <> the `normand` package, then you @@ -1184,10 +1328,11 @@ use the `--help` option to learn more. == {py3} API -The whole `normand` package/module API is: +The whole `normand` package/module public API is: [source,python] ---- +# Byte order. class ByteOrder(enum.Enum): # Big endian. BE = ... @@ -1196,7 +1341,8 @@ class ByteOrder(enum.Enum): LE = ... -class TextLoc: +# Text location. +class TextLocation: # Line number. @property def line_no(self) -> int: @@ -1208,16 +1354,23 @@ class TextLoc: ... +# Parsing error. class ParseError(RuntimeError): # Source text location. @property - def text_loc(self) -> TextLoc: + def text_loc(self) -> TextLocation: ... -SymbolsT = typing.Dict[str, int] +# Variables dictionary type (for type hints). +VariablesT = typing.Dict[str, typing.Union[int, float]] + + +# Labels dictionary type (for type hints). +LabelsT = typing.Dict[str, int] +# Parsing result. class ParseResult: # Generated data. @property @@ -1245,6 +1398,9 @@ class ParseResult: ... +# Parses the `normand` input using the initial state defined by +# `init_variables`, `init_labels`, `init_offset`, and `init_byte_order`, +# and returns the corresponding parsing result. def parse(normand: str, init_variables: typing.Optional[SymbolsT] = None, init_labels: typing.Optional[SymbolsT] = None, diff --git a/normand/normand.py b/normand/normand.py index c3c76ad..6b1e3d2 100644 --- a/normand/normand.py +++ b/normand/normand.py @@ -30,14 +30,15 @@ # Upstream repository: . __author__ = "Philippe Proulx" -__version__ = "0.7.0" +__version__ = "0.8.0" __all__ = [ "ByteOrder", "parse", "ParseError", "ParseResult", - "TextLoc", - "SymbolsT", + "TextLocation", + "LabelsT", + "VariablesT", "__author__", "__version__", ] @@ -49,21 +50,12 @@ import sys import enum import math import struct -from typing import ( - Any, - Set, - Dict, - List, - Union, - Pattern, - Callable, - NoReturn, - Optional, -) +import typing +from typing import Any, Set, Dict, List, Union, Pattern, Callable, NoReturn, Optional # Text location (line and column numbers). -class TextLoc: +class TextLocation: @classmethod def _create(cls, line_no: int, col_no: int): self = cls.__new__(cls) @@ -88,12 +80,12 @@ class TextLoc: return self._col_no def __repr__(self): - return "TextLoc({}, {})".format(self._line_no, self._col_no) + return "TextLocation({}, {})".format(self._line_no, self._col_no) # Any item. class _Item: - def __init__(self, text_loc: TextLoc): + def __init__(self, text_loc: TextLocation): self._text_loc = text_loc # Source text location. @@ -118,7 +110,7 @@ class _RepableItem: # Single byte. class _Byte(_ScalarItem, _RepableItem): - def __init__(self, val: int, text_loc: TextLoc): + def __init__(self, val: int, text_loc: TextLocation): super().__init__(text_loc) self._val = val @@ -137,7 +129,7 @@ class _Byte(_ScalarItem, _RepableItem): # String. class _Str(_ScalarItem, _RepableItem): - def __init__(self, data: bytes, text_loc: TextLoc): + def __init__(self, data: bytes, text_loc: TextLocation): super().__init__(text_loc) self._data = data @@ -166,7 +158,7 @@ class ByteOrder(enum.Enum): # Byte order setting. class _SetBo(_Item): - def __init__(self, bo: ByteOrder, text_loc: TextLoc): + def __init__(self, bo: ByteOrder, text_loc: TextLocation): super().__init__(text_loc) self._bo = bo @@ -180,7 +172,7 @@ class _SetBo(_Item): # Label. class _Label(_Item): - def __init__(self, name: str, text_loc: TextLoc): + def __init__(self, name: str, text_loc: TextLocation): super().__init__(text_loc) self._name = name @@ -195,7 +187,7 @@ class _Label(_Item): # Offset setting. class _SetOffset(_Item): - def __init__(self, val: int, text_loc: TextLoc): + def __init__(self, val: int, text_loc: TextLocation): super().__init__(text_loc) self._val = val @@ -210,7 +202,7 @@ class _SetOffset(_Item): # Offset alignment. class _AlignOffset(_Item): - def __init__(self, val: int, pad_val: int, text_loc: TextLoc): + def __init__(self, val: int, pad_val: int, text_loc: TextLocation): super().__init__(text_loc) self._val = val self._pad_val = pad_val @@ -251,7 +243,7 @@ class _ExprMixin: # Variable assignment. class _VarAssign(_Item, _ExprMixin): def __init__( - self, name: str, expr_str: str, expr: ast.Expression, text_loc: TextLoc + self, name: str, expr_str: str, expr: ast.Expression, text_loc: TextLocation ): super().__init__(text_loc) _ExprMixin.__init__(self, expr_str, expr) @@ -274,7 +266,7 @@ class _VarAssign(_Item, _ExprMixin): # Fixed-length number, possibly needing more than one byte. class _FlNum(_ScalarItem, _RepableItem, _ExprMixin): def __init__( - self, expr_str: str, expr: ast.Expression, len: int, text_loc: TextLoc + self, expr_str: str, expr: ast.Expression, len: int, text_loc: TextLocation ): super().__init__(text_loc) _ExprMixin.__init__(self, expr_str, expr) @@ -300,7 +292,7 @@ class _FlNum(_ScalarItem, _RepableItem, _ExprMixin): # LEB128 integer. class _Leb128Int(_Item, _RepableItem, _ExprMixin): - def __init__(self, expr_str: str, expr: ast.Expression, text_loc: TextLoc): + def __init__(self, expr_str: str, expr: ast.Expression, text_loc: TextLocation): super().__init__(text_loc) _ExprMixin.__init__(self, expr_str, expr) @@ -325,7 +317,7 @@ class _SLeb128Int(_Leb128Int, _RepableItem, _ExprMixin): # Group of items. class _Group(_Item, _RepableItem): - def __init__(self, items: List[_Item], text_loc: TextLoc): + def __init__(self, items: List[_Item], text_loc: TextLocation): super().__init__(text_loc) self._items = items @@ -341,7 +333,7 @@ class _Group(_Item, _RepableItem): # Repetition item. class _Rep(_Item, _ExprMixin): def __init__( - self, item: _Item, expr_str: str, expr: ast.Expression, text_loc: TextLoc + self, item: _Item, expr_str: str, expr: ast.Expression, text_loc: TextLocation ): super().__init__(text_loc) _ExprMixin.__init__(self, expr_str, expr) @@ -368,7 +360,7 @@ _ExprItemT = Union[_FlNum, _Leb128Int, _VarAssign, _Rep] # A parsing error containing a message and a text location. class ParseError(RuntimeError): @classmethod - def _create(cls, msg: str, text_loc: TextLoc): + def _create(cls, msg: str, text_loc: TextLocation): self = cls.__new__(cls) self._init(msg, text_loc) return self @@ -376,7 +368,7 @@ class ParseError(RuntimeError): def __init__(self, *args, **kwargs): # type: ignore raise NotImplementedError - def _init(self, msg: str, text_loc: TextLoc): + def _init(self, msg: str, text_loc: TextLocation): super().__init__(msg) self._text_loc = text_loc @@ -387,12 +379,16 @@ class ParseError(RuntimeError): # Raises a parsing error, forwarding the parameters to the constructor. -def _raise_error(msg: str, text_loc: TextLoc) -> NoReturn: +def _raise_error(msg: str, text_loc: TextLocation) -> NoReturn: raise ParseError._create(msg, text_loc) # pyright: ignore[reportPrivateUsage] -# Variable/label dictionary type. -SymbolsT = Dict[str, Union[int, float]] +# Variables dictionary type (for type hints). +VariablesT = Dict[str, Union[int, float]] + + +# Labels dictionary type (for type hints). +LabelsT = Dict[str, int] # Python name pattern. @@ -406,7 +402,7 @@ _py_name_pat = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*") class _Parser: # Builds a parser to parse the Normand input `normand`, parsing # immediately. - def __init__(self, normand: str, variables: SymbolsT, labels: SymbolsT): + def __init__(self, normand: str, variables: VariablesT, labels: LabelsT): self._normand = normand self._at = 0 self._line_no = 1 @@ -423,7 +419,7 @@ class _Parser: # Current text location. @property def _text_loc(self): - return TextLoc._create( # pyright: ignore[reportPrivateUsage] + return TextLocation._create( # pyright: ignore[reportPrivateUsage] self._line_no, self._col_no ) @@ -485,7 +481,7 @@ class _Parser: # Pattern for _skip_ws_and_comments() _ws_or_syms_or_comments_pat = re.compile( - r"(?:[\s!/\\?&:;.,+[\]_=|-]|#[^#]*?(?:\n|#))*" + r"(?:[\s/\\?&:;.,+[\]_=|-]|#[^#]*?(?:\n|#))*" ) # Skips as many whitespaces, insignificant symbol characters, and @@ -672,7 +668,7 @@ class _Parser: # Returns a stripped expression string and an AST expression node # from the expression string `expr_str` at text location `text_loc`. - def _ast_expr_from_str(self, expr_str: str, text_loc: TextLoc): + def _ast_expr_from_str(self, expr_str: str, text_loc: TextLocation): # Create an expression node from the expression string expr_str = expr_str.strip().replace("\n", " ") @@ -828,7 +824,7 @@ class _Parser: self._expect_pat(self._val_var_assign_set_bo_suffix_pat, "Expecting `}`") return item - # Pattern for _try_parse_set_offset_val() and _try_parse_rep() + # Common positive constant integer pattern _pos_const_int_pat = re.compile(r"0[Xx][A-Fa-f0-9]+|\d+") # Tries to parse an offset setting value (after the initial `<`), @@ -956,6 +952,77 @@ class _Parser: # Return item return _AlignOffset(val, pad_val, begin_text_loc) + # Patterns for _expect_rep_mul_expr() + _rep_expr_prefix_pat = re.compile(r"\{") + _rep_expr_pat = re.compile(r"[^}p]+") + _rep_expr_suffix_pat = re.compile(r"\}") + + # Parses the multiplier expression of a repetition (block or + # post-item) and returns the expression string and AST node. + def _expect_rep_mul_expr(self): + expr_text_loc = self._text_loc + + # Constant integer? + m = self._try_parse_pat(self._pos_const_int_pat) + + if m is None: + # Name? + m = self._try_parse_pat(_py_name_pat) + + if m is None: + # Expression? + if self._try_parse_pat(self._rep_expr_prefix_pat) is None: + # At this point it's invalid + self._raise_error( + "Expecting a positive integral multiplier, a name, or `{`" + ) + + # Expect an expression + expr_text_loc = self._text_loc + m = self._expect_pat(self._rep_expr_pat, "Expecting an expression") + expr_str = m.group(0) + + # Expect `}` + self._expect_pat(self._rep_expr_suffix_pat, "Expecting `}`") + else: + expr_str = m.group(0) + else: + expr_str = m.group(0) + + return self._ast_expr_from_str(expr_str, expr_text_loc) + + # Pattern for _try_parse_rep_block() + _rep_block_prefix_pat = re.compile(r"!r(?:epeat)?\b\s*") + _rep_block_end_pat = re.compile(r"!end\b\s*") + + # Tries to parse a repetition block, returning a repetition item on + # success. + def _try_parse_rep_block(self): + begin_text_loc = self._text_loc + + # Match prefix + if self._try_parse_pat(self._rep_block_prefix_pat) is None: + # No match + return + + # Expect expression + self._skip_ws_and_comments() + expr_str, expr = self._expect_rep_mul_expr() + + # Parse items + self._skip_ws_and_comments() + items_text_loc = self._text_loc + items = self._parse_items() + + # Expect end of block + self._skip_ws_and_comments() + self._expect_pat( + self._rep_block_end_pat, "Expecting an item or `!end` (end of repetition)" + ) + + # Return item + return _Rep(_Group(items, items_text_loc), expr_str, expr, begin_text_loc) + # Tries to parse a base item (anything except a repetition), # returning it on success. def _try_parse_base_item(self): @@ -995,45 +1062,26 @@ class _Parser: if item is not None: return item - # Pattern for _try_parse_rep() - _rep_prefix_pat = re.compile(r"\*\s*") - _rep_expr_prefix_pat = re.compile(r"\{") - _rep_expr_pat = re.compile(r"[^}p]+") - _rep_expr_suffix_pat = re.compile(r"\}") + # Repetition (block) item? + item = self._try_parse_rep_block() - # Tries to parse a repetition, returning the expression string and - # AST expression node on success. - def _try_parse_rep(self): + if item is not None: + return item + + # Pattern for _try_parse_rep_post() + _rep_post_prefix_pat = re.compile(r"\*") + + # Tries to parse a post-item repetition, returning the expression + # string and AST expression node on success. + def _try_parse_rep_post(self): # Match prefix - if self._try_parse_pat(self._rep_prefix_pat) is None: + if self._try_parse_pat(self._rep_post_prefix_pat) is None: # No match return - # Expect and return a decimal multiplier + # Return expression string and AST expression self._skip_ws_and_comments() - - # Integer? - m = self._try_parse_pat(self._pos_const_int_pat) - - if m is None: - # Expression? - if self._try_parse_pat(self._rep_expr_prefix_pat) is None: - # At this point it's invalid - self._raise_error("Expecting a positive integral multiplier or `{`") - - # Expect an expression - expr_str_loc = self._text_loc - m = self._expect_pat(self._rep_expr_pat, "Expecting an expression") - expr_str = self._ast_expr_from_str(m.group(0), expr_str_loc) - - # Expect `}` - self._expect_pat(self._rep_expr_suffix_pat, "Expecting `}`") - expr_str = m.group(0) - else: - expr_str_loc = self._text_loc - expr_str = m.group(0) - - return self._ast_expr_from_str(expr_str, expr_str_loc) + return self._expect_rep_mul_expr() # Tries to parse an item, possibly followed by a repetition, # returning `True` on success. @@ -1053,7 +1101,7 @@ class _Parser: if isinstance(item, _RepableItem): self._skip_ws_and_comments() rep_text_loc = self._text_loc - rep_ret = self._try_parse_rep() + rep_ret = self._try_parse_rep_post() if rep_ret is not None: item = _Rep(item, rep_ret[0], rep_ret[1], rep_text_loc) @@ -1104,8 +1152,8 @@ class ParseResult: def _create( cls, data: bytearray, - variables: SymbolsT, - labels: SymbolsT, + variables: VariablesT, + labels: LabelsT, offset: int, bo: Optional[ByteOrder], ): @@ -1119,8 +1167,8 @@ class ParseResult: def _init( self, data: bytearray, - variables: SymbolsT, - labels: SymbolsT, + variables: VariablesT, + labels: LabelsT, offset: int, bo: Optional[ByteOrder], ): @@ -1192,31 +1240,21 @@ class _NodeVisitor(ast.NodeVisitor): # Expression validator: validates that all the names within the # expression are allowed. class _ExprValidator(_NodeVisitor): - def __init__(self, item: _ExprItemT, allowed_names: Set[str], icitte_allowed: bool): + def __init__(self, item: _ExprItemT, allowed_names: Set[str]): super().__init__() self._item = item self._allowed_names = allowed_names - self._icitte_allowed = icitte_allowed def _visit_name(self, name: str): # Make sure the name refers to a known and reachable # variable/label name. - if name == _icitte_name and not self._icitte_allowed: - _raise_error( - "Illegal reserved name `{}` in expression `{}`".format( - _icitte_name, self._item.expr_str - ), - self._item.text_loc, - ) - elif name != _icitte_name and name not in self._allowed_names: + if name != _icitte_name and name not in self._allowed_names: msg = "Illegal (unknown or unreachable) variable/label name `{}` in expression `{}`".format( name, self._item.expr_str ) allowed_names = self._allowed_names.copy() - - if self._icitte_allowed: - allowed_names.add(_icitte_name) + allowed_names.add(_icitte_name) if len(allowed_names) > 0: allowed_names_str = ", ".join( @@ -1248,8 +1286,8 @@ class _ExprNamesVisitor(_NodeVisitor): class _GenState: def __init__( self, - variables: SymbolsT, - labels: SymbolsT, + variables: VariablesT, + labels: LabelsT, offset: int, bo: Optional[ByteOrder], ): @@ -1268,7 +1306,7 @@ class _GenState: # The steps of generation are: # # 1. Validate that each repetition and LEB128 integer expression uses -# only reachable names and not `ICITTE`. +# only reachable names. # # 2. Compute and keep the effective repetition count and LEB128 integer # value for each repetition and LEB128 integer instance. @@ -1289,8 +1327,8 @@ class _Gen: def __init__( self, group: _Group, - variables: SymbolsT, - labels: SymbolsT, + variables: VariablesT, + labels: LabelsT, offset: int, bo: Optional[ByteOrder], ): @@ -1386,15 +1424,15 @@ class _Gen: elif item.name in allowed_variable_names: allowed_variable_names.remove(item.name) elif isinstance(item, _Leb128Int): - # Validate the expression (`ICITTE` allowed) - _ExprValidator( - item, allowed_label_names | allowed_variable_names, True - ).visit(item.expr) + # Validate the expression + _ExprValidator(item, allowed_label_names | allowed_variable_names).visit( + item.expr + ) elif type(item) is _Rep: - # Validate the expression first (`ICITTE` not allowed) - _ExprValidator( - item, allowed_label_names | allowed_variable_names, False - ).visit(item.expr) + # Validate the expression first + _ExprValidator(item, allowed_label_names | allowed_variable_names).visit( + item.expr + ) # Validate inner item _Gen._validate_vl_exprs( @@ -1413,29 +1451,25 @@ class _Gen: # Evaluates the expression of `item` considering the current # generation state `state`. # - # If `allow_icitte` is `True`, then the `ICITTE` name is available - # for the expression to evaluate. - # # If `allow_float` is `True`, then the type of the result may be # `float` too. @staticmethod def _eval_item_expr( item: _ExprItemT, state: _GenState, - allow_icitte: bool, allow_float: bool = False, ): - syms = state.labels.copy() + syms = {} # type: VariablesT + syms.update(state.labels) - # Set the `ICITTE` name to the current offset, if any - if allow_icitte: - syms[_icitte_name] = state.offset + # Set the `ICITTE` name to the current offset + syms[_icitte_name] = state.offset # Add the current variables syms.update(state.variables) # Validate the node and its children - _ExprValidator(item, set(syms.keys()), True).visit(item.expr) + _ExprValidator(item, set(syms.keys())).visit(item.expr) # Compile and evaluate expression node try: @@ -1529,16 +1563,14 @@ class _Gen: if do_eval: # Evaluate the expression and keep the result - state.variables[item.name] = _Gen._eval_item_expr( - item, state, True, True - ) + state.variables[item.name] = _Gen._eval_item_expr(item, state, True) elif type(item) is _SetOffset: state.offset = item.val elif type(item) is _AlignOffset: state.offset = _Gen._align_offset(state.offset, item) elif isinstance(item, _Leb128Int): # Evaluate the expression - val = _Gen._eval_item_expr(item, state, True) + val = _Gen._eval_item_expr(item, state) # Validate result if type(item) is _ULeb128Int and val < 0: @@ -1557,7 +1589,7 @@ class _Gen: state.offset += _Gen._leb128_size_for_val(val, type(item) is _SLeb128Int) elif type(item) is _Rep: # Evaluate the expression and keep the result - val = _Gen._eval_item_expr(item, state, False) + val = _Gen._eval_item_expr(item, state) # Validate result if val < 0: @@ -1669,7 +1701,7 @@ class _Gen: self, item: _VarAssign, state: _GenState, next_vl_instance: int ): # Update variable - state.variables[item.name] = self._eval_item_expr(item, state, True, True) + state.variables[item.name] = self._eval_item_expr(item, state, True) return next_vl_instance # Handles the fixed-length integer item `item`. @@ -1732,7 +1764,7 @@ class _Gen: self, item: _FlNum, state: _GenState, next_vl_instance: int ): # Compute value - val = self._eval_item_expr(item, state, True, True) + val = self._eval_item_expr(item, state, True) # Validate current byte order if state.bo is None and item.len > 8: @@ -1916,8 +1948,8 @@ class _Gen: # Raises `ParseError` on any parsing error. def parse( normand: str, - init_variables: Optional[SymbolsT] = None, - init_labels: Optional[SymbolsT] = None, + init_variables: Optional[VariablesT] = None, + init_labels: Optional[LabelsT] = None, init_offset: int = 0, init_byte_order: Optional[ByteOrder] = None, ): @@ -1997,7 +2029,7 @@ def _raise_cli_error(msg: str) -> NoReturn: # Returns a dictionary of string to integers from the list of strings # `args` containing `NAME=VAL` entries. def _dict_from_arg(args: Optional[List[str]]): - d = {} # type: SymbolsT + d = {} # type: LabelsT if args is None: return d @@ -2028,7 +2060,7 @@ def _try_run_cli(): normand = f.read() # Variables and labels - variables = _dict_from_arg(args.var) + variables = typing.cast(VariablesT, _dict_from_arg(args.var)) labels = _dict_from_arg(args.label) # Validate offset diff --git a/pyproject.toml b/pyproject.toml index f131ef7..c439ac7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ [tool.poetry] name = 'normand' -version = '0.7.0' +version = '0.8.0' description = 'Text-to-binary processor with its own language' license = 'MIT' authors = ['Philippe Proulx '] diff --git a/tests/fail-rep-blk-empty-expr.nt b/tests/fail-rep-blk-empty-expr.nt new file mode 100644 index 0000000..b5b40f5 --- /dev/null +++ b/tests/fail-rep-blk-empty-expr.nt @@ -0,0 +1,3 @@ +!repeat { } 77 !end +--- +1:10 - Invalid expression ``: invalid syntax diff --git a/tests/fail-rep-blk-eval-type-1.nt b/tests/fail-rep-blk-eval-type-1.nt new file mode 100644 index 0000000..91766e0 --- /dev/null +++ b/tests/fail-rep-blk-eval-type-1.nt @@ -0,0 +1,3 @@ +!repeat { [1, 2, 3] } 77 !end +--- +1:1 - Invalid expression `[1, 2, 3]`: expecting result type `int`, not `list` diff --git a/tests/fail-rep-blk-eval-type-2.nt b/tests/fail-rep-blk-eval-type-2.nt new file mode 100644 index 0000000..52acf49 --- /dev/null +++ b/tests/fail-rep-blk-eval-type-2.nt @@ -0,0 +1,3 @@ +!repeat {3.4} 77 !end +--- +1:1 - Invalid expression `3.4`: expecting result type `int`, not `float` diff --git a/tests/fail-rep-blk-eval.nt b/tests/fail-rep-blk-eval.nt new file mode 100644 index 0000000..93e7ac8 --- /dev/null +++ b/tests/fail-rep-blk-eval.nt @@ -0,0 +1,3 @@ +aa !repeat { 23 + zoom(14) } bb !end +--- +1:4 - Failed to evaluate expression `23 + zoom(14)`: name 'zoom' is not defined diff --git a/tests/fail-rep-empty-expr.nt b/tests/fail-rep-empty-expr.nt deleted file mode 100644 index e5db8f0..0000000 --- a/tests/fail-rep-empty-expr.nt +++ /dev/null @@ -1,3 +0,0 @@ -77 * { } ---- -1:7 - Invalid expression ``: invalid syntax diff --git a/tests/fail-rep-eval-type-1.nt b/tests/fail-rep-eval-type-1.nt deleted file mode 100644 index c2d4e22..0000000 --- a/tests/fail-rep-eval-type-1.nt +++ /dev/null @@ -1,3 +0,0 @@ -77 * { [1, 2, 3] } ---- -1:4 - Invalid expression `[1, 2, 3]`: expecting result type `int`, not `list` diff --git a/tests/fail-rep-eval-type-2.nt b/tests/fail-rep-eval-type-2.nt deleted file mode 100644 index 7fb72c7..0000000 --- a/tests/fail-rep-eval-type-2.nt +++ /dev/null @@ -1,3 +0,0 @@ -77 * { 3.4 } ---- -1:4 - Invalid expression `3.4`: expecting result type `int`, not `float` diff --git a/tests/fail-rep-eval.nt b/tests/fail-rep-eval.nt deleted file mode 100644 index 6f3c898..0000000 --- a/tests/fail-rep-eval.nt +++ /dev/null @@ -1,3 +0,0 @@ -aa bb * { 23 + zoom(14) } ---- -1:7 - Failed to evaluate expression `23 + zoom(14)`: name 'zoom' is not defined diff --git a/tests/fail-rep-icitte.nt b/tests/fail-rep-icitte.nt deleted file mode 100644 index 5badb82..0000000 --- a/tests/fail-rep-icitte.nt +++ /dev/null @@ -1,3 +0,0 @@ -99 * {ICITTE * 2} ---- -1:4 - Illegal reserved name `ICITTE` in expression `ICITTE * 2` diff --git a/tests/fail-rep-inval-count.nt b/tests/fail-rep-inval-count.nt deleted file mode 100644 index 74c6007..0000000 --- a/tests/fail-rep-inval-count.nt +++ /dev/null @@ -1,3 +0,0 @@ -88 * salut ---- -1:6 - Expecting a positive integral multiplier or `{` diff --git a/tests/fail-rep-neg.nt b/tests/fail-rep-neg.nt deleted file mode 100644 index 2e37761..0000000 --- a/tests/fail-rep-neg.nt +++ /dev/null @@ -1,3 +0,0 @@ -aa ff * {-meow} ---- -1:14 - Invalid expression `-meow`: unexpected negative result -1 diff --git a/tests/fail-rep-post-empty-expr.nt b/tests/fail-rep-post-empty-expr.nt new file mode 100644 index 0000000..e5db8f0 --- /dev/null +++ b/tests/fail-rep-post-empty-expr.nt @@ -0,0 +1,3 @@ +77 * { } +--- +1:7 - Invalid expression ``: invalid syntax diff --git a/tests/fail-rep-post-eval-type-1.nt b/tests/fail-rep-post-eval-type-1.nt new file mode 100644 index 0000000..c2d4e22 --- /dev/null +++ b/tests/fail-rep-post-eval-type-1.nt @@ -0,0 +1,3 @@ +77 * { [1, 2, 3] } +--- +1:4 - Invalid expression `[1, 2, 3]`: expecting result type `int`, not `list` diff --git a/tests/fail-rep-post-eval-type-2.nt b/tests/fail-rep-post-eval-type-2.nt new file mode 100644 index 0000000..7fb72c7 --- /dev/null +++ b/tests/fail-rep-post-eval-type-2.nt @@ -0,0 +1,3 @@ +77 * { 3.4 } +--- +1:4 - Invalid expression `3.4`: expecting result type `int`, not `float` diff --git a/tests/fail-rep-post-eval.nt b/tests/fail-rep-post-eval.nt new file mode 100644 index 0000000..6f3c898 --- /dev/null +++ b/tests/fail-rep-post-eval.nt @@ -0,0 +1,3 @@ +aa bb * { 23 + zoom(14) } +--- +1:7 - Failed to evaluate expression `23 + zoom(14)`: name 'zoom' is not defined diff --git a/tests/fail-rep-post-inval-count.nt b/tests/fail-rep-post-inval-count.nt new file mode 100644 index 0000000..13eddc6 --- /dev/null +++ b/tests/fail-rep-post-inval-count.nt @@ -0,0 +1,3 @@ +88 * "salut" +--- +1:6 - Expecting a positive integral multiplier, a name, or `{` diff --git a/tests/fail-rep-post-neg.nt b/tests/fail-rep-post-neg.nt new file mode 100644 index 0000000..2e37761 --- /dev/null +++ b/tests/fail-rep-post-neg.nt @@ -0,0 +1,3 @@ +aa ff * {-meow} +--- +1:14 - Invalid expression `-meow`: unexpected negative result -1 diff --git a/tests/fail-rep-post-unreachable-label-1.nt b/tests/fail-rep-post-unreachable-label-1.nt new file mode 100644 index 0000000..abb5db0 --- /dev/null +++ b/tests/fail-rep-post-unreachable-label-1.nt @@ -0,0 +1,6 @@ + +aa bb {kilo = 23} cc +dd * {mix} +ee +--- +3:4 - Illegal (unknown or unreachable) variable/label name `mix` in expression `mix`; the legal names are {`ICITTE`, `kilo`, `meow`} diff --git a/tests/fail-rep-post-unreachable-label-2.nt b/tests/fail-rep-post-unreachable-label-2.nt new file mode 100644 index 0000000..80e8e8a --- /dev/null +++ b/tests/fail-rep-post-unreachable-label-2.nt @@ -0,0 +1,6 @@ + +aa {kilo = 99} bb {kilo = mix} cc +dd * {kilo} +ee +--- +3:4 - Illegal (unknown or unreachable) variable/label name `kilo` in expression `kilo`; the legal names are {`ICITTE`, `meow`} diff --git a/tests/fail-rep-post-unreachable-label-3.nt b/tests/fail-rep-post-unreachable-label-3.nt new file mode 100644 index 0000000..4fc98f3 --- /dev/null +++ b/tests/fail-rep-post-unreachable-label-3.nt @@ -0,0 +1,9 @@ +aa {mix = 23} bb cc +( + dd ee * {meow} + ff + +) +"salut" +--- +3:9 - Illegal (unknown or unreachable) variable/label name `meow` in expression `meow`; the legal names are {`ICITTE`, `flake`, `mix`} diff --git a/tests/fail-rep-unreachable-label-1.nt b/tests/fail-rep-unreachable-label-1.nt deleted file mode 100644 index 0a64750..0000000 --- a/tests/fail-rep-unreachable-label-1.nt +++ /dev/null @@ -1,6 +0,0 @@ - -aa bb {kilo = 23} cc -dd * {mix} -ee ---- -3:4 - Illegal (unknown or unreachable) variable/label name `mix` in expression `mix`; the legal names are {`kilo`, `meow`} diff --git a/tests/fail-rep-unreachable-label-2.nt b/tests/fail-rep-unreachable-label-2.nt deleted file mode 100644 index 1dffea3..0000000 --- a/tests/fail-rep-unreachable-label-2.nt +++ /dev/null @@ -1,6 +0,0 @@ - -aa {kilo = 99} bb {kilo = mix} cc -dd * {kilo} -ee ---- -3:4 - Illegal (unknown or unreachable) variable/label name `kilo` in expression `kilo`; the legal names are {`meow`} diff --git a/tests/fail-rep-unreachable-label-3.nt b/tests/fail-rep-unreachable-label-3.nt deleted file mode 100644 index f01cf27..0000000 --- a/tests/fail-rep-unreachable-label-3.nt +++ /dev/null @@ -1,9 +0,0 @@ -aa {mix = 23} bb cc -( - dd ee * {meow} - ff - -) -"salut" ---- -3:9 - Illegal (unknown or unreachable) variable/label name `meow` in expression `meow`; the legal names are {`flake`, `mix`} diff --git a/tests/pass-comment-sym-bin-const.nt b/tests/pass-comment-sym-bin-const.nt index 4e666f0..2e39488 100644 --- a/tests/pass-comment-sym-bin-const.nt +++ b/tests/pass-comment-sym-bin-const.nt @@ -1,5 +1,5 @@ -%!1/01\0?1&0:1;0 %.0,1+0[1]0_1=0|1 %1111-0000 -% 1! 0 / 1 \ 0 ? 1 & 0 : 1 ; 0 +%1/01\0?1&0:1;0 %.0,1+0[1]0_1=0|1 %1111-0000 +% 1 0 / 1 \ 0 ? 1 & 0 : 1 ; 0 % . 0 , 1 + 0 [ 1 ] 0 _ 1 = 0 | 1 % 1111 - 0000 --- diff --git a/tests/pass-comment-sym-group.nt b/tests/pass-comment-sym-group.nt index 7ceea98..0b33c27 100644 --- a/tests/pass-comment-sym-group.nt +++ b/tests/pass-comment-sym-group.nt @@ -1,3 +1,3 @@ -(0!12/3\4?5&6:7;8.9,a+b[c]d_e=f|0-1(!/\?&:;.,+[]_=|-)) +(012/3\4?5&6:7;8.9,a+b[c]d_e=f|0-1(/\?&:;.,+[]_=|-)) --- 01 23 45 67 89 ab cd ef 01 diff --git a/tests/pass-comment-sym-hex-const.nt b/tests/pass-comment-sym-hex-const.nt index 3b6be9a..4c3b990 100644 --- a/tests/pass-comment-sym-hex-const.nt +++ b/tests/pass-comment-sym-hex-const.nt @@ -1,6 +1,6 @@ -! / \ ? & : ; . , + [ ] _ = | - -0!12/3\4?5&6:7;8.9,a+b[c]d_e=f|0-1 -0 ! 1 2 / 3 \ 4 ? 5 & 6 : 7 ; 8 . 9 , a + b [ c ] d_e = f | 0 - 1 +/ \ ? & : ; . , + [ ] _ = | - +012/3\4?5&6:7;8.9,a+b[c]d_e=f|0-1 +0 1 2 / 3 \ 4 ? 5 & 6 : 7 ; 8 . 9 , a + b [ c ] d_e = f | 0 - 1 --- 01 23 45 67 89 ab cd ef 01 01 23 45 67 89 ab cd ef 01 diff --git a/tests/pass-comment-sym-rep-post.nt b/tests/pass-comment-sym-rep-post.nt new file mode 100644 index 0000000..08dc0c3 --- /dev/null +++ b/tests/pass-comment-sym-rep-post.nt @@ -0,0 +1,4 @@ +# repetition +ff/\?&:;.,+[]_=|-*/\?&:;.,+[]_=|-5 +--- +ff ff ff ff ff diff --git a/tests/pass-comment-sym-rep.nt b/tests/pass-comment-sym-rep.nt deleted file mode 100644 index b58bcc8..0000000 --- a/tests/pass-comment-sym-rep.nt +++ /dev/null @@ -1,4 +0,0 @@ -# repetition -ff!/\?&:;.,+[]_=|-*!/\?&:;.,+[]_=|-5 ---- -ff ff ff ff ff diff --git a/tests/pass-comment-text-rep-post.nt b/tests/pass-comment-text-rep-post.nt new file mode 100644 index 0000000..9a69fff --- /dev/null +++ b/tests/pass-comment-text-rep-post.nt @@ -0,0 +1,3 @@ +ff#comment#*#comment#5 +--- +ff ff ff ff ff diff --git a/tests/pass-comment-text-rep.nt b/tests/pass-comment-text-rep.nt deleted file mode 100644 index 9a69fff..0000000 --- a/tests/pass-comment-text-rep.nt +++ /dev/null @@ -1,3 +0,0 @@ -ff#comment#*#comment#5 ---- -ff ff ff ff ff diff --git a/tests/pass-readme-intro-rep.nt b/tests/pass-readme-intro-rep.nt index 586afb3..d4c0cee 100644 --- a/tests/pass-readme-intro-rep.nt +++ b/tests/pass-readme-intro-rep.nt @@ -1,4 +1,8 @@ aa bb * 5 cc "yeah\0" * {zoom * 3} + +!repeat 3 + ff ee "juice" +!end --- aa bb bb bb bb bb cc 79 65 61 68 00 79 65 61 68 00 79 65 61 68 00 79 65 61 68 00 79 65 61 68 00 @@ -7,3 +11,5 @@ aa bb bb bb bb bb cc 79 65 61 68 00 79 65 61 68 61 68 00 79 65 61 68 00 79 65 61 68 00 79 65 61 68 00 79 65 61 68 00 79 65 61 68 00 79 65 61 68 00 79 65 61 68 00 79 65 61 68 00 79 65 61 68 00 +ff ee 6a 75 69 63 65 ff ee 6a 75 69 63 65 ff ee +6a 75 69 63 65 diff --git a/tests/pass-readme-learn-rep-1.nt b/tests/pass-readme-learn-rep-1.nt deleted file mode 100644 index 74283c7..0000000 --- a/tests/pass-readme-learn-rep-1.nt +++ /dev/null @@ -1,18 +0,0 @@ -{end - ICITTE - 1 : 8} * 0x100 ---- -ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 -ef ee ed ec eb ea e9 e8 e7 e6 e5 e4 e3 e2 e1 e0 -df de dd dc db da d9 d8 d7 d6 d5 d4 d3 d2 d1 d0 -cf ce cd cc cb ca c9 c8 c7 c6 c5 c4 c3 c2 c1 c0 -bf be bd bc bb ba b9 b8 b7 b6 b5 b4 b3 b2 b1 b0 -af ae ad ac ab aa a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 -9f 9e 9d 9c 9b 9a 99 98 97 96 95 94 93 92 91 90 -8f 8e 8d 8c 8b 8a 89 88 87 86 85 84 83 82 81 80 -7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70 -6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60 -5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50 -4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40 -3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 -2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 -1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 -0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 diff --git a/tests/pass-readme-learn-rep-2.nt b/tests/pass-readme-learn-rep-2.nt deleted file mode 100644 index 5bf9be1..0000000 --- a/tests/pass-readme-learn-rep-2.nt +++ /dev/null @@ -1,22 +0,0 @@ -{times = 1} -aa bb cc dd -( - - (ee ff) * {here + 1} - 11 22 33 * {times} - {times = times + 1} -) * 3 -"coucou!" ---- -aa bb cc dd ee ff ee ff ee ff ee ff ee ff 11 22 -33 ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee -ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee -ff ee ff ee ff 11 22 33 33 ee ff ee ff ee ff ee -ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee -ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee -ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee -ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee -ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee -ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee -ff ee ff ee ff ee ff ee ff ee ff ee ff 11 22 33 -33 33 63 6f 75 63 6f 75 21 diff --git a/tests/pass-readme-learn-rep-3-cond-0.nt b/tests/pass-readme-learn-rep-3-cond-0.nt deleted file mode 100644 index df2d985..0000000 --- a/tests/pass-readme-learn-rep-3-cond-0.nt +++ /dev/null @@ -1,6 +0,0 @@ -{cond = 0} -aa bb cc dd -(ee ff "meow mix" 00) * {cond} -{be} {-1993:16} ---- -aa bb cc dd f8 37 diff --git a/tests/pass-readme-learn-rep-3-cond-1.nt b/tests/pass-readme-learn-rep-3-cond-1.nt deleted file mode 100644 index f96f821..0000000 --- a/tests/pass-readme-learn-rep-3-cond-1.nt +++ /dev/null @@ -1,6 +0,0 @@ -{cond = 1} -aa bb cc dd -(ee ff "meow mix" 00) * {cond} -{be} {-1993:16} ---- -aa bb cc dd ee ff 6d 65 6f 77 20 6d 69 78 00 f8 37 diff --git a/tests/pass-readme-learn-rep-blk-1.nt b/tests/pass-readme-learn-rep-blk-1.nt new file mode 100644 index 0000000..3483a59 --- /dev/null +++ b/tests/pass-readme-learn-rep-blk-1.nt @@ -0,0 +1,22 @@ +!repeat 0x100 + {end - ICITTE - 1 : 8} +!end + + +--- +ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 +ef ee ed ec eb ea e9 e8 e7 e6 e5 e4 e3 e2 e1 e0 +df de dd dc db da d9 d8 d7 d6 d5 d4 d3 d2 d1 d0 +cf ce cd cc cb ca c9 c8 c7 c6 c5 c4 c3 c2 c1 c0 +bf be bd bc bb ba b9 b8 b7 b6 b5 b4 b3 b2 b1 b0 +af ae ad ac ab aa a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 +9f 9e 9d 9c 9b 9a 99 98 97 96 95 94 93 92 91 90 +8f 8e 8d 8c 8b 8a 89 88 87 86 85 84 83 82 81 80 +7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70 +6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60 +5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50 +4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40 +3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 +2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 +1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 +0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 diff --git a/tests/pass-readme-learn-rep-blk-2.nt b/tests/pass-readme-learn-rep-blk-2.nt new file mode 100644 index 0000000..f6b9e6d --- /dev/null +++ b/tests/pass-readme-learn-rep-blk-2.nt @@ -0,0 +1,30 @@ +{times = 1} + +aa bb cc dd + +!repeat 3 + + + !repeat {here + 1} + ee ff + !end + + 11 22 !repeat times 33 !end + + {times = times + 1} +!end + +"coucou!" +--- +aa bb cc dd ee ff ee ff ee ff ee ff ee ff 11 22 +33 ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff 11 22 33 33 ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff 11 22 33 +33 33 63 6f 75 63 6f 75 21 diff --git a/tests/pass-readme-learn-rep-blk-3-cond-0.nt b/tests/pass-readme-learn-rep-blk-3-cond-0.nt new file mode 100644 index 0000000..930dc62 --- /dev/null +++ b/tests/pass-readme-learn-rep-blk-3-cond-0.nt @@ -0,0 +1,11 @@ +{cond = 0} + +aa bb cc dd + +!repeat cond + ee ff "meow mix" 00 +!end + +{be} {-1993:16} +--- +aa bb cc dd f8 37 diff --git a/tests/pass-readme-learn-rep-blk-3-cond-1.nt b/tests/pass-readme-learn-rep-blk-3-cond-1.nt new file mode 100644 index 0000000..fbc6276 --- /dev/null +++ b/tests/pass-readme-learn-rep-blk-3-cond-1.nt @@ -0,0 +1,11 @@ +{cond = 1} + +aa bb cc dd + +!repeat cond + ee ff "meow mix" 00 +!end + +{be} {-1993:16} +--- +aa bb cc dd ee ff 6d 65 6f 77 20 6d 69 78 00 f8 37 diff --git a/tests/pass-readme-learn-rep-post-1.nt b/tests/pass-readme-learn-rep-post-1.nt new file mode 100644 index 0000000..74283c7 --- /dev/null +++ b/tests/pass-readme-learn-rep-post-1.nt @@ -0,0 +1,18 @@ +{end - ICITTE - 1 : 8} * 0x100 +--- +ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 +ef ee ed ec eb ea e9 e8 e7 e6 e5 e4 e3 e2 e1 e0 +df de dd dc db da d9 d8 d7 d6 d5 d4 d3 d2 d1 d0 +cf ce cd cc cb ca c9 c8 c7 c6 c5 c4 c3 c2 c1 c0 +bf be bd bc bb ba b9 b8 b7 b6 b5 b4 b3 b2 b1 b0 +af ae ad ac ab aa a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 +9f 9e 9d 9c 9b 9a 99 98 97 96 95 94 93 92 91 90 +8f 8e 8d 8c 8b 8a 89 88 87 86 85 84 83 82 81 80 +7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70 +6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60 +5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50 +4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40 +3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 +2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 +1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 +0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 diff --git a/tests/pass-readme-learn-rep-post-2.nt b/tests/pass-readme-learn-rep-post-2.nt new file mode 100644 index 0000000..5bf9be1 --- /dev/null +++ b/tests/pass-readme-learn-rep-post-2.nt @@ -0,0 +1,22 @@ +{times = 1} +aa bb cc dd +( + + (ee ff) * {here + 1} + 11 22 33 * {times} + {times = times + 1} +) * 3 +"coucou!" +--- +aa bb cc dd ee ff ee ff ee ff ee ff ee ff 11 22 +33 ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff 11 22 33 33 ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff ee ff ee +ff ee ff ee ff ee ff ee ff ee ff ee ff 11 22 33 +33 33 63 6f 75 63 6f 75 21 diff --git a/tests/pass-rep-all-bytes.nt b/tests/pass-rep-all-bytes.nt deleted file mode 100644 index 494f343..0000000 --- a/tests/pass-rep-all-bytes.nt +++ /dev/null @@ -1,18 +0,0 @@ -{ICITTE:8} * 256 ---- -00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f -10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f -20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f -30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f -40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f -50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f -60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f -70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f -80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f -90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f -a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af -b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf -c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf -d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df -e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef -f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff diff --git a/tests/pass-rep-blk-all-bytes.nt b/tests/pass-rep-blk-all-bytes.nt new file mode 100644 index 0000000..f875059 --- /dev/null +++ b/tests/pass-rep-blk-all-bytes.nt @@ -0,0 +1,18 @@ +!repeat 256 {ICITTE:8} !end +--- +00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f +10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f +20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f +30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f +40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f +50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f +60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f +70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f +80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f +90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f +a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af +b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf +c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf +d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df +e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef +f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff diff --git a/tests/pass-rep-blk-cond.nt b/tests/pass-rep-blk-cond.nt new file mode 100644 index 0000000..aa9fd56 --- /dev/null +++ b/tests/pass-rep-blk-cond.nt @@ -0,0 +1,18 @@ +!repeat 10 + + aa bb cc dd + + {include = int(beg >= 4 * (end - beg))} + !repeat include 11 22 33 44 !end +!end +--- +aa bb cc dd +aa bb cc dd +aa bb cc dd +aa bb cc dd +aa bb cc dd 11 22 33 44 +aa bb cc dd 11 22 33 44 +aa bb cc dd 11 22 33 44 +aa bb cc dd 11 22 33 44 +aa bb cc dd 11 22 33 44 +aa bb cc dd 11 22 33 44 diff --git a/tests/pass-rep-blk-const-bin.nt b/tests/pass-rep-blk-const-bin.nt new file mode 100644 index 0000000..a6db9c6 --- /dev/null +++ b/tests/pass-rep-blk-const-bin.nt @@ -0,0 +1,3 @@ +!repeat 5 %11001010 !end +--- +ca ca ca ca ca diff --git a/tests/pass-rep-blk-const-dec.nt b/tests/pass-rep-blk-const-dec.nt new file mode 100644 index 0000000..caa7e37 --- /dev/null +++ b/tests/pass-rep-blk-const-dec.nt @@ -0,0 +1,3 @@ +!repeat 5 $-36 !end +--- +dc dc dc dc dc diff --git a/tests/pass-rep-blk-const-hex.nt b/tests/pass-rep-blk-const-hex.nt new file mode 100644 index 0000000..cf9067b --- /dev/null +++ b/tests/pass-rep-blk-const-hex.nt @@ -0,0 +1,3 @@ +!repeat 5 4b !end +--- +4b 4b 4b 4b 4b diff --git a/tests/pass-rep-blk-expr-label-inner.nt b/tests/pass-rep-blk-expr-label-inner.nt new file mode 100644 index 0000000..6486371 --- /dev/null +++ b/tests/pass-rep-blk-expr-label-inner.nt @@ -0,0 +1,20 @@ +11 +!repeat 2 + aa bb + + cc !repeat meow dd !end + ee ff +!end +22 +--- +11 + +aa bb +cc dd dd dd +ee ff + +aa bb +cc dd dd dd dd dd dd dd dd dd dd dd +ee ff + +22 diff --git a/tests/pass-rep-blk-expr-label.nt b/tests/pass-rep-blk-expr-label.nt new file mode 100644 index 0000000..ca39ded --- /dev/null +++ b/tests/pass-rep-blk-expr-label.nt @@ -0,0 +1,8 @@ +aa bb + +cc !repeat meow dd !end +ee ff +--- +aa bb +cc dd dd +ee ff diff --git a/tests/pass-rep-blk-expr-var-1.nt b/tests/pass-rep-blk-expr-var-1.nt new file mode 100644 index 0000000..1ca6d5d --- /dev/null +++ b/tests/pass-rep-blk-expr-var-1.nt @@ -0,0 +1,8 @@ +aa bb +{meow = 3} +cc !repeat meow dd !end +ee ff +--- +aa bb +cc dd dd dd +ee ff diff --git a/tests/pass-rep-blk-expr-var-2.nt b/tests/pass-rep-blk-expr-var-2.nt new file mode 100644 index 0000000..1e7d4c8 --- /dev/null +++ b/tests/pass-rep-blk-expr-var-2.nt @@ -0,0 +1,18 @@ +aa bb +{meow = 3} +{meow = end} +11 22 +!repeat 2 + {meow = mix * 2} + cc !repeat meow dd !end +!end +ee ff +!repeat meow 88 !end + +--- +aa bb +11 22 +cc dd dd +cc dd dd +ee ff +88 88 diff --git a/tests/pass-rep-blk-group.nt b/tests/pass-rep-blk-group.nt new file mode 100644 index 0000000..a0b264a --- /dev/null +++ b/tests/pass-rep-blk-group.nt @@ -0,0 +1,51 @@ +aa +!repeat 0xa + bb cc + !repeat 3 + dd ee + !end +!end +ff +--- +aa + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee +ff diff --git a/tests/pass-rep-blk-icitte.nt b/tests/pass-rep-blk-icitte.nt new file mode 100644 index 0000000..bcdd175 --- /dev/null +++ b/tests/pass-rep-blk-icitte.nt @@ -0,0 +1,9 @@ +aa bb cc +!repeat ICITTE + dd +!end +ee ff +--- +aa bb cc +dd dd dd +ee ff diff --git a/tests/pass-rep-blk-label.nt b/tests/pass-rep-blk-label.nt new file mode 100644 index 0000000..033374e --- /dev/null +++ b/tests/pass-rep-blk-label.nt @@ -0,0 +1,3 @@ +aa ff dd !repeat meow bb !end cc +--- +aa ff dd bb bb cc diff --git a/tests/pass-rep-blk-r.nt b/tests/pass-rep-blk-r.nt new file mode 100644 index 0000000..c267e38 --- /dev/null +++ b/tests/pass-rep-blk-r.nt @@ -0,0 +1,7 @@ +!r 3 + aa bb cc +!end +--- +aa bb cc +aa bb cc +aa bb cc diff --git a/tests/pass-rep-blk-rep.nt b/tests/pass-rep-blk-rep.nt new file mode 100644 index 0000000..234c473 --- /dev/null +++ b/tests/pass-rep-blk-rep.nt @@ -0,0 +1,12 @@ +!repeat 2 + !repeat 8 + !repeat 4 + AA + !end + !end +!end +--- +aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa diff --git a/tests/pass-rep-blk-str-u16be.nt b/tests/pass-rep-blk-str-u16be.nt new file mode 100644 index 0000000..8f68aec --- /dev/null +++ b/tests/pass-rep-blk-str-u16be.nt @@ -0,0 +1,5 @@ +!repeat 3 u16be"yo" !end +--- +00 79 00 6f +00 79 00 6f +00 79 00 6f diff --git a/tests/pass-rep-blk-str-u16le.nt b/tests/pass-rep-blk-str-u16le.nt new file mode 100644 index 0000000..9290579 --- /dev/null +++ b/tests/pass-rep-blk-str-u16le.nt @@ -0,0 +1,5 @@ +!repeat 3 u16le"yo" !end +--- +79 00 6f 00 +79 00 6f 00 +79 00 6f 00 diff --git a/tests/pass-rep-blk-str-u32be.nt b/tests/pass-rep-blk-str-u32be.nt new file mode 100644 index 0000000..04c6962 --- /dev/null +++ b/tests/pass-rep-blk-str-u32be.nt @@ -0,0 +1,5 @@ +!repeat 3 u32be"yo" !end +--- +00 00 00 79 00 00 00 6f +00 00 00 79 00 00 00 6f +00 00 00 79 00 00 00 6f diff --git a/tests/pass-rep-blk-str-u32le.nt b/tests/pass-rep-blk-str-u32le.nt new file mode 100644 index 0000000..e874539 --- /dev/null +++ b/tests/pass-rep-blk-str-u32le.nt @@ -0,0 +1,5 @@ +!repeat 3 u32le"yo" !end +--- +79 00 00 00 6f 00 00 00 +79 00 00 00 6f 00 00 00 +79 00 00 00 6f 00 00 00 diff --git a/tests/pass-rep-blk-str-u8.nt b/tests/pass-rep-blk-str-u8.nt new file mode 100644 index 0000000..12e85c6 --- /dev/null +++ b/tests/pass-rep-blk-str-u8.nt @@ -0,0 +1,5 @@ +!repeat 3 "yo" !end +--- +79 6f +79 6f +79 6f diff --git a/tests/pass-rep-blk-var.nt b/tests/pass-rep-blk-var.nt new file mode 100644 index 0000000..dd690aa --- /dev/null +++ b/tests/pass-rep-blk-var.nt @@ -0,0 +1,3 @@ +aa {meow = 5} dd !repeat meow bb !end cc +--- +aa dd bb bb bb bb bb cc diff --git a/tests/pass-rep-blk-zero.nt b/tests/pass-rep-blk-zero.nt new file mode 100644 index 0000000..8c58975 --- /dev/null +++ b/tests/pass-rep-blk-zero.nt @@ -0,0 +1,3 @@ +aa !repeat 0 bb !end cc +--- +aa cc diff --git a/tests/pass-rep-cond.nt b/tests/pass-rep-cond.nt deleted file mode 100644 index 87a7c0c..0000000 --- a/tests/pass-rep-cond.nt +++ /dev/null @@ -1,18 +0,0 @@ -( - - aa bb cc dd - - {include = int(beg >= 4 * (end - beg))} - (11 22 33 44) * {include} -) * 10 ---- -aa bb cc dd -aa bb cc dd -aa bb cc dd -aa bb cc dd -aa bb cc dd 11 22 33 44 -aa bb cc dd 11 22 33 44 -aa bb cc dd 11 22 33 44 -aa bb cc dd 11 22 33 44 -aa bb cc dd 11 22 33 44 -aa bb cc dd 11 22 33 44 diff --git a/tests/pass-rep-const-bin.nt b/tests/pass-rep-const-bin.nt deleted file mode 100644 index 607a86d..0000000 --- a/tests/pass-rep-const-bin.nt +++ /dev/null @@ -1,3 +0,0 @@ -%11001010*5 ---- -ca ca ca ca ca diff --git a/tests/pass-rep-const-dec.nt b/tests/pass-rep-const-dec.nt deleted file mode 100644 index fb7dec5..0000000 --- a/tests/pass-rep-const-dec.nt +++ /dev/null @@ -1,3 +0,0 @@ -$-36*5 ---- -dc dc dc dc dc diff --git a/tests/pass-rep-const-hex.nt b/tests/pass-rep-const-hex.nt deleted file mode 100644 index af172d5..0000000 --- a/tests/pass-rep-const-hex.nt +++ /dev/null @@ -1,3 +0,0 @@ -4b*5 ---- -4b 4b 4b 4b 4b diff --git a/tests/pass-rep-expr-label-inner.nt b/tests/pass-rep-expr-label-inner.nt deleted file mode 100644 index 895f5c1..0000000 --- a/tests/pass-rep-expr-label-inner.nt +++ /dev/null @@ -1,20 +0,0 @@ -11 -( - aa bb - - cc dd * {meow} - ee ff -) * 2 -22 ---- -11 - -aa bb -cc dd dd dd -ee ff - -aa bb -cc dd dd dd dd dd dd dd dd dd dd dd -ee ff - -22 diff --git a/tests/pass-rep-expr-label.nt b/tests/pass-rep-expr-label.nt deleted file mode 100644 index 1275025..0000000 --- a/tests/pass-rep-expr-label.nt +++ /dev/null @@ -1,8 +0,0 @@ -aa bb - -cc dd * {meow} -ee ff ---- -aa bb -cc dd dd -ee ff diff --git a/tests/pass-rep-expr-var-1.nt b/tests/pass-rep-expr-var-1.nt deleted file mode 100644 index 64eb8f5..0000000 --- a/tests/pass-rep-expr-var-1.nt +++ /dev/null @@ -1,9 +0,0 @@ - -aa bb -{meow = 3} -cc dd * {meow} -ee ff ---- -aa bb -cc dd dd dd -ee ff diff --git a/tests/pass-rep-expr-var-2.nt b/tests/pass-rep-expr-var-2.nt deleted file mode 100644 index 92e0066..0000000 --- a/tests/pass-rep-expr-var-2.nt +++ /dev/null @@ -1,18 +0,0 @@ -aa bb -{meow = 3} -{meow = end} -11 22 -( - {meow = mix * 2} - cc dd * {meow} -) * 2 -ee ff -88 * {meow} - ---- -aa bb -11 22 -cc dd dd -cc dd dd -ee ff -88 88 diff --git a/tests/pass-rep-group.nt b/tests/pass-rep-group.nt deleted file mode 100644 index 80e1f17..0000000 --- a/tests/pass-rep-group.nt +++ /dev/null @@ -1,44 +0,0 @@ -aa (bb cc (dd ee) * 3) * 0xa ff ---- -aa - bb cc - dd ee - dd ee - dd ee - bb cc - dd ee - dd ee - dd ee - bb cc - dd ee - dd ee - dd ee - bb cc - dd ee - dd ee - dd ee - bb cc - dd ee - dd ee - dd ee - bb cc - dd ee - dd ee - dd ee - bb cc - dd ee - dd ee - dd ee - bb cc - dd ee - dd ee - dd ee - bb cc - dd ee - dd ee - dd ee - bb cc - dd ee - dd ee - dd ee -ff diff --git a/tests/pass-rep-one.nt b/tests/pass-rep-one.nt deleted file mode 100644 index 3484211..0000000 --- a/tests/pass-rep-one.nt +++ /dev/null @@ -1,3 +0,0 @@ -aa bb * 1 cc ---- -aa bb cc diff --git a/tests/pass-rep-post-all-bytes.nt b/tests/pass-rep-post-all-bytes.nt new file mode 100644 index 0000000..494f343 --- /dev/null +++ b/tests/pass-rep-post-all-bytes.nt @@ -0,0 +1,18 @@ +{ICITTE:8} * 256 +--- +00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f +10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f +20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f +30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f +40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f +50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f +60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f +70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f +80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f +90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f +a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af +b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf +c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf +d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df +e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef +f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff diff --git a/tests/pass-rep-post-cond.nt b/tests/pass-rep-post-cond.nt new file mode 100644 index 0000000..87a7c0c --- /dev/null +++ b/tests/pass-rep-post-cond.nt @@ -0,0 +1,18 @@ +( + + aa bb cc dd + + {include = int(beg >= 4 * (end - beg))} + (11 22 33 44) * {include} +) * 10 +--- +aa bb cc dd +aa bb cc dd +aa bb cc dd +aa bb cc dd +aa bb cc dd 11 22 33 44 +aa bb cc dd 11 22 33 44 +aa bb cc dd 11 22 33 44 +aa bb cc dd 11 22 33 44 +aa bb cc dd 11 22 33 44 +aa bb cc dd 11 22 33 44 diff --git a/tests/pass-rep-post-const-bin.nt b/tests/pass-rep-post-const-bin.nt new file mode 100644 index 0000000..607a86d --- /dev/null +++ b/tests/pass-rep-post-const-bin.nt @@ -0,0 +1,3 @@ +%11001010*5 +--- +ca ca ca ca ca diff --git a/tests/pass-rep-post-const-dec.nt b/tests/pass-rep-post-const-dec.nt new file mode 100644 index 0000000..fb7dec5 --- /dev/null +++ b/tests/pass-rep-post-const-dec.nt @@ -0,0 +1,3 @@ +$-36*5 +--- +dc dc dc dc dc diff --git a/tests/pass-rep-post-const-hex.nt b/tests/pass-rep-post-const-hex.nt new file mode 100644 index 0000000..af172d5 --- /dev/null +++ b/tests/pass-rep-post-const-hex.nt @@ -0,0 +1,3 @@ +4b*5 +--- +4b 4b 4b 4b 4b diff --git a/tests/pass-rep-post-expr-label-inner.nt b/tests/pass-rep-post-expr-label-inner.nt new file mode 100644 index 0000000..895f5c1 --- /dev/null +++ b/tests/pass-rep-post-expr-label-inner.nt @@ -0,0 +1,20 @@ +11 +( + aa bb + + cc dd * {meow} + ee ff +) * 2 +22 +--- +11 + +aa bb +cc dd dd dd +ee ff + +aa bb +cc dd dd dd dd dd dd dd dd dd dd dd +ee ff + +22 diff --git a/tests/pass-rep-post-expr-label.nt b/tests/pass-rep-post-expr-label.nt new file mode 100644 index 0000000..1275025 --- /dev/null +++ b/tests/pass-rep-post-expr-label.nt @@ -0,0 +1,8 @@ +aa bb + +cc dd * {meow} +ee ff +--- +aa bb +cc dd dd +ee ff diff --git a/tests/pass-rep-post-expr-var-1.nt b/tests/pass-rep-post-expr-var-1.nt new file mode 100644 index 0000000..22f5797 --- /dev/null +++ b/tests/pass-rep-post-expr-var-1.nt @@ -0,0 +1,8 @@ +aa bb +{meow = 3} +cc dd * {meow} +ee ff +--- +aa bb +cc dd dd dd +ee ff diff --git a/tests/pass-rep-post-expr-var-2.nt b/tests/pass-rep-post-expr-var-2.nt new file mode 100644 index 0000000..92e0066 --- /dev/null +++ b/tests/pass-rep-post-expr-var-2.nt @@ -0,0 +1,18 @@ +aa bb +{meow = 3} +{meow = end} +11 22 +( + {meow = mix * 2} + cc dd * {meow} +) * 2 +ee ff +88 * {meow} + +--- +aa bb +11 22 +cc dd dd +cc dd dd +ee ff +88 88 diff --git a/tests/pass-rep-post-group.nt b/tests/pass-rep-post-group.nt new file mode 100644 index 0000000..80e1f17 --- /dev/null +++ b/tests/pass-rep-post-group.nt @@ -0,0 +1,44 @@ +aa (bb cc (dd ee) * 3) * 0xa ff +--- +aa + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee + bb cc + dd ee + dd ee + dd ee +ff diff --git a/tests/pass-rep-post-icitte.nt b/tests/pass-rep-post-icitte.nt new file mode 100644 index 0000000..738614b --- /dev/null +++ b/tests/pass-rep-post-icitte.nt @@ -0,0 +1,5 @@ +aa bb cc dd*ICITTE ee ff +--- +aa bb cc +dd dd dd +ee ff diff --git a/tests/pass-rep-post-label.nt b/tests/pass-rep-post-label.nt new file mode 100644 index 0000000..3d53a3b --- /dev/null +++ b/tests/pass-rep-post-label.nt @@ -0,0 +1,3 @@ +aa ff dd bb * meow cc +--- +aa ff dd bb bb cc diff --git a/tests/pass-rep-post-rep.nt b/tests/pass-rep-post-rep.nt new file mode 100644 index 0000000..3166497 --- /dev/null +++ b/tests/pass-rep-post-rep.nt @@ -0,0 +1,6 @@ +((AA * 4) * 8) * 2 +--- +aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa +aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa diff --git a/tests/pass-rep-post-str-u16be.nt b/tests/pass-rep-post-str-u16be.nt new file mode 100644 index 0000000..a43f1b1 --- /dev/null +++ b/tests/pass-rep-post-str-u16be.nt @@ -0,0 +1,5 @@ +u16be"yo"*3 +--- +00 79 00 6f +00 79 00 6f +00 79 00 6f diff --git a/tests/pass-rep-post-str-u16le.nt b/tests/pass-rep-post-str-u16le.nt new file mode 100644 index 0000000..8577499 --- /dev/null +++ b/tests/pass-rep-post-str-u16le.nt @@ -0,0 +1,5 @@ +u16le"yo"*3 +--- +79 00 6f 00 +79 00 6f 00 +79 00 6f 00 diff --git a/tests/pass-rep-post-str-u32be.nt b/tests/pass-rep-post-str-u32be.nt new file mode 100644 index 0000000..cd4efc0 --- /dev/null +++ b/tests/pass-rep-post-str-u32be.nt @@ -0,0 +1,5 @@ +u32be"yo"*3 +--- +00 00 00 79 00 00 00 6f +00 00 00 79 00 00 00 6f +00 00 00 79 00 00 00 6f diff --git a/tests/pass-rep-post-str-u32le.nt b/tests/pass-rep-post-str-u32le.nt new file mode 100644 index 0000000..33ef354 --- /dev/null +++ b/tests/pass-rep-post-str-u32le.nt @@ -0,0 +1,5 @@ +u32le"yo"*3 +--- +79 00 00 00 6f 00 00 00 +79 00 00 00 6f 00 00 00 +79 00 00 00 6f 00 00 00 diff --git a/tests/pass-rep-post-str-u8.nt b/tests/pass-rep-post-str-u8.nt new file mode 100644 index 0000000..84100a6 --- /dev/null +++ b/tests/pass-rep-post-str-u8.nt @@ -0,0 +1,5 @@ +"yo"*3 +--- +79 6f +79 6f +79 6f diff --git a/tests/pass-rep-post-var.nt b/tests/pass-rep-post-var.nt new file mode 100644 index 0000000..632f06e --- /dev/null +++ b/tests/pass-rep-post-var.nt @@ -0,0 +1,3 @@ +aa {meow = 5} dd bb * meow cc +--- +aa dd bb bb bb bb bb cc diff --git a/tests/pass-rep-post-zero.nt b/tests/pass-rep-post-zero.nt new file mode 100644 index 0000000..2f677a4 --- /dev/null +++ b/tests/pass-rep-post-zero.nt @@ -0,0 +1,3 @@ +aa bb * 0 cc +--- +aa cc diff --git a/tests/pass-rep-rep.nt b/tests/pass-rep-rep.nt deleted file mode 100644 index 3166497..0000000 --- a/tests/pass-rep-rep.nt +++ /dev/null @@ -1,6 +0,0 @@ -((AA * 4) * 8) * 2 ---- -aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa -aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa -aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa -aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa diff --git a/tests/pass-rep-str-u16be.nt b/tests/pass-rep-str-u16be.nt deleted file mode 100644 index a43f1b1..0000000 --- a/tests/pass-rep-str-u16be.nt +++ /dev/null @@ -1,5 +0,0 @@ -u16be"yo"*3 ---- -00 79 00 6f -00 79 00 6f -00 79 00 6f diff --git a/tests/pass-rep-str-u16le.nt b/tests/pass-rep-str-u16le.nt deleted file mode 100644 index 8577499..0000000 --- a/tests/pass-rep-str-u16le.nt +++ /dev/null @@ -1,5 +0,0 @@ -u16le"yo"*3 ---- -79 00 6f 00 -79 00 6f 00 -79 00 6f 00 diff --git a/tests/pass-rep-str-u32be.nt b/tests/pass-rep-str-u32be.nt deleted file mode 100644 index cd4efc0..0000000 --- a/tests/pass-rep-str-u32be.nt +++ /dev/null @@ -1,5 +0,0 @@ -u32be"yo"*3 ---- -00 00 00 79 00 00 00 6f -00 00 00 79 00 00 00 6f -00 00 00 79 00 00 00 6f diff --git a/tests/pass-rep-str-u32le.nt b/tests/pass-rep-str-u32le.nt deleted file mode 100644 index 33ef354..0000000 --- a/tests/pass-rep-str-u32le.nt +++ /dev/null @@ -1,5 +0,0 @@ -u32le"yo"*3 ---- -79 00 00 00 6f 00 00 00 -79 00 00 00 6f 00 00 00 -79 00 00 00 6f 00 00 00 diff --git a/tests/pass-rep-str-u8.nt b/tests/pass-rep-str-u8.nt deleted file mode 100644 index 84100a6..0000000 --- a/tests/pass-rep-str-u8.nt +++ /dev/null @@ -1,5 +0,0 @@ -"yo"*3 ---- -79 6f -79 6f -79 6f diff --git a/tests/pass-rep-zero.nt b/tests/pass-rep-zero.nt deleted file mode 100644 index 2f677a4..0000000 --- a/tests/pass-rep-zero.nt +++ /dev/null @@ -1,3 +0,0 @@ -aa bb * 0 cc ---- -aa cc