The bytecode format === NOTE: This datestamp header is currently not implemented There are four components in the datestamp header: TOY_VERSION_MAJOR TOY_VERSION_MINOR TOY_VERSION_PATCH TOY_VERSION_BUILD The first three are each one unsigned byte, and the fourth is a null terminated C-string. * Under no circumstance, should you ever run bytecode whose major version is different * Under no circumstance, should you ever run bytecode whose minor version is above the interpreter’s minor version * You may, at your own risk, attempt to run bytecode whose patch version is different from the interpreter’s patch version * You may, at your own risk, attempt to run bytecode whose build version is different from the interpreter’s build version An additional note: The contents of the build string may be anything, such as: * the compilation date and time of the interpreter * a marker identifying the current fork and/or branch * identification information, such as the developer's copyright * a link to Risk Astley's "Never Gonna Give You Up" on YouTube Please note that in the final bytecode, if the null terminator of TOY_VERSION_BUILD is not 4-byte aligned, extra space will be allocated to round out the header's size to a multiple of 4. The contents of the extra bytes are undefined. === Bytecode Format Structure .header: N total size # size of this routine, including all data and subroutines N .jumps count # the number of entries in the jump table (should be data count + routine count) N .param count # the number of parameter fields expected (a secondary jump table, used for subroutine parameters) N .data count # the number of data fields present N .subs count # the number of subroutines present .code start # absolute address of .code; mandatory .param start # absolute addess of .param; omitted if not needed .datatable start # absolute address of .datatable; omitted if not needed .data start # absolute address of .data; omitted if not needed .subs start # absolute address of .subs; omitted if not needed # additional metadata fields can be added later .code: # opcode instructions read and 'executed' by the interpreter (aligned to 4-byte widths) [READ, TOY_VALUE_STRING, Toy_StringType, stringLength] [jumpIndex] .jumps: # a layer of indirection for quickly looking up values in .data and .subs 0 -> {string, 0x00} 4 -> {fn, 0xFF} .param: # a list of names, stored in .data, to be used for any provided function arguments .data: # data that can't be cleanly embedded into .code, such as strings "Hello world\0" .subs: # an extension of .data, used exclusively for subroutines (they also follow this spec, recursively)