millfork

Millfork: a middle-level programming language targeting 6502- and Z80-based microcomputers and home consoles

This project is maintained by KarolS

< back to index

Macros and inlining

Macros

Functions defined with the macro keyword are not actual functions, but they are used as syntax replacements.

It implies the following:

When invoking a macro, you need to pass variables as arguments to parameters annotated with ref and constants as arguments annotated with const.

Invoking a non-asm macro requires the types of variables via ref parameters to match precisely. No type conversions are performed. Exception: parameters of type void can accept a variable of any type.

For parameters defined as const, register(XX) or call, the usual type conversions are performed.

You can invoke a macro from assembly, by preceding the invocation with +

Examples:

macro void inc_x() {
    x += 1
}
byte add_two_1(byte x) {
    inc_x()
    inc_x()
    return x
}

macro void inc(byte b) {
    b += 1
}
byte add_two_2(byte x) {
    inc(x)
    inc(x)
    return x
}
macro void perform_twice(void call f) {
    f
    f
}
byte add_two_3(byte x) {
    perform_twice(inc(x))
    return x
}

macro void add(byte b, byte v) {
    b += v
}
macro void retu(byte result) {
    return result
}
byte add_two_4(byte x) {
    add(x, 2)
    retu(x)
}

macro asm byte add_asm(byte ref b, byte const v) {
    LDA b
    CLC
    ADC #v
    STA b
    // no RTS!
}
byte add_two_5(byte x) {
    add_asm(x, 2)
    return x
}

macro asm byte add_asm_2(byte ref b, byte register(x) v) {
    TXA
    CLC
    ADC b
    STA b
    // no RTS!
}
byte add_two_6(byte x) {
    add_asm_2(x, 2)
    return x
}

Automatic inlining

You can control inlining behavior in several ways:

Automatic subroutine extraction

Subroutine extraction is the opposite of inlining.

When given the -fsubroutine-extraction, the compiler will attempt to extract common code fragments to new subroutines. The code will get smaller and slower.

Generally, when using -fsubroutine-extraction, it’s recommended to also use -finline. This allows the compiler to first inline and optimize code and then extract it back when appropriate.