/lightir-vm

lightir: lightweight, integer, register-based virtual machine

Primary LanguageCThe UnlicenseUnlicense

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.