Next: , Previous: , Up: Top   [Contents][Index]

6 Programs for patterns and macros


Next: , Up: Programs for patterns and macros   [Contents][Index]

6.1 Introduction to programs

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: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.2 Stacks

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: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.3 Programs

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.


Next: , Up: Programs   [Contents][Index]

6.3.1 Data types

There are 2 types of data that are placed on the stack:

Strings

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

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: , Previous: , Up: Programs   [Contents][Index]

6.3.2 Instructions

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: , Up: Programs   [Contents][Index]

6.3.3 Call to a program

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: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.4 Selecting a stack

Eight different stacks (ah) 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.

instruction: stack_?

Selects the new active stack. The ? can be a letter from ah representing stacks a to h.

pop: 0

push: 0


Next: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.5 Manipulation on the stack

instruction: dup

Duplicates the top entry of the active stack.

pop: 0

push: 1

instruction: pop

Pops and thereby removes the top entry of the active stack.

pop: 1

push: 0

instruction: pop_to_?

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

instruction: swap

Swaps the top entry and the top - 1 entry of the active stack.

pop: 0

push: 0

instruction: set_base

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

instruction: base_=_1

Same as set_base whereby the base is set as 1.

pop: 0

push: 0


Next: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.6 Copy between stacks

instruction: copyto_?

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

instruction: copyfr_?

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

instruction: putarg?

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

instruction: putarg

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

instruction: getarg?

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

instruction: getarg

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: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.7 Collecting argument strings

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.

instruction: begin

Sets the start position of the argument string at the end position of the pattern match.

pop: 0

push: 0

instruction: begin-?

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

instruction: begin+?

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

instruction: end

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

instruction: end-?

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

instruction: abort

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

instruction: stop

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: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.8 Program flow

instruction: ifthen

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

instruction: if else endif

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

instruction: while

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

instruction: while_st

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

instruction: endwhile

Returns to the while or while_st instruction.

pop: 0

push: 0

instruction: nop

No operation. Does nothing.

pop: 0

push: 0


Next: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.9 Getting variables

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.

instruction: argpos

Pushes the current position of the pattern matching to the stack. The first position of a pattern is position 0.

pop: 0

push: 1

instruction: argnum

Pushes the number of arguments collected on stack a to the stack.

pop: 0

push: 1

instruction: m_depth

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: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.10 Comparing values

Several compare instructions for comparing values on the stack exist. These instructions push a false (= 0) or true (= 1) on the stack.

instruction: =?

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

instruction: >?

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

instruction: >=?

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

instruction: <?

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

instruction: <=?

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

instruction: =

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

instruction: !=

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

instruction: >

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

instruction: >=

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

instruction: <

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

instruction: <=

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: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.11 Mathematical instructions

instruction: +

Pops two values from the top of the stack and adds these values.

pop: 2

push: 1

instruction: -

Pops two values from the top of the stack and subtracts the top value from the top - 1 value.

pop: 2

push: 1

instruction: *

Pops two values from the top of the stack and multiplies these values.

pop: 2

push: 1

instruction: /

Pops two values from the top of the stack and divides these values.

pop: 2

push: 1

instruction: mod

Pops two values from the top of the stack and returns the modulo (rest value after division).

pop: 2

push: 1

instruction: power

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: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.12 Logical bit instructions

instruction: shift_l

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

instruction: shift_r

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

instruction: <<1

Bit shifts value at the top of the stack one bit to the left.

pop: 1

push: 1

instruction: >>1

Bit shifts value at the top of the stack one bit to the right.

pop: 1

push: 1

instruction: bit_and

Pops two values from the top of the stack and returns the bit AND of these values.

pop: 2

push: 1

instruction: bit_or

Pops two values from the top of the stack and returns the bit OR of these values.

pop: 2

push: 1

instruction: bit_exor

Pops two values from the top of the stack and returns the bit EXclusive OR of these values.

pop: 2

push: 1

instruction: ~

Performs the bit NOT on the value on the top of the stack.

pop: 1

push: 1


Next: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.13 Logical instructions

instruction: and

Pops two values from the top of the stack and returns the logical AND.

pop: 2

push: 1

instruction: or

Pops two values from the top of the stack and returns the logical OR.

pop: 2

push: 1

instruction: !

Pops the top value and returns the logical NOT.

pop: 1

push: 1


Next: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.14 String instructions

instruction: cat

Concatenates the two strings from the top of the stack, leaving a single string on the stack.

pop: 2

push: 1

instruction: strcmp

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

instruction: ifcmpset

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

instruction: strlen

Pops the top and returns the length of the string.

pop: 1

push: 1

instruction: str*

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: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.15 Output manipulation instructions

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.

instruction: get_st

Get pattern part from the start position of the pattern part and stores the string on the stack.

pop: 0

push: 1

instruction: get_st+?

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

instruction: getlast?

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

instruction: putoutst

Replace output from start position set by begin up to the current position by string on the stack.

pop: 1

push: 0

instruction: putout

Replace pattern part by string on the stack.

pop: 1

push: 0

instruction: putout-?

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: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.16 Instructions for overruling macro settings

The following instructions are meant to set the recursion of output of the calling macro (the mcall) by the called macro.

instruction: recur_y

Overrules the setting of recursive macro output. The macro output is set to recursive.

pop: 0

push: 0

instruction: recur_n

Overrules the setting of recursive macro output. The macro output is set to not recursive.

pop: 0

push: 0

instruction: nooverr

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.

instruction: no_macro

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: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.17 Operator stack instructions

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.

instruction: opexif>

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

instruction: opexif>=

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

instruction: opexif<

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

instruction: opexif<=

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

instruction: opexall

Will execute all the instructions on the instruction stack.

pop: 0

push: 0

instruction: opexto

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

instruction: oppush

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: , Previous: , Up: Programs for patterns and macros   [Contents][Index]

6.18 Calling a builtin function

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.

instruction: fun_call

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: , Up: Programs for patterns and macros   [Contents][Index]

6.19 Manipulation of stacks

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.

instruction: free_no

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

instruction: free_yes

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: , Up: Programs for patterns and macros   [Contents][Index]