add initial stuff, is very broken because of overflows
This commit is contained in:
		
							parent
							
								
									039aa7e9f9
								
							
						
					
					
						commit
						f476b74c3f
					
				| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
#define ZRL_OPCODES_H
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "fixed.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
| 
						 | 
				
			
			@ -10,8 +11,8 @@ typedef enum {
 | 
			
		|||
  OP_GET_PC,        /* pc   : dest = current program counter */
 | 
			
		||||
  OP_CALL,          /* call : creates a new frame */
 | 
			
		||||
  OP_RETURN,        /* retn : returns from a frame to the parent frame */
 | 
			
		||||
  OP_LOAD,   /* load : dest = &[next memory location] */
 | 
			
		||||
  OP_STORE,  /* stor : next memory location = src1 as float */
 | 
			
		||||
  OP_LOAD,          /* load : dest = &[next code location] */
 | 
			
		||||
  OP_STORE,         /* stor : next code location = src1 as float */
 | 
			
		||||
  OP_PUSH,          /* push : push str ref from register onto the stack and copy str  */
 | 
			
		||||
  OP_POP,           /* pop  : pop int from stack onto the register */
 | 
			
		||||
  OP_REG_MOV,       /* rmov : dest = src1	   */
 | 
			
		||||
| 
						 | 
				
			
			@ -56,15 +57,15 @@ typedef enum {
 | 
			
		|||
  OP_JLT_REAL,      /* jler : jump to address dest if src1 as real < src2 as real */
 | 
			
		||||
  OP_JLE_REAL,      /* jger : jump to address dest if src1 as real <= src2 as real */
 | 
			
		||||
  OP_INT_TO_STRING, /* itos : dest = src1 as str */
 | 
			
		||||
  OP_UINT_TO_STRING, /* utos : dest = src1 as str */
 | 
			
		||||
  OP_REAL_TO_STRING, /* rtos : dest = src1 as str */
 | 
			
		||||
  OP_UINT_TO_STRING,/* utos : dest = src1 as str */
 | 
			
		||||
  OP_REAL_TO_STRING,/* rtos : dest = src1 as str */
 | 
			
		||||
  OP_CMP_STRING,    /* cmps : dest = (str == src2) as bool */
 | 
			
		||||
  OP_STRING_TO_INT, /* stoi : dest = src1 as int */
 | 
			
		||||
  OP_STRING_TO_UINT, /* stou : dest = src1 as uint */
 | 
			
		||||
  OP_STRING_TO_REAL, /* stor : dest = src1 as real */
 | 
			
		||||
  OP_STRING_TO_UINT,/* stou : dest = src1 as uint */
 | 
			
		||||
  OP_STRING_TO_REAL,/* stor : dest = src1 as real */
 | 
			
		||||
  /* to remove (replace with device), just for testing for now */
 | 
			
		||||
  OP_DBG_PRINT_STRING,
 | 
			
		||||
  OP_DBG_READ_STRING,
 | 
			
		||||
  OP_DBG_PRINT_STRING,/* puts : write src1 as str to stdout */
 | 
			
		||||
  OP_DBG_READ_STRING, /* gets : read to dest as str from stdin */
 | 
			
		||||
} Opcode;
 | 
			
		||||
 | 
			
		||||
/* defines a uint32 opcode */
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +77,7 @@ typedef enum {
 | 
			
		|||
 | 
			
		||||
typedef union value_u {
 | 
			
		||||
  int32_t i;  /* Integers */
 | 
			
		||||
  float f;    /* Float */
 | 
			
		||||
  fixed_t f;  /* Fixed point */
 | 
			
		||||
  uint32_t u; /* Unsigned integers, also used for pointer address */
 | 
			
		||||
  char c[4];  /* 4 Byte char array for string packing */
 | 
			
		||||
} Value;
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +124,7 @@ typedef struct device_s {
 | 
			
		|||
  uint32_t flags;                    /* permissions, status, etc. */
 | 
			
		||||
} Device;
 | 
			
		||||
 | 
			
		||||
#define MEMORY_SIZE (640 * 480 + 65536)
 | 
			
		||||
#define MEMORY_SIZE ((640 * 480) + 65536)
 | 
			
		||||
#define CODE_SIZE 8192
 | 
			
		||||
#define FRAMES_SIZE 128
 | 
			
		||||
#define STACK_SIZE 256
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										277
									
								
								src/vm.c
								
								
								
								
							
							
						
						
									
										277
									
								
								src/vm.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
#include "vm.h"
 | 
			
		||||
#include "device.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "fixed.h"
 | 
			
		||||
#include "opcodes.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/* no inline fn in ANSI C :( */
 | 
			
		||||
#define COMPARE_AND_JUMP(type, accessor, op)                                   \
 | 
			
		||||
| 
						 | 
				
			
			@ -12,17 +14,6 @@
 | 
			
		|||
    return true;                                                               \
 | 
			
		||||
  } while (0)
 | 
			
		||||
 | 
			
		||||
#define MATH_OP(accessor, op)                                                  \
 | 
			
		||||
  do {                                                                         \
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].accessor =                              \
 | 
			
		||||
        vm->frames[vm->fp]                                                     \
 | 
			
		||||
            .registers[src1]                                                   \
 | 
			
		||||
            .accessor op vm->frames[vm->fp]                                    \
 | 
			
		||||
            .registers[src2]                                                   \
 | 
			
		||||
            .accessor;                                                         \
 | 
			
		||||
    return true;                                                               \
 | 
			
		||||
  } while (0)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Embeds a string into the VM
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -49,11 +40,17 @@ uint32_t str_alloc(VM *vm, const char *str, uint32_t length) {
 | 
			
		|||
 | 
			
		||||
  vm->memory[str_addr].u = length;
 | 
			
		||||
  vm->frames[vm->fp].allocated.end = vm->mp;
 | 
			
		||||
 | 
			
		||||
  return str_addr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t real_alloc(VM *vm, float v) {
 | 
			
		||||
uint32_t float_as_real_alloc(VM *vm, float v) {
 | 
			
		||||
  uint32_t addr = vm->mp;
 | 
			
		||||
  vm->memory[vm->mp++].f = float_to_fixed(v);
 | 
			
		||||
  vm->frames[vm->fp].allocated.end++;
 | 
			
		||||
  return addr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t real_alloc(VM *vm, fixed_t v) {
 | 
			
		||||
  uint32_t addr = vm->mp;
 | 
			
		||||
  vm->memory[vm->mp++].f = v;
 | 
			
		||||
  vm->frames[vm->fp].allocated.end++;
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +71,94 @@ uint32_t int_alloc(VM *vm, int32_t v) {
 | 
			
		|||
  return addr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define MAX_LEN_INT32 12  /* -2147483648 plus null terminator */
 | 
			
		||||
#define MAX_LEN_UINT32 11 /* 4294967295 plus null terminator */
 | 
			
		||||
#define MAX_LEN_FIXED 20  /* Enough for fixed-point representation */
 | 
			
		||||
const char radix_set[11] = "0123456789";
 | 
			
		||||
 | 
			
		||||
/* Convert int32 to string */
 | 
			
		||||
uint32_t int_to_string(VM *vm, int32_t v) {
 | 
			
		||||
  char buffer[MAX_LEN_INT32] = {0};
 | 
			
		||||
  int32_t n = v;
 | 
			
		||||
  bool neg = n < 0;
 | 
			
		||||
  if (neg)
 | 
			
		||||
    n = -n;
 | 
			
		||||
  int i = MAX_LEN_INT32;
 | 
			
		||||
  do {
 | 
			
		||||
    buffer[--i] = radix_set[n % 10];
 | 
			
		||||
    n /= 10;
 | 
			
		||||
  } while (n > 0);
 | 
			
		||||
  if (neg)
 | 
			
		||||
    buffer[--i] = '-';
 | 
			
		||||
  /* Ensure at least one digit is written for 0 */
 | 
			
		||||
  if (v == 0)
 | 
			
		||||
    buffer[--i] = '0';
 | 
			
		||||
 | 
			
		||||
  uint32_t len = MAX_LEN_INT32 - i;
 | 
			
		||||
  return str_alloc(vm, buffer + i, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Convert uint32 to string */
 | 
			
		||||
uint32_t nat_to_string(VM *vm, uint32_t v) {
 | 
			
		||||
  char buffer[MAX_LEN_INT32] = {0};
 | 
			
		||||
  uint32_t n = v;
 | 
			
		||||
  int i = MAX_LEN_INT32;
 | 
			
		||||
  do {
 | 
			
		||||
    buffer[--i] = radix_set[n % 10];
 | 
			
		||||
    n /= 10;
 | 
			
		||||
  } while (n > 0);
 | 
			
		||||
  /* Ensure at least one digit is written for 0 */
 | 
			
		||||
  if (v == 0)
 | 
			
		||||
    buffer[--i] = '0';
 | 
			
		||||
 | 
			
		||||
  uint32_t len = MAX_LEN_INT32 - i;
 | 
			
		||||
  return str_alloc(vm, buffer + i, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Convert fixed-point to string */
 | 
			
		||||
uint32_t real_to_string(VM *vm, fixed_t q) {
 | 
			
		||||
  char buffer[MAX_LEN_FIXED] = {0};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /* Extract integer part (top 16 bits) */
 | 
			
		||||
  int32_t int_part = q >> 16;
 | 
			
		||||
  /* Extract fractional part (bottom 16 bits) */
 | 
			
		||||
  int32_t frac_part = q & 0xFFFF;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  int32_t n = frac_part;
 | 
			
		||||
  bool neg = n < 0;
 | 
			
		||||
  if (neg)
 | 
			
		||||
    n = -n;
 | 
			
		||||
  int i = MAX_LEN_FIXED;
 | 
			
		||||
  do {
 | 
			
		||||
    buffer[--i] = radix_set[n % 10];
 | 
			
		||||
    n /= 10;
 | 
			
		||||
  } while (n > 0);
 | 
			
		||||
  if (neg)
 | 
			
		||||
    buffer[--i] = '-';
 | 
			
		||||
  /* Ensure at least one digit is written for 0 */
 | 
			
		||||
  if (frac_part == 0)
 | 
			
		||||
    buffer[--i] = '0';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /* Convert integer part to string (reverse order) */
 | 
			
		||||
  do {
 | 
			
		||||
    buffer[--i] = radix_set[int_part % 10];
 | 
			
		||||
    int_part /= 10;
 | 
			
		||||
  } while (int_part > 0);
 | 
			
		||||
  /* Ensure at least one digit is written for 0 */
 | 
			
		||||
  if (int_part == 0)
 | 
			
		||||
    buffer[--i] = '0';    
 | 
			
		||||
 | 
			
		||||
  /* Null-terminate */
 | 
			
		||||
  buffer[i] = '\0';
 | 
			
		||||
 | 
			
		||||
  int32_t len = (MAX_LEN_INT32 - i);
 | 
			
		||||
  printf("i=%d, len=%d", i, len);
 | 
			
		||||
  return str_alloc(vm, buffer + i, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Step to the next opcode in the vm.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -108,7 +193,9 @@ bool step_vm(VM *vm) {
 | 
			
		|||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_LOAD: {
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].u = vm->code[vm->pc++].u;
 | 
			
		||||
    uint32_t ptr = vm->code[vm->pc++].u;
 | 
			
		||||
    Value v = vm->memory[ptr];
 | 
			
		||||
    vm->frames[vm->fp].registers[dest] = v;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_STORE: {
 | 
			
		||||
| 
						 | 
				
			
			@ -134,11 +221,13 @@ bool step_vm(VM *vm) {
 | 
			
		|||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_PUSH: {
 | 
			
		||||
    vm->stack[++vm->sp] = vm->frames[vm->fp].registers[dest];
 | 
			
		||||
    Value v = vm->frames[vm->fp].registers[dest];
 | 
			
		||||
    vm->stack[++vm->sp] = v;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_POP: {
 | 
			
		||||
    vm->frames[vm->fp].registers[dest] = vm->stack[vm->sp--];
 | 
			
		||||
    Value v = vm->stack[vm->sp--];
 | 
			
		||||
    vm->frames[vm->fp].registers[dest] = v;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_MEM_ALLOC: {
 | 
			
		||||
| 
						 | 
				
			
			@ -317,48 +406,98 @@ bool step_vm(VM *vm) {
 | 
			
		|||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_ADD_INT:
 | 
			
		||||
    MATH_OP(i, +);
 | 
			
		||||
  case OP_SUB_INT:
 | 
			
		||||
    MATH_OP(i, -);
 | 
			
		||||
  case OP_MUL_INT:
 | 
			
		||||
    MATH_OP(i, *);
 | 
			
		||||
  case OP_DIV_INT:
 | 
			
		||||
    MATH_OP(i, /);
 | 
			
		||||
  case OP_ADD_UINT:
 | 
			
		||||
    MATH_OP(u, +);
 | 
			
		||||
  case OP_SUB_UINT:
 | 
			
		||||
    MATH_OP(u, -);
 | 
			
		||||
  case OP_MUL_UINT:
 | 
			
		||||
    MATH_OP(u, *);
 | 
			
		||||
  case OP_DIV_UINT:
 | 
			
		||||
    MATH_OP(u, /);
 | 
			
		||||
  case OP_ADD_REAL:
 | 
			
		||||
    MATH_OP(f, +);
 | 
			
		||||
  case OP_SUB_REAL:
 | 
			
		||||
    MATH_OP(f, -);
 | 
			
		||||
  case OP_MUL_REAL:
 | 
			
		||||
    MATH_OP(f, *);
 | 
			
		||||
  case OP_DIV_REAL:
 | 
			
		||||
    MATH_OP(f, /);
 | 
			
		||||
  case OP_ADD_INT: {
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].i =
 | 
			
		||||
        vm->frames[vm->fp].registers[src1].i +
 | 
			
		||||
        vm->frames[vm->fp].registers[src2].i;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_SUB_INT:{
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].i =
 | 
			
		||||
        vm->frames[vm->fp].registers[src1].i -
 | 
			
		||||
        vm->frames[vm->fp].registers[src2].i;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_MUL_INT:{
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].i =
 | 
			
		||||
        vm->frames[vm->fp].registers[src1].i *
 | 
			
		||||
        vm->frames[vm->fp].registers[src2].i;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_DIV_INT:{
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].i =
 | 
			
		||||
        vm->frames[vm->fp].registers[src1].i /
 | 
			
		||||
        vm->frames[vm->fp].registers[src2].i;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_ADD_UINT:{
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].u =
 | 
			
		||||
        vm->frames[vm->fp].registers[src1].u +
 | 
			
		||||
        vm->frames[vm->fp].registers[src2].u;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_SUB_UINT:{
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].u =
 | 
			
		||||
        vm->frames[vm->fp].registers[src1].u -
 | 
			
		||||
        vm->frames[vm->fp].registers[src2].u;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_MUL_UINT:{
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].u =
 | 
			
		||||
        vm->frames[vm->fp].registers[src1].u *
 | 
			
		||||
        vm->frames[vm->fp].registers[src2].u;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_DIV_UINT:{
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].u =
 | 
			
		||||
        vm->frames[vm->fp].registers[src1].u /
 | 
			
		||||
        vm->frames[vm->fp].registers[src2].u;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_ADD_REAL:{
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].f =
 | 
			
		||||
        fixed_add(vm->frames[vm->fp].registers[src1].f,
 | 
			
		||||
                  vm->frames[vm->fp].registers[src2].f);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_SUB_REAL:{
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].f =
 | 
			
		||||
        fixed_sub(vm->frames[vm->fp].registers[src1].f,
 | 
			
		||||
                  vm->frames[vm->fp].registers[src2].f);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_MUL_REAL: {
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].f =
 | 
			
		||||
        fixed_mul(vm->frames[vm->fp].registers[src1].f,
 | 
			
		||||
                  vm->frames[vm->fp].registers[src2].f);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_DIV_REAL: {
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].f =
 | 
			
		||||
        fixed_div(vm->frames[vm->fp].registers[src1].f,
 | 
			
		||||
                  vm->frames[vm->fp].registers[src2].f);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_REAL_TO_INT: {
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].i =
 | 
			
		||||
        (int32_t)(vm->frames[vm->fp].registers[src1].f);
 | 
			
		||||
        fixed_to_int(vm->frames[vm->fp].registers[src1].f);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_INT_TO_REAL: {
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].f =
 | 
			
		||||
        (float)(vm->frames[vm->fp].registers[src1].i);
 | 
			
		||||
        int_to_fixed(vm->frames[vm->fp].registers[src1].i);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_REAL_TO_UINT: {
 | 
			
		||||
    fixed_t f = vm->frames[vm->fp].registers[src1].f;
 | 
			
		||||
    int32_t i = fixed_to_int(f);
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].u =
 | 
			
		||||
        (uint32_t)(vm->frames[vm->fp].registers[src1].f);
 | 
			
		||||
        (uint32_t)i;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_UINT_TO_REAL: {
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].f =
 | 
			
		||||
        (float)(vm->frames[vm->fp].registers[src1].u);
 | 
			
		||||
        int_to_fixed(vm->frames[vm->fp].registers[src1].u);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_REG_SWAP: {
 | 
			
		||||
| 
						 | 
				
			
			@ -420,38 +559,48 @@ bool step_vm(VM *vm) {
 | 
			
		|||
    COMPARE_AND_JUMP(int32_t, i, ==);
 | 
			
		||||
  }
 | 
			
		||||
  case OP_JGT_REAL: {
 | 
			
		||||
    COMPARE_AND_JUMP(float, u, >);
 | 
			
		||||
    fixed_t value = vm->frames[vm->fp].registers[src1].f;
 | 
			
		||||
    fixed_t value2 = vm->frames[vm->fp].registers[src2].f;
 | 
			
		||||
    vm->pc =
 | 
			
		||||
        fixed_gt(value, value2) ? vm->frames[vm->fp].registers[dest].u : vm->pc;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_JLT_REAL: {
 | 
			
		||||
    COMPARE_AND_JUMP(float, u, <);
 | 
			
		||||
    fixed_t value = vm->frames[vm->fp].registers[src1].f;
 | 
			
		||||
    fixed_t value2 = vm->frames[vm->fp].registers[src2].f;
 | 
			
		||||
    vm->pc =
 | 
			
		||||
        fixed_lt(value, value2) ? vm->frames[vm->fp].registers[dest].u : vm->pc;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_JGE_REAL: {
 | 
			
		||||
    COMPARE_AND_JUMP(float, u, >=);
 | 
			
		||||
    fixed_t value = vm->frames[vm->fp].registers[src1].f;
 | 
			
		||||
    fixed_t value2 = vm->frames[vm->fp].registers[src2].f;
 | 
			
		||||
    vm->pc =
 | 
			
		||||
        fixed_ge(value, value2) ? vm->frames[vm->fp].registers[dest].u : vm->pc;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_JLE_REAL: {
 | 
			
		||||
    COMPARE_AND_JUMP(float, u, <=);
 | 
			
		||||
    fixed_t value = vm->frames[vm->fp].registers[src1].f;
 | 
			
		||||
    fixed_t value2 = vm->frames[vm->fp].registers[src2].f;
 | 
			
		||||
    vm->pc =
 | 
			
		||||
        fixed_le(value, value2) ? vm->frames[vm->fp].registers[dest].u : vm->pc;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_INT_TO_STRING: {
 | 
			
		||||
    int32_t a = (int32_t)vm->frames[vm->fp].registers[src1].i; /* get value */
 | 
			
		||||
    char buffer[32];
 | 
			
		||||
    int len = sprintf(buffer, "%d", a);
 | 
			
		||||
    uint32_t ptr = str_alloc(vm, buffer, len); /* copy buffer to dest */
 | 
			
		||||
    int32_t a = vm->frames[vm->fp].registers[src1].i; 
 | 
			
		||||
    uint32_t ptr = int_to_string(vm, a);
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].u = ptr;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_UINT_TO_STRING: {
 | 
			
		||||
    uint32_t a = (uint32_t)vm->frames[vm->fp].registers[src1].u; /* get value */
 | 
			
		||||
    char buffer[32];
 | 
			
		||||
    int len = sprintf(buffer, "%d", a);
 | 
			
		||||
    uint32_t ptr = str_alloc(vm, buffer, len); /* copy buffer to dest */
 | 
			
		||||
    uint32_t a = vm->frames[vm->fp].registers[src1].u;
 | 
			
		||||
    uint32_t ptr = nat_to_string(vm, a);
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].u = ptr;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_REAL_TO_STRING: {
 | 
			
		||||
    float a = (float)vm->frames[vm->fp].registers[src1].f; /* get value */
 | 
			
		||||
    char buffer[32];
 | 
			
		||||
    int len = sprintf(buffer, "%f", a);
 | 
			
		||||
    uint32_t ptr = str_alloc(vm, buffer, len); /* copy buffer to dest */
 | 
			
		||||
    fixed_t a = vm->frames[vm->fp].registers[src1].f; 
 | 
			
		||||
    uint32_t ptr = real_to_string(vm, a);
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].u = ptr;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -484,7 +633,7 @@ bool step_vm(VM *vm) {
 | 
			
		|||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_DBG_PRINT_STRING: {
 | 
			
		||||
    uint32_t ptr = (uint32_t)vm->frames[vm->fp].registers[src1].u;
 | 
			
		||||
    uint32_t ptr = vm->frames[vm->fp].registers[src1].u;
 | 
			
		||||
    uint32_t length = vm->memory[ptr].u;
 | 
			
		||||
    uint32_t str_src = ptr + 1;
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
| 
						 | 
				
			
			@ -498,8 +647,8 @@ bool step_vm(VM *vm) {
 | 
			
		|||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_CMP_STRING: {
 | 
			
		||||
    uint32_t addr1 = (uint32_t)vm->frames[vm->fp].registers[src1].u;
 | 
			
		||||
    uint32_t addr2 = (uint32_t)vm->frames[vm->fp].registers[src2].u;
 | 
			
		||||
    uint32_t addr1 = vm->frames[vm->fp].registers[src1].u;
 | 
			
		||||
    uint32_t addr2 = vm->frames[vm->fp].registers[src2].u;
 | 
			
		||||
    uint32_t length1 = vm->memory[addr1 - 1].u;
 | 
			
		||||
    uint32_t length2 = vm->memory[addr2 - 1].u;
 | 
			
		||||
    uint32_t equal =
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								src/vm.h
								
								
								
								
							
							
						
						
									
										3
									
								
								src/vm.h
								
								
								
								
							| 
						 | 
				
			
			@ -6,7 +6,8 @@
 | 
			
		|||
VM* init_vm();
 | 
			
		||||
bool step_vm(VM *vm);
 | 
			
		||||
uint32_t str_alloc(VM *vm, const char *str, uint32_t length);
 | 
			
		||||
uint32_t real_alloc(VM *vm, float v);
 | 
			
		||||
uint32_t float_as_real_alloc(VM *vm, float v);
 | 
			
		||||
uint32_t real_alloc(VM *vm, fixed_t v);
 | 
			
		||||
uint32_t nat_alloc(VM *vm, uint32_t v);
 | 
			
		||||
uint32_t int_alloc(VM *vm, int32_t v);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue