split up code and memory
This commit is contained in:
		
							parent
							
								
									035397209d
								
							
						
					
					
						commit
						5184b60136
					
				| 
						 | 
				
			
			@ -10,13 +10,11 @@ int main(int argc, char **argv) {
 | 
			
		|||
  vm.stack_size = STACK_SIZE;
 | 
			
		||||
  vm.memory_size = MEMORY_SIZE;
 | 
			
		||||
 | 
			
		||||
  uint32_t end = 0;
 | 
			
		||||
 | 
			
		||||
  /* test_add_compile(vm.memory); */
 | 
			
		||||
  /* test_add_function_compile(vm.memory); */
 | 
			
		||||
  /* end = test_loop_compile(vm.memory); */
 | 
			
		||||
  end = test_hello_world_compile(vm.memory);
 | 
			
		||||
  /* test_recursive_function_compile(vm.memory); */
 | 
			
		||||
  /* test_add_compile(&vm); */
 | 
			
		||||
  /* test_add_function_compile(&vm); */
 | 
			
		||||
  /* test_loop_compile(&vm); */
 | 
			
		||||
  test_hello_world_compile(&vm);
 | 
			
		||||
  /* test_recursive_function_compile(&vm); */
 | 
			
		||||
 | 
			
		||||
  uint32_t buffer_size = 640 * 480 * sizeof(uint32_t);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -24,8 +22,8 @@ int main(int argc, char **argv) {
 | 
			
		|||
  screen.type = SCREEN;
 | 
			
		||||
  screen.s = (Screen){.width = (uint8_t)480,
 | 
			
		||||
                      .height = (uint8_t)640,
 | 
			
		||||
                      .allocated = {end, buffer_size},
 | 
			
		||||
                      .buffer = &vm.memory[end]};
 | 
			
		||||
                      .allocated = {vm.mp, buffer_size},
 | 
			
		||||
                      .buffer = &vm.memory[vm.mp]};
 | 
			
		||||
  vm.devices[vm.dp++] = screen;
 | 
			
		||||
  vm.mp += buffer_size;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,15 +55,17 @@ typedef union device_u {
 | 
			
		|||
} Device;
 | 
			
		||||
 | 
			
		||||
#define MEMORY_SIZE 65536
 | 
			
		||||
#define CODE_SIZE 8192
 | 
			
		||||
#define FRAMES_SIZE 128 
 | 
			
		||||
#define STACK_SIZE 256
 | 
			
		||||
#define DEVICES_SIZE 8
 | 
			
		||||
typedef struct vm_s {
 | 
			
		||||
  uint32_t pc; /* Program counter */
 | 
			
		||||
  uint32_t fp; /* Frame pointer (current frame) */
 | 
			
		||||
  uint32_t pc; /* program counter */
 | 
			
		||||
  uint32_t cp; /* code pointer (last allocated opcode) */
 | 
			
		||||
  uint32_t fp; /* frame pointer (current frame) */
 | 
			
		||||
  uint32_t sp; /* stack pointer (top of stack) */
 | 
			
		||||
  uint32_t rp; /* return stack pointer (top of stack) */
 | 
			
		||||
  uint32_t mp; /* Memory pointer (last allocated value) */
 | 
			
		||||
  uint32_t mp; /* memory pointer (last allocated value) */
 | 
			
		||||
  uint32_t dp; /* device pointer (last allocated device) */
 | 
			
		||||
  uint8_t devices_size;
 | 
			
		||||
  Device devices[DEVICES_SIZE];
 | 
			
		||||
| 
						 | 
				
			
			@ -73,8 +75,10 @@ typedef struct vm_s {
 | 
			
		|||
  Value stack[STACK_SIZE]; /* main stack */
 | 
			
		||||
  uint32_t return_stack_size;
 | 
			
		||||
  Value return_stack[STACK_SIZE]; /* return stack (for recursion) */
 | 
			
		||||
  uint32_t code_size;
 | 
			
		||||
  Value code[CODE_SIZE]; /* code block */
 | 
			
		||||
  uint32_t memory_size;
 | 
			
		||||
  Value memory[MEMORY_SIZE]; /* memory array */
 | 
			
		||||
  Value memory[MEMORY_SIZE]; /* memory block */
 | 
			
		||||
} VM;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										225
									
								
								src/test.c
								
								
								
								
							
							
						
						
									
										225
									
								
								src/test.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,130 +1,125 @@
 | 
			
		|||
#include "test.h"
 | 
			
		||||
 | 
			
		||||
uint32_t test_hello_world_compile(Value *memory) {
 | 
			
		||||
  uint32_t i = 0;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADU, 1, 0, 0);
 | 
			
		||||
  memory[i++].u = 4;
 | 
			
		||||
  memory[i++].u = OP(OP_PRINT_STRING, 0, 1, 0); /* print("nuqneH 'u'?"); */
 | 
			
		||||
  memory[i++].u = OP(OP_HALT, 0, 0, 0); /* explicit halt */
 | 
			
		||||
  memory[i++].u = 12;
 | 
			
		||||
  memory[i].c[0] = 'n';
 | 
			
		||||
  memory[i].c[1] = 'u';
 | 
			
		||||
  memory[i].c[2] = 'q';
 | 
			
		||||
  memory[i++].c[3] = 'n';
 | 
			
		||||
  memory[i].c[0] = 'e';
 | 
			
		||||
  memory[i].c[1] = 'H';
 | 
			
		||||
  memory[i].c[2] = ' ';
 | 
			
		||||
  memory[i++].c[3] = '\'';
 | 
			
		||||
  memory[i].c[0] = 'u';
 | 
			
		||||
  memory[i].c[1] = '\'';
 | 
			
		||||
  memory[i].c[2] = '?';
 | 
			
		||||
  memory[i++].c[3] = '\0';
 | 
			
		||||
  return i;
 | 
			
		||||
bool test_hello_world_compile(VM *vm) {
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADU, 1, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = 0;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 1, 0); /* print("nuqneH 'u'?"); */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_HALT, 0, 0, 0); /* explicit halt */
 | 
			
		||||
  vm->memory[vm->mp++].u = 12;
 | 
			
		||||
  vm->memory[vm->mp].c[0] = 'n';
 | 
			
		||||
  vm->memory[vm->mp].c[1] = 'u';
 | 
			
		||||
  vm->memory[vm->mp].c[2] = 'q';
 | 
			
		||||
  vm->memory[vm->mp++].c[3] = 'n';
 | 
			
		||||
  vm->memory[vm->mp].c[0] = 'e';
 | 
			
		||||
  vm->memory[vm->mp].c[1] = 'H';
 | 
			
		||||
  vm->memory[vm->mp].c[2] = ' ';
 | 
			
		||||
  vm->memory[vm->mp++].c[3] = '\'';
 | 
			
		||||
  vm->memory[vm->mp].c[0] = 'u';
 | 
			
		||||
  vm->memory[vm->mp].c[1] = '\'';
 | 
			
		||||
  vm->memory[vm->mp].c[2] = '?';
 | 
			
		||||
  vm->memory[vm->mp++].c[3] = '\0';
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t test_add_compile(Value *memory) {
 | 
			
		||||
  uint32_t i = 0;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADU, 0, 0, 0);
 | 
			
		||||
  memory[i++].u = 1;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADU, 1, 0, 0);
 | 
			
		||||
  memory[i++].u = 2;
 | 
			
		||||
  memory[i++].u = OP(OP_ADD_UINT, 2, 1, 0); /* let sum = 1 + 2; */
 | 
			
		||||
  memory[i++].u = OP(OP_UINT_TO_STRING, 3, 2, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(sum.toS()); */
 | 
			
		||||
  memory[i++].u = OP(OP_HALT, 0, 0, 0); /* explicit halt */
 | 
			
		||||
  return i;
 | 
			
		||||
bool test_add_compile(VM *vm) {
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADU, 0, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = 1;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADU, 1, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = 2;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_ADD_UINT, 2, 1, 0); /* let sum = 1 + 2; */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_UINT_TO_STRING, 3, 2, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(sum.toS()); */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_HALT, 0, 0, 0); /* explicit halt */
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t test_loop_compile(Value *memory) {
 | 
			
		||||
  uint32_t i = 0;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADF, 0, 0, 0); /* let a = 5.0 */
 | 
			
		||||
  memory[i++].f = 5.0f;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADI, 1, 0, 0); /* do (i = 5, 0, -1) { */
 | 
			
		||||
  memory[i++].i = 5000;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADI, 2, 0, 0); /* loop check value */
 | 
			
		||||
  memory[i++].i = 0;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADI, 3, 0, 0); /* loop incriment value */
 | 
			
		||||
  memory[i++].i = -1;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADU, 4, 0, 0); /* loop start */
 | 
			
		||||
  uint32_t jmp = i + 1;
 | 
			
		||||
  memory[i++].u = jmp;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADF, 5, 0, 0);
 | 
			
		||||
  memory[i++].f = 5.0f;
 | 
			
		||||
  memory[i++].u = OP(OP_ADD_REAL, 0, 0, 5); /* a += 5.0; */
 | 
			
		||||
  memory[i++].u = OP(OP_ADD_INT, 1, 1, 3);  /* (implied by loop) i = i + (-1) */
 | 
			
		||||
  memory[i++].u = OP(OP_JGE_INT, 4, 1, 2);  /* } */
 | 
			
		||||
  memory[i++].u = OP(OP_REAL_TO_UINT, 1, 0, 0); /* let b = a as nat; */
 | 
			
		||||
  memory[i++].u = OP(OP_READ_STRING, 2, 0, 0);  /* let user_string = gets(); */
 | 
			
		||||
  memory[i++].u = OP(OP_UINT_TO_STRING, 3, 1, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(a.toS()); */
 | 
			
		||||
  memory[i++].u = OP(OP_REAL_TO_STRING, 3, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(b.toS()); */
 | 
			
		||||
  memory[i++].u = OP(OP_PRINT_STRING, 0, 2, 0); /* print(user_string); */
 | 
			
		||||
  memory[i++].u = OP(OP_HALT, 0, 0, 0);         /* program done */
 | 
			
		||||
  return i;
 | 
			
		||||
bool test_loop_compile(VM *vm) {
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADF, 0, 0, 0); /* let a = 5.0 */
 | 
			
		||||
  vm->code[vm->cp++].f = 5.0f;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADI, 1, 0, 0); /* do (i = 50000, 0, -1) { */
 | 
			
		||||
  vm->code[vm->cp++].i = 50000;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADI, 2, 0, 0); /* loop check value */
 | 
			
		||||
  vm->code[vm->cp++].i = 0;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADI, 3, 0, 0); /* loop incriment value */
 | 
			
		||||
  vm->code[vm->cp++].i = -1;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADU, 4, 0, 0); /* loop start */
 | 
			
		||||
  uint32_t jmp = vm->cp + 1;
 | 
			
		||||
  vm->code[vm->cp++].u = jmp;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADF, 5, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].f = 5.0f;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_ADD_REAL, 0, 0, 5); /* a += 5.0; */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_ADD_INT, 1, 1, 3);  /* (implied by loop) i = i + (-1) */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_JGE_INT, 4, 1, 2);  /* } */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_REAL_TO_UINT, 1, 0, 0); /* let b = a as nat; */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_READ_STRING, 2, 0, 0);  /* let user_string = gets(); */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_UINT_TO_STRING, 3, 1, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(a.toS()); */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_REAL_TO_STRING, 3, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 3, 0); /* print(b.toS()); */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 2, 0); /* print(user_string); */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_HALT, 0, 0, 0);         /* program done */
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t test_add_function_compile(Value *memory) {
 | 
			
		||||
  uint32_t i = 0;
 | 
			
		||||
bool test_add_function_compile(VM *vm) {
 | 
			
		||||
  /* fn main() */
 | 
			
		||||
  memory[i++].u = OP(OP_LOADI, 0, 0, 0); /* 1 */
 | 
			
		||||
  memory[i++].i = 1;
 | 
			
		||||
  memory[i++].u = OP(OP_PUSHI, 0, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_LOADI, 0, 0, 0); /* 1 */
 | 
			
		||||
  memory[i++].i = 1;
 | 
			
		||||
  memory[i++].u = OP(OP_PUSHI, 0, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_CALL, 0, 0, 0); /* ); */
 | 
			
		||||
  memory[i++].u = 12;
 | 
			
		||||
  memory[i++].u = OP(OP_POPI, 0, 0, 0); /* get return value */
 | 
			
		||||
  memory[i++].u = OP(OP_INT_TO_STRING, 1, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_PRINT_STRING, 0, 1, 0); /* print(sum.toS()); */
 | 
			
		||||
  memory[i++].u = OP(OP_HALT, 0, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADI, 0, 0, 0); /* 1 */
 | 
			
		||||
  vm->code[vm->cp++].i = 1;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PUSHI, 0, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADI, 0, 0, 0); /* 1 */
 | 
			
		||||
  vm->code[vm->cp++].i = 1;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PUSHI, 0, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_CALL, 0, 0, 0); /* ); */
 | 
			
		||||
  vm->code[vm->cp++].u = 12;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_POPI, 0, 0, 0); /* get return value */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_INT_TO_STRING, 1, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 1, 0); /* print(sum.toS()); */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_HALT, 0, 0, 0);
 | 
			
		||||
  /* fn add() */
 | 
			
		||||
  memory[i++].u = OP(OP_POPI, 0, 0, 0); /* a int */
 | 
			
		||||
  memory[i++].u = OP(OP_POPI, 1, 0, 0); /* b int */
 | 
			
		||||
  memory[i++].u = OP(OP_ADD_INT, 2, 1, 0); /* a + b */
 | 
			
		||||
  memory[i++].u = OP(OP_PUSHI, 2, 0, 0); /* push on stack */
 | 
			
		||||
  memory[i++].u = OP(OP_RETURN, 0, 0, 0);
 | 
			
		||||
  return i;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_POPI, 0, 0, 0); /* a int */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_POPI, 1, 0, 0); /* b int */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_ADD_INT, 2, 1, 0); /* a + b */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PUSHI, 2, 0, 0); /* push on stack */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_RETURN, 0, 0, 0);
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t test_recursive_function_compile(Value *memory) {
 | 
			
		||||
  uint32_t i = 0;
 | 
			
		||||
bool test_recursive_function_compile(VM *vm) {
 | 
			
		||||
  /* fn main() */
 | 
			
		||||
  memory[i++].u = OP(OP_LOADI, 0, 0, 0); /* 35 */
 | 
			
		||||
  memory[i++].i = 35;
 | 
			
		||||
  memory[i++].u = OP(OP_PUSHI, 0, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_CALL, 0, 0, 0); /* ); */
 | 
			
		||||
  memory[i++].u = 9;
 | 
			
		||||
  memory[i++].u = OP(OP_POPI, 0, 0, 0); /* get return value */
 | 
			
		||||
  memory[i++].u = OP(OP_INT_TO_STRING, 1, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_PRINT_STRING, 0, 1, 0); /* print(fib(35).toS()); */
 | 
			
		||||
  memory[i++].u = OP(OP_HALT, 0, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADI, 0, 0, 0); /* 35 */
 | 
			
		||||
  vm->code[vm->cp++].i = 35;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PUSHI, 0, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_CALL, 0, 0, 0); /* ); */
 | 
			
		||||
  vm->code[vm->cp++].u = 9;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_POPI, 0, 0, 0); /* get return value */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_INT_TO_STRING, 1, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PRINT_STRING, 0, 1, 0); /* print(fib(35).toS()); */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_HALT, 0, 0, 0);
 | 
			
		||||
  /* fn fib() */
 | 
			
		||||
  memory[i++].u = OP(OP_POPI, 0, 0, 0); /* n int */
 | 
			
		||||
  memory[i++].u = OP(OP_LOADI, 1, 0, 0); /* 2 */
 | 
			
		||||
  memory[i++].i = 2;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADI, 2, 0, 0); /* &fib */
 | 
			
		||||
  memory[i++].i = 32;
 | 
			
		||||
  memory[i++].u = OP(OP_JLT_INT, 2, 0, 1); 
 | 
			
		||||
  memory[i++].u = OP(OP_LOADI, 3, 0, 0); /* 2 */
 | 
			
		||||
  memory[i++].i = 2;
 | 
			
		||||
  memory[i++].u = OP(OP_SUB_INT, 4, 0, 3);
 | 
			
		||||
  memory[i++].u = OP(OP_PUSHI, 4, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_CALL, 0, 0, 0); /* fib(n - 2) */
 | 
			
		||||
  memory[i++].u = 9;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADI, 3, 0, 0); /* 1 */
 | 
			
		||||
  memory[i++].i = 1;
 | 
			
		||||
  memory[i++].u = OP(OP_SUB_INT, 4, 0, 3);
 | 
			
		||||
  memory[i++].u = OP(OP_PUSHI, 4, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_CALL, 0, 0, 0); /* fib(n - 1) */
 | 
			
		||||
  memory[i++].u = 9;
 | 
			
		||||
  memory[i++].u = OP(OP_POPI, 4, 0, 0); 
 | 
			
		||||
  memory[i++].u = OP(OP_POPI, 5, 0, 0); 
 | 
			
		||||
  memory[i++].u = OP(OP_ADD_INT, 6, 5, 4);
 | 
			
		||||
  memory[i++].u = OP(OP_PUSHI, 6, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_RETURN, 0, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_PUSHI, 0, 0, 0); 
 | 
			
		||||
  memory[i++].u = OP(OP_RETURN, 0, 0, 0);
 | 
			
		||||
  return i;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_POPI, 0, 0, 0); /* n int */
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADI, 1, 0, 0); /* 2 */
 | 
			
		||||
  vm->code[vm->cp++].i = 2;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADI, 2, 0, 0); /* &fib */
 | 
			
		||||
  vm->code[vm->cp++].i = 32;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_JLT_INT, 2, 0, 1); 
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADI, 3, 0, 0); /* 2 */
 | 
			
		||||
  vm->code[vm->cp++].i = 2;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_SUB_INT, 4, 0, 3);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PUSHI, 4, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_CALL, 0, 0, 0); /* fib(n - 2) */
 | 
			
		||||
  vm->code[vm->cp++].u = 9;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_LOADI, 3, 0, 0); /* 1 */
 | 
			
		||||
  vm->code[vm->cp++].i = 1;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_SUB_INT, 4, 0, 3);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PUSHI, 4, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_CALL, 0, 0, 0); /* fib(n - 1) */
 | 
			
		||||
  vm->code[vm->cp++].u = 9;
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_POPI, 4, 0, 0); 
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_POPI, 5, 0, 0); 
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_ADD_INT, 6, 5, 4);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PUSHI, 6, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_RETURN, 0, 0, 0);
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_PUSHI, 0, 0, 0); 
 | 
			
		||||
  vm->code[vm->cp++].u = OP(OP_RETURN, 0, 0, 0);
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								src/test.h
								
								
								
								
							
							
						
						
									
										10
									
								
								src/test.h
								
								
								
								
							| 
						 | 
				
			
			@ -3,10 +3,10 @@
 | 
			
		|||
 | 
			
		||||
