IMCC - Macros


This document describes the macro layer of IMCC.


The macro support for IMCC was designed to be a drop in replacement for the original macro layer.

One exception is the .macro_const macro, which is only usable in PASM mode. For PIR mode, please use the .const directive instead.

The addition of the '.' preface will hopefully make things easier to parse, inasmuch as everything within an assembler file that needs to be expanded or processed by the macro engine will have a period ('.') prepended to it.

The macro layer implements constants, macros, local labels and including of files.

A macro definition starts with a line consisting of ".macro", the name for the newly created macro and an optional list of parameters. Thereafter follows the definition of the macro which can span several lines. The definition is ended by ".endm". In the macro definition the formal parameters, preceded by a '.', are valid macros.

  .macro swap (A,B,TEMP) # . marks the directive
    set .TEMP,.A         # . marks the special variable.
    set .A,.B
    set .B,.TEMP
  .endm                  # And . marks the end of the macro.

Macros support labels, defined using .label, that are local to a given macro expansion. The syntax looks something like this:

  .macro SpinForever (Count)
    .label $LOOP: dec .COUNT    # ".label $LOOP" defines a local label.
                  branch .$LOOP # Jump to said label.

Include this macro as many times as you like; the branch statement should do the right thing every time. To use a global label, do just as you usually do.

The ".include" statement is followed by a string literal. The file of this name is include literally in the assembly.

The include file is searched for in the current directory and in runtime/parrot/include, in that order. The first file of that name to be found is included.

Expansion ^

Constant definitions have the form

  .macro_const name {register}
  .macro_const name {signed_integer}
  .macro_const name {signed_float}
  .macro_const name {"string constant"}
  .macro_const name {'string constant'}

They don't generate any code, but create a new macro directive .name

Given the line:

  '.macro_const HelloWorld "Hello, World!"'

one can expand HelloWorld via:

  'print .HelloWorld' # Note the period to indicate a thing to expand.

The contents of external files can be included by use of the .include macro:

  .include "{filename}"

The contents of the included file are inserted at the point where the .include macro occurs. This means that code like this:

  print "Hello "
  .include "foo.pasm"

where foo.pasm contains:

  print "World \n"


  print "Hello "
  print "World \n"

Attempting to include a non-existent file is a non-fatal error.

  .macro name ({arguments?})

Optional arguments are simply identifiers separated by commas. These arguments are matched to instances inside the macro named '.foo'. A simple example follows:

  .macro inc3 (A)
    inc .A # Mark the argument to expand with a '.'.
    inc .A
    inc .A

  .inc3(I0) # Expands to the obvious ('inc I0\n') x 3

Using braces, { }, allows you to use commas and parenthesis inside parameters for a macro. See runtime/parrot/include/hllmacros.pir for examples and possible usage.