Next: Emulation examples, Previous: Builtin functions, Up: Top [Contents][Index]
Next: Stacks, Up: Programs for patterns and macros [Contents][Index]
A part of the flexibility of m0 is based on the possibility of using small programs
executed when a pattern or macro is found.
The programming environment is forth like with stacks to be used for variables and forth like instructions.
Every macro starts its own stack environment for the collection of the arguments. It is thus normally not possible to transfer information between macros through the stack.
Next: Programs, Previous: Introduction to programs, Up: Programs for patterns and macros [Contents][Index]
The programming environment contains 8 stacks. The 8 stacks are 8 separate stacks for data and 8 separate stacks for instructions.
The instruction stacks can be used to implement parsers for e.g. infix notation. Special instructions are used to put instructions on the instruction stacks. Normal instructions execute directly on the active stack.
Instructions placed on the instruction stacks work on the corresponding data stacks.
An overview of the stacks:
|n| <- top |.| |.| |2| |1| | | | | | | | | | | | | | | | | | | | | | | |0| | |0| | |0| | |0| | |0| | |0| | |0| | |0| | <- bottom ----- ----- ----- ----- ----- ----- ----- ----- |d|i| |d|i| |d|i| |d|i| |d|i| |d|i| |d|i| |d|i| a b c d e f g h a - h = stacks d = data stack i = instruction stack 0 = bottom of stack, a[0] = name of macro a[1] = first argument a[n] = argument n
In the following descriptions of instructions the values are indicated as:
After the macro is started the stacks are empty, except for position 0 on stack a that holds the name of the macro.
The stacks are not cleared between the different possible patterns executed inside a macro.
At the end of the macro execution the stacks are deleted, except if a special instruction is used (see Manipulation of stacks).
Next: Selecting a stack, Previous: Stacks, Up: Programs for patterns and macros [Contents][Index]
Programs are a sequence of instructions, data or calls to other programs.
An instruction, a piece of data or a call are all single words separated by
one or multiple spaces or newlines (\n).
If a word is not one of these, an error is output.
| • Data types: | ||
| • Instructions: | ||
| • Call to a program: |
Next: Instructions, Up: Programs [Contents][Index]
There are 2 types of data that are placed on the stack:
Strings are formed by one or more bytes. A string can be put on the top of a stack by enclosing the string in ".
Numbers are signed integers with a length of 64 bits. A number can be put on the top of the stack by only using digits (0 - 9) with a possible - for negative numbers in the program.
These types are automatically converted depending on the instructions used.
A string can contain a decimal, binary (starts with 0b), octal (starts with 0), hexadecimal (starts with 0x) or radix number (starts with 0r a number between 2 - 36 and :).
A number will be converted to a decimal number string.
Next: Call to a program, Previous: Data types, Up: Programs [Contents][Index]
If a word is not data or a call, it is assumed to represent an instruction.
All possible instructions are described in the following parts.
It is not possible to define own instructions like in a real forth language. Instead a call to a program can be used.
Previous: Instructions, Up: Programs [Contents][Index]
A separate program can be defined by using the function program (see Functions for defining patterns). The name
used in the definition of the program can be used to call the program from another
program.
The call of a program starts with the character @ and is directly
without a space followed by the name given to the program.
Next: Manipulation on the stack, Previous: Programs, Up: Programs for patterns and macros [Contents][Index]
Eight different stacks (a – h) are available. The first stack (a) is used to place the arguments of a macro.
The stack to be used must be selected. The default selection after the macro execution is started is stack a. Thus if no other stack than
the stack a is used it is not necessary to select it.
Selects the new active stack. The ? can be a letter from a – h representing stacks a to h.
pop: 0
push: 0
Next: Copy between stacks, Previous: Selecting a stack, Up: Programs for patterns and macros [Contents][Index]
Duplicates the top entry of the active stack.
pop: 0
push: 1
Pops and thereby removes the top entry of the active stack.
pop: 1
push: 0
Will pop the stack to the position of the stack indicated by the number (?). The ? can be a number from 0 - 9.
pop: depending on the stack.
push: 0
Swaps the top entry and the top - 1 entry of the active stack.
pop: 0
push: 0
Sets the base of stack a to the value on the topĀ of the stack. The base is used as the bottom when multiple arguments are output in the default argument substitution. This can be used to implement a shift macro, that shifts the arguments.
pop: 1
push: 0
Same as set_base whereby the base is set as 1.
pop: 0
push: 0
Next: Collecting argument strings, Previous: Manipulation on the stack, Up: Programs for patterns and macros [Contents][Index]
Copy the top entry of the active stack to the top on another stack. The ? can be a letter from a - h representing stacks a to h.
pop: 0
push: 1
Copy the top entry from another stack to the top of the active stack. The ? can be a letter from a - h representing stacks a to h.
pop: 0
push: 1
Copy the top entry of the active stack to position ? of stack a where the arguments are stored. The ? can be a number
from 0 - 9 representing the name of the macro (position 0) and the first 9 arguments (positions 1 - 9).
pop: 0
push: 0
Copy the top - 1 entry of the active stack to the position given by the top of the active stack of stack a.
pop: 1
push: 0
Copy the entry at position ? of stack a to the top entry of the active stack. The ? can be a number
from 0 - 9 representing the name of the macro (position 0) and the first 9 arguments (positions 1 - 9).
pop: 0
push: 1
Copy the entry of stack a, at the position indicated by the value at the top of the active stack, to the top entry of the active stack.
pop: 1
push: 1
Next: Program flow, Previous: Copy between stacks, Up: Programs for patterns and macros [Contents][Index]
The following instructions are used for collecting arguments.
The begin instructions will set the start position of the argument.
The end instructions will set the end position of the argument and copy the argument to the (active) stack.
If multiple begin instructions are used before an end instruction
only the first use will set the start position.
The arguments are always pushed to the stack as a string.
Sets the start position of the argument string at the end position of the pattern match.
pop: 0
push: 0
Sets the start position of the argument string at the end position minus the number (?) of the pattern match. The ? can be 1 - 4.
pop: 0
push: 0
Sets the start position of the argument string at the begin position plus the number (?) of the pattern match. The ? can be 0 - 2.
This instruction works only correct with a fixed length pattern part.
pop: 0
push: 0
Sets the end position of the argument string at the begin position of the pattern match and copies this string to the top of the stack. This instruction works only correct with a fixed length pattern part.
pop: 0
push: 1
Sets the end position of the argument string at the end position of the pattern match minus ? and copies this string to
the top of the stack. The ? can be 0 - 4.
pop: 0
push: 1
Aborts the collection of arguments. No arguments are collected and the bytes used in the matching till so far are returned to the input. Used when no arguments are detected or no argument start is detected after the macro.
pop: 0
push: 0
This stops the pattern. Normally used when all arguments are collected e.g. after detecting stop character of arguments.
It is necessary to use the stop instruction when collecting arguments, otherwise the complete input will be
used for the arguments of the macro. This instruction is not needed for the single programs for macros or when using patterns
to fill in the definition.
pop: 0
push: 0
Next: Getting variables, Previous: Collecting argument strings, Up: Programs for patterns and macros [Contents][Index]
Pops the top of the stack and continues to the next instruction if true or skips to the instruction after the next instruction if false.
pop: 1
push: 0
Pops the top of the stack and continues to the next instruction if true or skips to the instruction after the else if false.
The endif indicates the end of the instructions after the else. The else is optional.
pop: 1
push: 0
Pops the top of the stack and continues to the next instruction if true or skips
to the instruction after the endwhile instruction if false.
pop: 1
push: 0
Continues to the next instruction if the stack is not empty or skips
to the instruction after the endwhile instruction if the stack is empty.
pop: 0
push: 0
Returns to the while or while_st instruction.
pop: 0
push: 0
No operation. Does nothing.
pop: 0
push: 0
Next: Comparing values, Previous: Program flow, Up: Programs for patterns and macros [Contents][Index]
Sometimes it is necessary to have information of the process available. This information is available in variables that can be accessed and put on a stack.
Pushes the current position of the pattern matching to the stack. The first position of a pattern is position 0.
pop: 0
push: 1
Pushes the number of arguments collected on stack a to the stack.
pop: 0
push: 1
Pushes the current depth of macro calls to the stack. Since the programs always run inside a macro, this should be at least 1. This is already available in the argument collection.
pop: 0
push: 1
Next: Mathematical instructions, Previous: Getting variables, Up: Programs for patterns and macros [Contents][Index]
Several compare instructions for comparing values on the stack exist.
These instructions push a false (= 0) or true (= 1) on the stack.
Pops the top of the stack and compares this with ?. The ? can be 0 - 3.
If the values are equal then the return value is 1 otherwise it is 0.
pop: 1
push: 1
Pops the top of the stack and compares this with ?. The ? can be 0 - 3.
If stack value is larger than the ? then the return value is 1 otherwise it is 0.
pop: 1
push: 1
Pops the top of the stack and compares this with ?. The ? can be 0 - 3.
If stack value is larger or equal than the ? then the return value is 1 otherwise it is 0.
pop: 1
push: 1
Pops the top of the stack and compares this with ?. The ? can be 0 - 3.
If stack value is smaller than the ? then the return value is 1 otherwise it is 0.
pop: 1
push: 1
Pops the top of the stack and compares this with ?. The ? can be 0 - 3.
If stack value is smaller or equal than the ? then the return value is 1 otherwise it is 0.
pop: 1
push: 1
Pops the two top values of the stack and compares these. If the values are equal then the return value is 1 otherwise it is 0.
pop: 2
push: 1
Pops the two top values of the stack and compares these. If the values are not equal then the return value is 1 otherwise it is 0.
pop: 2
push: 1
Pops the two top values of the stack and compares these. If the first value is larger than the second value then the return value is 1 otherwise it is 0.
pop: 2
push: 1
Pops the two top values of the stack and compares these. If the first value is larger or equal than the second value then the return value is 1 otherwise it is 0.
pop: 2
push: 1
Pops the two top values of the stack and compares these. If the first value is smaller than the second value then the return value is 1 otherwise it is 0.
pop: 2
push: 1
Pops the two top values of the stack and compares these. If the first value is smaller or equal than the second value then the return value is 1 otherwise it is 0.
pop: 2
push: 1
Next: Logical bit instructions, Previous: Comparing values, Up: Programs for patterns and macros [Contents][Index]
Pops two values from the top of the stack and adds these values.
pop: 2
push: 1
Pops two values from the top of the stack and subtracts the top value from the top - 1 value.
pop: 2
push: 1
Pops two values from the top of the stack and multiplies these values.
pop: 2
push: 1
Pops two values from the top of the stack and divides these values.
pop: 2
push: 1
Pops two values from the top of the stack and returns the modulo (rest value after division).
pop: 2
push: 1
Pops two values from the top of the stack and returns the power (first value to the power of second value).
pop: 2
push: 1
Next: Logical instructions, Previous: Mathematical instructions, Up: Programs for patterns and macros [Contents][Index]
Pops two values from the top of the stack and bit shifts first value left by number of bits of second value.
pop: 2
push: 1
Pops two values from the top of the stack and bit shifts first value right by number of bits of second value.
pop: 2
push: 1
Bit shifts value at the top of the stack one bit to the left.
pop: 1
push: 1
Bit shifts value at the top of the stack one bit to the right.
pop: 1
push: 1
Pops two values from the top of the stack and returns the bit AND of these values.
pop: 2
push: 1
Pops two values from the top of the stack and returns the bit OR of these values.
pop: 2
push: 1
Pops two values from the top of the stack and returns the bit EXclusive OR of these values.
pop: 2
push: 1
Performs the bit NOT on the value on the top of the stack.
pop: 1
push: 1
Next: String instructions, Previous: Logical bit instructions, Up: Programs for patterns and macros [Contents][Index]
Pops two values from the top of the stack and returns the logical AND.
pop: 2
push: 1
Pops two values from the top of the stack and returns the logical OR.
pop: 2
push: 1
Pops the top value and returns the logical NOT.
pop: 1
push: 1
Next: Output manipulation instructions, Previous: Logical instructions, Up: Programs for patterns and macros [Contents][Index]
Concatenates the two strings from the top of the stack, leaving a single string on the stack.
pop: 2
push: 1
Compares the two strings from the top of the stack. If the strings are equal a true is returned to
the stack, otherwise a false is returned to the stack.
pop: 2
push: 1
A special compare instruction to implement if else macros.
It works on the 5 or 3 top positions of the stack. This depends on the number of arguments (on stack a) collected so far, not on the actual number of arguments on the stack.
If the number of arguments is 3 or a multiple of 3, then the 5 top positions are used. If the number of arguments is 1 or a multiple of 3 more (like 4, 7, 10, etc.), then the 3 top positions are used.
The stack should look in case of 5 top positions as:
top : string used if compare is true top - 1: second string to compare top - 2: first string to compare top - 3: flag of previous compares top - 4: valid string if flag == 1
In the case of 5 top positions, the instruction will:
The stack should look in case of 3 top positions as:
top : string used if flag is false top - 1: flag of previous compares top - 2: valid string if flag == 1
In the case of 3 top positions, the instruction will:
Using this instruction in a pattern enables the implementation of an ifelse
macro.
pop: depends on values on stack
push: depends on values on stack
Pops the top and returns the length of the string.
pop: 1
push: 1
Pops the two top positions, multiplies the string at top - 1 by a number at the top position and returns the string.
pop: 2
push: 1
Next: Instructions for overruling macro settings, Previous: String instructions, Up: Programs for patterns and macros [Contents][Index]
These instructions are used by the argument substitution pattern. They are used to change the output while processing the input. Since the input of argument collection is never directly output (only through the stack), these instructions are normally not useful during argument collection.
The current position in the output, where these instructions are executed, is the end of the pattern part.
Get pattern part from the start position of the pattern part and stores the string on the stack.
pop: 0
push: 1
Get pattern part from the start position of the pattern part + offset (?)
and stores the string on the stack.
The offset (?) can be 1 to 3.
pop: 0
push: 1
Get pattern part from the end position of the pattern part - offset (?)
and stores the string on the stack.
The offset (?) can be 1 to 5.
pop: 0
push: 1
Replace output from start position set by begin up to the current position by string on the stack.
pop: 1
push: 0
Replace pattern part by string on the stack.
pop: 1
push: 0
Replace output from rearward position (?) up to the current position by string on the stack.
The rearward position (?) can be 0 to 5.
pop: 1
push: 0
Next: Operator stack instructions, Previous: Output manipulation instructions, Up: Programs for patterns and macros [Contents][Index]
The following instructions are meant to set the recursion of output of the
calling macro (the mcall) by the called macro.
Overrules the setting of recursive macro output. The macro output is set to recursive.
pop: 0
push: 0
Overrules the setting of recursive macro output. The macro output is set to not recursive.
pop: 0
push: 0
Turns the overrule of the setting of recursive macro output off.
pop: 0
push: 0
The following instructions are only useful to influence the recursion during the collection of arguments.
When a program uses this instruction, no macros are called anymore during the collection of arguments.
Normally only useful for very specific
cases in emulation. It is used in the m6 emulation for specific
handling of argument collection with macros that select the following
text in a definition text.
Outside of the collection of arguments this instruction will have no influence.
pop: 0
push: 0
Next: Calling a builtin function, Previous: Instructions for overruling macro settings, Up: Programs for patterns and macros [Contents][Index]
The following instructions can be used for parsing and work on the instruction stack.
The opex instructions execute the instructions on the instruction stack or
store an instruction on the instruction stack depending on a condition.
Operator execute if (opexif) will execute the instructions on the instruction stack as long as
the rank gotten from the top of the stack is larger than the rank of the instruction on the
instruction stack.
Will push the instruction following the opexif on the instruction stack with the rank
gotten from the top of the stack.
pop: 1
push: 0
Same as opexif> but will execute the instructions as long as the rank is larger or equal
than the rank of the instruction on the instruction stack.
pop: 1
push: 0
Same as opexif> but will execute the instructions as long as the rank is smaller
than the rank of the instruction on the instruction stack.
pop: 1
push: 0
Same as opexif> but will execute the instructions as long as the rank is smaller or equal
than the rank of the instruction on the instruction stack.
pop: 1
push: 0
Will execute all the instructions on the instruction stack.
pop: 0
push: 0
Will execute all instructions on the instruction stack until an instruction is found on
the instruction stack that
is the same as the instruction after the opexto.
This last instruction on the stack will be executed, the instruction after the opexto not.
pop: 0
push: 0
Pushes the the instruction after the oppush on the instruction stack with the rank
gotten from the top of the stack.
pop: 1
push: 0
Next: Manipulation of stacks, Previous: Operator stack instructions, Up: Programs for patterns and macros [Contents][Index]
With the following instruction it is possible to make a macro wherein the builtin executed is dependent on arguments of the function.
This can be useful in an emulation to adapt the macro to specialities of the emulated macro.
The function call will call the builtin function with the name found on the top of the stack.
If the name does not exist, an error is output.
The function will be immediately called, so the arguments on stack a should already be correct. It is possible to call multiple builtin functions in one macro.
pop: 1
push: 0
Previous: Calling a builtin function, Up: Programs for patterns and macros [Contents][Index]
Normally the stacks are created at the start of a macro and removed or made free at the end of a macro. The following instructions manipulate this behaviour.
These instructions make the exchange of information between macros possible. This can be useful in an emulation.
This instruction sets the active stack to not be made free or removed at the end of the macro.
The stack of a macro can get additional entries from macros that are later called if these later called macros use this instruction. This means that macros called during the argument collection can push entries on a stack of the currently executing macro.
pop: 0
push: 0
This instruction sets the active stack to the default of being freed or removed at the end of the macro.
pop: 0
push: 0
Previous: Calling a builtin function, Up: Programs for patterns and macros [Contents][Index]