#include "opcodes.h"
 | 
			
		||||
 | 
			
		||||
uint32_t test_hello_world_compile (Value *memory);
 | 
			
		||||
uint32_t test_add_compile (Value *memory);
 | 
			
		||||
uint32_t test_loop_compile (Value *memory);
 | 
			
		||||
uint32_t test_add_function_compile(Value *memory);
 | 
			
		||||
uint32_t test_recursive_function_compile(Value *memory);
 | 
			
		||||
bool test_hello_world_compile (VM *vm);
 | 
			
		||||
bool test_add_compile (VM *vm);
 | 
			
		||||
bool test_loop_compile (VM *vm);
 | 
			
		||||
bool test_add_function_compile(VM *vm);
 | 
			
		||||
bool test_recursive_function_compile(VM *vm);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								src/vm.c
								
								
								
								
							
							
						
						
									
										16
									
								
								src/vm.c
								
								
								
								
							| 
						 | 
				
			
			@ -41,7 +41,7 @@ void mem_strcpy(Value *memory, const char *str, uint32_t length,
 | 
			
		|||
 */
 | 
			
		||||
bool step_vm(VM *vm) {
 | 
			
		||||
  /* Get current instruction & Advance to next instruction */
 | 
			
		||||
  uint32_t instruction = vm->memory[vm->pc++].u;
 | 
			
		||||
  uint32_t instruction = vm->code[vm->pc++].u;
 | 
			
		||||
 | 
			
		||||
  uint8_t opcode = (instruction >> 24) & 0xFF;
 | 
			
		||||
  uint8_t dest = (instruction >> 16) & 0xFF;
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ bool step_vm(VM *vm) {
 | 
			
		|||
  case OP_HALT:
 | 
			
		||||
    return false;
 | 
			
		||||
  case OP_CALL:; /* whats up with this semicolon? ANSI C does not allow you to create a variabel after a case, so this noop is here */
 | 
			
		||||
    uint32_t jmp = vm->memory[vm->pc++].u; /* location of function in memory */
 | 
			
		||||
    uint32_t jmp = vm->code[vm->pc++].u; /* location of function in code */
 | 
			
		||||
    vm->return_stack[vm->rp++].u = vm->pc; /* set return address */
 | 
			
		||||
    vm->fp++; /* increment to the next free frame */
 | 
			
		||||
    vm->frames[vm->fp].allocated.start = vm->mp; /* set start of new memory block */
 | 
			
		||||
| 
						 | 
				
			
			@ -63,22 +63,22 @@ bool step_vm(VM *vm) {
 | 
			
		|||
    vm->mp = vm->frames[vm->fp--].allocated.start; /* reset memory pointer to start of old slice, pop the frame */
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_LOADI:
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].i = vm->memory[vm->pc++].i;
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].i = vm->code[vm->pc++].i;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_LOADU:
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].u = vm->memory[vm->pc++].u;
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].u = vm->code[vm->pc++].u;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_LOADF:
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].f = vm->memory[vm->pc++].f;
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].f = vm->code[vm->pc++].f;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_STOREI:
 | 
			
		||||
    vm->memory[vm->pc++].i = vm->frames[vm->fp].registers[dest].i;
 | 
			
		||||
    vm->code[vm->pc++].i = vm->frames[vm->fp].registers[dest].i;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_STOREU:
 | 
			
		||||
    vm->memory[vm->pc++].u = vm->frames[vm->fp].registers[dest].u;
 | 
			
		||||
    vm->code[vm->pc++].u = vm->frames[vm->fp].registers[dest].u;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_STOREF:
 | 
			
		||||
    vm->memory[vm->pc++].f = vm->frames[vm->fp].registers[dest].f;
 | 
			
		||||
    vm->code[vm->pc++].f = vm->frames[vm->fp].registers[dest].f;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_PUSHI:
 | 
			
		||||
    vm->stack[++vm->sp].i = vm->frames[vm->fp].registers[dest].i;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
local a = 5.0
 | 
			
		||||
for i = 5, 0, -1 do
 | 
			
		||||
for i = 50000, 0, -1 do
 | 
			
		||||
  a = a + 5.0
 | 
			
		||||
end
 | 
			
		||||
local b = math.floor(a)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
my $a = 5.0;
 | 
			
		||||
for (my $i = 5; $i >= 0; $i--) {
 | 
			
		||||
for (my $i = 50000; $i >= 0; $i--) {
 | 
			
		||||
  $a += 5.0;
 | 
			
		||||
}
 | 
			
		||||
my $b = int($a);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
a = 5.0
 | 
			
		||||
for i in range(5, -1, -1):
 | 
			
		||||
for i in range(50000, -1, -1):
 | 
			
		||||
  a += 5.0
 | 
			
		||||
b = int(a)
 | 
			
		||||
user_string = input("Enter a string: ")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
let a = 5.0;
 | 
			
		||||
do (let i = 5, 0, -1) {
 | 
			
		||||
do (let i = 50000, 0, -1) {
 | 
			
		||||
  a += 5.0;
 | 
			
		||||
}
 | 
			
		||||
let b = a as nat;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue