aboutsummaryrefslogtreecommitdiff
path: root/src/runtime.c
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2023-10-23 00:09:12 +0100
committerAryadev Chavali <aryadev@aryadevchavali.com>2023-10-23 00:09:12 +0100
commitae9bc91713f86cfc16e801ca33654a47082ddb2b (patch)
tree99b3ff0d9e729feeb42689ca181a294199dc69af /src/runtime.c
parent45ad8f7296722cc3cec0a6974f9d2519c9f36d4b (diff)
downloadovm-ae9bc91713f86cfc16e801ca33654a47082ddb2b.tar.gz
ovm-ae9bc91713f86cfc16e801ca33654a47082ddb2b.tar.bz2
ovm-ae9bc91713f86cfc16e801ca33654a47082ddb2b.zip
Added and implemented OP_PRINT*
Here is where we may have differing interpretations of what the bits in the data pile may actually mean. This in particular refers to printing the signed or unsigned versions of the bits given. Also, interpreting some byte as a character or just a raw number.
Diffstat (limited to 'src/runtime.c')
-rw-r--r--src/runtime.c77
1 files changed, 74 insertions, 3 deletions
diff --git a/src/runtime.c b/src/runtime.c
index ac1cf58..f653ac3 100644
--- a/src/runtime.c
+++ b/src/runtime.c
@@ -11,6 +11,7 @@
*/
#include <assert.h>
+#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -54,7 +55,7 @@ const char *err_as_cstr(err_t err)
err_t vm_execute(vm_t *vm)
{
- static_assert(NUMBER_OF_OPCODES == 37, "vm_execute: Out of date");
+ static_assert(NUMBER_OF_OPCODES == 43, "vm_execute: Out of date");
struct Program *prog = &vm->program;
if (prog->ptr >= prog->max)
return ERR_END_OF_PROGRAM;
@@ -135,12 +136,82 @@ err_t vm_execute(vm_t *vm)
return ERR_INVALID_PROGRAM_ADDRESS;
prog->ptr = addr;
}
+ else if (instruction.opcode >= OP_PRINT_CHAR &&
+ instruction.opcode <= OP_PRINT_WORD)
+ {
+ data_t datum = {0};
+ enum
+ {
+ TYPE_CHAR,
+ TYPE_BYTE,
+ TYPE_INT,
+ TYPE_HWORD,
+ TYPE_LONG,
+ TYPE_WORD
+ } print_type;
+ err_t err = ERR_OK;
+ if (instruction.opcode == OP_PRINT_BYTE ||
+ instruction.opcode == OP_PRINT_CHAR)
+ {
+ print_type = instruction.opcode == OP_PRINT_BYTE ? TYPE_BYTE : TYPE_CHAR;
+ err = vm_pop_byte(vm, &datum);
+ }
+ else if (instruction.opcode == OP_PRINT_HWORD ||
+ instruction.opcode == OP_PRINT_INT)
+ {
+ print_type = instruction.opcode == OP_PRINT_HWORD ? TYPE_HWORD : TYPE_INT;
+ err = vm_pop_hword(vm, &datum);
+ }
+ else if (instruction.opcode == OP_PRINT_WORD ||
+ instruction.opcode == OP_PRINT_LONG)
+ {
+ print_type = instruction.opcode == OP_PRINT_WORD ? TYPE_WORD : TYPE_LONG;
+ err = vm_pop_word(vm, &datum);
+ }
+
+ if (err)
+ return err;
+
+ switch (print_type)
+ {
+ case TYPE_CHAR: {
+ char c = 0;
+ memcpy(&c, &datum.as_byte, 1);
+ printf("%c", c);
+ break;
+ }
+ case TYPE_BYTE:
+ printf("0x%x", datum.as_byte);
+ break;
+ case TYPE_INT: {
+ int32_t i = 0;
+ memcpy(&i, &datum.as_hword, HWORD_SIZE);
+ printf("%" PRId32, i);
+ break;
+ }
+ case TYPE_HWORD:
+ printf("%" PRIu32, datum.as_hword);
+ break;
+ case TYPE_LONG: {
+ int64_t i = 0;
+ memcpy(&i, &datum.as_word, WORD_SIZE);
+ printf("%" PRId64, i);
+ break;
+ }
+ case TYPE_WORD:
+ printf("%" PRIu64, datum.as_word);
+ break;
+ }
+
+ prog->ptr++;
+ }
else if (instruction.opcode == OP_HALT)
{
// Do nothing here. Should be caught by callers of vm_execute
- return ERR_OK;
}
- return ERR_INVALID_OPCODE;
+ else
+ return ERR_INVALID_OPCODE;
+ return ERR_OK;
}
err_t vm_execute_all(vm_t *vm)