convert to register based instead of mem2mem
This commit is contained in:
		
							parent
							
								
									16117b9a3a
								
							
						
					
					
						commit
						d27d4259aa
					
				| 
						 | 
				
			
			@ -5,71 +5,51 @@
 | 
			
		|||
 | 
			
		||||
Code *demo_add_compile() {
 | 
			
		||||
  Code *code = (Code *)malloc(sizeof(Code));
 | 
			
		||||
  Word memory[MEMORY_SIZE] = {0}; /* Memory array */
 | 
			
		||||
  Value memory[MEMORY_SIZE] = {0}; /* Memory array */
 | 
			
		||||
  code->memory = memory;
 | 
			
		||||
  code->size = MEMORY_SIZE;
 | 
			
		||||
  code->current.pc = 1;
 | 
			
		||||
 | 
			
		||||
  int i = 1;
 | 
			
		||||
  uint32_t i = 1;
 | 
			
		||||
  memory[0].c[0] = 0;
 | 
			
		||||
  memory[0].c[1] = 'z';
 | 
			
		||||
  memory[0].c[2] = 'r';
 | 
			
		||||
  memory[0].c[3] = 'e';
 | 
			
		||||
  memory[i++].u = OP_ADD_REAL;
 | 
			
		||||
  memory[i++].u = 102;
 | 
			
		||||
  memory[i++].u = 103;
 | 
			
		||||
  memory[i++].u = 103;
 | 
			
		||||
  memory[i++].u = OP_SUB_UINT;
 | 
			
		||||
  memory[i++].u = 100;
 | 
			
		||||
  memory[i++].u = 101;
 | 
			
		||||
  memory[i++].u = 100;
 | 
			
		||||
  memory[i++].u = OP_JGT_UINT;
 | 
			
		||||
  memory[i++].u = 100;
 | 
			
		||||
  memory[i++].u = 99;
 | 
			
		||||
  memory[i++].u = 1;
 | 
			
		||||
  memory[i++].u = OP_REAL_TO_STRING;
 | 
			
		||||
  memory[i++].u = 103;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADU, 0, 0, 0);
 | 
			
		||||
  memory[i++].u = 0;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADU, 1, 0, 0);
 | 
			
		||||
  memory[i++].u = 5;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADU, 2, 0, 0);
 | 
			
		||||
  memory[i++].u = 1;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADF, 3, 0, 0);
 | 
			
		||||
  memory[i++].f = 5.0f;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADF, 4, 0, 0);
 | 
			
		||||
  memory[i++].f = 5.0f;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADU, 5, 0, 0);
 | 
			
		||||
  memory[i++].u = 200;
 | 
			
		||||
  memory[i++].u = OP_PRINT_STRING;
 | 
			
		||||
  memory[i++].u = 201;
 | 
			
		||||
  memory[i++].u = 1;
 | 
			
		||||
  memory[i++].u = 1;
 | 
			
		||||
  memory[i++].u = OP_REAL_TO_UINT;
 | 
			
		||||
  memory[i++].u = 103;
 | 
			
		||||
  memory[i++].u = 1;
 | 
			
		||||
  memory[i++].u = 103;
 | 
			
		||||
  memory[i++].u = OP_UINT_TO_STRING;
 | 
			
		||||
  memory[i++].u = 103;
 | 
			
		||||
  memory[i++].u = 1;
 | 
			
		||||
  memory[i++].u = 104;
 | 
			
		||||
  memory[i++].u = OP_PRINT_STRING;
 | 
			
		||||
  memory[i++].u = 105;
 | 
			
		||||
  memory[i++].u = 1;
 | 
			
		||||
  memory[i++].u = 1;
 | 
			
		||||
  memory[i++].u = OP_READ_STRING;
 | 
			
		||||
  memory[i++].u = 1;
 | 
			
		||||
  memory[i++].u = 1;
 | 
			
		||||
  memory[i++].u = 109;
 | 
			
		||||
  memory[i++].u = OP_PRINT_STRING;
 | 
			
		||||
  memory[i++].u = 110;
 | 
			
		||||
  memory[i++].u = 1;
 | 
			
		||||
  memory[i++].u = 1;
 | 
			
		||||
  memory[i++].u = OP_HALT;
 | 
			
		||||
  memory[i++].u = 0;
 | 
			
		||||
  memory[i++].u = 0;
 | 
			
		||||
  memory[i++].u = 0;
 | 
			
		||||
  memory[99].u = 0;
 | 
			
		||||
  memory[100].u = 5;
 | 
			
		||||
  memory[101].u = 1;
 | 
			
		||||
  memory[102].f = 5.0f;
 | 
			
		||||
  memory[103].f = 5.0f;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADU, 6, 0, 0);
 | 
			
		||||
  memory[i++].u = 250;
 | 
			
		||||
  memory[i++].u = OP(OP_LOADU, 7, 0, 0);
 | 
			
		||||
  memory[i++].u = 252;
 | 
			
		||||
  uint32_t jmp = i;
 | 
			
		||||
  memory[i++].u = OP(OP_ADD_REAL, 4, 4, 3);
 | 
			
		||||
  memory[i++].u = OP(OP_SUB_UINT, 1, 1, 2);
 | 
			
		||||
  memory[i++].u = OP(OP_JGT_UINT, jmp, 1, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_REAL_TO_STRING, 5, 4, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_PRINT_STRING, 0, 5, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_REAL_TO_UINT, 1, 4, 4);
 | 
			
		||||
  memory[i++].u = OP(OP_UINT_TO_STRING, 6, 1, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_PRINT_STRING, 0, 6, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_READ_STRING, 7, 0, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_PRINT_STRING, 0, 7, 0);
 | 
			
		||||
  memory[i++].u = OP(OP_HALT, 0, 0, 0);
 | 
			
		||||
 | 
			
		||||
  return code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Code *compile(char *buffer) {
 | 
			
		||||
  Code *code = (Code *)malloc(sizeof(Code));
 | 
			
		||||
  Word memory[MEMORY_SIZE] = {0}; /* Memory array */
 | 
			
		||||
  Value memory[MEMORY_SIZE] = {0}; /* Memory array */
 | 
			
		||||
  code->memory = memory;
 | 
			
		||||
  code->size = MEMORY_SIZE;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,8 @@
 | 
			
		|||
 | 
			
		||||
typedef struct Code Code;
 | 
			
		||||
struct Code {
 | 
			
		||||
  Word *memory; 
 | 
			
		||||
  Value *memory; 
 | 
			
		||||
  VMFrame current;
 | 
			
		||||
  uint32_t size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
#include "debug.h"
 | 
			
		||||
 | 
			
		||||
int core_dump(Word *memory, uint32_t memory_size) {
 | 
			
		||||
int core_dump(Value *memory, uint32_t memory_size) {
 | 
			
		||||
  FILE *file = fopen("memory_dump.bin", "wb");
 | 
			
		||||
  if (!file) {
 | 
			
		||||
    perror("Failed to open file");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,6 @@
 | 
			
		|||
 | 
			
		||||
#include "vm.h"
 | 
			
		||||
 | 
			
		||||
int core_dump(Word *memory, uint32_t memory_size);
 | 
			
		||||
int core_dump(Value *memory, uint32_t memory_size);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ unsigned int hash_##StructType(char *s) { \
 | 
			
		|||
  return hashval % HASHSIZE; \
 | 
			
		||||
} \
 | 
			
		||||
\
 | 
			
		||||
StructType *lookup_##StructType(StructType **map, char *s) { \
 | 
			
		||||
StructType *get_##StructType(StructType **map, char *s) { \
 | 
			
		||||
  StructType *np; \
 | 
			
		||||
  for (np = map[hash_##StructType(s)]; np != NULL; np = np->next) \
 | 
			
		||||
    if (strcmp(s, np->keyword) == 0) \
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ StructType *lookup_##StructType(StructType **map, char *s) { \
 | 
			
		|||
StructType *put_##StructType(StructType **map, char *keyword, TokenType token) { \
 | 
			
		||||
  StructType *np; \
 | 
			
		||||
  unsigned int hashval; \
 | 
			
		||||
  if ((np = lookup_##StructType(map, keyword)) == NULL) { \
 | 
			
		||||
  if ((np = get_##StructType(map, keyword)) == NULL) { \
 | 
			
		||||
    np = (StructType *)malloc(sizeof(*np)); \
 | 
			
		||||
    if (np == NULL || (np->keyword = strdup(keyword)) == NULL) \
 | 
			
		||||
      return NULL; \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ uint32_t pc = 1; /* Program counter */
 | 
			
		|||
Code *code;
 | 
			
		||||
 | 
			
		||||
void mainloop() {
 | 
			
		||||
  pc = step_vm(code->memory, code->size, pc);
 | 
			
		||||
  pc = step_vm(&code->current, code->memory);
 | 
			
		||||
  if (pc == 0) {
 | 
			
		||||
#ifdef __EMSCRIPTEN__
 | 
			
		||||
    emscripten_cancel_main_loop(); /* this should "kill" the app. */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,12 +6,25 @@
 | 
			
		|||
typedef union {
 | 
			
		||||
  int32_t i;  /* Integers */
 | 
			
		||||
  float f;    /* Float */
 | 
			
		||||
  uint32_t u; /* Unsigned integers */
 | 
			
		||||
  uint32_t u; /* Unsigned integers, also used for pointer address */
 | 
			
		||||
  char c[4];  /* 4 Byte char array for string packing */
 | 
			
		||||
} Word;
 | 
			
		||||
} Value;
 | 
			
		||||
 | 
			
		||||
#define MAX_REGS 255
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  Value registers[MAX_REGS]; /* R0-R255 */
 | 
			
		||||
  uint32_t pc;               /* Program counter */
 | 
			
		||||
} VMFrame;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  OP_HALT,           /* terminate execution */
 | 
			
		||||
  OP_LOADI,          /* loads an int from memory */
 | 
			
		||||
  OP_LOADU,          /* loads a uint from memory */
 | 
			
		||||
  OP_LOADF,          /* loads a float from memory */
 | 
			
		||||
  OP_STOREI,         /* stores a int to memory */
 | 
			
		||||
  OP_STOREU,         /* stores a uint to memory */
 | 
			
		||||
  OP_STOREF,         /* stores a float to memory */
 | 
			
		||||
  OP_ADD_INT,        /* dest = src1 + src2  */
 | 
			
		||||
  OP_SUB_INT,        /* dest = src1 - src2  */
 | 
			
		||||
  OP_MUL_INT,        /* dest = src1 * src2  */
 | 
			
		||||
| 
						 | 
				
			
			@ -53,4 +66,7 @@ typedef enum {
 | 
			
		|||
  OP_CMP_STRING,     /* dest = (str == src2) as bool */
 | 
			
		||||
} Opcode;
 | 
			
		||||
 | 
			
		||||
/* defines a uint32 opcode */
 | 
			
		||||
#define OP(opcode, a, b, c) ((opcode << 24) | (a << 16) | (b << 8) | c)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								src/parser.c
								
								
								
								
							
							
						
						
									
										18
									
								
								src/parser.c
								
								
								
								
							| 
						 | 
				
			
			@ -50,14 +50,6 @@ void initTokenMap() {
 | 
			
		|||
  put_TokenMap(tokenMap, "sll", TOKEN_SHIFTLEFT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TokenType get_Token(char *s) {
 | 
			
		||||
  TokenMap *np;
 | 
			
		||||
  for (np = tokenMap[hash_TokenMap(s)]; np != NULL; np = np->next)
 | 
			
		||||
    if (strcmp(s, np->keyword) == 0)
 | 
			
		||||
      return np->token;
 | 
			
		||||
  return TOKEN_IDENTIFIER;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct Tokenizer Tokenizer;
 | 
			
		||||
struct Tokenizer {
 | 
			
		||||
  char *start;
 | 
			
		||||
| 
						 | 
				
			
			@ -144,9 +136,17 @@ static char *currentTokenToS() {
 | 
			
		|||
  return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TokenType getToken(char *s) {
 | 
			
		||||
  TokenMap *np;
 | 
			
		||||
  for (np = tokenMap[hash_TokenMap(s)]; np != NULL; np = np->next)
 | 
			
		||||
    if (strcmp(s, np->keyword) == 0)
 | 
			
		||||
      return np->token;
 | 
			
		||||
  return TOKEN_IDENTIFIER;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static TokenType identifierType() {
 | 
			
		||||
  char *check = currentTokenToS();
 | 
			
		||||
  TokenType t = get_Token(check);
 | 
			
		||||
  TokenType t = getToken(check);
 | 
			
		||||
  free(check);
 | 
			
		||||
  return t;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										146
									
								
								src/vm.c
								
								
								
								
							
							
						
						
									
										146
									
								
								src/vm.c
								
								
								
								
							| 
						 | 
				
			
			@ -2,52 +2,67 @@
 | 
			
		|||
 | 
			
		||||
#define COMPARE_AND_JUMP(type, accessor, op)                                   \
 | 
			
		||||
  do {                                                                         \
 | 
			
		||||
    type value = memory[src1_addr].accessor;                                   \
 | 
			
		||||
    type value2 = memory[src2_addr].accessor;                                  \
 | 
			
		||||
    uint32_t jump_target = dest_addr;                                          \
 | 
			
		||||
    pc = (value op value2) ? jump_target : pc;                                 \
 | 
			
		||||
    return pc;                                                                 \
 | 
			
		||||
    type value = frame->registers[src1].accessor;                              \
 | 
			
		||||
    type value2 = frame->registers[src2].accessor;                             \
 | 
			
		||||
    frame->pc = (value op value2) ? dest : frame->pc;                          \
 | 
			
		||||
    return frame->pc;                                                          \
 | 
			
		||||
  } while (0)
 | 
			
		||||
 | 
			
		||||
#define MATH_OP(accessor, op)                                                  \
 | 
			
		||||
  do {                                                                         \
 | 
			
		||||
    memory[dest_addr].accessor =                                               \
 | 
			
		||||
        memory[src1_addr].accessor op memory[src2_addr].accessor;              \
 | 
			
		||||
    return pc;                                                                 \
 | 
			
		||||
    frame->registers[dest].accessor =                                          \
 | 
			
		||||
        frame->registers[src1].accessor op frame->registers[src2].accessor;    \
 | 
			
		||||
    return frame->pc;                                                          \
 | 
			
		||||
  } while (0)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * String copy in data memory.
 | 
			
		||||
 */
 | 
			
		||||
void mem_strcpy(Word *memory, const char *str, uint32_t length,
 | 
			
		||||
                uint32_t dest_addr) {
 | 
			
		||||
  memory[dest_addr].u = length;
 | 
			
		||||
  uint32_t buffer_addr = dest_addr + 1;
 | 
			
		||||
void mem_strcpy(Value *memory, const char *str, uint32_t length,
 | 
			
		||||
                uint32_t dest) {
 | 
			
		||||
  memory[dest].u = length;
 | 
			
		||||
  uint32_t buffer = dest + 1;
 | 
			
		||||
  uint32_t i;
 | 
			
		||||
  for (i = 0; i < length; i++) {
 | 
			
		||||
    memory[buffer_addr + (i / 4)].c[i % 4] = str[i];
 | 
			
		||||
    memory[buffer + (i / 4)].c[i % 4] = str[i];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Step to the next opcode in the vm.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t step_vm(Word *memory, uint32_t memory_size, uint32_t pc) {
 | 
			
		||||
  Opcode opcode = memory[pc].u;
 | 
			
		||||
  uint32_t src1_addr = memory[pc + 1].u;
 | 
			
		||||
  uint32_t src2_addr = memory[pc + 2].u;
 | 
			
		||||
  uint32_t dest_addr = memory[pc + 3].u;
 | 
			
		||||
  pc += 4; /* Advance to next instruction */
 | 
			
		||||
uint32_t step_vm(VMFrame *frame, Value *memory) {
 | 
			
		||||
  uint32_t instruction = memory[frame->pc].u;
 | 
			
		||||
 | 
			
		||||
  if (src1_addr >= memory_size || src2_addr >= memory_size ||
 | 
			
		||||
      dest_addr >= memory_size) {
 | 
			
		||||
    printf("Invalid memory address!\n");
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  /* Extract 8-bit register indices from 32-bit instruction */
 | 
			
		||||
  uint8_t opcode = (instruction >> 24) & 0xFF;
 | 
			
		||||
  uint8_t dest = (instruction >> 16) & 0xFF;
 | 
			
		||||
  uint8_t src1 = (instruction >> 8) & 0xFF;
 | 
			
		||||
  uint8_t src2 = instruction & 0xFF;
 | 
			
		||||
  /* Advance to next instruction */
 | 
			
		||||
  frame->pc++;
 | 
			
		||||
 | 
			
		||||
  switch (opcode) {
 | 
			
		||||
  case OP_HALT:
 | 
			
		||||
    return 0;
 | 
			
		||||
  case OP_LOADI:
 | 
			
		||||
    frame->registers[dest].i = memory[frame->pc++].i;
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  case OP_LOADU:
 | 
			
		||||
    frame->registers[dest].u = memory[frame->pc++].u;
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  case OP_LOADF:
 | 
			
		||||
    frame->registers[dest].f = memory[frame->pc++].f;
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  case OP_STOREI:
 | 
			
		||||
    memory[frame->pc++].i = frame->registers[src1].i;
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  case OP_STOREU:
 | 
			
		||||
    memory[frame->pc++].u = frame->registers[src1].u;
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  case OP_STOREF:
 | 
			
		||||
    memory[frame->pc++].f = frame->registers[src1].f;
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  case OP_ADD_INT:
 | 
			
		||||
    MATH_OP(i, +);
 | 
			
		||||
  case OP_SUB_INT:
 | 
			
		||||
| 
						 | 
				
			
			@ -73,27 +88,23 @@ uint32_t step_vm(Word *memory, uint32_t memory_size, uint32_t pc) {
 | 
			
		|||
  case OP_DIV_REAL:
 | 
			
		||||
    MATH_OP(f, /);
 | 
			
		||||
  case OP_REAL_TO_INT:
 | 
			
		||||
    memory[dest_addr].i = (int32_t)(memory[src1_addr].f);
 | 
			
		||||
    return pc;
 | 
			
		||||
 | 
			
		||||
    frame->registers[dest].i = (int32_t)(frame->registers[src1].f);
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  case OP_INT_TO_REAL:
 | 
			
		||||
    memory[dest_addr].f = (float)(memory[src1_addr].i);
 | 
			
		||||
    return pc;
 | 
			
		||||
 | 
			
		||||
    frame->registers[dest].f = (float)(frame->registers[src1].i);
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  case OP_REAL_TO_UINT:
 | 
			
		||||
    memory[dest_addr].u = (uint32_t)(memory[src1_addr].f);
 | 
			
		||||
    return pc;
 | 
			
		||||
 | 
			
		||||
    frame->registers[dest].u = (uint32_t)(frame->registers[src1].f);
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  case OP_UINT_TO_REAL:
 | 
			
		||||
    memory[dest_addr].f = (float)(memory[src1_addr].u);
 | 
			
		||||
    return pc;
 | 
			
		||||
 | 
			
		||||
    frame->registers[dest].f = (float)(frame->registers[src1].u);
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  case OP_MOV:
 | 
			
		||||
    memory[dest_addr] = memory[src1_addr];
 | 
			
		||||
    return pc;
 | 
			
		||||
    frame->registers[dest] = frame->registers[src1];
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  case OP_JMP:
 | 
			
		||||
    pc = src1_addr; /* Jump to address */
 | 
			
		||||
    return pc;
 | 
			
		||||
    frame->pc = frame->registers[src1].u; /* Jump to address */
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  case OP_JEQ_UINT: {
 | 
			
		||||
    COMPARE_AND_JUMP(uint32_t, u, ==);
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -140,59 +151,64 @@ uint32_t step_vm(Word *memory, uint32_t memory_size, uint32_t pc) {
 | 
			
		|||
    COMPARE_AND_JUMP(int32_t, u, <=);
 | 
			
		||||
  }
 | 
			
		||||
  case OP_INT_TO_STRING: {
 | 
			
		||||
    int32_t a = (int32_t)memory[src1_addr].i;
 | 
			
		||||
    int32_t a = (int32_t)frame->registers[src1].i;
 | 
			
		||||
    uint32_t str_dest = (uint32_t)frame->registers[dest].u;
 | 
			
		||||
    char buffer[32];
 | 
			
		||||
    int len = sprintf(buffer, "%d", a);
 | 
			
		||||
    mem_strcpy(memory, buffer, len, dest_addr);
 | 
			
		||||
    return pc;
 | 
			
		||||
    mem_strcpy(memory, buffer, len, str_dest);
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_UINT_TO_STRING: {
 | 
			
		||||
    uint32_t a = (uint32_t)memory[src1_addr].u;
 | 
			
		||||
    uint32_t a = (uint32_t)frame->registers[src1].u;
 | 
			
		||||
    uint32_t str_dest = (uint32_t)frame->registers[dest].u;
 | 
			
		||||
    char buffer[32];
 | 
			
		||||
    int len = sprintf(buffer, "%d", a);
 | 
			
		||||
    mem_strcpy(memory, buffer, len, dest_addr);
 | 
			
		||||
    return pc;
 | 
			
		||||
    mem_strcpy(memory, buffer, len, str_dest);
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_REAL_TO_STRING: {
 | 
			
		||||
    float a = (float)memory[src1_addr].f;
 | 
			
		||||
    float a = (float)frame->registers[src1].f;
 | 
			
		||||
    uint32_t str_dest = (uint32_t)frame->registers[dest].u;
 | 
			
		||||
    char buffer[32];
 | 
			
		||||
    int len = sprintf(buffer, "%f", a);
 | 
			
		||||
    mem_strcpy(memory, buffer, len, dest_addr);
 | 
			
		||||
    return pc;
 | 
			
		||||
    mem_strcpy(memory, buffer, len, str_dest);
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_READ_STRING: {
 | 
			
		||||
    uint32_t buffer_addr = dest_addr + 1;
 | 
			
		||||
    uint32_t str_dest = (uint32_t)frame->registers[dest].u;
 | 
			
		||||
    uint32_t buffer = str_dest + 1;
 | 
			
		||||
    uint32_t length = 0;
 | 
			
		||||
    while (1) {
 | 
			
		||||
      int ch = getchar();
 | 
			
		||||
      if (ch == '\n' || ch == EOF) {
 | 
			
		||||
        memory[buffer_addr + (length / 4)].c[length % 4] = '\0';
 | 
			
		||||
        memory[buffer + (length / 4)].c[length % 4] = '\0';
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      memory[buffer_addr + (length / 4)].c[length % 4] = ch;
 | 
			
		||||
      memory[buffer + (length / 4)].c[length % 4] = ch;
 | 
			
		||||
      length++;
 | 
			
		||||
    }
 | 
			
		||||
    memory[dest_addr].u = length;
 | 
			
		||||
    return pc;
 | 
			
		||||
    memory[str_dest].u = length;
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_PRINT_STRING: {
 | 
			
		||||
    uint32_t string_addr = src1_addr;
 | 
			
		||||
    uint32_t length = memory[src1_addr - 1].u;
 | 
			
		||||
    uint32_t ptr = (uint32_t)frame->registers[src1].u;
 | 
			
		||||
    uint32_t length = memory[ptr].u;
 | 
			
		||||
    uint32_t str_src = ptr + 1;
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
    for (i = 0; i < length; i++) {
 | 
			
		||||
      uint8_t ch = memory[string_addr + (i / 4)].c[i % 4];
 | 
			
		||||
      uint8_t ch = memory[str_src + (i / 4)].c[i % 4];
 | 
			
		||||
      if (ch == '\0')
 | 
			
		||||
        break;
 | 
			
		||||
      putchar(ch);
 | 
			
		||||
    }
 | 
			
		||||
    putchar('\n');
 | 
			
		||||
    return pc;
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  }
 | 
			
		||||
  case OP_CMP_STRING: {
 | 
			
		||||
    uint32_t addr1 = src1_addr;
 | 
			
		||||
    uint32_t addr2 = src2_addr;
 | 
			
		||||
    uint32_t length1 = memory[src1_addr - 1].u;
 | 
			
		||||
    uint32_t length2 = memory[src2_addr - 1].u;
 | 
			
		||||
    uint32_t addr1 = (uint32_t)frame->registers[src1].u;
 | 
			
		||||
    uint32_t addr2 = (uint32_t)frame->registers[src2].u;
 | 
			
		||||
    uint32_t length1 = memory[addr1 - 1].u;
 | 
			
		||||
    uint32_t length2 = memory[addr2 - 1].u;
 | 
			
		||||
    uint32_t equal = 1;
 | 
			
		||||
 | 
			
		||||
    if (length1 != length2) {
 | 
			
		||||
| 
						 | 
				
			
			@ -207,11 +223,11 @@ uint32_t step_vm(Word *memory, uint32_t memory_size, uint32_t pc) {
 | 
			
		|||
          break;
 | 
			
		||||
        }
 | 
			
		||||
        if ((char1 & 0xFF) == '\0' && (char2 & 0xFF) == '\0')
 | 
			
		||||
          return pc;
 | 
			
		||||
          return frame->pc;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    memory[dest_addr].u = equal;
 | 
			
		||||
    return pc;
 | 
			
		||||
    memory[dest].u = equal;
 | 
			
		||||
    return frame->pc;
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue