#ifndef DBLTW_VM_H #define DBLTW_VM_H #include "joey.h" #define OPCODE_ADD 0x01 // Add #define OPCODE_BOC 0x02 // Branch On Condition #define OPCODE_EXE 0x03 // Execute VM Function #define OPCODE_JMP 0x04 // Jump to Address #define OPCODE_HLT 0x05 // Halt Execution #define OPCODE_POP 0x06 // Pop into Variable #define OPCODE_PUC 0x07 // Push Constant #define OPCODE_PUV 0x08 // Push Variable #define OPCODE_SUB 0x09 // Subtract #define OPCODE_LAST OPCODE_SUB typedef struct vmContext_ VMContextT; typedef void (*VMFuncT)(VMContextT *context, juint16 stackCount); typedef struct { jint16 value; jint16 allocated; char *text; } PairT; // Signed / string pair. typedef struct { juint16 value; jint16 allocated; char *text; } UPairT; // Unsigned / string pair. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpadded" typedef struct { PairT *stack; // Stack for computations PairT *variables; // All variable storage UPairT *labels; // Lable jump table UPairT *variableTable; // Exported variable name-to-index table juint16 variablesCount; // Number of variables in program juint16 labelCount; // Number of exported labels currently loaded juint16 variableTableCount; // Number of exported variables currently loaded juint16 stackCount; // Maximum size stack has been juint16 sp; // Stack pointer juint16 pc; // Program counter byte *memory; // Program byte stream juint16 programSize; // Number of bytes in program byte stream VMFuncT *functions; // Native function pointers juint16 functionCount; // Number of native functions attached juint16 headerBytes; // Header bytes (used for PC calculations) } PrivateT; #pragma GCC diagnostic pop typedef struct vmContext_ { PrivateT private; PairT *working; // Working space for operands } VMContextT; bool vmAddFunction(VMContextT *context, VMFuncT function); bool vmCreate(VMContextT *context); bool vmDestroy(VMContextT *context); bool vmGetPCIndex(VMContextT *context, char *label, juint16 *pc); bool vmGetVariable(VMContextT *context, char *name, PairT *item); bool vmGetVariableIndex(VMContextT *context, char *name, juint16 *index); bool vmIsItemNumber(PairT *item); bool vmLoad(VMContextT *context, char *filename); bool vmPop(VMContextT *context, PairT *item); bool vmPush(VMContextT *context, PairT *item); void vmSetItem(PairT *item, char *text, jint16 *value); bool vmSetPC(VMContextT *context, char *label); bool vmSetPCByIndex(VMContextT *context, juint16 index); bool vmSetVariable(VMContextT *context, char *name, PairT *item); bool vmSetVariableByIndex(VMContextT *context, jint16 index, PairT *item); bool vmStep(VMContextT *context); bool vmRun(VMContextT *context); #endif