M4
'''m4''' reads text input, expands macros in the text, and prints the result. It can be used as a front-end to a compiler or assembler, or for general purpose expanding etc.
Various builtin macros can do integer arithmetic, run shell commands, access files, divert output to temporary buffers for re-ordering, etc. define creates new macros.
define(`foo', `blah blah: $1')
foo(123)
=>
blah blah: 123
Control flow is limited to ifelse, but it's easy to construct loops by recursion. GNU m4 includes examples of macros implementing various general-purpose loops.
Quoting data values against premature or unwanted expansion can be a little tricky. The default quote characters are and </code> and <code>'</code>. If they would occur in text too often then <code>changequote()</code> can set something else. Autoconf changes to <code>[</code> and <code>]</code> since <code>' occur often in its Bourne Shell output.
When a macro expands, its value (with $1 etc parameters substituted) is re-read as input. This is how macro definitions can contain further macros to expand.
define(`foo', `bar(`$1',x,`$2')')
Various m4 implementations, including BSD, have a fixed limit on the amount "push-back" text to be re-read. GNU m4 has no limit except available memory. A limit restricts the size of macro values and the data they might operate on. Cutting data into pieces can keep expansions to a reasonable size.
The simple text re-reading means that macro calls are "properly tail recursive". If an expansion ends with another macro call then that call can re-expand recursively or by co-routining endlessly. But a tail call must be the very last thing, no newline or other fixed text after. See Factorial for an example of such recursion.
One implementation of this Unix macro processor m4 is the GNU m4
Tasks
- 100 doors
- A+B
- Ackermann function
- Anagrams
- Apply a callback to an array
- Arithmetic/Integer
- Associative array/Iteration
- Averages/Arithmetic mean
- Binary search
- Combinations
- Comments
- Compile-time calculation
- Count in factors
- Count in octal
- Day of the week
- Detect division by zero
- Dragon curve
- Dynamic variable names
- Empty program
- Enumerations
- Even or odd
- Execute a system command
- Exponentiation operator
- Factorial
- Fibonacci sequence
- FizzBuzz
- Function definition
- Generic swap
- Greatest subsequential sum
- Hello world!
- Hello world/Newline omission
- Hello world/Standard error
- Hello world/Text
- Include a file
- Increment a numerical string
- Interactive programming
- Inverted syntax
- Jensen's Device
- Knapsack problem/Unbounded
- Knuth shuffle
- Literals/Integer
- Literals/String
- Logical operations
- Longest common subsequence
- Look-and-say sequence
- Loops/Break
- Loops/Downward for
- Loops/For
- Loops/For with a specified step
- Loops/Infinite
- Loops/N plus one half
- Mutual recursion
- Non-decimal radices/Convert
- One-dimensional cellular automata
- Palindrome detection
- Perfect numbers
- Playing cards
- Power set
- Primality by trial division
- Program termination
- Quine
- Read entire file
- Regular expressions
- Reverse a string
- Roman numerals/Encode
- SEDOLs
- Sieve of Eratosthenes
- Sorting algorithms/Bogosort
- Sorting algorithms/Bubble sort
- Sorting algorithms/Counting sort
- Sorting algorithms/Heapsort
- Sorting algorithms/Quicksort
- String case
- String concatenation
- Text processing/Max licenses in use
- Tokenize a string
- Variadic function
- Zig-zag matrix