add function example
This commit is contained in:
		
							parent
							
								
									c63d149bdb
								
							
						
					
					
						commit
						7ec2f90d38
					
				| 
						 | 
				
			
			@ -44,19 +44,39 @@ uint32_t test_loop_compile(Value *memory) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
uint32_t test_add_function_compile(Value *memory) {
 | 
			
		||||
  uint32_t i = 0;
 | 
			
		||||
  memory[i++].u = OP(OP_POP_ARGS, 0, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_ADD_INT, 2, 1, 0);
 | 
			
		||||
  uint32_t i = 3;
 | 
			
		||||
  memory[i++].u = OP(OP_POPU, 0, 0, 0); /* return ptr */
 | 
			
		||||
  memory[i++].u = OP(OP_POPI, 1, 0, 0); /* a int */
 | 
			
		||||
  memory[i++].u = OP(OP_POPI, 2, 0, 0); /* b int */
 | 
			
		||||
  memory[i++].u = OP(OP_ADD_INT, 3, 2, 1); /* a + b */
 | 
			
		||||
  memory[i++].u = OP(OP_PUSHI, 3, 0, 0); /* return */
 | 
			
		||||
  memory[i++].u = OP(OP_RETURN, 0, 0, 0);
 | 
			
		||||
  uint32_t main = i;
 | 
			
		||||
  memory[0].u = OP(OP_LOADF, 0, 0, 0);
 | 
			
		||||
  memory[1].u = main;
 | 
			
		||||
  memory[2].u = OP(OP_JMP, 0, 0, 0); /* jump to '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);
 | 
			
		||||
  uint32_t add_fn_return = i + 6; /* after the call */
 | 
			
		||||
  memory[i++].u = OP(OP_LOADI, 0, 0, 0); /* return */
 | 
			
		||||
  memory[i++].u = add_fn_return;
 | 
			
		||||
  memory[i++].u = OP(OP_PUSHU, 0, 0, 0); 
 | 
			
		||||
  memory[i++].u = OP(OP_LOADU, 0, 0, 0); /* add fn ptr */
 | 
			
		||||
  memory[i++].u = 3;
 | 
			
		||||
  memory[i++].u = OP(OP_CALL, 0, 0, 0); /* ); */
 | 
			
		||||
  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);
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t test_recursive_function_compile(Value *memory) {
 | 
			
		||||
  uint32_t i = 0;
 | 
			
		||||
  memory[i++].u = OP(OP_POP_ARGS, 0, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_ADD_INT, 2, 1, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_RETURN, 0, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_HALT, 0, 0, 0);
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										24
									
								
								src/debug.c
								
								
								
								
							
							
						
						
									
										24
									
								
								src/debug.c
								
								
								
								
							| 
						 | 
				
			
			@ -23,6 +23,12 @@ void printOp(uint8_t op, uint8_t dest, uint8_t src1, uint8_t src2) {
 | 
			
		|||
  case OP_HALT:
 | 
			
		||||
    printf("[HALT] $%d, $%d, $%d\n", dest, src1, src2);
 | 
			
		||||
    break;
 | 
			
		||||
  case OP_CALL:
 | 
			
		||||
    printf("[CALL] $%d, $%d, $%d\n", dest, src1, src2);
 | 
			
		||||
    break;
 | 
			
		||||
  case OP_RETURN:
 | 
			
		||||
    printf("[RETURN] $%d, $%d, $%d\n", dest, src1, src2);
 | 
			
		||||
    break;
 | 
			
		||||
  case OP_LOADI:
 | 
			
		||||
    printf("[LOADI] $%d, $%d, $%d\n", dest, src1, src2);
 | 
			
		||||
    break;
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +47,24 @@ void printOp(uint8_t op, uint8_t dest, uint8_t src1, uint8_t src2) {
 | 
			
		|||
  case OP_STOREF:
 | 
			
		||||
    printf("[STOREF] $%d, $%d, $%d\n", dest, src1, src2);
 | 
			
		||||
    break;
 | 
			
		||||
  case OP_PUSHI:
 | 
			
		||||
    printf("[PUSHI] $%d, $%d, $%d\n", dest, src1, src2);
 | 
			
		||||
    break;
 | 
			
		||||
  case OP_PUSHU:
 | 
			
		||||
    printf("[PUSHU] $%d, $%d, $%d\n", dest, src1, src2);
 | 
			
		||||
    break;
 | 
			
		||||
  case OP_PUSHF:
 | 
			
		||||
    printf("[PUSHF] $%d, $%d, $%d\n", dest, src1, src2);
 | 
			
		||||
    break;
 | 
			
		||||
  case OP_POPI:
 | 
			
		||||
    printf("[POPI] $%d, $%d, $%d\n", dest, src1, src2);
 | 
			
		||||
    break;
 | 
			
		||||
  case OP_POPU:
 | 
			
		||||
    printf("[POPU] $%d, $%d, $%d\n", dest, src1, src2);
 | 
			
		||||
    break;
 | 
			
		||||
  case OP_POPF:
 | 
			
		||||
    printf("[POPF] $%d, $%d, $%d\n", dest, src1, src2);
 | 
			
		||||
    break;
 | 
			
		||||
  case OP_ADD_INT:
 | 
			
		||||
    printf("[ADD_INT] $%d, $%d, $%d\n", dest, src1, src2);
 | 
			
		||||
    break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,7 +54,7 @@ int main(int argc, char **argv) {
 | 
			
		|||
  vm.frames_size = FRAMES_SIZE;
 | 
			
		||||
  vm.stack_size = STACK_SIZE;
 | 
			
		||||
  vm.memory_size = MEMORY_SIZE;
 | 
			
		||||
  vm.frames[vm.fp].allocated.end = test_loop_compile(vm.memory);
 | 
			
		||||
  vm.frames[vm.fp].allocated.end = test_add_function_compile(vm.memory);
 | 
			
		||||
 | 
			
		||||
#ifdef __EMSCRIPTEN__
 | 
			
		||||
  emscripten_set_main_loop(mainloop, 0, 1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ typedef struct {
 | 
			
		|||
 | 
			
		||||
#define MAX_REGS 256
 | 
			
		||||
typedef struct {
 | 
			
		||||
  Value registers[MAX_REGS]; /* R0-R[MAX_REGS-1] */
 | 
			
		||||
  Value registers[MAX_REGS]; /* R0-R255 */
 | 
			
		||||
  uint32_t rp;               /* register pointer (last unused) */
 | 
			
		||||
  Slice allocated;           /* start and end of global allocated block */
 | 
			
		||||
} Frame;
 | 
			
		||||
| 
						 | 
				
			
			@ -31,11 +31,11 @@ typedef struct {
 | 
			
		|||
  uint32_t rp; /* Return stack pointer (top of stack) */
 | 
			
		||||
  uint32_t mp; /* Memory pointer (last allocated value) */
 | 
			
		||||
  uint32_t frames_size;
 | 
			
		||||
  Frame frames[FRAMES_SIZE];
 | 
			
		||||
  Frame frames[FRAMES_SIZE]; /* function call frames */
 | 
			
		||||
  uint32_t stack_size;
 | 
			
		||||
  Value stack[STACK_SIZE];
 | 
			
		||||
  Value stack[STACK_SIZE]; /* main stack */
 | 
			
		||||
  uint32_t memory_size;
 | 
			
		||||
  Value memory[MEMORY_SIZE]; /* Memory array */
 | 
			
		||||
  Value memory[MEMORY_SIZE]; /* memory array */
 | 
			
		||||
} VM;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								src/vm.c
								
								
								
								
							
							
						
						
									
										27
									
								
								src/vm.c
								
								
								
								
							| 
						 | 
				
			
			@ -54,7 +54,6 @@ bool step_vm(VM *vm) {
 | 
			
		|||
  case OP_HALT:
 | 
			
		||||
    return false;
 | 
			
		||||
  case OP_CALL:
 | 
			
		||||
    vm->stack[++vm->rp].u = vm->pc; /* push return address */
 | 
			
		||||
    vm->pc = vm->frames[vm->fp]
 | 
			
		||||
                 .registers[dest]
 | 
			
		||||
                 .u; /* set pc to location of function in memory */
 | 
			
		||||
| 
						 | 
				
			
			@ -85,13 +84,31 @@ bool step_vm(VM *vm) {
 | 
			
		|||
    vm->frames[vm->fp].registers[dest].f = vm->memory[vm->pc++].f;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_STOREI:
 | 
			
		||||
    vm->memory[vm->pc++].i = vm->frames[vm->fp].registers[src1].i;
 | 
			
		||||
    vm->memory[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[src1].u;
 | 
			
		||||
    vm->memory[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[src1].f;
 | 
			
		||||
    vm->memory[vm->pc++].f = vm->frames[vm->fp].registers[dest].f;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_PUSHI:
 | 
			
		||||
    vm->stack[++vm->rp].i = vm->frames[vm->fp].registers[dest].i;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_PUSHU:
 | 
			
		||||
    vm->stack[++vm->rp].u = vm->frames[vm->fp].registers[dest].u;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_PUSHF:
 | 
			
		||||
    vm->stack[++vm->rp].f = vm->frames[vm->fp].registers[dest].f;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_POPI:
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].i = vm->stack[vm->rp--].i;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_POPU:
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].u = vm->stack[vm->rp--].u;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_POPF:
 | 
			
		||||
    vm->frames[vm->fp].registers[dest].f = vm->stack[vm->rp--].f;
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_ADD_INT:
 | 
			
		||||
    MATH_OP(i, +);
 | 
			
		||||
| 
						 | 
				
			
			@ -137,7 +154,7 @@ bool step_vm(VM *vm) {
 | 
			
		|||
    vm->frames[vm->fp].registers[dest] = vm->frames[vm->fp].registers[src1];
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_JMP:
 | 
			
		||||
    vm->pc = vm->frames[vm->fp].registers[src1].u; /* Jump to address */
 | 
			
		||||
    vm->pc = vm->frames[vm->fp].registers[dest].u; /* Jump to address */
 | 
			
		||||
    return true;
 | 
			
		||||
  case OP_JEQ_UINT: {
 | 
			
		||||
    COMPARE_AND_JUMP(uint32_t, u, ==);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue