m4: Eval

 
 12.2 Evaluating integer expressions
 ===================================
 
 Integer expressions are evaluated with 'eval':
 
  -- Builtin: eval (EXPRESSION, [RADIX = 10], [WIDTH])
      Expands to the value of EXPRESSION.  The expansion is empty if a
      problem is encountered while parsing the arguments.  If specified,
      RADIX and WIDTH control the format of the output.
 
      Calculations are done with 32-bit signed numbers.  Overflow
      silently results in wraparound.  A warning is issued if division by
      zero is attempted, or if EXPRESSION could not be parsed.
 
      Expressions can contain the following operators, listed in order of
      decreasing precedence.
 
      '()'
           Parentheses
      '+ - ~ !'
           Unary plus and minus, and bitwise and logical negation
      '**'
           Exponentiation
      '* / %'
           Multiplication, division, and modulo
      '+ -'
           Addition and subtraction
      '<< >>'
           Shift left or right
      '> >= < <='
           Relational operators
      '== !='
           Equality operators
      '&'
           Bitwise and
      '^'
           Bitwise exclusive-or
      '|'
           Bitwise or
      '&&'
           Logical and
      '||'
           Logical or
 
      The macro 'eval' is recognized only with parameters.
 
    All binary operators, except exponentiation, are left associative.  C
 operators that perform variable assignment, such as '+=' or '--', are
 not implemented, since 'eval' only operates on constants, not variables.
 Attempting to use them results in an error.  However, since traditional
 implementations treated '=' as an undocumented alias for '==' as opposed
 to an assignment operator, this usage is supported as a special case.
 Be aware that a future version of GNU M4 may support assignment
 semantics as an extension when POSIX mode is not requested, and that
 using '=' to check equality is not portable.
 
      eval(`2 = 2')
      error->m4:stdin:1: Warning: recommend ==, not =, for equality operator
      =>1
      eval(`++0')
      error->m4:stdin:2: invalid operator in eval: ++0
      =>
      eval(`0 |= 1')
      error->m4:stdin:3: invalid operator in eval: 0 |= 1
      =>
 
    Note that some older 'm4' implementations use '^' as an alternate
 operator for the exponentiation, although POSIX requires the C behavior
 of bitwise exclusive-or.  The precedence of the negation operators, '~'
 and '!', was traditionally lower than equality.  The unary operators
 could not be used reliably more than once on the same term without
 intervening parentheses.  The traditional precedence of the equality
 operators '==' and '!=' was identical instead of lower than the
 relational operators such as '<', even through GNU M4 1.4.8.  Starting
 with version 1.4.9, GNU M4 correctly follows POSIX precedence rules.  M4
 scripts designed to be portable between releases must be aware that
 parentheses may be required to enforce C precedence rules.  Likewise,
 division by zero, even in the unused branch of a short-circuiting
 operator, is not always well-defined in other implementations.
 
    Following are some examples where the current version of M4 follows C
 precedence rules, but where older versions and some other
 implementations of 'm4' require explicit parentheses to get the correct
 result:
 
      eval(`1 == 2 > 0')
      =>1
      eval(`(1 == 2) > 0')
      =>0
      eval(`! 0 * 2')
      =>2
      eval(`! (0 * 2)')
      =>1
      eval(`1 | 1 ^ 1')
      =>1
      eval(`(1 | 1) ^ 1')
      =>0
      eval(`+ + - ~ ! ~ 0')
      =>1
      eval(`2 || 1 / 0')
      =>1
      eval(`0 || 1 / 0')
      error->m4:stdin:9: divide by zero in eval: 0 || 1 / 0
      =>
      eval(`0 && 1 % 0')
      =>0
      eval(`2 && 1 % 0')
      error->m4:stdin:11: modulo by zero in eval: 2 && 1 % 0
      =>
 
    As a GNU extension, the operator '**' performs integral
 exponentiation.  The operator is right-associative, and if evaluated,
 the exponent must be non-negative, and at least one of the arguments
 must be non-zero, or a warning is issued.
 
      eval(`2 ** 3 ** 2')
      =>512
      eval(`(2 ** 3) ** 2')
      =>64
      eval(`0 ** 1')
      =>0
      eval(`2 ** 0')
      =>1
      eval(`0 ** 0')
      =>
      error->m4:stdin:5: divide by zero in eval: 0 ** 0
      eval(`4 ** -2')
      error->m4:stdin:6: negative exponent in eval: 4 ** -2
      =>
 
    Within EXPRESSION, (but not RADIX or WIDTH), numbers without a
 special prefix are decimal.  A simple '0' prefix introduces an octal
 number.  '0x' introduces a hexadecimal number.  As GNU extensions, '0b'
 introduces a binary number.  '0r' introduces a number expressed in any
 radix between 1 and 36: the prefix should be immediately followed by the
 decimal expression of the radix, a colon, then the digits making the
 number.  For radix 1, leading zeros are ignored, and all remaining
 digits must be '1'; for all other radices, the digits are '0', '1', '2',
 ....  Beyond '9', the digits are 'a', 'b' ... up to 'z'.  Lower and
 upper case letters can be used interchangeably in numbers prefixes and
 as number digits.
 
    Parentheses may be used to group subexpressions whenever needed.  For
 the relational operators, a true relation returns '1', and a false
 relation return '0'.
 
    Here are a few examples of use of 'eval'.
 
      eval(`-3 * 5')
      =>-15
      eval(`-99 / 10')
      =>-9
      eval(`-99 % 10')
      =>-9
      eval(`99 % -10')
      =>9
      eval(index(`Hello world', `llo') >= 0)
      =>1
      eval(`0r1:0111 + 0b100 + 0r3:12')
      =>12
      define(`square', `eval(`($1) ** 2')')
      =>
      square(`9')
      =>81
      square(square(`5')` + 1')
      =>676
      define(`foo', `666')
      =>
      eval(`foo / 6')
      error->m4:stdin:11: bad expression in eval: foo / 6
      =>
      eval(foo / 6)
      =>111
 
    As the last two lines show, 'eval' does not handle macro names, even
 if they expand to a valid expression (or part of a valid expression).
 Therefore all macros must be expanded before they are passed to 'eval'.
 
    Some calculations are not portable to other implementations, since
 they have undefined semantics in C, but GNU 'm4' has well-defined
 behavior on overflow.  When shifting, an out-of-range shift amount is
 implicitly brought into the range of 32-bit signed integers using an
 implicit bit-wise and with 0x1f).
 
      define(`max_int', eval(`0x7fffffff'))
      =>
      define(`min_int', incr(max_int))
      =>
      eval(min_int` < 0')
      =>1
      eval(max_int` > 0')
      =>1
      ifelse(eval(min_int` / -1'), min_int, `overflow occurred')
      =>overflow occurred
      min_int
      =>-2147483648
      eval(`0x80000000 % -1')
      =>0
      eval(`-4 >> 1')
      =>-2
      eval(`-4 >> 33')
      =>-2
 
    If RADIX is specified, it specifies the radix to be used in the
 expansion.  The default radix is 10; this is also the case if RADIX is
 the empty string.  A warning results if the radix is outside the range
 of 1 through 36, inclusive.  The result of 'eval' is always taken to be
 signed.  No radix prefix is output, and for radices greater than 10, the
 digits are lower case.  The WIDTH argument specifies the minimum output
 width, excluding any negative sign.  The result is zero-padded to extend
 the expansion to the requested width.  A warning results if the width is
 negative.  If RADIX or WIDTH is out of bounds, the expansion of 'eval'
 is empty.
 
      eval(`666', `10')
      =>666
      eval(`666', `11')
      =>556
      eval(`666', `6')
      =>3030
      eval(`666', `6', `10')
      =>0000003030
      eval(`-666', `6', `10')
      =>-0000003030
      eval(`10', `', `0')
      =>10
      `0r1:'eval(`10', `1', `11')
      =>0r1:01111111111
      eval(`10', `16')
      =>a
      eval(`1', `37')
      error->m4:stdin:9: radix 37 in builtin `eval' out of range
      =>
      eval(`1', , `-1')
      error->m4:stdin:10: negative width to builtin `eval'
      =>
      eval()
      error->m4:stdin:11: empty string treated as 0 in builtin `eval'
      =>0