This package offers both a portable {py3} module and a command-line
tool.
-WARNING: This version of Normand is 0.12, meaning both the Normand
+WARNING: This version of Normand is 0.13, meaning both the Normand
language and the module/CLI interface aren't stable.
ifdef::env-github[]
+0x40
{ICITTE:8}
"meow mix"
-+200~0xff
++200~FFh
{ICITTE:8}
----
+
The latter serve to improve readability so that you may write, for
example, a MAC address or a UUID as is.
+[[const-int]] Many items require a _constant integer_, possibly
+negative, in which case it may start with `-` for a negative integer. A
+positive constant integer is any of:
+
+Decimal::
+ One or mode digits (`0` to `9`).
+
+Hexadecimal::
+ One of:
++
+* The `0x` or `0X` prefix followed with one or more hexadecimal digits
+ (`0` to `9`, `a` to `f`, or `A` to `F`).
+* One or more hexadecimal digits followed with the `h` or `H` suffix.
+
+Octal::
+ One of:
++
+* The `0o` or `0O` prefix followed with one or more octal digits
+ (`0` to `7`).
+* One or more octal digits followed with the `o`, `O`, `q`, or `Q`
+ suffix.
+
+Binary::
+ One of:
++
+* 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.
+
You can test the examples of this section with the `normand`
<<command-line-tool,command-line tool>> as such:
A byte constant is:
Hexadecimal form::
- Two consecutive hexits.
+ Two consecutive hexadecimal digits.
Decimal form::
- A decimal number after the `$` prefix.
+ One or more digits after the `$` prefix.
Binary form::
Eight bits after the `%` prefix.
The available lengths are 8, 16, 24, 32, 40, 48, 56, and 64.
* A floating point number
- ([IEEE{nbsp}754-2008[https://standards.ieee.org/standard/754-2008.html]).
+ (IEEE{nbsp}754-2008[https://standards.ieee.org/standard/754-2008.html]).
+
The available length are 32 (_binary32_) and 64 (_binary64_).
expression may contain:
+
--
-* The name of any <<label,label>> defined before{nbsp}__**L**__.
+* The name of any <<label,label>> defined before{nbsp}__**L**__
+ which isn't within a nested group.
* The name of any <<variable-assignment,variable>> known
at{nbsp}__**L**__.
--
. The `<` prefix.
-. A positive integer (hexadecimal starting with `0x` or `0X` accepted)
- which is the new current offset.
+. A <<const-int,positive constant integer>> which is the new current
+ offset.
. The `>` suffix.
. The `@` prefix.
-. A positive integer (hexadecimal starting with `0x` or `0X` accepted)
- which is the alignment value in _bits_.
+. A <<const-int,positive constant integer>> which is the alignment value
+ in _bits_.
+
This value must be greater than zero and a multiple of{nbsp}8.
+
--
. The ``pass:[~]`` prefix.
-. A positive integer (hexadecimal starting with `0x` or `0X` accepted)
- which is the value of the byte to use as padding to align the
- <<cur-offset,current offset>>.
+. A <<const-int,positive constant integer>> which is the value of the
+ byte to use as padding to align the <<cur-offset,current offset>>.
--
+
Without this section, the padding byte value is zero.
. One of:
-** A positive integer (hexadecimal starting with `0x` or `0X` accepted)
- which is the current offset target.
+** A <<const-int,positive constant integer>> which is the current offset
+ target.
** The ``pass:[{]`` prefix, a valid {py3} expression of which the
evaluation result type is `int` or `bool` (automatically converted to
+
--
. The ``pass:[~]`` prefix.
-. A positive integer (hexadecimal starting with `0x` or `0X` accepted)
- which is the value of the byte to use as padding to reach the
- current offset target.
+. A <<const-int,positive constant integer>> which is the value of the
+ byte to use as padding to reach the current offset target.
--
+
Without this section, the padding byte value is zero.
. One of:
-** A positive integer (hexadecimal starting with `0x` or `0X` accepted)
- which is the number of times to repeat the previous item.
+** A <<const-int,positive constant integer>> which is the number of
+ times to repeat the previous item.
** The ``pass:[{]`` prefix, a valid {py3} expression of which the
evaluation result type is `int` or `bool` (automatically converted to
Input:
----
-!repeat 0x100
+!repeat 0o400
{end - ICITTE - 1 : 8}
!end
A parameter value is one of:
+
--
-* A positive integer (hexadecimal starting with `0x` or `0X` accepted).
+* A <<const-int,constant integer>>, possibly negative.
* The ``pass:[{]`` prefix, a valid {py3} expression of which the
evaluation result type is `int` or `bool` (automatically converted to
# Upstream repository: <https://github.com/efficios/normand>.
__author__ = "Philippe Proulx"
-__version__ = "0.12.0"
+__version__ = "0.13.0"
__all__ = [
"__author__",
"__version__",
self._expect_pat(self._val_var_assign_set_bo_suffix_pat, "Expecting `}`")
return item
+ # Returns a normalized version (so as to be parseable by int()) of
+ # the constant integer string `s`, possibly negative, dealing with
+ # any radix suffix.
+ @staticmethod
+ def _norm_const_int(s: str):
+ neg = ""
+ pos = s
+
+ if s.startswith("-"):
+ neg = "-"
+ pos = s[1:]
+
+ for r in "xXoObB":
+ if pos.startswith("0" + r):
+ # Already correct
+ return s
+
+ # Try suffix
+ asm_suf_base = {
+ "h": "x",
+ "H": "x",
+ "q": "o",
+ "Q": "o",
+ "o": "o",
+ "O": "o",
+ "b": "b",
+ "B": "B",
+ }
+
+ for suf in asm_suf_base:
+ if pos[-1] == suf:
+ s = "{}0{}{}".format(neg, asm_suf_base[suf], pos.rstrip(suf))
+
+ return s
+
# Common constant integer patterns
- _pos_const_int_pat = re.compile(r"0[Xx][A-Fa-f0-9]+|\d+")
+ _pos_const_int_pat = re.compile(
+ r"0[Xx][A-Fa-f0-9]+|0[Oo][0-7]+|0[Bb][01]+|[A-Fa-f0-9]+[hH]|[0-7]+[qQoO]|[01]+[bB]|\d+"
+ )
_const_int_pat = re.compile(r"(?P<neg>-)?(?:{})".format(_pos_const_int_pat.pattern))
# Tries to parse an offset setting value (after the initial `<`),
return
# Return item
- return _SetOffset(int(m.group(0), 0), begin_text_loc)
+ return _SetOffset(int(self._norm_const_int(m.group(0)), 0), begin_text_loc)
# Tries to parse a label name (after the initial `<`), returning a
# label item on success.
)
# Validate
- pad_val = int(m.group(0), 0)
+ pad_val = int(self._norm_const_int(m.group(0)), 0)
if pad_val > 255:
_raise_error(
if m.group("neg") == "-" and not allow_neg:
_raise_error("Expecting a positive constant integer", expr_text_loc)
- expr_str = m.group(0)
+ expr_str = self._norm_const_int(m.group(0))
return self._ast_expr_from_str(expr_str, expr_text_loc)