Added opcode_as_cstr, opcode_type_as_cstr and inst_print
Pretty self explanatory, helps with logging.
This commit is contained in:
104
src/inst.c
104
src/inst.c
@@ -16,6 +16,92 @@
|
|||||||
|
|
||||||
#include "./inst.h"
|
#include "./inst.h"
|
||||||
|
|
||||||
|
const char *opcode_as_cstr(opcode_t code)
|
||||||
|
{
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case OP_NOOP:
|
||||||
|
return "NOOP";
|
||||||
|
break;
|
||||||
|
case OP_PUSH_BYTE:
|
||||||
|
return "PUSH_BYTE";
|
||||||
|
break;
|
||||||
|
case OP_PUSH_WORD:
|
||||||
|
return "PUSH_WORD";
|
||||||
|
break;
|
||||||
|
case OP_PUSH_FLOAT:
|
||||||
|
return "PUSH_FLOAT";
|
||||||
|
break;
|
||||||
|
case OP_PUSH_BYTE_REGISTER:
|
||||||
|
return "PUSH_BYTE_REGISTER";
|
||||||
|
break;
|
||||||
|
case OP_PUSH_WORD_REGISTER:
|
||||||
|
return "PUSH_WORD_REGISTER";
|
||||||
|
break;
|
||||||
|
case OP_PUSH_FLOAT_REGISTER:
|
||||||
|
return "PUSH_FLOAT_REGISTER";
|
||||||
|
break;
|
||||||
|
case OP_POP_BYTE:
|
||||||
|
return "POP_BYTE";
|
||||||
|
break;
|
||||||
|
case OP_POP_WORD:
|
||||||
|
return "POP_WORD";
|
||||||
|
break;
|
||||||
|
case OP_POP_FLOAT:
|
||||||
|
return "POP_FLOAT";
|
||||||
|
break;
|
||||||
|
case OP_MOV_BYTE:
|
||||||
|
return "MOV_BYTE";
|
||||||
|
break;
|
||||||
|
case OP_MOV_WORD:
|
||||||
|
return "MOV_WORD";
|
||||||
|
break;
|
||||||
|
case OP_MOV_FLOAT:
|
||||||
|
return "MOV_FLOAT";
|
||||||
|
break;
|
||||||
|
case OP_HALT:
|
||||||
|
return "HALT";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *opcode_type_as_cstr(opcode_type_t type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case OP_TYPE_PUSH:
|
||||||
|
return "TYPE_PUSH";
|
||||||
|
case OP_TYPE_PUSH_REGISTER:
|
||||||
|
return "TYPE_PUSH_REGISTER";
|
||||||
|
case OP_TYPE_POP:
|
||||||
|
return "TYPE_POP";
|
||||||
|
case OP_TYPE_MOV:
|
||||||
|
return "TYPE_MOV";
|
||||||
|
case OP_TYPE_HALT:
|
||||||
|
return "TYPE_HALT";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_print(data_t datum, data_type_t type, FILE *fp)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DATA_TYPE_NIL:
|
||||||
|
break;
|
||||||
|
case DATA_TYPE_BYTE:
|
||||||
|
fprintf(fp, "%X", datum.as_byte);
|
||||||
|
break;
|
||||||
|
case DATA_TYPE_WORD:
|
||||||
|
fprintf(fp, "%lX", datum.as_word);
|
||||||
|
break;
|
||||||
|
case DATA_TYPE_FLOAT:
|
||||||
|
fprintf(fp, "%f", datum.as_float);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data_type_t get_opcode_data_type(opcode_t opcode)
|
data_type_t get_opcode_data_type(opcode_t opcode)
|
||||||
{
|
{
|
||||||
data_type_t type = DATA_TYPE_NIL;
|
data_type_t type = DATA_TYPE_NIL;
|
||||||
@@ -30,6 +116,24 @@ data_type_t get_opcode_data_type(opcode_t opcode)
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void inst_print(inst_t instruction, FILE *fp)
|
||||||
|
{
|
||||||
|
fprintf(fp, "(%s", opcode_as_cstr(instruction.opcode));
|
||||||
|
if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_PUSH))
|
||||||
|
{
|
||||||
|
data_type_t type = get_opcode_data_type(instruction.opcode);
|
||||||
|
fprintf(fp, ", datum=");
|
||||||
|
data_print(instruction.operand, type, fp);
|
||||||
|
}
|
||||||
|
else if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_PUSH_REGISTER) ||
|
||||||
|
OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_MOV))
|
||||||
|
{
|
||||||
|
fprintf(fp, ", reg=");
|
||||||
|
data_print(instruction.operand, DATA_TYPE_BYTE, fp);
|
||||||
|
}
|
||||||
|
fprintf(fp, ")");
|
||||||
|
}
|
||||||
|
|
||||||
size_t inst_bytecode_size(inst_t inst)
|
size_t inst_bytecode_size(inst_t inst)
|
||||||
{
|
{
|
||||||
size_t size = 1; // for opcode
|
size_t size = 1; // for opcode
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef INST_H
|
#ifndef INST_H
|
||||||
#define INST_H
|
#define INST_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "./base.h"
|
#include "./base.h"
|
||||||
@@ -42,6 +43,8 @@ typedef enum
|
|||||||
OP_HALT = 0b10000000, // top of the byte is a HALT
|
OP_HALT = 0b10000000, // top of the byte is a HALT
|
||||||
} opcode_t;
|
} opcode_t;
|
||||||
|
|
||||||
|
const char *opcode_as_cstr(opcode_t);
|
||||||
|
|
||||||
// Masks and values to check if an opcode is of a type
|
// Masks and values to check if an opcode is of a type
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@@ -52,6 +55,8 @@ typedef enum
|
|||||||
OP_TYPE_HALT = 0b10000000,
|
OP_TYPE_HALT = 0b10000000,
|
||||||
} opcode_type_t;
|
} opcode_type_t;
|
||||||
|
|
||||||
|
const char *opcode_type_as_cstr(opcode_type_t);
|
||||||
|
|
||||||
#define OPCODE_IS_TYPE(OPCODE, OP_TYPE) (((OPCODE) & (OP_TYPE)) == (OP_TYPE))
|
#define OPCODE_IS_TYPE(OPCODE, OP_TYPE) (((OPCODE) & (OP_TYPE)) == (OP_TYPE))
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -60,6 +65,8 @@ typedef struct
|
|||||||
data_t operand;
|
data_t operand;
|
||||||
} inst_t;
|
} inst_t;
|
||||||
|
|
||||||
|
void inst_print(inst_t, FILE *);
|
||||||
|
|
||||||
size_t inst_bytecode_size(inst_t);
|
size_t inst_bytecode_size(inst_t);
|
||||||
void inst_write_bytecode(inst_t, darr_t *);
|
void inst_write_bytecode(inst_t, darr_t *);
|
||||||
// Here the dynamic array is a preloaded buffer of bytes, where
|
// Here the dynamic array is a preloaded buffer of bytes, where
|
||||||
|
|||||||
Reference in New Issue
Block a user