dbltw/vm/vm.h
2020-05-13 19:08:25 -05:00

82 lines
2.9 KiB
C

#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