add float and int >,<,>=,<=
This commit is contained in:
parent
dc89a24701
commit
d4d887e6a1
11
src/main.c
11
src/main.c
|
@ -5,10 +5,10 @@
|
||||||
#define MEMORY_SIZE 1024
|
#define MEMORY_SIZE 1024
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Data memory[MEMORY_SIZE]; /* Memory array */
|
Data memory[MEMORY_SIZE] = {0}; /* Memory array */
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
memory[i++].u = OP_ADD_F32;
|
memory[i++].u = OP_ADD_REAL;
|
||||||
memory[i++].u = 102;
|
memory[i++].u = 102;
|
||||||
memory[i++].u = 103;
|
memory[i++].u = 103;
|
||||||
memory[i++].u = 103;
|
memory[i++].u = 103;
|
||||||
|
@ -16,11 +16,11 @@ int main() {
|
||||||
memory[i++].u = 100;
|
memory[i++].u = 100;
|
||||||
memory[i++].u = 101;
|
memory[i++].u = 101;
|
||||||
memory[i++].u = 100;
|
memory[i++].u = 100;
|
||||||
memory[i++].u = OP_JGZ;
|
memory[i++].u = OP_JGT_INT;
|
||||||
memory[i++].u = 100;
|
memory[i++].u = 100;
|
||||||
|
memory[i++].u = 99;
|
||||||
memory[i++].u = 0;
|
memory[i++].u = 0;
|
||||||
memory[i++].u = 0;
|
memory[i++].u = OP_REAL_TO_INT;
|
||||||
memory[i++].u = OP_F32_TO_INT;
|
|
||||||
memory[i++].u = 103;
|
memory[i++].u = 103;
|
||||||
memory[i++].u = 0;
|
memory[i++].u = 0;
|
||||||
memory[i++].u = 103;
|
memory[i++].u = 103;
|
||||||
|
@ -44,6 +44,7 @@ int main() {
|
||||||
memory[i++].u = 0;
|
memory[i++].u = 0;
|
||||||
memory[i++].u = 0;
|
memory[i++].u = 0;
|
||||||
memory[i++].u = 0;
|
memory[i++].u = 0;
|
||||||
|
memory[99].u = 0;
|
||||||
memory[100].u = 5;
|
memory[100].u = 5;
|
||||||
memory[101].u = 1;
|
memory[101].u = 1;
|
||||||
memory[102].f = 5.f;
|
memory[102].f = 5.f;
|
||||||
|
|
79
src/vm.c
79
src/vm.c
|
@ -56,30 +56,30 @@ void run_vm(Data *memory, uint32_t memory_size) {
|
||||||
memory[dest_addr].u = memory[src1_addr].u / memory[src2_addr].u;
|
memory[dest_addr].u = memory[src1_addr].u / memory[src2_addr].u;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_ADD_F32:
|
case OP_ADD_REAL:
|
||||||
memory[dest_addr].f = memory[src1_addr].f + memory[src2_addr].f;
|
memory[dest_addr].f = memory[src1_addr].f + memory[src2_addr].f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_SUB_F32:
|
case OP_SUB_REAL:
|
||||||
memory[dest_addr].f = memory[src1_addr].f - memory[src2_addr].f;
|
memory[dest_addr].f = memory[src1_addr].f - memory[src2_addr].f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_MUL_F32:
|
case OP_MUL_REAL:
|
||||||
memory[dest_addr].f = memory[src1_addr].f * memory[src2_addr].f;
|
memory[dest_addr].f = memory[src1_addr].f * memory[src2_addr].f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_DIV_F32:
|
case OP_DIV_REAL:
|
||||||
if (memory[src2_addr].f == 0.0f) {
|
if (memory[src2_addr].f == 0.0f) {
|
||||||
printf("Division by zero error at address %d\n", pc - 4);
|
printf("Division by zero error at address %d\n", pc - 4);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
memory[dest_addr].f = memory[src1_addr].f / memory[src2_addr].f;
|
memory[dest_addr].f = memory[src1_addr].f / memory[src2_addr].f;
|
||||||
break;
|
break;
|
||||||
case OP_F32_TO_INT: {
|
case OP_REAL_TO_INT: {
|
||||||
memory[dest_addr].u = (uint32_t)memory[src1_addr].f;
|
memory[dest_addr].u = (uint32_t)memory[src1_addr].f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_INT_TO_F32: {
|
case OP_INT_TO_REAL: {
|
||||||
memory[dest_addr].f = (float)memory[src1_addr].u;
|
memory[dest_addr].f = (float)memory[src1_addr].u;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -89,13 +89,68 @@ void run_vm(Data *memory, uint32_t memory_size) {
|
||||||
case OP_JMP:
|
case OP_JMP:
|
||||||
pc = src1_addr; /* Jump to address */
|
pc = src1_addr; /* Jump to address */
|
||||||
break;
|
break;
|
||||||
case OP_JGZ: {
|
case OP_JGT_INT: {
|
||||||
uint32_t value = memory[src1_addr].u;
|
uint32_t value = memory[src1_addr].u;
|
||||||
uint32_t jump_target = src2_addr;
|
uint32_t value2 = memory[src2_addr].u;
|
||||||
|
uint32_t jump_target = dest_addr;
|
||||||
|
|
||||||
/* Branchless greater-than-zero check */
|
pc = (value > value2) ? jump_target : pc;
|
||||||
int32_t mask = -((uint32_t)(value > 0));
|
break;
|
||||||
pc = (jump_target & mask) | (pc & ~mask);
|
}
|
||||||
|
case OP_JLT_INT: {
|
||||||
|
uint32_t value = memory[src1_addr].u;
|
||||||
|
uint32_t value2 = memory[src2_addr].u;
|
||||||
|
uint32_t jump_target = dest_addr;
|
||||||
|
|
||||||
|
pc = (value < value2) ? jump_target : pc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_JGT_REAL: {
|
||||||
|
float value = memory[src1_addr].f;
|
||||||
|
float value2 = memory[src2_addr].f;
|
||||||
|
uint32_t jump_target = dest_addr;
|
||||||
|
|
||||||
|
pc = (value > value2) ? jump_target : pc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_JLT_REAL: {
|
||||||
|
float value = memory[src1_addr].f;
|
||||||
|
float value2 = memory[src2_addr].f;
|
||||||
|
uint32_t jump_target = dest_addr;
|
||||||
|
|
||||||
|
pc = (value < value2) ? jump_target : pc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_JGE_INT: {
|
||||||
|
uint32_t value = memory[src1_addr].u;
|
||||||
|
uint32_t value2 = memory[src2_addr].u;
|
||||||
|
uint32_t jump_target = dest_addr;
|
||||||
|
|
||||||
|
pc = (value >= value2) ? jump_target : pc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_JLE_INT: {
|
||||||
|
uint32_t value = memory[src1_addr].u;
|
||||||
|
uint32_t value2 = memory[src2_addr].u;
|
||||||
|
uint32_t jump_target = dest_addr;
|
||||||
|
|
||||||
|
pc = (value <= value2) ? jump_target : pc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_JGE_REAL: {
|
||||||
|
float value = memory[src1_addr].f;
|
||||||
|
float value2 = memory[src2_addr].f;
|
||||||
|
uint32_t jump_target = dest_addr;
|
||||||
|
|
||||||
|
pc = (value >= value2) ? jump_target : pc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_JLE_REAL: {
|
||||||
|
float value = memory[src1_addr].f;
|
||||||
|
float value2 = memory[src2_addr].f;
|
||||||
|
uint32_t jump_target = dest_addr;
|
||||||
|
|
||||||
|
pc = (value <= value2) ? jump_target : pc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_INT_TO_STRING: {
|
case OP_INT_TO_STRING: {
|
||||||
|
@ -105,7 +160,7 @@ void run_vm(Data *memory, uint32_t memory_size) {
|
||||||
mem_strcpy(memory, buffer, strlen(buffer), dest_addr);
|
mem_strcpy(memory, buffer, strlen(buffer), dest_addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_F32_TO_STRING: {
|
case OP_REAL_TO_STRING: {
|
||||||
float a = memory[src1_addr].f;
|
float a = memory[src1_addr].f;
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
sprintf(buffer, "%f", a);
|
sprintf(buffer, "%f", a);
|
||||||
|
|
23
src/vm.h
23
src/vm.h
|
@ -15,17 +15,24 @@ typedef enum {
|
||||||
OP_SUB, /* dest = src1 - src2 */
|
OP_SUB, /* dest = src1 - src2 */
|
||||||
OP_MUL, /* dest = src1 * src2 */
|
OP_MUL, /* dest = src1 * src2 */
|
||||||
OP_DIV, /* dest = src1 / src2 */
|
OP_DIV, /* dest = src1 / src2 */
|
||||||
OP_ADD_F32, /* dest = src1 + src2 */
|
OP_JGT_INT, /* jump to address dest if src1 as int > src2 as int*/
|
||||||
OP_SUB_F32, /* dest = src1 - src2 */
|
OP_JLT_INT, /* jump to address dest if src1 as int < src2 as int */
|
||||||
OP_MUL_F32, /* dest = src1 * src2 */
|
OP_JLE_INT, /* jump to address dest if src1 as int <= src2 as int */
|
||||||
OP_DIV_F32, /* dest = src1 / src2 */
|
OP_JGE_INT, /* jump to address dest if src1 as int >= src2 as int*/
|
||||||
OP_F32_TO_INT, /* dest = src1 as int */
|
OP_INT_TO_REAL, /* dest = src1 as f32 */
|
||||||
OP_INT_TO_F32, /* dest = src1 as f32 */
|
OP_ADD_REAL, /* dest = src1 + src2 */
|
||||||
|
OP_SUB_REAL, /* dest = src1 - src2 */
|
||||||
|
OP_MUL_REAL, /* dest = src1 * src2 */
|
||||||
|
OP_DIV_REAL, /* dest = src1 / src2 */
|
||||||
|
OP_JGE_REAL, /* jump to address dest if src1 as real >= src2 as real */
|
||||||
|
OP_JGT_REAL, /* jump to address dest if src1 as real > src2 as real */
|
||||||
|
OP_JLT_REAL, /* jump to address dest if src1 as real < src2 as real */
|
||||||
|
OP_JLE_REAL, /* jump to address dest if src1 as real <= src2 as real */
|
||||||
|
OP_REAL_TO_INT, /* dest = src1 as int */
|
||||||
OP_MOV, /* dest = src1 */
|
OP_MOV, /* dest = src1 */
|
||||||
OP_JMP, /* jump to address src1 unconditionally */
|
OP_JMP, /* jump to address src1 unconditionally */
|
||||||
OP_JGZ, /* jump to address dest if src1 > 0 */
|
|
||||||
OP_INT_TO_STRING, /* dest = src1 as str */
|
OP_INT_TO_STRING, /* dest = src1 as str */
|
||||||
OP_F32_TO_STRING, /* dest = src2 as str */
|
OP_REAL_TO_STRING, /* dest = src2 as str */
|
||||||
OP_READ_STRING, /* dest = src1 */
|
OP_READ_STRING, /* dest = src1 */
|
||||||
OP_PRINT_STRING, /* dest = src1 */
|
OP_PRINT_STRING, /* dest = src1 */
|
||||||
OP_CMP_STRING, /* dest = src1 */
|
OP_CMP_STRING, /* dest = src1 */
|
||||||
|
|
Loading…
Reference in New Issue