# Learning GNU Make Functions with Arithmetic

[article]
`# The following operators return a non-empty string if their result# is true:## gt     First argument greater than second argument# gte     First argument greater than or equal to second argument# lt     First argument less than second argument # lte     First argument less than or equal to second argument# eq    First argument is numerically equal to the second argument# ne    First argument is not numerically equal to the second argumentgt = \$(filter-out \$(words \$2),\$(words \$(call max,\$1,\$2)))lt = \$(filter-out \$(words \$1),\$(words \$(call max,\$1,\$2)))eq = \$(filter \$(words \$1),\$(words \$2))ne = \$(filter-out \$(words \$1),\$(words \$2))gte = \$(call gt,\$1,\$2)\$(call eq,\$1,\$2)lte = \$(call lt,\$1,\$2)\$(call eq,\$1,\$2)# increment adds 1 to its argument, decrement subtracts 1.  Note that# decrement does not range check and hence will not underflow, but# will incorrectly say that 0 - 1 = 0increment = \$1 xdecrement = \$(wordlist 2,\$(words \$1),\$1)# double doubles its argument, and halve halves itdouble = \$1 \$1halve = \$(subst xx,x,\$(filter-out xy x y,\$(join \$1,\$(foreach a,\$1,y x))))# This code implements a reverse polish notation calculator by# transforming a comma-separated list of operators (+ - * /) and# numbers stored in the calc variable into the appropriate calls to# the arithmetic functions defined in this Makefile# This is the current stack of numbers entered into the# calculator. The push function puts an item onto the top of the stack# (the start of the list) and pop removes the top item.stack := push = \$(eval stack := \$\$1 \$(stack))pop = \$(word 1,\$(stack))\$(eval stack := \$(wordlist 2,\$(words \$(stack)),\$(stack)))# pope and pushd are used to pop a number off the stack and encode it# and push a number onto the stack after decodingpope = \$(call encode,\$(call pop))pushd = \$(call push,\$(call decode,\$1))# calculate runs through the input numbers and operations and either# pushes a number on the stack, or pops two numbers off and does a# calculation followed by pushing the result back.  When calculate# finished there will be one item on the stack which is the result.comma := ,calculate=\$(foreach t,\$(subst \$(comma), ,\$1),\$(call handle,\$t))\$(stack)# seq is a string equality operator that returns true (a non-empty# string) if the two strings are equalseq = \$(filter \$1,\$2)# handle is used by calculate to handle a single token.  If it's an# operator then the appropriate operator function is called, if it's a# number then it is pushed.handle = \$(call pushd,                                                 \             \$(if \$(call seq,+,\$1),                                    \                 \$(call plus,\$(call pope),\$(call pope)),               \                 \$(if \$(call seq,-,\$1),                                \                     \$(call subtract,\$(call pope),\$(call pope)),       \                     \$(if \$(call seq,*,\$1),                            \                         \$(call multiply,\$(call pope),\$(call pope)),   \                         \$(if \$(call seq,/,\$1),                        \                             \$(call divide,\$(call pope),\$(call pope)), \                             \$(call encode,\$1)))))).PHONY: calccalc: ; @echo \$(call calculate,\$(calc))`

## Pages

### About the author

AgileConnection is a TechWell community.

Through conferences, training, consulting, and online resources, TechWell helps you develop and deliver great software every day.