High Level Language Macros ^

These macros are to make it easier to write readable and maintainable PIR by preprocessing common HLL forms into their low level PIR forms. These are not actually high level constructs, but merely preprocessor directives.

Conditionals ^

When a conditional is labeled as a parameter, the valid syntax is limited. Only code snippets such as $P0, $I0 <= 42, null $P0, are allowed. Groupings such as $I0 <= 42 || $I0 > 142 are not allowed, although it is possible to write a macro that contains two parameters representing conditionals. It's important to avoid the { } delimiter on the conditionals since a newline in the conditional renders the generated PIR invalid.

Code blocks ^

The macro preprocessor is very simple. But it allows using braces to delimit code that contains commas or right parenthesis, ), without causing an error. This allows for nesting macros to near infinite depths. And macro parameter that uses a comma or right parenthesis must be enclosed in braces.

Macros ^


This is the most simple of macros. Because PIR statements are delimited by newlines, putting multiple statements, no matter how simple or short, is not allowed. Sometimes for readability you wish to have two on the same line. Using .NL() in a line will insert a linebreak.

.If(conditional, code)

Runs the code in code if conditional is true.

.Unless(conditional, code)

Runs the code in code if conditional is false.

.IfElse(conditional, true, false)

Runs the code in true if conditional is true, otherwise runs the code in false.

.While(conditional, code)

Runs the code in code as long as conditional is true.

.DoWhile(code, conditional)

Runs the code in code once, and then as long as conditional is true.


Runs the code in code forever.

.For(start, conditional, continue, code)

First start is executed, such as i = 0, and then if the conditional is true, runs code, and then the continue code, such as inc i.

.Foreach(name, array, code)

A simple foreach loop. Given the aggregate array, which must be a register, it iterates through the array, putting each value into name to work with in code.

Examples ^

Good morning! ^

"Hello, world!" is so mundane, make it more fun.

    .include "tm.pasm"
    .include "hllmacros.pir"
    .sub main :main
        $I0 = time
        $P0 = decodelocaltime $I0
        $I0 = $P0[.TM_HOUR]
        .IfElse($I0 < 12,{
            print "Good morning!\n"
            .IfElse($I0 > 18,{
                print "Good night!\n"
                print "Good evening!\n"

Simple looping ^

A simple demonstration of the For loop.

    .include "hllmacros.pir"
    .sub main :main
        print "For\n"
        .For(i = 0 , i < 5, inc i,
            print "\t"
            print i
            print "\n"

A simple demonstration of the Foreach loop.

    .include "hllmacros.pir"
    .sub main :main
        print "Foreach\n"
        .local pmc array, letter
        array = new 'ResizablePMCArray'
        push array, "a"
        push array, "b"
        push array, "c"
        .Foreach(letter, array, {
            print "\t"
            print letter
            print " "
            .IfElse(letter == 'b',
                print "is b\n"
                print "isn't b\n"

Using .NL()

    .local int i, j
    .For({i = 0 .NL() j = 11}, i < j, {inc i .NL() dec j }, {
        print i
        print "\t"
        print j
        print "\n"

Caveats ^

The .Foreach macro is not nestable within itself currently. You can use other macros inside a .Foreach loop, and the .Foreach loop can be nested inside other macros.

    .Foreach(foo, bar, {
        .Foreach(foobar, foo, {
            print foobar

Will not run as you would expect.