LIGHTIR: lightweight, integer, register-based virtual machine ------------------------------------------------------------- Implements a simple virutal machine capable of 64 bit integer math. The virtual machine has 8 registers by default, though this is configurable up to 16 by defining LIGHTIR_NUM_REGS before importing "virtualmachine.h" The virtual machine comes with an assembler. Assembly instructions: M = memory location (label) I = immediate argument (integer, e.g. '-644', '0', ...) R = register ('r1', 'r2', ...) ld R, M load register with contents of memory location M st R, M store register to memory location M set R, I set register to immediate value I cpy R, R copy second register to first register add R, R first register += second register sub R, R first register -= second register mul R, R first register *= second register div R, R first register /= second register addm R, M register += contents of memory location M subm R, M register -= contents of memory location M mulm R, M register *= contents of memory location M divm R, M register /= contents of memory location M addi R, I register += immediate value subi R, I register -= immediate value muli R, I register *= immediate value divi R, I register /= immediate value jp R, M jump to location M if register value is > 0 jpz R, M jump to location M if register value is >= 0 jz R, M jump to location M if register value is zero jn R, M jump to location M if register value is < 0 jnz R, M jump to location M if register value is <= 0 j M jump to location M nop no operation stop return from execution, set program counter out of bounds yield return from execution, advance program counter 1 instruction the following instructions use stdio.h and can be disabled by defining LIGHTIR_DISABLE_STDIO before including virtualmachine.h getp R prompt user for a number, read a number from stdin into R get R read a number from stdin into R (no prompt) put R print the content of the register to stdout dbgr prints value of all registers and the program counter dbgm R, M prints R consecutive integers starting at location M There is also the pseudo-instruction "data", which should be followed by a number and reserves space in memory for one int64, initialized by the given number. - Comments begin with # and proceed until the end of the line. - Labels must occur at the start of the line, and must be followed by a colon - M must be a label, in all examples above. - The magnitude of immediate values is limited to 53 bits. See example-*.lightir for clarity. Building: cc lightir.c -o lightir Usage - assembling code: ./lightir as [assembly_filename] > [bytecode_filename] Usage - disassembling code: ./lightir disas [bytecode_filename] Note: there's no data segment or other way to differentiate data from instructions. So in the disassembly, data will appear as (possibly garbage) instructions. Positive integers (unless absurdly large) usually appear as 'stop'. Usage - interpreting bytecode: ./lightir run [bytecode_filename] The runtime components are all contained in the single header file virtualmachine.h, so in principle this could be embedded in other programs. Define LIGHTIR_IMPLEMENTATION before including the header file in exactly one .c file.