# Copyright: 2001-2004 The Perl Foundation.  All Rights Reserved.
# $Id: macros.pod 7449 2005-01-11 04:04:18Z scog $

=head1 NAME

IMCC - Macros

=head1 OVERVIEW

This document describes the macro layer of IMCC.

=head1 DESCRIPTION

The macro support for IMCC was designed to be a drop in replacement for
the original F<assemble.pl> macro layer.

One exception is the B<.constant> macro, which is only usable in PASM mode. 
For PIR mode, please use the B<.const> directive instead. Also note that you 
have to use B<.sym> inside macros to define symbols, as B<.local> is used for 
local labels.

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 B<.local>, that are local to a 
given macro expansion. The syntax looks something like this:

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

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.

Constants are new and the syntax looks like:

  .constant Hash 6 # Again, . marks the directive

  new P0, .Hash # . marks the special variable for expansion.

Several constants are predefined, namely the PMC classes, e.g.

  .constant Array 0
  .constant PerlUndef 1
  ...

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
F<runtime/parrot/include>, in that order. The first file of that name
to be found is included.

=head2 Expansion

Constant definitions have the form

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

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

Given the line:

  '.constant HelloWorld "Hello, World!"'

one can expand HelloWorld via:

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

Some predefined constants exist for your convenience, namely:

  .Array
  .Hash
  .PerlArray

and the other PMC types.

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

  .include "{filename}"

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

  print "Hello "
  .include "foo.pasm"
  end

where F<foo.pasm> contains:

  print "World \n"

becomes:

  print "Hello "
  print "World \n"
  end

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

  .macro name ({arguments?})
  ...
  .endm

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
  .endm

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