#!/usr/bin/env python # @author Alexander Koch 2016 import sys import struct # File format description (GVM) # # ---- (header) # uint32_t [magic ] 0xACCE55 (Access) # uint32_t [num_codes] number of instructions # ---- (instruction) # uint8_t [opcode ] operation # uint8_t [args ] argument count # value* [values ] argument values # ---- (value) # uint8_t [tag ] type tag # void* [data ] direct read as val_t, for objects special condition # ---- # Introduction: # Label -> name, ':'; # Instruction -> opcode, {',', value} # Program -> {Label | Instruction} # # Use call to invoke a function / label # Also don't forget to write hlt at the end or your program. # Opcode definition: # Tuple: first=opcode, second=args opcodes = { 'hlt': (b'\x00', b'\x00'), 'push': (b'\x01', b'\x01'), 'pop': (b'\x02', b'\x00'), 'store': (b'\x03', b'\x01'), 'load': (b'\x04', b'\x01'), 'gstore': (b'\x05', b'\x01'), 'gload': (b'\x06', b'\x01'), 'ldarg0': (b'\x07', b'\x00'), 'setarg0': (b'\x08', b'\x00'), 'iadd': (b'\x09', b'\x00'), 'isub': (b'\x0A', b'\x00'), 'imul': (b'\x0B', b'\x00'), 'idiv': (b'\x0C', b'\x00'), 'mod': (b'\x0D', b'\x00'), 'bitl': (b'\x0E', b'\x00'), 'bitr': (b'\x0F', b'\x00'), 'bitand': (b'\x10', b'\x00'), 'bitor': (b'\x11', b'\x00'), 'bitxor': (b'\x12', b'\x00'), 'bitnot': (b'\x13', b'\x00'), 'iminus': (b'\x14', b'\x00'), 'i2f': (b'\x15', b'\x00'), 'fadd': (b'\x16', b'\x00'), 'fsub': (b'\x17', b'\x00'), 'fmul': (b'\x18', b'\x00'), 'fdiv': (b'\x19', b'\x00'), 'fminus': (b'\x1A', b'\x00'), 'f2i': (b'\x1B', b'\x00'), 'not': (b'\x1C', b'\x00'), 'b2i': (b'\x1D', b'\x00'), 'syscall': (b'\x1E', b'\x01'), 'invoke': (b'\x1F', b'\x02'), 'reserve': (b'\x20', b'\x01'), 'ret': (b'\x21', b'\x00'), 'retvirtual': (b'\x22', b'\x00'), 'jmp': (b'\x23', b'\x01') } def check_int(s): if s[0] in ('-', '+'): return s[1:].isdigit() return s.isdigit() def writeValue(bytecode, arg): if check_int(arg): bytecode += b'\x01' bytecode += struct.pack(" 1: args = tokens[1].split(",") # Get the opcode opcode = tokens[0] # Remove trailing comma if opcode[-1:] == ',': opcode = opcode[:-1] # Test for labels elif opcode[-1:] == ':': # Get the label name label = opcode[:-1] labels[label] = bytecode_count continue # Test for call if opcode == "call": label = args[0] if label in labels: # invoke bytecode += b'\x1F' bytecode += b'\x02' # Arg1 bytecode += b'\x01' bytecode += struct.pack("