Go to the first, previous, next, last section, table of contents.


計算用の組み込みマクロ

m4にはCに似た文法の整数演算機構が組み込まれています。 単純なインクリメントとデクリメント操作のための組み込みマクロが便利な省略記法 として用意されています。

インクリメント演算子とデクリメント演算子

整数のインクリメントとデクリメントは組み込みマクロincrdecr によってサポートされています。

incr(number)
decr(number)

numberの数値を1だけ増やした値または1だけ減らした値に展開されます。

incr(4)
=>5
decr(7)
=>6

組み込みマクロincrおよびdecrは引数が与えられたときだけ認識されます。

整数式を計算する

整数式はevalを使って計算します。

eval(expression, opt radix, opt width)

このマクロはexpressionの値に展開されます。

式(expression)には次の演算子を含めることができます。 リストは優先順位の高い順に並んでいます。

-
単項差(unary minus)
**
累乗(exponentiation)
* / %
積(multiplication)、商(division)、剰余(modulo)
+ -
和(addition)、差(subtraction)
<< >>
左シフト(shift left)、右シフト(shift right)
== != > >= < <=
関係演算子(relational operator)
!
論理否定(logical negation)
~
ビットごとの論理否定(bitwise negation)
&
ビットごとの論理積(bitwise and)
^
ビットごとの排他的論理和(bitwise exclusive-or)
|
ビットごとの論理和(bitwise or)
&&
論理積(logical and)
||
論理和(logical or)

累乗(exponentiation)を除いたすべての演算子は左結合(left associative)をします。

m4の実装には`^'を累乗(exponentiation)演算子の代用として使うもの が多くありますが、`^'をビットごとの排他的論理和(bitwise exclusive-or) に使っている実装も多くあります。 GNU m4はこの点について動作の変更を行いました。 かつて`^'は累乗を行う演算子でしたが、 現在はビットごとの排他的論理和を行う演算子となっています。

特別な接頭辞(prefix)がついていない数字は10進数となります。 `0'のみの接頭辞は8進数の始まりを表します。 `0x'は16進数の始まりを表します。 `0b'は2進数の始まりを表します。 `0r'は1から36までの任意の基数で表現した数字の始まりを表します。 `0r'の後には10進数で表現した基数、コロン(:)、 および数値を表す数字列を続けなくてはなりません。 いずれの基数で表すにしても数字としては`0', `1', `2', ...を使い、`9'から上は`a', `b' ... `z'までを 数字として使います。 アルファベットの大文字と小文字は基数を表す接頭辞および数値を表す数字列のなかで 区別なく使用することができます。

部分式をグループ化するために必要なときはカッコを使うことができます。 関係演算子は関係が真のときは1を返し、偽のときは0を返します。

evalの使用例をいくつか次に挙げます。

eval(-3 * 5)
=>-15
eval(index(`Hello world', `llo') >= 0)
=>1
define(`square', `eval(($1)**2)')
=>
square(9)
=>81
square(square(5)+1)
=>676
define(`foo', `666')
=>
eval(`foo'/6)
error-->51.eval:14: m4: Bad expression in eval: foo/6
=>
eval(foo/6)
=>111

最後から2番目の例が示しているようにevalがマクロ名を勝手に展開することはありません。 例えそれらが有効な式(もしくは有効な式の一部)に展開されるにしてもです。 したがって全てのマクロはevalに渡される前に展開済である必要があります。

radixを指定すると展開後のテキストではその基数が使われます。 デフォルトの基数は10です。 evalの結果は常に符号付き(signed)であると解釈されます。 引数widthは最低限の出力幅を指定します。 展開後のテキストが要求された幅になるように 結果には0が埋め草(zero-padded)として付加されます。

eval(666, 10)
=>666
eval(666, 11)
=>556
eval(666, 6)
=>3030
eval(666, 6, 10)
=>0000003030
eval(-666, 6, 10)
=>-000003030

radixは36より大きくてはいけないことに注意してください。

組み込みマクロevalは引数が与えられたときだけ認識されます。


Go to the first, previous, next, last section, table of contents.