This package offers both a portable {py3} module and a command-line
tool.
-WARNING: This version of Normand is 0.21, meaning both the Normand
+WARNING: This version of Normand is 0.22, meaning both the Normand
language and the module/CLI interface aren't stable.
ifdef::env-github[]
+
----
{strength = 4}
-{be} 67 <lbl> 44 $178 {(end - lbl) * 8 + strength : 16} $99 <end>
-{le} {-1993 : 32}
-{-3.141593 : 64}
+!be 67 <lbl> 44 $178 [(end - lbl) * 8 + strength : 16] $99 <end>
+!le [-1993 : 32]
+[-3.141593 : 64]
----
+
Output:
Input:
+
----
-aa bb cc {-1993 : sleb128} <meow> dd ee ff
-{meow * 199 : uleb128}
+aa bb cc [-1993 : sleb128] <meow> dd ee ff
+[meow * 199 : uleb128]
----
+
Output:
Input:
+
----
-{be}
+!be
- {199:32}
-@64 {43:64}
-@16 {-123:16}
-@32~255 {5584:32}
+ [199:32]
+@64 [43:64]
+@16 [-123:16]
+@32~255 [5584:32]
----
+
Output:
Input:
+
----
-{le}
-{0xdeadbeef:32}
-{-1993:16}
-{9:16}
+!le
+[0xdeadbeef:32]
+[-1993:16]
+[9:16]
+0x40
-{ICITTE:8}
+[ICITTE:8]
"meow mix"
+200~FFh
-{ICITTE:8}
+[ICITTE:8]
----
+
Output:
Input:
+
----
-"end of file @ " {end:8}
+"end of file @ " [end:8]
!transform gzip
"this part will be gzipped"
----
ff dd 01 ab $192 $-128 %1101:0011
-{end:8}
+[end:8]
{iter = 1}
!if {not something}
# five times because xyz
!repeat 5
- "hello world " {iter:8}
+ "hello world " [iter:8]
{iter = iter + 1}
!end
!end
nibbles and binary bits of <<byte-constant,byte constants>>:
----
-/ \ ? & : ; . , [ ] _ = | -
+& , - . / : ; = ? \ _ |
----
The latter serve to improve readability so that you may write, for
* The `0b` or `0B` prefix followed with one or more bits (`0` or `1`).
* One or more bits followed with the `b` or `B` suffix.
+In general, anything between `pass:[{]` and `}` is a {py3} expression.
+
You can test the examples of this section with the `normand`
<<command-line-tool,command-line tool>> as such:
Input:
----
-ab cd [3d 8F] CC
+ab cd (3d 8F) CC
----
Output:
The two accepted forms are:
[horizontal]
-``pass:[{be}]``:: Set the current byte order to big endian.
-``pass:[{le}]``:: Set the current byte order to little endian.
+`!be`:: Set the current byte order to big endian.
+`!le`:: Set the current byte order to little endian.
=== Fixed-length number
A fixed-length number is:
-. The ``pass:[{]`` prefix.
+. The `[` prefix.
. A valid {py3} expression.
+
`32` and `64`.
--
-. The `}` suffix.
+. The `]` suffix.
====
Input:
----
-{le} {345:16}
-{be} {-0xabcd:32}
+!le [345:16]
+!be [-0xabcd:32]
----
Output:
Input:
----
-{be}
+!be
# String length in bits
-{8 * (str_end - str_beg) : 16}
+[8 * (str_end - str_beg) : 16]
# String
<str_beg>
Input:
----
-{20 - ICITTE : 8} * 10
+[20 - ICITTE : 8] * 10
----
Output:
Input:
----
-{le}
-{2 * 0.0529 : 32}
+!le
+[2 * 0.0529 : 32]
----
Output:
An LEB128 integer is:
-. The ``pass:[{]`` prefix.
+. The `[` prefix.
. A valid {py3} expression of which the evaluation result type
is `int` or `bool` (automatically converted to `int`).
`sleb128`:: Use the signed LEB128 format.
--
-. The `}` suffix.
+. The `]` suffix.
====
Input:
----
-{624485 : uleb128}
+[624485 : uleb128]
----
Output:
aa bb cc dd
<meow>
ee ff
-{-981238311 + (meow * -23) : sleb128}
+[-981238311 + (meow * -23) : sleb128]
"hello"
----
Encoding suffix form:: {empty}
+
-. The ``pass:[{]`` prefix.
+. The `[` prefix.
. A valid {py3} expression of which the evaluation result type
is `bool`, `int`, `float`, or `str` (the first three automatically
ISO/IEC 8859-16.
--
-. The `}` suffix.
+. The `]` suffix.
====
Input:
{iter = 1}
!repeat 10
- {iter : s:u8} " "
+ u8{iter} " "
{iter = iter + 1}
!end
----
----
{meow = 'salut jérémie'}
-{meow.upper() : s:latin1}
+[meow.upper() : s:latin1]
----
Output:
Input:
----
- {ICITTE : 8} * 8
-<0x61> {ICITTE : 8} * 8
+ [ICITTE : 8] * 8
+<0x61> [ICITTE : 8] * 8
----
Output:
----
aa bb cc dd <meow> ee ff
<12> 11 22 33 <mix> 44 55
-{meow : 8} {mix : 8}
+[meow : 8] [mix : 8]
----
Output:
Input:
----
-{le}
+!le
77 88
-@32~0xcc {-893.5:32}
+@32~0xcc [-893.5:32]
@128~0x55 "meow"
----
** The ``pass:[{]`` prefix, a valid {py3} expression of which the
evaluation result type is `int` or `bool` (automatically converted to
- `int`), and the ``pass:[}]`` suffix.
+ `int`), and the `}` suffix.
+
For a filling at some source location{nbsp}__**L**__, this expression
may contain:
** A valid {py3} name.
+
For the name `__NAME__`, this is equivalent to the
-`pass:[{]__NAME__pass:[}]` form above.
+`pass:[{]__NAME__}` form above.
+
This value must be greater than or equal to the current offset where
----
!macro part(iter, fill)
- <0> "particular security " {ord('0') + iter : 8} +fill~0x80
+ <0> "particular security " [ord('0') + iter : 8] +fill~0x80
!end
{iter = 1}
Input:
----
-{mix = 101} {le}
-{meow = 42} 11 22 {meow:8} 33 {meow = ICITTE + 17}
-"yooo" {meow + mix : 16}
+{mix = 101} !le
+{meow = 42} 11 22 [meow:8] 33 {meow = ICITTE + 17}
+"yooo" [meow + mix : 16]
----
Output:
Input:
----
-{be}
+!be
(
<str_beg> u16le"sébastien diaz" <str_end>
- {ICITTE - str_beg : 8}
- {(end - str_beg) * 5 : 24}
+ [ICITTE - str_beg : 8]
+ [(end - str_beg) * 5 : 24]
) * 3
<end>
----
** The ``pass:[{]`` prefix, a valid {py3} expression of which the
evaluation result type is `int` or `bool` (automatically converted to
- `int`), and the ``pass:[}]`` suffix.
+ `int`), and the `}` suffix.
+
For a conditional block at some source location{nbsp}__**L**__, this
expression may contain:
** A valid {py3} name.
+
For the name `__NAME__`, this is equivalent to the
-`pass:[{]__NAME__pass:[}]` form above.
+`pass:[{]__NAME__}` form above.
. Zero or more items to be handled when the condition is true
except, recursively, a macro definition block.
** The ``pass:[{]`` prefix, a valid {py3} expression of which the
evaluation result type is `int` or `bool` (automatically converted to
- `int`), and the ``pass:[}]`` suffix.
+ `int`), and the `}` suffix.
+
For a repetition block at some source location{nbsp}__**L**__, this
expression may contain:
** A valid {py3} name.
+
For the name `__NAME__`, this is equivalent to the
-`pass:[{]__NAME__pass:[}]` form above.
+`pass:[{]__NAME__}` form above.
. Zero or more items except, recursively, a macro definition block.
----
!repeat 0o400
- {end - ICITTE - 1 : 8}
+ [end - ICITTE - 1 : 8]
!end
<end>
----
aa bb cc dd
-"size of compressed section: " {end - start : 8}
+"size of compressed section: " [end - start : 8]
<start>
@128~99h
-!t qp <beg> {ICITTE - beg : 8} * 50 !end
+!t qp <beg> [ICITTE - beg : 8] * 50 !end
----
Output:
====
----
!macro bake()
- {le} {ICITTE * 8 : 16}
+ !le [ICITTE * 8 : 16]
u16le"predict explode"
!end
----
{iter = 1}
!repeat rep
- {val + iter : uleb128}
- {0xdeadbeef : 32}
+ [val + iter : uleb128]
+ [0xdeadbeef : 32]
{iter = iter + 1}
!end
* The ``pass:[{]`` prefix, a valid {py3} expression of which the
evaluation result type is `int` or `bool` (automatically converted to
- `int`), and the ``pass:[}]`` suffix.
+ `int`), and the `}` suffix.
+
For a macro expansion at some source location{nbsp}__**L**__, this
expression may contain:
----
!macro bake()
- {le} {ICITTE * 8 : 16}
+ !le [ICITTE * 8 : 16]
u16le"predict explode"
!end
----
!macro A(val, is_be)
- {le}
+ !le
!if is_be
- {be}
+ !be
!end
- {val : 16}
+ [val : 16]
!end
!macro B(rep, is_be)
Input:
----
-!macro flt32be(val) {be} {val : 32} !end
+!macro flt32be(val) !be [val : 32] !end
"CHEETOS"
m:flt32be(-42.17)
** The ``pass:[{]`` prefix, a valid {py3} expression of which the
evaluation result type is `int` or `bool` (automatically converted to
- `int`), and the ``pass:[}]`` suffix.
+ `int`), and the `}` suffix.
+
For a post-item repetition at some source location{nbsp}__**L**__, this
expression may contain:
Input:
----
-{end - ICITTE - 1 : 8} * 0x100 <end>
+[end - ICITTE - 1 : 8] * 0x100 <end>
----
Output:
# Upstream repository: <https://github.com/efficios/normand>.
__author__ = "Philippe Proulx"
-__version__ = "0.21.0"
+__version__ = "0.22.0"
__all__ = [
"__author__",
"__version__",
self._label_names = set(labels.keys())
self._var_names = set(variables.keys())
self._macro_defs = {} # type: _MacroDefsT
+ self._base_item_parse_funcs = [
+ self._try_parse_byte,
+ self._try_parse_str,
+ self._try_parse_val,
+ self._try_parse_var_assign,
+ self._try_parse_set_bo,
+ self._try_parse_label_or_set_offset,
+ self._try_parse_align_offset,
+ self._try_parse_fill_until,
+ self._try_parse_group,
+ self._try_parse_rep_block,
+ self._try_parse_cond_block,
+ self._try_parse_macro_exp,
+ self._try_parse_trans_block,
+ ]
self._parse()
# Result (main group).
_comment_pat = re.compile(r"#[^#]*?(?:$|#)", re.M)
_ws_or_comments_pat = re.compile(r"(?:\s|{})*".format(_comment_pat.pattern), re.M)
_ws_or_syms_or_comments_pat = re.compile(
- r"(?:[\s/\\?&:;.,[\]_=|-]|{})*".format(_comment_pat.pattern), re.M
+ r"(?:[\s/\\?&:;.,_=|-]|{})*".format(_comment_pat.pattern), re.M
)
# Skips as many whitespaces and comments as possible, but not
return expr_str, expr
# Patterns for _try_parse_val()
- _val_expr_pat = re.compile(r"([^}:]+):\s*")
+ _val_prefix_pat = re.compile(r"\[")
+ _val_expr_pat = re.compile(r"([^\]:]+):")
_fl_num_len_fmt_pat = re.compile(r"8|16|24|32|40|48|56|64")
_leb128_int_fmt_pat = re.compile(r"(u|s)leb128")
+ _val_suffix_pat = re.compile(r"]")
# Tries to parse a value (number or string) and format (fixed length
# in bits, `uleb128`, `sleb128`, or `s:` followed with an encoding
# name), returning an item on success.
def _try_parse_val(self):
- begin_text_loc = self._text_loc
-
- # Match
- m_expr = self._try_parse_pat(self._val_expr_pat)
-
- if m_expr is None:
+ # Match prefix
+ if self._try_parse_pat(self._val_prefix_pat) is None:
# No match
return
+ # Expect expression and `:`
+ self._skip_ws_and_comments()
+ expr_text_loc = self._text_loc
+ m = self._expect_pat(self._val_expr_pat, "Expecting an expression")
+
# Create an expression node from the expression string
- expr_str, expr = self._ast_expr_from_str(m_expr.group(1), begin_text_loc)
+ expr_str, expr = self._ast_expr_from_str(m.group(1), expr_text_loc)
# Fixed length?
self._skip_ws_and_comments()
m_fmt = self._try_parse_pat(self._fl_num_len_fmt_pat)
- if m_fmt is None:
+ if m_fmt is not None:
+ # Create fixed-length number item
+ item = _FlNum(
+ expr_str,
+ expr,
+ int(m_fmt.group(0)),
+ expr_text_loc,
+ )
+ else:
# LEB128?
m_fmt = self._try_parse_pat(self._leb128_int_fmt_pat)
- if m_fmt is None:
+ if m_fmt is not None:
+ # Create LEB128 integer item
+ cls = _ULeb128Int if m_fmt.group(1) == "u" else _SLeb128Int
+ item = cls(expr_str, expr, expr_text_loc)
+ else:
# String encoding?
codec = self._try_parse_str_encoding(True)
- if codec is None:
+ if codec is not None:
+ # Create string item
+ item = _Str(expr_str, expr, codec, expr_text_loc)
+ else:
# At this point it's invalid
self._raise_error(
"Expecting a fixed length (multiple of eight bits), `uleb128`, `sleb128`, or `s:` followed with a valid encoding (`u8`, `u16be`, `u16le`, `u32be`, `u32le`, or `latin1` to `latin10`)"
)
- else:
- # Return string item
- return _Str(expr_str, expr, codec, begin_text_loc)
- # Return LEB128 integer item
- cls = _ULeb128Int if m_fmt.group(1) == "u" else _SLeb128Int
- return cls(expr_str, expr, begin_text_loc)
- else:
- # Return fixed-length number item
- return _FlNum(
- expr_str,
- expr,
- int(m_fmt.group(0)),
- begin_text_loc,
- )
+ # Expect `]`
+ self._skip_ws_and_comments()
+ m = self._expect_pat(self._val_suffix_pat, "Expecting `]`")
+
+ # Return item
+ return item
# Patterns for _try_parse_var_assign()
- _var_assign_name_equal_pat = re.compile(
- r"({})\s*=(?!=)".format(_py_name_pat.pattern)
- )
+ _var_assign_prefix_pat = re.compile(r"\{")
+ _var_assign_equal_pat = re.compile(r"=")
_var_assign_expr_pat = re.compile(r"[^}]+")
+ _var_assign_suffix_pat = re.compile(r"\}")
# Tries to parse a variable assignment, returning a variable
# assignment item on success.
def _try_parse_var_assign(self):
- begin_text_loc = self._text_loc
-
- # Match
- m = self._try_parse_pat(self._var_assign_name_equal_pat)
-
- if m is None:
+ # Match prefix
+ if self._try_parse_pat(self._var_assign_prefix_pat) is None:
# No match
return
- # Validate name
- name = m.group(1)
+ # Expect a name
+ self._skip_ws_and_comments()
+ name_text_loc = self._text_loc
+ m = self._expect_pat(_py_name_pat, "Expecting a valid Python name")
+ name = m.group(0)
+ # Expect `=`
+ self._skip_ws_and_comments()
+ self._expect_pat(self._var_assign_equal_pat, "Expecting `=`")
+
+ # Expect expression
+ self._skip_ws_and_comments()
+ expr_text_loc = self._text_loc
+ m_expr = self._expect_pat(self._var_assign_expr_pat, "Expecting an expression")
+
+ # Expect `}`
+ self._skip_ws_and_comments()
+ self._expect_pat(self._var_assign_suffix_pat, "Expecting `}`")
+
+ # Validate name
if name == _icitte_name:
_raise_error(
- "`{}` is a reserved variable name".format(_icitte_name), begin_text_loc
+ "`{}` is a reserved variable name".format(_icitte_name), name_text_loc
)
if name in self._label_names:
- _raise_error("Existing label named `{}`".format(name), begin_text_loc)
-
- # Expect an expression
- self._skip_ws_and_comments()
- m = self._expect_pat(self._var_assign_expr_pat, "Expecting an expression")
+ _raise_error("Existing label named `{}`".format(name), name_text_loc)
# Create an expression node from the expression string
- expr_str, expr = self._ast_expr_from_str(m.group(0), begin_text_loc)
+ expr_str, expr = self._ast_expr_from_str(m_expr.group(0), expr_text_loc)
# Add to known variable names
self._var_names.add(name)
name,
expr_str,
expr,
- begin_text_loc,
+ name_text_loc,
)
# Pattern for _try_parse_set_bo()
- _bo_pat = re.compile(r"[bl]e")
+ _set_bo_pat = re.compile(r"!([bl]e)\b")
- # Tries to parse a byte order name, returning a byte order setting
- # item on success.
+ # Tries to parse a byte order setting, returning a byte order
+ # setting item on success.
def _try_parse_set_bo(self):
begin_text_loc = self._text_loc
# Match
- m = self._try_parse_pat(self._bo_pat)
+ m = self._try_parse_pat(self._set_bo_pat)
if m is None:
# No match
return
# Return corresponding item
- if m.group(0) == "be":
- return _SetBo(ByteOrder.BE, begin_text_loc)
+ if m.group(1) == "be":
+ bo = ByteOrder.BE
else:
- assert m.group(0) == "le"
- return _SetBo(ByteOrder.LE, begin_text_loc)
-
- # Patterns for _try_parse_val_or_bo()
- _val_var_assign_set_bo_prefix_pat = re.compile(r"\{")
- _val_var_assign_set_bo_suffix_pat = re.compile(r"\}")
-
- # Tries to parse a value, a variable assignment, or a byte order
- # setting, returning an item on success.
- def _try_parse_val_or_var_assign_or_set_bo(self):
- # Match prefix
- if self._try_parse_pat(self._val_var_assign_set_bo_prefix_pat) is None:
- # No match
- return
-
- self._skip_ws_and_comments()
-
- # Variable assignment item?
- item = self._try_parse_var_assign()
-
- if item is None:
- # Value item?
- item = self._try_parse_val()
-
- if item is None:
- # Byte order setting item?
- item = self._try_parse_set_bo()
-
- if item is None:
- # At this point it's invalid
- self._raise_error(
- "Expecting a fixed-length number, a string, a variable assignment, or a byte order setting"
- )
+ assert m.group(1) == "le"
+ bo = ByteOrder.LE
- # Expect suffix
- self._skip_ws_and_comments()
- self._expect_pat(self._val_var_assign_set_bo_suffix_pat, "Expecting `}`")
- return item
+ return _SetBo(bo, begin_text_loc)
# Tries to parse an offset setting value (after the initial `<`),
# returning an offset item on success.
# Return item
return _MacroExp(name, params, begin_text_loc)
- # Tries to parse a base item (anything except a repetition),
- # returning it on success.
+ # Tries to parse a base item (anything except a post-item
+ # repetition), returning it on success.
def _try_parse_base_item(self):
- # Byte item?
- item = self._try_parse_byte()
+ for func in self._base_item_parse_funcs:
+ item = func()
- if item is not None:
- return item
-
- # String item?
- item = self._try_parse_str()
-
- if item is not None:
- return item
-
- # Value, variable assignment, or byte order setting item?
- item = self._try_parse_val_or_var_assign_or_set_bo()
-
- if item is not None:
- return item
-
- # Label or offset setting item?
- item = self._try_parse_label_or_set_offset()
-
- if item is not None:
- return item
-
- # Offset alignment item?
- item = self._try_parse_align_offset()
-
- if item is not None:
- return item
-
- # Filling item?
- item = self._try_parse_fill_until()
-
- if item is not None:
- return item
-
- # Group item?
- item = self._try_parse_group()
-
- if item is not None:
- return item
-
- # Repetition block item?
- item = self._try_parse_rep_block()
-
- if item is not None:
- return item
-
- # Conditional block item?
- item = self._try_parse_cond_block()
-
- if item is not None:
- return item
-
- # Macro expansion item?
- item = self._try_parse_macro_exp()
-
- if item is not None:
- return item
-
- # Transformation block item?
- item = self._try_parse_trans_block()
-
- if item is not None:
- return item
+ if item is not None:
+ return item
# Pattern for _try_parse_rep_post()
_rep_post_prefix_pat = re.compile(r"\*")
[tool.poetry]
name = 'normand'
-version = '0.21.0'
+version = '0.22.0'
description = 'Text-to-binary processor with its own language'
license = 'MIT'
authors = ['Philippe Proulx <eeppeliteloop@gmail.com>']
normand.parse(normand_text)
exc = exc_info.value
- expected_msg = ''
+ expected_msg = ""
for msg in reversed(exc.messages):
expected_msg += "{}:{} - {}\n".format(
-{be}
-{ 18.49 : 16 }
+!be
+[ 18.49 : 16 ]
---
2:3 - Invalid 16-bit length for a fixed-length floating point number (value 18.49)
aa bb
-{be}
-{ -(2**31) - 1 : 32 }
+!be
+[ -(2**31) - 1 : 32 ]
---
3:3 - Value -2,147,483,649 is outside the 32-bit range when evaluating expression `-(2**31) - 1`
-{be}
+!be
"yoyo"
-{ 2**32 : 32 }
+[ 2**32 : 32 ]
---
3:3 - Value 4,294,967,296 is outside the 32-bit range when evaluating expression `2**32`
-{ -129 : 8 }
+[ -129 : 8 ]
---
1:3 - Value -129 is outside the 8-bit range when evaluating expression `-129`
-{ 256 : 8 }
+[ 256 : 8 ]
---
1:3 - Value 256 is outside the 8-bit range when evaluating expression `256`
-{ : 8 }
+[ : 8 ]
---
-1:3 - Expecting a fixed-length number, a string, a variable assignment, or a byte order setting
+1:3 - Expecting an expression
-{ 'salut' : 8 }
+[ 'salut' : 8 ]
---
1:3 - Invalid expression `'salut'`: expecting result type `float` or `int`, not `str`
-{ 23 + zoom(14) : 8 }
+[ 23 + zoom(14) : 8 ]
---
1:3 - Failed to evaluate expression `23 + zoom(14)`: name 'zoom' is not defined
-{ 23 : 17 }
+[ 23 : 17 ]
---
1:8 - Expecting a fixed length (multiple of eight bits), `uleb128`, `sleb128`, or `s:` followed with a valid encoding (`u8`, `u16be`, `u16le`, `u32be`, `u32le`, or `latin1` to `latin10`)
-{ 19 + / 23 : 8 }
+[ 19 + / 23 : 8 ]
---
1:3 - Invalid expression `19 + / 23`: invalid syntax
-{ 34 : 16 }
+[ 34 : 16 ]
---
1:3 - Current byte order isn't defined at first fixed-length number (`34`) to encode on more than 8 bits
-{ 23 : }
+[ 23 : ]
---
1:9 - Expecting a fixed length (multiple of eight bits), `uleb128`, `sleb128`, or `s:` followed with a valid encoding (`u8`, `u16be`, `u16le`, `u32be`, `u32le`, or `latin1` to `latin10`)
-{ meow : 8 }
+[ meow : 8 ]
---
1:3 - Illegal (unknown or unreachable) variable/label name `meow` in expression `meow`; the legal names are {`ICITTE`}
-{ meow : 8 }
+[ meow : 8 ]
{ meow = 34 }
---
1:3 - Illegal (unknown or unreachable) variable/label name `meow` in expression `meow`; the legal names are {`ICITTE`}
!macro meow(yeah)
- {yeah:8}
+ [yeah:8]
!end
!macro mix(yeah)
!macro meow()
- {1993:8}
+ [1993:8]
!end
!macro mix()
-{ : sleb128 }
+[ : sleb128 ]
---
-1:3 - Expecting a fixed-length number, a string, a variable assignment, or a byte order setting
+1:3 - Expecting an expression
-{ : s:u8}
+[ : s:u8]
---
-1:3 - Expecting a fixed-length number, a string, a variable assignment, or a byte order setting
+1:3 - Expecting an expression
-{"a string" : s:latin11}
+["a string" : s:latin11]
---
1:17 - Expecting `u8`, `u16be`, `u16le`, `u32be`, `u32le`, or `latin1` to `latin10`
-{"a string" : s:u24be}
+["a string" : s:u24be]
---
1:18 - Expecting `8`, `16be`, `16le`, `32be` or `32le`
-{"a string" : slatin1}
+["a string" : slatin1]
---
1:16 - Expecting `:`
-{"a string" : }
+["a string" : ]
---
1:15 - Expecting a fixed length (multiple of eight bits), `uleb128`, `sleb128`, or `s:` followed with a valid encoding (`u8`, `u16be`, `u16le`, `u32be`, `u32le`, or `latin1` to `latin10`)
-{"a string" : latin1}
+["a string" : latin1]
---
1:15 - Expecting a fixed length (multiple of eight bits), `uleb128`, `sleb128`, or `s:` followed with a valid encoding (`u8`, `u16be`, `u16le`, `u32be`, `u32le`, or `latin1` to `latin10`)
-{"a string" : s:u}
+["a string" : s:u]
---
1:18 - Expecting `8`, `16be`, `16le`, `32be` or `32le`
{"a string"}
---
-1:2 - Expecting a fixed-length number, a string, a variable assignment, or a byte order setting
+1:2 - Expecting a valid Python name
!transform base64
"meow"
- {far:8}
+ [far:8]
"mix"
<far>
!end
-{ : uleb128 }
+[ : uleb128 ]
---
-1:3 - Expecting a fixed-length number, a string, a variable assignment, or a byte order setting
+1:3 - Expecting an expression
-{ 'salut' : uleb128 }
+[ 'salut' : uleb128 ]
---
1:3 - Invalid expression `'salut'`: expecting result type `int`, not `str`
-{ 45.2 : uleb128 }
+[ 45.2 : uleb128 ]
---
1:3 - Invalid expression `45.2`: expecting result type `int`, not `float`
-{ 23 + zoom(14) : uleb128 }
+[ 23 + zoom(14) : uleb128 ]
---
1:3 - Failed to evaluate expression `23 + zoom(14)`: name 'zoom' is not defined
-{ 19 + / 23 : uleb128 }
+[ 19 + / 23 : uleb128 ]
---
1:3 - Invalid expression `19 + / 23`: invalid syntax
-{ meow : 8 }
+[ meow : 8 ]
---
1:3 - Illegal (unknown or unreachable) variable/label name `meow` in expression `meow`; the legal names are {`ICITTE`}
-{ meow : uleb128 }
+[ meow : uleb128 ]
{ meow = 34 }
---
1:3 - Illegal (unknown or unreachable) variable/label name `meow` in expression `meow`; the legal names are {`ICITTE`}
<meow>
aa bb {kilo = 23} cc
-{mix : uleb128}
+[mix : uleb128]
ee <mix>
---
3:2 - Illegal (unknown or unreachable) variable/label name `mix` in expression `mix`; the legal names are {`ICITTE`, `kilo`, `meow`}
aa {mix = 23} bb <flake> cc
(
- dd {meow : uleb128}
+ dd [meow : uleb128]
ff
<meow>
)
{ hello }
---
-1:3 - Expecting a fixed-length number, a string, a variable assignment, or a byte order setting
+1:9 - Expecting `=`
{dim = 128}
-{le}
+!le
# Single pixel macro
!macro px(r, g, b)
- {r:8} {g:8} {b:8}
+ [r:8] [g:8] [b:8]
!end
# Header
"BM"
# File size
- {end : 32}
+ [end : 32]
# Reserved
00 00 00 00
# Bitmap data offset
- {data : 32}
+ [data : 32]
# DIB header
<dib_start>
# DIB header size
- {dib_end - dib_start : 32}
+ [dib_end - dib_start : 32]
# Bitmap width
- {dim : 16}
+ [dim : 16]
# Bitmap height
- {dim : 16}
+ [dim : 16]
# Planes
- {1 : 16}
+ [1 : 16]
# Bits/pixel
- {24 : 16}
+ [24 : 16]
<dib_end>
-{0xff:8}
-{be} {0x17:16} {0x17:16}
-{le} {0x23:16} {0x23:16}
-{be} {0x42:16} {0x42:16}
+[0xff:8]
+!be [0x17:16] [0x17:16]
+!le [0x23:16] [0x23:16]
+!be [0x42:16] [0x42:16]
---
ff
00 17 00 17
#bonjour tout le monde#s#bonjour tout le monde#:#bonjour tout le monde#u16be#bonjour tout le monde#"coucou"#bonjour tout le monde#
# byte order setting
-#bonjour tout le monde#{#bonjour tout le monde#be#bonjour tout le monde#}#bonjour tout le monde#{0xaabb:16}
-#bonjour tout le monde#{#bonjour tout le monde#le#bonjour tout le monde#}#bonjour tout le monde#{0xaabb:16}
+#bonjour tout le monde#!be#bonjour tout le monde#[0xaabb:16]
+#bonjour tout le monde#!le#bonjour tout le monde#[0xaabb:16]
# fixed-length number
-#bonjour tout le monde#{ 0xbeef :#bonjour tout le monde#16#bonjour tout le monde#}#bonjour tout le monde#
+#bonjour tout le monde#[#bonjour tout le monde#0xbeef :#bonjour tout le monde#16#bonjour tout le monde#]#bonjour tout le monde#
# LEB128 integer: unsigned
-#bonjour tout le monde#{ 12345678 :#bonjour tout le monde#uleb128#bonjour tout le monde#}#bonjour tout le monde#
+#bonjour tout le monde#[#bonjour tout le monde#12345678 :#bonjour tout le monde#uleb128#bonjour tout le monde#]#bonjour tout le monde#
# LEB128 integer: signed
-#bonjour tout le monde#{ -12345678 :#bonjour tout le monde#sleb128#bonjour tout le monde#}#bonjour tout le monde#
+#bonjour tout le monde#[#bonjour tout le monde#-12345678 :#bonjour tout le monde#sleb128#bonjour tout le monde#]#bonjour tout le monde#
# string: encoding before
#bonjour tout le monde#s#bonjour tout le monde#:#bonjour tout le monde#latin1#bonjour tout le monde#{ "allo" }#bonjour tout le monde#
# string: encoding after
-#bonjour tout le monde#{ 'meow mix' :#bonjour tout le monde#s#bonjour tout le monde#:#bonjour tout le monde#latin3#bonjour tout le monde#}#bonjour tout le monde#
+#bonjour tout le monde#[#bonjour tout le monde#'meow mix' :#bonjour tout le monde#s#bonjour tout le monde#:#bonjour tout le monde#latin3#bonjour tout le monde#]#bonjour tout le monde#
# current offset setting
-#bonjour tout le monde#<#bonjour tout le monde#18#bonjour tout le monde#>#bonjour tout le monde#{ICITTE-18:8}
+#bonjour tout le monde#<#bonjour tout le monde#18#bonjour tout le monde#>#bonjour tout le monde#[ICITTE-18:8]
# current offset alignment
#bonjour tout le monde#@#bonjour tout le monde#64#bonjour tout le monde#~#bonjour tout le monde#ffh#bonjour tout le monde#
#bonjour tout le monde#+#bonjour tout le monde#{ ICITTE+8+4+2+1+1 }#bonjour tout le monde#~#bonjour tout le monde#0xcc#bonjour tout le monde#
# label
-#bonjour tout le monde#<#bonjour tout le monde#salut#bonjour tout le monde#>#bonjour tout le monde#{salut-ICITTE:8}
+#bonjour tout le monde#<#bonjour tout le monde#salut#bonjour tout le monde#>#bonjour tout le monde#[salut-ICITTE:8]
# group
#bonjour tout le monde#(#bonjour tout le monde#aa#bonjour tout le monde#)#bonjour tout le monde#
# macro definition block
#bonjour tout le monde#!macro#bonjour tout le monde#gang#bonjour tout le monde#(#bonjour tout le monde#meow#bonjour tout le monde#,#bonjour tout le monde#mix#bonjour tout le monde#)#bonjour tout le monde#
- aa {meow:8} bb {mix:8}
+ aa [meow:8] bb [mix:8]
#bonjour tout le monde#!end#bonjour tout le monde#
# macro expansion
-%1/01\0?1&0:1;0 %.0,10[1]0_1=0|1 %1111-0000
+%1/01\0?1&0:1;0 %.0,1010_1=0|1 %1111-0000
% 1 0 / 1 \ 0 ? 1 & 0 : 1 ; 0
-% . 0 , 1 0 [ 1 ] 0 _ 1 = 0 | 1
+% . 0 , 1 0 1 0 _ 1 = 0 | 1
% 1111 - 0000
---
aa 55 f0
-(012/3\4?5&6:7;8.9,ab[c]d_e=f|0-1(/\?&:;.,[]_=|-))
+(012/3\4?5&6:7;8.9,abcd_e=f|0-1(/\?&:;.,_=|-))
---
01 23 45 67 89 ab cd ef 01
-/ \ ? & : ; . , [ ] _ = | -
-012/3\4?5&6:7;8.9,ab[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,abcd_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
!m ci(val)
- {val:8}
+ [val:8]
!end
m:ci(0b11001010)
!m ci(val)
- {val:8}
+ [val:8]
!end
m:ci(42)
!m ci(val)
- {val:8}
+ [val:8]
!end
m:ci(0x01)
!m ci(val)
- {val:8}
+ [val:8]
!end
m:ci(0o01)
-aa bb cc +{ICITTE} {ICITTE:8}
+aa bb cc +{ICITTE} [ICITTE:8]
---
aa bb cc 03
-aa {zoom = 10} bb cc +zoom {ICITTE:8}
+aa {zoom = 10} bb cc +zoom [ICITTE:8]
---
aa bb cc 00 00
00 00 00 00 00
-aa {zoom = 10} bb cc +zoom~0xcc {ICITTE:8}
-+ 15 ~ 255 {ICITTE:8}
+aa {zoom = 10} bb cc +zoom~0xcc [ICITTE:8]
++ 15 ~ 255 [ICITTE:8]
---
aa bb cc cc cc
cc cc cc cc cc
-aa bb cc +10 {ICITTE:8}
+aa bb cc +10 [ICITTE:8]
---
aa bb cc 00 00
00 00 00 00 00
-{be}
-{2.99792458e8:32}
-{-1.6021766208:32}
+!be
+[2.99792458e8:32]
+[-1.6021766208:32]
---
4d 8e f3 c2
bf cd 14 20
-{le}
-{2.99792458e8:32}
-{-1.6021766208:32}
+!le
+[2.99792458e8:32]
+[-1.6021766208:32]
---
c2 f3 8e 4d
20 14 cd bf
-{be}
-{2.99792458e8:64}
-{-1.6021766208:64}
+!be
+[2.99792458e8:64]
+[-1.6021766208:64]
---
41 b1 de 78 4a 00 00 00
bf f9 a2 83 f3 cc 07 58
-{le}
-{2.99792458e8:64}
-{-1.6021766208:64}
+!le
+[2.99792458e8:64]
+[-1.6021766208:64]
---
00 00 00 4a 78 de b1 41
58 07 cc f3 83 a2 f9 bf
-{be}
+!be
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{1966:16}
-{-1966:16}
-{1966 + var : 16}
-{1966 + lbl : 16}
-{1966 + var + lbl : 16}
-{-1:16}
+[1966:16]
+[-1966:16]
+[1966 + var : 16]
+[1966 + lbl : 16]
+[1966 + var + lbl : 16]
+[-1:16]
<end>
33
-{le}
+!le
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{1966:16}
-{-1966:16}
-{1966 + var : 16}
-{1966 + lbl : 16}
-{1966 + var + lbl : 16}
-{-1:16}
+[1966:16]
+[-1966:16]
+[1966 + var : 16]
+[1966 + lbl : 16]
+[1966 + var + lbl : 16]
+[-1:16]
<end>
33
-{be}
+!be
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{4192322:24}
-{-4192322:24}
-{4192322 + var : 24}
-{4192322 + lbl : 24}
-{4192322 + var + lbl : 24}
-{-1:24}
+[4192322:24]
+[-4192322:24]
+[4192322 + var : 24]
+[4192322 + lbl : 24]
+[4192322 + var + lbl : 24]
+[-1:24]
<end>
33
-{le}
+!le
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{4192322:24}
-{-4192322:24}
-{4192322 + var : 24}
-{4192322 + lbl : 24}
-{4192322 + var + lbl : 24}
-{-1:24}
+[4192322:24]
+[-4192322:24]
+[4192322 + var : 24]
+[4192322 + lbl : 24]
+[4192322 + var + lbl : 24]
+[-1:24]
<end>
33
-{be}
+!be
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{536890750:32}
-{-536890750:32}
-{536890750 + var : 32}
-{536890750 + lbl : 32}
-{536890750 + var + lbl : 32}
-{-1:32}
+[536890750:32]
+[-536890750:32]
+[536890750 + var : 32]
+[536890750 + lbl : 32]
+[536890750 + var + lbl : 32]
+[-1:32]
<end>
33
-{le}
+!le
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{536890750:32}
-{-536890750:32}
-{536890750 + var : 32}
-{536890750 + lbl : 32}
-{536890750 + var + lbl : 32}
-{-1:32}
+[536890750:32]
+[-536890750:32]
+[536890750 + var : 32]
+[536890750 + lbl : 32]
+[536890750 + var + lbl : 32]
+[-1:32]
<end>
33
-{be}
+!be
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{34359758191:40}
-{-34359758191:40}
-{34359758191 + var : 40}
-{34359758191 + lbl : 40}
-{34359758191 + var + lbl : 40}
-{-1:40}
+[34359758191:40]
+[-34359758191:40]
+[34359758191 + var : 40]
+[34359758191 + lbl : 40]
+[34359758191 + var + lbl : 40]
+[-1:40]
<end>
33
-{le}
+!le
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{34359758191:40}
-{-34359758191:40}
-{34359758191 + var : 40}
-{34359758191 + lbl : 40}
-{34359758191 + var + lbl : 40}
-{-1:40}
+[34359758191:40]
+[-34359758191:40]
+[34359758191 + var : 40]
+[34359758191 + lbl : 40]
+[34359758191 + var + lbl : 40]
+[-1:40]
<end>
33
-{be}
+!be
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{35184372059993:48}
-{-35184372059993:48}
-{35184372059993 + var : 48}
-{35184372059993 + lbl : 48}
-{35184372059993 + var + lbl : 48}
-{-1:48}
+[35184372059993:48]
+[-35184372059993:48]
+[35184372059993 + var : 48]
+[35184372059993 + lbl : 48]
+[35184372059993 + var + lbl : 48]
+[-1:48]
<end>
33
-{le}
+!le
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{35184372059993:48}
-{-35184372059993:48}
-{35184372059993 + var : 48}
-{35184372059993 + lbl : 48}
-{35184372059993 + var + lbl : 48}
-{-1:48}
+[35184372059993:48]
+[-35184372059993:48]
+[35184372059993 + var : 48]
+[35184372059993 + lbl : 48]
+[35184372059993 + var + lbl : 48]
+[-1:48]
<end>
33
-{be}
+!be
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{1125899906844617:56}
-{-1125899906844617:56}
-{1125899906844617 + var : 56}
-{1125899906844617 + lbl : 56}
-{1125899906844617 + var + lbl : 56}
-{-1:56}
+[1125899906844617:56]
+[-1125899906844617:56]
+[1125899906844617 + var : 56]
+[1125899906844617 + lbl : 56]
+[1125899906844617 + var + lbl : 56]
+[-1:56]
<end>
33
-{le}
+!le
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{1125899906844617:56}
-{-1125899906844617:56}
-{1125899906844617 + var : 56}
-{1125899906844617 + lbl : 56}
-{1125899906844617 + var + lbl : 56}
-{-1:56}
+[1125899906844617:56]
+[-1125899906844617:56]
+[1125899906844617 + var : 56]
+[1125899906844617 + lbl : 56]
+[1125899906844617 + var + lbl : 56]
+[-1:56]
<end>
33
-{be}
+!be
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{4611686018427387158:64}
-{-4611686018427387158:64}
-{4611686018427387158 + var : 64}
-{4611686018427387158 + lbl : 64}
-{4611686018427387158 + var + lbl : 64}
-{-1:64}
+[4611686018427387158:64]
+[-4611686018427387158:64]
+[4611686018427387158 + var : 64]
+[4611686018427387158 + lbl : 64]
+[4611686018427387158 + var + lbl : 64]
+[-1:64]
<end>
33
-{le}
+!le
{var = 5}
aa bb cc dd ee ff
<lbl>
33 44 55
-{4611686018427387158:64}
-{-4611686018427387158:64}
-{4611686018427387158 + var : 64}
-{4611686018427387158 + lbl : 64}
-{4611686018427387158 + var + lbl : 64}
-{-1:64}
+[4611686018427387158:64]
+[-4611686018427387158:64]
+[4611686018427387158 + var : 64]
+[4611686018427387158 + lbl : 64]
+[4611686018427387158 + var + lbl : 64]
+[-1:64]
<end>
33
<lbl>
33 44 55
-{66:8}
-{-66:8}
-{66 + var : 8}
-{66 + lbl : 8}
-{66 + var + lbl : 8}
+[66:8]
+[-66:8]
+[66 + var : 8]
+[66 + lbl : 8]
+[66 + var + lbl : 8]
<end>
33
aa bb cc dd ee ff
-{ICITTE + 23 : 8}
-{be}
-{ICITTE + 23 : 16}
-{ICITTE + 23 : 32}
-{ICITTE + 23 : 64}
+[ICITTE + 23 : 8]
+!be
+[ICITTE + 23 : 16]
+[ICITTE + 23 : 32]
+[ICITTE + 23 : 64]
---
aa bb cc dd ee ff
1d
-00 !group 11 <meow> 22 {mix-meow:8} 33 <mix> 44 !end * 2 55
+00 !group 11 <meow> 22 [mix-meow:8] 33 <mix> 44 !end * 2 55
---
00
11 22 03 33 44
00
!group
- 11 {mix:8} 22 <mix>
+ 11 [mix:8] 22 <mix>
!group
- <meow> {meow + mix : 8}
+ <meow> [meow + mix : 8]
!end * 3
33
!end * 2
00 <outer>
!group
- 11 <inner> 22 {outer:8} {inner:8} {end:8}
+ 11 <inner> 22 [outer:8] [inner:8] [end:8]
!end * 3
<end> ff
---
-00 (11 <meow> 22 {mix-meow:8} 33 <mix> 44) * 2 55
+00 (11 <meow> 22 [mix-meow:8] 33 <mix> 44) * 2 55
---
00
11 22 03 33 44
-00 (11 {mix:8} 22 <mix> (<meow> {meow + mix : 8}) * 3 33) * 2 44
+00 (11 [mix:8] 22 <mix> (<meow> [meow + mix : 8]) * 3 33) * 2 44
---
00
-00 <outer> (11 <inner> 22 {outer:8} {inner:8} {end:8}) * 3 <end> ff
+00 <outer> (11 <inner> 22 [outer:8] [inner:8] [end:8]) * 3 <end> ff
---
00
11 22 01 02 10
00 11
<meow>
22 33
-{meow:8}
+[meow:8]
44 55
-{mix:8}
+[mix:8]
66 77
< mix >
88 99
-{meow + mix : 8}
+[meow + mix : 8]
---
00 11
22 33
!m s()
- {le} {0xabcd:16}
+ !le [0xabcd:16]
!end
-{be} m:s() {0xabcd:16}
+!be m:s() [0xabcd:16]
---
cd ab
ab cd
!m s()
33 <zoom> 44
- {zoom:8}
+ [zoom:8]
!end
-11 22 <zoom> m:s() ff {zoom:8}
+11 22 <zoom> m:s() ff [zoom:8]
---
11 22
33 44 03
aa bb cc <0x100> dd
!end
-11 m:s() {ICITTE:8}
+11 m:s() [ICITTE:8]
---
11
aa bb cc dd
!m s()
{meow = 0x42}
- {meow:8}
+ [meow:8]
!end
-{meow = 0x23} m:s() {meow:8}
+{meow = 0x23} m:s() [meow:8]
---
42 23
!m butter(val)
- {val : 8}
+ [val : 8]
!end
m:butter(0x23) m:butter(0x42)
!m s()
- {0xabcd : 16}
+ [0xabcd : 16]
!end
-{be} m:s()
-{le} m:s()
+!be m:s()
+!le m:s()
---
ab cd
cd ab
!m s()
- {ICITTE : 8}
+ [ICITTE : 8]
!end
aa bb cc dd m:s() ee ff
!macro salut(a, b, c)
- "meow" {b : 32}
+ "meow" [b : 32]
!end
-{be}
+!be
aa bb
m:salut(42, 45.12, 12)
m:salut(42, -12.34e9, 12)
!macro salut(zoom)
- "meow " {zoom : s:latin1}
+ "meow " [zoom : s:latin1]
!end
-{be}
+!be
aa bb
m:salut("mix\n")
m:salut("meow")
aa bb cc dd
!if cond
- "hello" {val * 2 : 8}
+ "hello" [val * 2 : 8]
!end
!end
!end
!m butter(val)
{milk = val * 2}
- {be} {milk : 8}
+ !be [milk : 8]
!end
m:butter(0x23) m:butter(0x42)
<mix>
66 77 <0x3f>
88 <zoom> 99
-{meow:8}
-{mix:8}
-{zoom:8}
+[meow:8]
+[mix:8]
+[zoom:8]
---
00 11 22
33 44 55
-{be}
+!be
- {199:32}
-@64 {43:64}
-@16 {-123:16}
-@32~255 {5584:32}
+ [199:32]
+@64 [43:64]
+@16 [-123:16]
+@32~255 [5584:32]
---
00 00 00 c7 00 00 00 00 00 00 00 00 00 00 00 2b
ff 85 ff ff 00 00 15 d0
-{le}
-{0xdeadbeef:32}
-{-1993:16}
-{9:16}
+!le
+[0xdeadbeef:32]
+[-1993:16]
+[9:16]
+0x40
-{ICITTE:8}
+[ICITTE:8]
"meow mix"
+200~FFh
-{ICITTE:8}
+[ICITTE:8]
---
ef be ad de 37 f8 09 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{strength = 4}
-{be} 67 <lbl> 44 $178 {(end - lbl) * 8 + strength : 16} $99 <end>
-{le} {-1993 : 32}
-{-3.141593 : 64}
+!be 67 <lbl> 44 $178 [(end - lbl) * 8 + strength : 16] $99 <end>
+!le [-1993 : 32]
+[-3.141593 : 64]
---
67 44 b2 00 2c 63 37 f8 ff ff 7f bd c2 82 fb 21
09 c0
-aa bb cc {-1993 : sleb128} <meow> dd ee ff
-{meow * 199 : uleb128}
+aa bb cc [-1993 : sleb128] <meow> dd ee ff
+[meow * 199 : uleb128]
---
aa bb cc b7 70 dd ee ff e3 07
-{le}
+!le
77 88
-@32~0xcc {-893.5:32}
+@32~0xcc [-893.5:32]
@128~0x55 "meow"
---
77 88 cc cc 00 60 5f c4 55 55 55 55 55 55 55 55
-ab cd [3d 8F] CC
+ab cd (3d 8F) CC
---
ab cd 3d 8f cc
!macro part(iter, fill)
- <0> "particular security " {ord('0') + iter : 8} +fill~0x80
+ <0> "particular security " [ord('0') + iter : 8] +fill~0x80
!end
{iter = 1}
-{le} {345:16}
-{be} {-0xabcd:32}
+!le [345:16]
+!be [-0xabcd:32]
---
59 01 ff ff 54 33
-{be}
+!be
# String length in bits
-{8 * (str_end - str_beg) : 16}
+[8 * (str_end - str_beg) : 16]
# String
<str_beg>
-{20 - ICITTE : 8} * 10
+[20 - ICITTE : 8] * 10
---
14 13 12 11 10 0f 0e 0d 0c 0b
-{le}
-{2 * 0.0529 : 32}
+!le
+[2 * 0.0529 : 32]
---
ac ad d8 3d
-{be}
+!be
(
<str_beg> u16le"sébastien diaz" <str_end>
- {ICITTE - str_beg : 8}
- {(end - str_beg) * 5 : 24}
+ [ICITTE - str_beg : 8]
+ [(end - str_beg) * 5 : 24]
) * 3
<end>
---
-{624485 : uleb128}
+[624485 : uleb128]
---
e5 8e 26
aa bb cc dd
<meow>
ee ff
-{-981238311 + (meow * -23) : sleb128}
+[-981238311 + (meow * -23) : sleb128]
"hello"
---
aa bb cc dd ee ff fd fa 8d ac 7c 68 65 6c 6c 6f
!macro bake()
- {le} {ICITTE * 8 : 16}
+ !le [ICITTE * 8 : 16]
u16le"predict explode"
!end
{iter = 1}
!repeat rep
- {val + iter : uleb128}
- {0xdeadbeef : 32}
+ [val + iter : uleb128]
+ [0xdeadbeef : 32]
{iter = iter + 1}
!end
!macro bake()
- {le} {ICITTE * 8 : 16}
+ !le [ICITTE * 8 : 16]
u16le"predict explode"
!end
!macro A(val, is_be)
- {le}
+ !le
!if is_be
- {be}
+ !be
!end
- {val : 16}
+ [val : 16]
!end
!macro B(rep, is_be)
-!macro flt32be(val) {be} {val : 32} !end
+!macro flt32be(val) !be [val : 32] !end
"CHEETOS"
m:flt32be(-42.17)
- {ICITTE : 8} * 8
-<0x61> {ICITTE : 8} * 8
+ [ICITTE : 8] * 8
+<0x61> [ICITTE : 8] * 8
---
00 01 02 03 04 05 06 07 61 62 63 64 65 66 67 68
aa bb cc dd <meow> ee ff
<12> 11 22 33 <mix> 44 55
-{meow : 8} {mix : 8}
+[meow : 8] [mix : 8]
---
aa bb cc dd ee ff 11 22 33 44 55 04 0f
!repeat 0o400
- {end - ICITTE - 1 : 8}
+ [end - ICITTE - 1 : 8]
!end
<end>
ee ff "meow mix" 00
!end
-{be} {-1993:16}
+!be [-1993:16]
---
aa bb cc dd f8 37
ee ff "meow mix" 00
!end
-{be} {-1993:16}
+!be [-1993:16]
---
aa bb cc dd ee ff 6d 65 6f 77 20 6d 69 78 00 f8 37
-{end - ICITTE - 1 : 8} * 0x100 <end>
+[end - ICITTE - 1 : 8] * 0x100 <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
{iter = 1}
!repeat 10
- {iter : s:u8} " "
+ u8{iter} " "
{iter = iter + 1}
!end
---
{meow = 'salut jérémie'}
-{meow.upper() : s:latin1}
+[meow.upper() : s:latin1]
---
53 41 4c 55 54 20 4a c9 52 c9 4d 49 45
@128~99h
-!t qp <beg> {ICITTE - beg : 8} * 50 !end
+!t qp <beg> [ICITTE - beg : 8] * 50 !end
---
88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88
38 4b 5f 47 59 2b 43 6f 26 2a 41 54 44 58 25 44
-{mix = 101} {le}
-{meow = 42} 11 22 {meow:8} 33 {meow = ICITTE + 17}
-"yooo" {meow + mix : 16}
+{mix = 101} !le
+{meow = 42} 11 22 [meow:8] 33 {meow = ICITTE + 17}
+"yooo" [meow + mix : 16]
---
11 22 2a 33 79 6f 6f 6f 7a 00
-!repeat 256 {ICITTE:8} !end
+!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
-{ICITTE:8} * 256
+[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
-{-1 : sleb128}
+[-1 : sleb128]
---
7f
-{-6922985746849737371 : sleb128}
+[-6922985746849737371 : sleb128]
---
e5 aa b7 ef c8 a4 a7 f6 9f 7f
-{-116 : sleb128}
+[-116 : sleb128]
---
8c 7f
-{-8680 : sleb128}
+[-8680 : sleb128]
---
98 bc 7f
-{-2078359 : sleb128}
+[-2078359 : sleb128]
---
e9 92 81 7f
-{-238633602 : sleb128}
+[-238633602 : sleb128]
---
fe fa 9a 8e 7f
-{-23700055062 : sleb128}
+[-23700055062 : sleb128]
---
ea b7 f7 da a7 7f
-{-3724280114436 : sleb128}
+[-3724280114436 : sleb128]
---
fc a5 ed fc cd 93 7f
-{-547712888934486 : sleb128}
+[-547712888934486 : sleb128]
---
aa df c3 be ba bb 83 7f
-{-56890538594315647 : sleb128}
+[-56890538594315647 : sleb128]
---
81 a5 85 c0 b4 cb f8 9a 7f
-{-65:sleb128}
-{-64:sleb128}
-{63:sleb128}
-{64:sleb128}
+[-65:sleb128]
+[-64:sleb128]
+[63:sleb128]
+[64:sleb128]
---
bf 7f
40
-{-1:sleb128}
+[-1:sleb128]
---
7f
-{0:sleb128}
+[0:sleb128]
---
00
-{False : s:latin1}
-{True : s:latin1}
+[False : s:latin1]
+[True : s:latin1]
---
30
31
{meow = 'LÉGIFÉRER'}
-{meow.lower() : s:latin1}
-{ICITTE == len(meow) : 8}
+[meow.lower() : s:latin1]
+[ICITTE == len(meow) : 8]
---
6c e9 67 69 66 e9 72 65 72
01
-{"ãäåæçèéêëìíîïðñò" : s:latin1}
-{"ăäĺćçčéęëěíîďđńň" : s:latin2}
-{"µĥ·¸ışğĵ½żÀÁÂÄĊĈ" : s:latin3}
-{"ãäåæįčéęëėíîīđņō" : s:latin4}
-{"ãäåæçèéêëìíîïğñò" : s:latin5}
-{"ÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌ" : s:latin6}
-{"ÓŌÕÖ×ŲŁŚŪÜŻŽßąįā" : s:latin7}
-{"ãäåæçèéêëìíîïŵñò" : s:latin8}
-{"ÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒ" : s:latin9}
-{"łŽ”¶·žčș»ŒœŸżÀÁÂ" : s:latin10}
+["ãäåæçèéêëìíîïðñò" : s:latin1]
+["ăäĺćçčéęëěíîďđńň" : s:latin2]
+["µĥ·¸ışğĵ½żÀÁÂÄĊĈ" : s:latin3]
+["ãäåæįčéęëėíîīđņō" : s:latin4]
+["ãäåæçèéêëìíîïğñò" : s:latin5]
+["ÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌ" : s:latin6]
+["ÓŌÕÖ×ŲŁŚŪÜŻŽßąįā" : s:latin7]
+["ãäåæçèéêëìíîïŵñò" : s:latin8]
+["ÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒ" : s:latin9]
+["łŽ”¶·žčș»ŒœŸżÀÁÂ" : s:latin10]
---
e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2
e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2
{zoom = 'hello 🦊'}
-{zoom : s:u8}
-{zoom : s:u16be}
-{zoom : s:u16le}
-{zoom : s:u32be}
-{zoom : s:u32le}
+[zoom : s:u8]
+[zoom : s:u16be]
+[zoom : s:u16le]
+[zoom : s:u32be]
+[zoom : s:u32le]
---
68 65 6c 6c 6f 20 f0 9f a6 8a 00 68 00 65 00 6c
00 6c 00 6f 00 20 d8 3e dd 8a 68 00 65 00 6c 00
-{-23.42 : s:latin1}
+[-23.42 : s:latin1]
---
2d 32 33 2e 34 32
-{-42 : s:latin1}
+[-42 : s:latin1]
---
2d 34 32
!transform ascii85
"bonjour tout le monde"
- <beg1> {ICITTE - beg1 : 8} * 15
+ <beg1> [ICITTE - beg1 : 8] * 15
!end
!t a85
"bonjour tout le monde"
- <beg2> {ICITTE - beg2 : 8} * 15
+ <beg2> [ICITTE - beg2 : 8] * 15
!end
---
40 57 2d 2e 21 44 66 70 28 43 46 44 6c 3b 44 2b
!transform ascii85p
"bonjour tout le monde"
- <beg1> {ICITTE - beg1 : 8} * 15
+ <beg1> [ICITTE - beg1 : 8] * 15
!end
!t a85p
"bonjour tout le monde"
- <beg2> {ICITTE - beg2 : 8} * 15
+ <beg2> [ICITTE - beg2 : 8] * 15
!end
---
40 57 2d 2e 21 44 66 70 28 43 46 44 6c 3b 44 2b
!transform base16
"bonjour tout le monde"
- <beg1> {ICITTE - beg1 : 8} * 15
+ <beg1> [ICITTE - beg1 : 8] * 15
!end
!t b16
"bonjour tout le monde"
- <beg2> {ICITTE - beg2 : 8} * 15
+ <beg2> [ICITTE - beg2 : 8] * 15
!end
---
36 32 36 46 36 45 36 41 36 46 37 35 37 32 32 30
!transform base32
"bonjour tout le monde"
- <beg1> {ICITTE - beg1 : 8} * 15
+ <beg1> [ICITTE - beg1 : 8] * 15
!end
!t b32
"bonjour tout le monde"
- <beg2> {ICITTE - beg2 : 8} * 15
+ <beg2> [ICITTE - beg2 : 8] * 15
!end
---
4d 4a 58 57 34 32 54 50 4f 56 5a 43 41 35 44 50
!transform base64
"bonjour tout le monde"
- <beg1> {ICITTE - beg1 : 8} * 15
+ <beg1> [ICITTE - beg1 : 8] * 15
!end
!t b64
"bonjour tout le monde"
- <beg2> {ICITTE - beg2 : 8} * 15
+ <beg2> [ICITTE - beg2 : 8] * 15
!end
---
59 6d 39 75 61 6d 39 31 63 69 42 30 62 33 56 30
!transform base64u
"bonjour tout le monde"
- <beg1> {ICITTE - beg1 : 8} * 15
+ <beg1> [ICITTE - beg1 : 8] * 15
!end
!t b64u
"bonjour tout le monde"
- <beg2> {ICITTE - beg2 : 8} * 15
+ <beg2> [ICITTE - beg2 : 8] * 15
!end
---
59 6d 39 75 61 6d 39 31 63 69 42 30 62 33 56 30
!transform base85
"bonjour tout le monde"
- <beg1> {ICITTE - beg1 : 8} * 15
+ <beg1> [ICITTE - beg1 : 8] * 15
!end
!t b85
"bonjour tout le monde"
- <beg2> {ICITTE - beg2 : 8} * 15
+ <beg2> [ICITTE - beg2 : 8] * 15
!end
---
56 73 43 44 30 5a 2a 5f 37 59 62 5a 3e 51 5a 41
!transform base85p
"bonjour tout le monde"
- <beg1> {ICITTE - beg1 : 8} * 15
+ <beg1> [ICITTE - beg1 : 8] * 15
!end
!t b85p
"bonjour tout le monde"
- <beg2> {ICITTE - beg2 : 8} * 15
+ <beg2> [ICITTE - beg2 : 8] * 15
!end
---
56 73 43 44 30 5a 2a 5f 37 59 62 5a 3e 51 5a 41
!transform quopri
"bonjour tout le monde"
- <beg1> {ICITTE - beg1 : 8} * 15
+ <beg1> [ICITTE - beg1 : 8] * 15
!end
!t qp
"bonjour tout le monde"
- <beg2> {ICITTE - beg2 : 8} * 15
+ <beg2> [ICITTE - beg2 : 8] * 15
!end
---
62 6f 6e 6a 6f 75 72 20 74 6f 75 74 20 6c 65 20
!transform quoprit
"bonjour tout le monde"
- <beg1> {ICITTE - beg1 : 8} * 15
+ <beg1> [ICITTE - beg1 : 8] * 15
!end
!t qpt
"bonjour tout le monde"
- <beg2> {ICITTE - beg2 : 8} * 15
+ <beg2> [ICITTE - beg2 : 8] * 15
!end
---
62 6f 6e 6a 6f 75 72 3d 32 30 74 6f 75 74 3d 32
-{2 : uleb128}
+[2 : uleb128]
---
02
-{11662943340368564545 : uleb128}
+[11662943340368564545 : uleb128]
---
c1 a2 b4 b1 cd a5 c6 ed a1 01
-{138 : uleb128}
+[138 : uleb128]
---
8a 01
-{22454 : uleb128}
+[22454 : uleb128]
---
b6 af 01
-{3003030 : uleb128}
+[3003030 : uleb128]
---
96 a5 b7 01
-{480029143 : uleb128}
+[480029143 : uleb128]
---
d7 d3 f2 e4 01
-{65632604596 : uleb128}
+[65632604596 : uleb128]
---
b4 a3 88 c0 f4 01
-{5790353763547 : uleb128}
+[5790353763547 : uleb128]
---
db d9 ea df c2 a8 01
-{946008033604205 : uleb128}
+[946008033604205 : uleb128]
---
ed e4 b0 c6 ba 8c d7 01
-{119795752416646235 : uleb128}
+[119795752416646235 : uleb128]
---
db a8 94 a3 a2 b3 e6 d4 01
aa bb
<meow>
cc dd
- {meow * 500 : uleb128}
+ [meow * 500 : uleb128]
ee ff
) * 2
22
aa bb
<meow>
11 22
-{meow * 199 : uleb128}
+[meow * 199 : uleb128]
ee ff
---
aa bb
aa bb
{meow = 1111}
-cc {meow : uleb128}
+cc [meow : uleb128]
ee ff
---
aa bb
-{127:uleb128}
-{128:uleb128}
+[127:uleb128]
+[128:uleb128]
---
7f
80 01
-{0:uleb128}
+[0:uleb128]
---
00
-{be} aa {meow = 32.5} bb {meow : 32} cc
+!be aa {meow = 32.5} bb [meow : 32] cc
---
aa bb 42 02 00 00 cc
aa bb cc {meow = ICITTE + 3} dd ee ff
-{meow : 8}
+[meow : 8]
---
aa bb cc dd ee ff
06
-<11> {be} aa <meow>
+<11> !be aa <meow>
bb cc dd*5
{mix = meow}
ee
-{mix:8}
+[mix:8]
ff
---
aa
{var = 0x18}
aa bb
-{var:8}
+[var:8]
cc dd
<meow>
{var = var - ICITTE}
{mix = meow + 23}
-{var:8}
-{mix:8}
+[var:8]
+[mix:8]
---
aa bb
18
def test_init_labels():
labels = {"yo": 0x88, "meow": 123} # type: normand.LabelsT
- res = normand.parse("11 22 {yo:8} 33", init_labels=labels.copy())
+ res = normand.parse("11 22 [yo:8] 33", init_labels=labels.copy())
assert res.data == bytearray([0x11, 0x22, 0x88, 0x33])
assert res.labels == labels.copy()
def test_init_vars():
variables = {"zoom": 0x88, "bateau": -123.45} # type: normand.VariablesT
- res = normand.parse("11 22 {zoom:8} 33", init_variables=variables.copy())
+ res = normand.parse("11 22 [zoom:8] 33", init_variables=variables.copy())
assert res.data == bytearray([0x11, 0x22, 0x88, 0x33])
assert res.variables == variables.copy()
def test_init_offset():
- res = normand.parse("11 22 {ICITTE:8} 33", init_offset=0x23)
+ res = normand.parse("11 22 [ICITTE:8] 33", init_offset=0x23)
assert res.data == bytearray([0x11, 0x22, 0x25, 0x33])
assert res.offset == 0x27
if bo == normand.ByteOrder.LE:
h_byte, l_byte = l_byte, h_byte
- res = normand.parse("11 22 {-1993:16} 33", init_byte_order=bo)
+ res = normand.parse("11 22 [-1993:16] 33", init_byte_order=bo)
assert res.data == bytearray([0x11, 0x22, h_byte, l_byte, 0x33])
assert res.byte_order == bo
def test_final_byte_order_none():
- res = normand.parse("11 22 33 {-19:8} 44 55")
+ res = normand.parse("11 22 33 [-19:8] 44 55")
assert res.byte_order is None
def test_final_byte_order_be():
- res = normand.parse("11 22 {le} 33 {-19:8} 44 ( {be} 88 ) * 3 55")
+ res = normand.parse("11 22 !le 33 [-19:8] 44 ( !be 88 ) * 3 55")
assert res.byte_order == normand.ByteOrder.BE
def test_final_byte_order_le():
- res = normand.parse("11 22 {be} 33 {-19:8} 44 ( {le} 88 ) * 3 55")
+ res = normand.parse("11 22 !be 33 [-19:8] 44 ( !le 88 ) * 3 55")
assert res.byte_order == normand.ByteOrder.LE