Module Format

A Blaze module is a binary file that holds the intermediate representation of a Blaze program. It consists of variable, function and class data.

A .blzm file consists of the following sections, in order:

  • Header
  • Constants
  • Variables
  • Functions
  • Classes

The following is the formal definition of a module file:

struct module {
    head :: header;

    const_count :: uint32;
    constants :: constant[const_count];

    var_count :: uint32;
    variables :: variable[var_count];

    func_count :: uint32;
    functions :: function[func_count];

    class_count :: uint32;
    classes :: class[class_count];
}

The header holds the version of the format it uses and the name of the module. It's defined as:

struct header {
    identifier :: uint32;
    v_major :: uint8;
    v_minor :: uint8;

    name_len :: uint16;
    name :: char[name_len];

    is_debug :: bool;
}

Constants

Constants are values that appear once or multiple times in code, such as numbers (eg. 10, 69, 420, etc.) and strings (eg. "Hello World"), that can be referenced by the rest of the module. The following is the definition of a constant:

enum ctype :: uint8 {
    0: NUMBER;
    1: STRING;
}

struct constant {
    type :: ctype;

    if(type == ctype.NUMBER) {
        value :: float64;
    } else if(type == ctype.STRING) {
        len :: uint16;
        value :: char[len];
    }
}

Variables

Each variable in the module is defined with a name and a visibility modifier.

enum vtype :: uint8 {
    0: PRIVATE; 
    1: PUBLIC;
    2: EXTERNAL;
}

struct variable {
    type :: vtype;
    name_ref :: uint16;  // index to string constant (one-indexed)
}

Functions

Functions include name reference, argument information, and their instruction bytecode.

struct instruction {
    op :: opcode;
    arg :: uint8;
}

struct function {
    name_ref :: uint16;  // index to string constant (one-indexed)
    num_args :: uint8;
    varargs :: bool;
    local_count :: uint8;

    // instruction block
    inst_count :: uint16;
    instructions :: instruction[inst_count];
}

Classes

Each class includes its name, member identifiers, and a reference to its constructor.

struct class {
    name_ref :: uint16;  // index to string constant (one-indexed)

    member_count :: uint8;
    members :: uint16[member_count]; // list of string constant refs (zero-indexed)

    constructor_ref :: uint16; // reference to function (zero-indexed)
}

Full Definition

// Constants
enum ctype :: uint8 {
    0: NUMBER;
    1: STRING;
}

struct constant {
    type :: ctype;

    if(type == ctype.NUMBER) {
        value :: float64;
    } else if(type == ctype.STRING) {
        len :: uint16;
        value :: char[len];
    }
}

// Variables
enum vtype :: uint8 {
    0: PRIVATE; 
    1: PUBLIC;
    2: EXTERNAL;
}

struct variable {
    type :: vtype;
    name_ref :: uint16;  // index to string constant (one-indexed)
}

// Functions
enum opcode :: uint8 {
    0: NOP;
    1: POP;
    2: EXTENDED_ARG;
    3: LDNULL;
    4: LDARG;
    5: LDCONST;
    6: LDLOCAL;
    7: LDVAR;
    8: LDFUNC;
    9: LDCLASS;
    10: LDBOOL;
    11: STLOCAL;
    12: STVAR;
    13: STARG;
    14: CALL;
    15: RET;
    16: ADD;
    17: SUB;
    18: MUL;
    19: DIV;
    20: INTDIV;
    21: THROW;
    22: CATCH;
    23: TRY_END;
    24: EQ;
    25: LT;
    26: LTE;
    27: NOT;
    28: JMP;
    29: JMPB;
    30: JMPA;
    31: JMPT;
    32: JMPF;
    33: OR;
    34: AND;
    35: DUP;
    36: VARARGS;
    37: LDLIST;
    38: LDOBJ;
    39: LDINDEX;
    40: STINDEX;
    41: LDPROP;
    42: STPROP;
    43: LDEVENT;
    44: ITER;
    45: NEW;
    46: ATTACH;
}

struct instruction {
    op :: opcode;
    arg :: uint8;
}

struct function {
    name_ref :: uint16;  // index to string constant (one-indexed)
    num_args :: uint8;
    varargs :: bool;
    local_count :: uint8;

    // instruction block
    inst_count :: uint16;
    instructions :: instruction[inst_count];
}

// Classes
struct class {
    name_ref :: uint16;  // index to string constant (one-indexed)

    member_count :: uint8;
    members :: uint16[member_count]; // list of string constant refs (zero-indexed)

    constructor_ref :: uint16; // reference to function (zero-indexed)
}


struct header {
    identifier :: uint32;
    v_major :: uint8;
    v_minor :: uint8;

    name_len :: uint16;
    name :: char[name_len];

    is_debug :: bool;
}

@entry
struct module {
    head :: header;

    const_count :: uint32;
    constants :: constant[const_count];

    var_count :: uint32;
    variables :: variable[var_count];

    func_count :: uint32;
    functions :: function[func_count];

    class_count :: uint32;
    classes :: class[class_count];
}