# macroOverview(4)

[Home] [Commands] [Variables] [Macro-Dev] [Glossary]

## MACRO LANGUAGE OVERVIEW

MicroEmacs macro language is a run-time interpreted language and uses a prefix notation form, that is operators appear before their arguments, sometimes known as Polish notation, i.e. '`+ 3 4`' rather than the more conventional infix notation '`3 + 4`').

Every line is self contained, you cannot make a single command span multiple line (by using something like a '\' character as in C or tcl).

Comments start with semi-colon '`;`', anything to the right of an unquoted semi-colon is ignored.

    ; I'm a comment and exist to the end of line.
    set-variable #l1 1     ; I am a comment to the end of line.

There are three types of line

- Blank or comment line
- Process flow control lines using directives (i.e. '`!if #l1`')
- Executable command lines (i.e. `forward-line`)

The first letter of any word or token on a line is very important and informs MicroEmacs and the user what type of token it is. The basic token start characters are:

`;` Comment
`$` System or environment variable
`%` User variable
`:` Buffer variable
`.` Command variable
`#` Register variable
`@` Macro variable
`!` Directive
`&` Function
`"` A string, which finishes at the next unquoted `"`.
`0-9` A number, which is read as a string
`*` A goto label

If its not one of the above then it must be the first letter of a command name.

## Escape Character

Backslash '`\`' is escape character in macro scripts, so every normal occurrence needs to be doubled.

The MicroEmacs macro language uses a backslash '`\`' character as an escape character. In order to use a backslash character in macro arguments then all backslash characters should be themselves escaped with another backslash i.e. '`\`' becomes '`\\`' or '`\\`' becomes '`\\\\`'. If the escaping is omitted then it is likely that the command will receive an incorrect character sequence that will be misinterpreted and cause the command to fail or perform an incorrect action.

## Comments

Comments may appear anywhere on a line and everything to the right of the semi-colon to the end of the line is ignored:

    ; this is a comment
    set-variable #l0 1    ; this part of the line is a comment.

## System or environment variables

MicroEmacs system variables start with '`$`' and are used to configure most aspects of the editor (such as tab widths, window drawing characters etc.). There are a fixed list of system variables, see MicroEmacs - Macro Language Glossary.

If a given variable name is not a recognized system variable (e.g. `$PATH`) then MicroEmacs treats it as an environment variable, using set-variable(2) to change an environment variable. This is useful when used in conjunction with one of MicroEmacs's shell commands. If the environment variable does not exist its value is returned as the string "`ERROR`".

## User variables

User variables commence with a percentage character '`%`' and have a global context within the editor, but unlike the system variables they do not span into the environment space (i.e. private to MicroEmacs).

The use of User Variables is discouraged because of their scope, historically MicroEmacs only supported system and user variables. If two different macros use the same variable then things go wrong which is principally why they are no longer used. Macros have become a very large part of JASSPA's MicroEmacs and therefore they must be reliable by the nature of their global scope they are considered unreliable.

A few commands still use them but this is more for historical reasons, for example xgrep's %xgrep-com(5) variable to set the default grep command would be better implemented as the command variable `.xgrep.com`, see below.

## Buffer Variables

Buffer variables are set in the context of a buffer, each buffer has its own independent list of buffer variables so this type of variable is used by macros which need to store buffer context information. As an example, a file hook may allow each buffer to have its own private $fill-ignore(5) value (the variable is global). It may stores each buffer's own fill ignore in the variable `:fill-ignore`. This is private to the buffer. Referencing the variable `:fill-ignore` retrieves the current buffer's `:fill-ignore` variable, if it not set its value is returned as "`ERROR`". Referencing `:*scratch*:fill-ignore` retrieves the "`*scratch*`" buffer's `:fill-ignore` value.

The operator &exist(4) may be used to determine if the buffer variable has been created and set.

## Command Variables

Command variables are set in the context of a command or macro and are similar to buffer variables. `.var` retrieves the the current macros command variable whereas `.hilight.var` will get command hilight command variable.

It is important to understand that these variables are stored with the command and the command must exist before the variable is used. As an example of the command variable scope, consider the following macro definitions.

    define-macro Test1
        ml-write &spr "Test1 .foo is [%s]" .foo
    !emacro
    set-variable .Test1.foo "hello world"
    define-macro Test2
        ml-write &spr "Test1 .foo is [%s]" .Test1.foo
    !emacro

On running Test1 and Test2 both will print "`Test1` `.foo` `is` `[hello` `world]`". The initialisation of `.Test1.foo` is performed outside of the macro and is done only once, once the variable has been initialized the line is discarded. This discard reduces the run-time memory overhead.

## Register Variables

Most variables are used to store temporary information, once a macro completes the variable is no longer required. Register variables are used for this purpose, their scope is only the current macro's execution as such they are the most efficient variables to use.

A new set of registers is created every time that a macro is executed, called `#l0` through to `#l9`. Where macros are nested then the parent registers are effectively stacked and may be access through `#p0` through to `#p9`, this is especially useful when writing recursive macros or macros which must return values as they may return a processed result in the parents register. A single set of registers always exists which is the global registers `#g0` through to `#g9`, for a first level macro then this forms its parent register variable.

## Macro variables

Macro variables commence with a at-sign `@` and are only available in the context of a macro and are used to retrieve the numeric argument, parameters etc. The variables include:-

@? - Boolean determines if a numeric argument was supplied
@# - The value of the numeric argument

@0 - The name of the macro
@1 - The first argument of macro
@2 - The second argument of macro
@3 ... @n

@p - The name of the calling (or parent) macro.

## Directives

The Macro Directives are denoted by a ! prefix and provide control over the command sequence. Directives are used to define macros and affect the macro execution sequence. i.e.

    define-macro if-test
        set-variable #l0 1
        !if #l0
            ml-write "you will see this"
            !return
        !elif &not #l0
            ml-write "you will not see this"
            !abort
        !else
            ml-write "you will not see this"
            !abort
        !endif
    !emacro

The common directives are:-

!abort

!abort terminates a macro and exits with a false status.

!return

!return terminates a macro and exits with a true status.

!while/!continue/!done

!while defines a conditional loop that is tested before entry to the loop, the !continue statement within the loop allows the loop to be broken. !while loops may not be nested, but may be contained within a !repeat/!until construct.

!repeat/!until

!repeat defines a conditional loop that is tested on exit from the loop. !repeat loops may not be nested, but may be contained within a !while/!done construct.

define-macro/!emacro

define-macro defines a new macro which is terminated with a !emacro.

!if/!elif/!else/!endif

!if defines a conditional statement, where there is more than one condition then the !elif directive may continue the conditional test.

!goto/!tgoto

!goto and !tgoto provide an absolute unconditional and conditional jump to a *label in a file, respectively. A !goto label is defined as line commencing with a `*` followed by a name i.e. *label.

!force command

!force ignores the return status of a command while executing a macro, thereby ignoring any exceptions which would otherwise halt macro execution.

## Functions

All functions are denoted by a & prefix, they are perhaps miss named and should be called operators as they operate on variables and literal strings to produce a new result.

There are different type of functions:

- Numeric - interprets arguments as numbers i.e. add two numbers &add(4).
- String - interprets arguments as strings i.e. to concatenate two strings together &cat(4).
- Logical - boolean operators i.e. greater than &great(4).
- Key - key bindings i.e. key binding of command kbind(4).
- Bitwise - bit-wise numerical operators i.e. bitwise AND &band(4).
- File - file interaction i.e. find a file &find(4).
- Lists - string item lists i.e. find item in list &lfind(4).
- Miscellaneous - miscellaneous functions to which query and return information to the caller i.e. registry query &reg(4).

The functions use a postfix notation as the function appears before the arguments.

    set-variable #l0 2
    set-variable #l1 1
    !if &gre #l0 #l1
        ml-write "#l0 is greater than #l1"
    !endif

    ml-write &cat "#l0 + #l1 = " &add #l0 #l1

The interpretation of strings and numbers is discussed in the next section.

## Strings and Numbers

All variables are treated as strings within MicroEmacs so the integer value of 102 is the string `"102"`. Where functions require an integer argument (i.e. &add) the strings are converted to integers, operated on and converted back to a string result. Floating point notation is not understood.

Integers may be expressed in different bases:

`0xXXX` - Hexadecimal notation i.e. 0x12af.
`0oooo` - Octal notation requires a leading 012673.
`ddddd` - Decimal notation 12345.

Strings do not necessarily need to be quoted, provided that the string is unambiguous and does not include any special characters then all input between white spaces is considered to be a string. Strings may be quoted '`"string"`', within a quoted string then a backslash '`\`'is used as an escape character. the escape sequences that are interpreted include:

`\\` - A backslash character.
`\t` - A literal TAB character.
`\n` - A literal NEWLINE character.
`\xx` - A hexadecimal character.

## SEE ALSO

Introduction to Variable Functions
Macro Glossary
Macro Debugging Crash Course
Writing MicroEmacs Macros

(c) Copyright JASSPA 2009
Last Modified: 2009/08/29
Generated On: 2009/10/12

</HMTL>