Refactor with a consistent coding style

This commit refactors the project using a single, consistent coding
style, derived from the Linux Kernel Coding Style, available here:

https://www.kernel.org/doc/Documentation/CodingStyle

This includes, but is not limited to:
* Removal of typedefs, especially for structs
* Limiting lines to a reasonable length, 80 characters, mostly
* K&R style braces
* Removal of CamelCase
This commit is contained in:
Joseph Kogut 2016-08-28 20:31:12 -07:00
parent a4c540f5a0
commit ca87b3c5e9
22 changed files with 670 additions and 491 deletions

View file

@ -3,60 +3,83 @@
#include <stddef.h>
#include "tvm_file.h"
#include "tvm_preprocessor.h"
#include "tvm_stack.h"
#include "tvm_memory.h"
#include "tvm_program.h"
#include "tvm_stack.h"
#include "tvm_parser.h"
#include "tvm_tokens.h"
typedef struct tvm_s
struct tvm_ctx {
struct tvm_prog *prog;
struct tvm_mem *mem;
};
struct tvm_ctx *tvm_vm_create();
void tvm_vm_destroy(struct tvm_ctx *vm);
int tvm_vm_interpret(struct tvm_ctx *vm, char *filename);
void tvm_vm_run(struct tvm_ctx *vm);
static inline void tvm_step(struct tvm_ctx *vm, int *instr_idx)
{
tvm_program_t *pProgram;
tvm_memory_t *pMemory;
} tvm_t;
int *arg0 = vm->prog->args[*instr_idx][0],
*arg1 = vm->prog->args[*instr_idx][1];
tvm_t *tvm_create();
void tvm_destroy(tvm_t *vm);
int tvm_interpret(tvm_t *vm, char *filename);
void tvm_run(tvm_t *vm);
static inline void tvm_step(tvm_t *vm, int *instr_idx)
{
int *arg0 = vm->pProgram->args[*instr_idx][0], *arg1 = vm->pProgram->args[*instr_idx][1];
switch(vm->pProgram->instr[*instr_idx])
{
switch (vm->prog->instr[*instr_idx]) {
/* nop */ case 0x0: break;
/* int */ case 0x1: /* unimplemented */ break;
/* mov */ case 0x2: *arg0 = *arg1; break;
/* push */ case 0x3: stack_push(vm->pMemory, arg0); break;
/* pop */ case 0x4: stack_pop(vm->pMemory, arg0); break;
/* pushf */ case 0x5: stack_push(vm->pMemory, &vm->pMemory->FLAGS); break;
/* popf */ case 0x6: stack_pop(vm->pMemory, arg0); break;
/* push */ case 0x3: tvm_stack_push(vm->mem, arg0); break;
/* pop */ case 0x4: tvm_stack_pop(vm->mem, arg0); break;
/* pushf */ case 0x5: tvm_stack_push(vm->mem, &vm->mem->FLAGS); break;
/* popf */ case 0x6: tvm_stack_pop(vm->mem, arg0); break;
/* inc */ case 0x7: ++(*arg0); break;
/* dec */ case 0x8: --(*arg0); break;
/* add */ case 0x9: *arg0 += *arg1; break;
/* sub */ case 0xA: *arg0 -= *arg1; break;
/* mul */ case 0xB: *arg0 *= *arg1; break;
/* div */ case 0xC: *arg0 /= *arg1; break;
/* mod */ case 0xD: vm->pMemory->remainder = *arg0 % *arg1; break;
/* rem */ case 0xE: *arg0 = vm->pMemory->remainder; break;
/* mod */ case 0xD: vm->mem->remainder = *arg0 % *arg1; break;
/* rem */ case 0xE: *arg0 = vm->mem->remainder; break;
/* not */ case 0xF: *arg0 = ~(*arg0); break;
/* xor */ case 0x10: *arg0 ^= *arg1; break;
/* or */ case 0x11: *arg0 |= *arg1; break;
/* and */ case 0x12: *arg0 &= *arg1; break;
/* shl */ case 0x13: *arg0 <<= *arg1; break;
/* shr */ case 0x14: *arg0 >>= *arg1; break;
/* cmp */ case 0x15: vm->pMemory->FLAGS = ((*arg0 == *arg1) | (*arg0 > *arg1) << 1); break;
/* call */ case 0x17: stack_push(vm->pMemory, instr_idx);
/* cmp */ case 0x15: vm->mem->FLAGS =
((*arg0 == *arg1) | (*arg0 > *arg1) << 1);
break;
/* call */ case 0x17: tvm_stack_push(vm->mem, instr_idx);
/* jmp */ case 0x16: *instr_idx = *arg0 - 1; break;
/* ret */ case 0x18: stack_pop(vm->pMemory, instr_idx); break;
/* je */ case 0x19: if(vm->pMemory->FLAGS & 0x1) *instr_idx = *arg0 - 1; break;
/* jne */ case 0x1A: if(!(vm->pMemory->FLAGS & 0x1)) *instr_idx = *arg0 - 1; break;
/* jg */ case 0x1B: if(vm->pMemory->FLAGS & 0x2) *instr_idx = *arg0 - 1; break;
/* jge */ case 0x1C: if(vm->pMemory->FLAGS & 0x3) *instr_idx = *arg0 - 1; break;
/* jl */ case 0x1D: if(!(vm->pMemory->FLAGS & 0x3)) *instr_idx = *arg0 - 1; break;
/* jle */ case 0x1E: if(!(vm->pMemory->FLAGS & 0x2)) *instr_idx = *arg0 - 1; break;
/* ret */ case 0x18: tvm_stack_pop(vm->mem, instr_idx);
break;
/* je */ case 0x19:
*instr_idx = (vm->mem->FLAGS & 0x1)
? *arg0 - 1 : *instr_idx;
break;
/* jne */ case 0x1A:
*instr_idx = (!(vm->mem->FLAGS & 0x1))
? *arg0 - 1 : *instr_idx;
break;
/* jg */ case 0x1B:
*instr_idx = (vm->mem->FLAGS & 0x2)
? *arg0 - 1 : *instr_idx;
break;
/* jge */ case 0x1C:
*instr_idx = (vm->mem->FLAGS & 0x3)
? *arg0 - 1 : *instr_idx;
break;
/* jl */ case 0x1D:
*instr_idx = (!(vm->mem->FLAGS & 0x3))
? *arg0 - 1 : *instr_idx;
break;
/* jle */ case 0x1E:
*instr_idx = (!(vm->mem->FLAGS & 0x2))
? *arg0 - 1 : *instr_idx;
break;
/* prn */ case 0x1F: printf("%i\n", *arg0);
};
}

View file

@ -4,27 +4,26 @@
#define KEY_LENGTH 64
#define HTAB_SIZE 4096
typedef struct tvm_htab_node_s
{
struct tvm_htab_node {
char *key;
int value;
void *valptr;
struct tvm_htab_node_s *next;
} tvm_htab_node_t;
struct tvm_htab_node *next;
};
typedef struct tvm_htab_s
{
struct tvm_htab_ctx {
unsigned int num_nodes;
unsigned int size;
tvm_htab_node_t **nodes;
} tvm_htab_t;
struct tvm_htab_node **nodes;
};
tvm_htab_t* htab_create();
void htab_destroy(tvm_htab_t *htab);
struct tvm_htab_ctx *tvm_htab_create();
void tvm_htab_destroy(struct tvm_htab_ctx *htab);
int htab_add(tvm_htab_t *htab, const char *key, int value);
int htab_add_ref(tvm_htab_t *htab, const char *key, const void *valptr, int len);
int htab_find(tvm_htab_t *htab, const char *key);
char *htab_find_ref(tvm_htab_t *htab, const char *key);
int tvm_htab_add(struct tvm_htab_ctx *htab, const char *key, int value);
int tvm_htab_add_ref(struct tvm_htab_ctx *htab,
const char *key, const void *valptr, int len);
int tvm_htab_find(struct tvm_htab_ctx *htab, const char *key);
char *tvm_htab_find_ref(struct tvm_htab_ctx *htab, const char *key);
#endif

View file

@ -6,16 +6,16 @@
#include "tvm_htab.h"
typedef struct tvm_lexer_s
{
struct tvm_lexer_ctx {
char **source_lines;
char ***tokens;
} tvm_lexer_t;
};
tvm_lexer_t *lexer_create();
void lexer_destroy(tvm_lexer_t *l);
struct tvm_lexer_ctx *lexer_create();
void tvm_lexer_destroy(struct tvm_lexer_ctx *l);
/* Tokenize the character array "source" into lines and tokens */
void lex(tvm_lexer_t *lexer, char *source, tvm_htab_t *defines);
void tvm_lex(struct tvm_lexer_ctx *lexer,
char *source, struct tvm_htab_ctx *defines);
#endif

View file

@ -6,28 +6,25 @@
#define MIN_MEMORY_SIZE (64 * 1024 * 1024) /* 64 MB */
typedef union
{
union tvm_reg_u {
int32_t i32;
int32_t *i32_ptr;
union
{
union {
int16_t h;
int16_t l;
} i16;
} tvm_register_t;
};
typedef struct
{
struct tvm_mem {
/*
Similar to x86 FLAGS register
0x1 EQUAL
0x2 GREATER
*/
* Similar to x86 FLAGS register
*
* 0x1 EQUAL
* 0x2 GREATER
*
*/
int FLAGS;
int remainder;
@ -35,10 +32,10 @@ typedef struct
void *mem_space;
int mem_space_size;
tvm_register_t *registers;
} tvm_memory_t;
union tvm_reg_u *registers;
};
tvm_memory_t *memory_create(size_t size);
void memory_destroy(tvm_memory_t *mem);
struct tvm_mem *tvm_mem_create(size_t size);
void tvm_mem_destroy(struct tvm_mem *mem);
#endif

View file

@ -1,12 +1,13 @@
#ifndef TVM_PARSER_H_
#define TVM_PARSER_H_
#include <tvm/tvm_program.h>
#include "tvm.h"
#include "tvm_program.h"
int parse_labels(tvm_program_t *p, const char ***tokens);
int parse_instructions(tvm_program_t *pProgram, const char ***tokens, tvm_memory_t *pMemory);
int tvm_parse_labels(struct tvm_ctx *vm, const char ***tokens);
int tvm_parse_program(struct tvm_ctx *vm, const char ***tokens);
int *tvm_add_value(tvm_program_t *p, const int val);
int *tvm_add_value(struct tvm_ctx *vm, const int val);
int tvm_parse_value(const char *str);
#endif

View file

@ -3,6 +3,6 @@
#include "tvm_htab.h"
int tvm_preprocess(char *src, int *src_len, tvm_htab_t *defines);
int tvm_preprocess(char *src, int *src_len, struct tvm_htab_ctx *defines);
#endif

View file

@ -8,30 +8,23 @@
#include "tvm_htab.h"
#include "tvm_memory.h"
typedef struct tvm_program_s
{
struct tvm_prog {
int start;
int num_instructions;
int *instr;
int ***args;
int num_instr;
int *instr;
int ***args;
int **values;
int num_values;
tvm_htab_t *defines;
tvm_htab_t *label_htab;
} tvm_program_t;
struct tvm_htab_ctx *defines;
struct tvm_htab_ctx *label_htab;
};
/* Create and initialize an empty program object */
tvm_program_t *program_create();
struct tvm_prog *tvm_prog_create();
/* Interpret a source file into bytecode, and store it in a program object */
int program_interpret(tvm_program_t *p, char *filename, tvm_memory_t *pMemory);
void program_destroy(tvm_program_t *p);
void tvm_prog_destroy(struct tvm_prog *p);
#endif

View file

@ -7,19 +7,20 @@
/* Initialize our stack by setting the base pointer and stack pointer */
inline void stack_create(tvm_memory_t *mem, size_t size)
static inline void tvm_stack_create(struct tvm_mem *mem, size_t size)
{
mem->registers[0x7].i32_ptr = ((int32_t *)mem->mem_space) + (size / sizeof(int32_t));
mem->registers[0x7].i32_ptr =
((int32_t *)mem->mem_space) + (size / sizeof(int32_t));
mem->registers[0x6].i32_ptr = mem->registers[0x7].i32_ptr;
}
inline void stack_push(tvm_memory_t *mem, int *item)
static inline void tvm_stack_push(struct tvm_mem *mem, int *item)
{
mem->registers[0x6].i32_ptr -= 1;
*mem->registers[0x6].i32_ptr = *item;
}
inline void stack_pop(tvm_memory_t *mem, int *dest)
static inline void tvm_stack_pop(struct tvm_mem *mem, int *dest)
{
*dest = *mem->registers[0x6].i32_ptr;
mem->registers[0x6].i32_ptr += 1;

24
include/tvm/tvm_tokens.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef _TVM_TOKENS_H_
#define _TVM_TOKENS_H_
#define TOK_INCLUDE "%include"
#define TOK_DEFINE "%define"
static const char *tvm_opcode_map[] = {
"nop", "int", "mov",
"push", "pop", "pushf", "popf",
"inc", "dec", "add", "sub", "mul", "div", "mod", "rem",
"not", "xor", "or", "and", "shl", "shr",
"cmp", "jmp", "call", "ret",
"je", "jne", "jg", "jge", "jl", "jle",
"prn", 0
};
static const char *tvm_register_map[] = {
"eax", "ebx", "ecx", "edx",
"esi", "edi", "esp", "ebp",
"eip",
"r08", "r09", "r10", "r11",
"r12", "r13", "r14", "r15", 0};
#endif

View file

@ -1,36 +1,86 @@
#include <tvm/tvm.h>
tvm_t *tvm_create(char *filename)
#include <tvm/tvm_lexer.h>
#include <tvm/tvm_parser.h>
struct tvm_ctx *tvm_vm_create(char *filename)
{
tvm_t *vm = (tvm_t*)calloc(1, sizeof(tvm_t));
struct tvm_ctx *vm =
(struct tvm_ctx *)calloc(1, sizeof(struct tvm_ctx));
vm->pMemory = memory_create(MIN_MEMORY_SIZE);
vm->pProgram = program_create();
vm->mem = tvm_mem_create(MIN_MEMORY_SIZE);
vm->prog = tvm_prog_create();
stack_create(vm->pMemory, MIN_STACK_SIZE);
tvm_stack_create(vm->mem, MIN_STACK_SIZE);
if(!vm || !vm->pMemory || !vm->pProgram) return NULL;
if (!vm || !vm->mem || !vm->prog)
return NULL;
return vm;
}
int tvm_interpret(tvm_t *vm, char *filename)
int tvm_vm_interpret(struct tvm_ctx *vm, char *filename)
{
if(program_interpret(vm->pProgram, filename, vm->pMemory) != 0) return 1;
FILE *filp = NULL;
int source_length = 0;
/* Attempt to open the file.
* If the file cannot be opened, try once more.
*/
if (filename) {
for (int i = 0; i < 2; i++) {
if (!filp)
filp = tvm_fopen(filename, ".vm", "r");
}
}
if (!filp) {
printf("File was not found, or does not exist. Unable to interpret.\n");
return 1;
}
source_length = tvm_flength(filp);
char *source = calloc(source_length, sizeof(char));
tvm_fcopy(source, source_length, filp);
fclose(filp);
int err = tvm_preprocess(source, &source_length, vm->prog->defines);
/* The preprocessor encountered a problem. */
if (err < 0)
return 1;
struct tvm_lexer_ctx *lexer_ctx = lexer_create();
tvm_lex(lexer_ctx, source, vm->prog->defines);
free(source);
if (tvm_parse_labels(vm, (const char ***)lexer_ctx->tokens) != 0)
return 1;
if (tvm_parse_program(vm, (const char ***)lexer_ctx->tokens) != 0)
return 1;
tvm_lexer_destroy(lexer_ctx);
return 0;
}
void tvm_destroy(tvm_t *vm)
void tvm_vm_run(struct tvm_ctx *vm)
{
if(vm && vm->pMemory) memory_destroy(vm->pMemory);
if(vm && vm->pProgram) program_destroy(vm->pProgram);
if(vm) free(vm);
int *instr_idx = &vm->mem->registers[0x8].i32;
*instr_idx = vm->prog->start;
for (; vm->prog->instr[*instr_idx] != -0x1; ++(*instr_idx))
tvm_step(vm, instr_idx);
}
void tvm_run(tvm_t *vm)
void tvm_vm_destroy(struct tvm_ctx *vm)
{
int *instr_idx = &vm->pMemory->registers[0x8].i32; *instr_idx = vm->pProgram->start;
for(;vm->pProgram->instr[*instr_idx] != -0x1; ++(*instr_idx)) tvm_step(vm, instr_idx);
if (vm && vm->mem)
tvm_mem_destroy(vm->mem);
if (vm && vm->prog)
tvm_prog_destroy(vm->prog);
if (vm)
free(vm);
}

View file

@ -2,43 +2,45 @@
FILE *tvm_fopen(const char *filename, const char *extension, const char *mode)
{
FILE *pFile = NULL;
FILE *filp = NULL;
size_t fname_chars = strlen(filename) + strlen(extension) + 1;
char *fname = calloc(fname_chars, sizeof(char));
int i;
strcpy(fname, filename);
for(i = 0; i < 2 && !pFile; i++)
{
if(i > 0) strcat(fname, extension);
pFile = fopen(fname, mode);
for (i = 0; i < 2 && !filp; i++) {
if (i > 0)
strcat(fname, extension);
filp = fopen(fname, mode);
}
free(fname);
return pFile;
return filp;
}
int tvm_fcopy(char *dest, size_t size, FILE* src)
int tvm_fcopy(char *dest, size_t size, FILE *filp)
{
size_t i;
long pos = ftell(src);
long pos = ftell(filp);
for(i = 0; i < size && !feof(src); i++) dest[i] = fgetc(src);
for (i = 0; i < size && !feof(filp); i++)
dest[i] = fgetc(filp);
dest[i - 1] = 0;
fseek(src, pos, SEEK_SET);
fseek(filp, pos, SEEK_SET);
return 0;
}
int tvm_flength(FILE *f)
int tvm_flength(FILE *filp)
{
int length;
long pos = ftell(f);
long pos = ftell(filp);
for(length = 0; !feof(f); length++) fgetc(f);
fseek(f, pos, SEEK_SET);
for (length = 0; !feof(filp); length++)
fgetc(filp);
fseek(filp, pos, SEEK_SET);
return length;
}

View file

@ -5,27 +5,27 @@
#define HTAB_LOAD_FACTOR 0.7
tvm_htab_t *htab_create()
struct tvm_htab_ctx *tvm_htab_create()
{
tvm_htab_t *htab = (tvm_htab_t *)calloc(1, sizeof(tvm_htab_t));
struct tvm_htab_ctx *htab =
(struct tvm_htab_ctx *)calloc(1, sizeof(struct tvm_htab_ctx));
htab->size = HTAB_SIZE;
htab->nodes = (tvm_htab_node_t **)calloc(htab->size, sizeof(tvm_htab_node_t *));
htab->nodes = (struct tvm_htab_node **)calloc(
htab->size, sizeof(struct tvm_htab_node *));
htab->num_nodes = 0;
return htab;
}
void htab_destroy(tvm_htab_t *htab)
void tvm_htab_destroy(struct tvm_htab_ctx *htab)
{
int i;
tvm_htab_node_t *node, *next;
struct tvm_htab_node *node, *next;
for(i = 0; i < htab->size; i++)
{
for (int i = 0; i < htab->size; i++) {
node = htab->nodes[i];
while(node)
{
while (node) {
next = node->next;
if(node->valptr)
if (node->valptr)
free(node->valptr);
free(node->key);
free(node);
@ -37,43 +37,48 @@ void htab_destroy(tvm_htab_t *htab)
free(htab);
}
static inline unsigned htab_hash(const char *k, const unsigned int size)
static inline unsigned int htab_hash(const char *k, const unsigned int size)
{
unsigned int hash = 1;
char *c; for(c = (char*)k; *c; c++)
char *c; for (c = (char *)k; *c; c++)
hash += (hash << *c) - *c;
return hash % size;
}
static void htab_rehash(tvm_htab_t *orig, unsigned int size)
static void htab_rehash(struct tvm_htab_ctx *orig, unsigned int size)
{
int i;
tvm_htab_node_t *node, *next;
tvm_htab_t *new;
struct tvm_htab_node *node, *next;
struct tvm_htab_ctx *new;
new = (tvm_htab_t *)calloc(1, sizeof(tvm_htab_t));
new->nodes = (tvm_htab_node_t **)calloc(size, sizeof(tvm_htab_node_t *));
new = (struct tvm_htab_ctx *)calloc(1, sizeof(struct tvm_htab_ctx));
new->nodes = (struct tvm_htab_node **)calloc(
size, sizeof(struct tvm_htab_node *));
new->size = size;
new->num_nodes = 0;
/* Traverse the original hash table, rehashing
every entry into the new table and deleting
original entries */
for(i = 0; i < orig->size; i++)
{
* every entry into the new table and deleting
* original entries
*/
for (i = 0; i < orig->size; i++) {
node = orig->nodes[i];
while(node)
{
while (node) {
next = node->next;
if (node->valptr)
{
htab_add_ref(new, node->key, node->valptr, strlen(node->valptr) + 1);
if (node->valptr) {
tvm_htab_add_ref(
new, node->key,
node->valptr,
strlen(node->valptr) + 1
);
free(node->valptr);
}
else
htab_add(new, node->key, node->value);
} else
tvm_htab_add(new, node->key, node->value);
free(node->key);
free(node);
node = next;
@ -83,24 +88,25 @@ static void htab_rehash(tvm_htab_t *orig, unsigned int size)
free(orig->nodes);
/* Transpose the new hash table onto the old one */
memcpy(orig, new, sizeof(tvm_htab_t));
memcpy(orig, new, sizeof(struct tvm_htab_ctx));
free(new);
}
static tvm_htab_node_t *htab_add_core(tvm_htab_t *htab, const char *k)
static struct tvm_htab_node *htab_add_core(
struct tvm_htab_ctx *htab, const char *k)
{
/* Increase bucket count and rehash if the
load factor is too high */
if((float)++htab->num_nodes / htab->size > HTAB_LOAD_FACTOR)
* load factor is too high
*/
if ((float) ++htab->num_nodes / htab->size > HTAB_LOAD_FACTOR)
htab_rehash(htab, htab->num_nodes * 2);
int hash = htab_hash(k, htab->size);
tvm_htab_node_t *node = htab->nodes[hash];
tvm_htab_node_t *prev = NULL;
struct tvm_htab_node *node = htab->nodes[hash];
struct tvm_htab_node *prev = NULL;
if(node)
{
while(node->next)
if (node) {
while (node->next)
node = node->next;
prev = node;
@ -109,22 +115,24 @@ static tvm_htab_node_t *htab_add_core(tvm_htab_t *htab, const char *k)
/* Allocate space, and copy the key/value pair. */
node = calloc(1, sizeof(tvm_htab_node_t));
node = calloc(1, sizeof(struct tvm_htab_node));
node->key = (char *)calloc((strlen(k) + 1), sizeof(char));
strcpy(node->key, k);
if(prev) prev->next = node;
else htab->nodes[hash] = node; /* root node */
if (prev)
prev->next = node;
else
htab->nodes[hash] = node; /* root node */
node->next = NULL;
return node;
}
int htab_add(tvm_htab_t *htab, const char *key, int value)
int tvm_htab_add(struct tvm_htab_ctx *htab, const char *key, int value)
{
tvm_htab_node_t *node = htab_add_core(htab, key);
struct tvm_htab_node *node = htab_add_core(htab, key);
if (!node)
return -1;
@ -134,9 +142,10 @@ int htab_add(tvm_htab_t *htab, const char *key, int value)
return 0;
}
int htab_add_ref(tvm_htab_t *htab, const char *key, const void *valptr, int len)
int tvm_htab_add_ref(
struct tvm_htab_ctx *htab, const char *key, const void *valptr, int len)
{
tvm_htab_node_t *node = htab_add_core(htab, key);
struct tvm_htab_node *node = htab_add_core(htab, key);
if (!node)
return -1;
@ -147,35 +156,35 @@ int htab_add_ref(tvm_htab_t *htab, const char *key, const void *valptr, int len)
return 0;
}
static tvm_htab_node_t *htab_find_core(tvm_htab_t *htab, const char *key)
static struct tvm_htab_node *htab_find_core(
struct tvm_htab_ctx *htab, const char *key)
{
int hash = htab_hash(key, htab->size);
tvm_htab_node_t *node = htab->nodes[hash];
struct tvm_htab_node *node = htab->nodes[hash];
while (node)
{
if(!strcmp(node->key, key))
while (node) {
if (!strcmp(node->key, key))
return node;
else
node = node->next;
node = node->next;
}
return NULL;
}
int htab_find(tvm_htab_t *htab, const char *key)
int tvm_htab_find(struct tvm_htab_ctx *htab, const char *key)
{
tvm_htab_node_t *node = htab_find_core(htab, key);
if(!node)
struct tvm_htab_node *node = htab_find_core(htab, key);
if (!node)
return -1;
return node->value;
}
char *htab_find_ref(tvm_htab_t *htab, const char *key)
char *tvm_htab_find_ref(struct tvm_htab_ctx *htab, const char *key)
{
tvm_htab_node_t *node = htab_find_core(htab, key);
struct tvm_htab_node *node = htab_find_core(htab, key);
if (!node)
return NULL;

View file

@ -4,19 +4,19 @@
#include <stdlib.h>
#include <string.h>
tvm_lexer_t *lexer_create()
struct tvm_lexer_ctx *lexer_create()
{
return (tvm_lexer_t *)calloc(1, sizeof(tvm_lexer_t));
return (struct tvm_lexer_ctx *)calloc(1, sizeof(struct tvm_lexer_ctx));
}
void lexer_destroy(tvm_lexer_t *lexer)
void tvm_lexer_destroy(struct tvm_lexer_ctx *lexer)
{
for(int i = 0; lexer->source_lines[i]; i++) free(lexer->source_lines[i]);
for (int i = 0; lexer->source_lines[i]; i++)
free(lexer->source_lines[i]);
free(lexer->source_lines);
for(int i = 0; lexer->tokens[i]; i++)
{
for(int j = 0; j < MAX_TOKENS; j++)
for (int i = 0; lexer->tokens[i]; i++) {
for (int j = 0; j < MAX_TOKENS; j++)
free(lexer->tokens[i][j]);
free(lexer->tokens[i]);
@ -26,50 +26,51 @@ void lexer_destroy(tvm_lexer_t *lexer)
free(lexer);
}
void lex(tvm_lexer_t *lexer, char *source, tvm_htab_t *defines)
void tvm_lex(
struct tvm_lexer_ctx *lexer, char *source, struct tvm_htab_ctx *defines)
{
int i, j;
char *pToken, *pLine = strtok(source, "\n");
char *tokp, *linep = strtok(source, "\n");
/* Split the source into individual lines */
for(i = 0; pLine; i++)
{
lexer->source_lines = (char **)realloc(lexer->source_lines, sizeof(char *) * (i + 2));
lexer->source_lines[i] = (char *)calloc(1, strlen(pLine) + 1);
for (i = 0; linep; i++) {
lexer->source_lines = (char **)realloc(
lexer->source_lines, sizeof(char *) * (i + 2));
lexer->source_lines[i] = (char *)calloc(1, strlen(linep) + 1);
strcpy(lexer->source_lines[i], pLine);
strcpy(lexer->source_lines[i], linep);
/* Ignore comments delimited by '#' */
char* comment_delimiter = strchr(lexer->source_lines[i], '#');
char *comment_delimiter = strchr(lexer->source_lines[i], '#');
if(comment_delimiter) *comment_delimiter = 0;
if (comment_delimiter)
*comment_delimiter = 0;
pLine = strtok(NULL, "\n");
linep = strtok(NULL, "\n");
}
/* NULL terminate the array to make iteration later easier*/
lexer->source_lines[i] = NULL;
/* Split the source into individual tokens */
for(i = 0; lexer->source_lines[i]; i++)
{
lexer->tokens = (char ***)realloc(lexer->tokens, sizeof(char **) * (i + 2));
for (i = 0; lexer->source_lines[i]; i++) {
lexer->tokens = (char ***)realloc(
lexer->tokens, sizeof(char **) * (i + 2));
lexer->tokens[i] = (char **)calloc(MAX_TOKENS, sizeof(char *));
pToken = strtok(lexer->source_lines[i], " \t,");
tokp = strtok(lexer->source_lines[i], " \t,");
for(j = 0; (pToken && j < MAX_TOKENS); j++)
{
char *token = htab_find_ref(defines, pToken);
token = token ? token : pToken;
for (j = 0; (tokp && j < MAX_TOKENS); j++) {
char *token = tvm_htab_find_ref(defines, tokp);
lexer->tokens[i][j] = (char *)calloc(1, (strlen(token) + 1));
token = token ? token : tokp;
lexer->tokens[i][j] = calloc(1, (strlen(token) + 1));
strcpy(lexer->tokens[i][j], token);
pToken = strtok(NULL, " \t,");
tokp = strtok(NULL, " \t,");
}
}
lexer->tokens[i] = NULL;
htab_destroy(defines);
tvm_htab_destroy(defines);
}

View file

@ -5,11 +5,12 @@
#define NUM_REGISTERS 17
tvm_memory_t *memory_create(size_t size)
struct tvm_mem *tvm_mem_create(size_t size)
{
tvm_memory_t *m = (tvm_memory_t *)calloc(1, sizeof(tvm_memory_t));
struct tvm_mem *m =
(struct tvm_mem *)calloc(1, sizeof(struct tvm_mem));
m->registers = calloc(NUM_REGISTERS, sizeof(tvm_register_t));
m->registers = calloc(NUM_REGISTERS, sizeof(union tvm_reg_u));
m->mem_space_size = size;
m->mem_space = (int *)calloc(size, 1);
@ -17,7 +18,7 @@ tvm_memory_t *memory_create(size_t size)
return m;
}
void memory_destroy(tvm_memory_t *m)
void tvm_mem_destroy(struct tvm_mem *m)
{
free(m->mem_space);
free(m->registers);

View file

@ -1,139 +1,212 @@
#include <tvm/tvm_parser.h>
#include <tvm/tvm_file.h>
#include <tvm/tvm_lexer.h>
#include <tvm/tvm_tokens.h>
const char *tvm_opcode_map[] = {"nop", "int", "mov", "push", "pop", "pushf", "popf", "inc", "dec", "add", "sub", "mul", "div", "mod", "rem",
"not", "xor", "or", "and", "shl", "shr", "cmp", "jmp", "call", "ret", "je", "jne", "jg", "jge", "jl", "jle", "prn", 0};
const char *tvm_register_map[] = {"eax", "ebx", "ecx", "edx", "esi", "edi", "esp", "ebp", "eip", "r08", "r09", "r10", "r11", "r12", "r13", "r14", "r15", 0};
static int *token_to_register(const char *token, tvm_memory_t *pMemory);
static int *token_to_register(const char *token, struct tvm_mem *mem);
static int instr_to_opcode(const char *instr);
int parse_labels(tvm_program_t *p, const char ***tokens)
int tvm_parse_labels(struct tvm_ctx *vm, const char ***tokens)
{
int num_instructions = 0;
for(int i = 0; tokens[i]; i++)
{
int num_instr = 0;
struct tvm_prog *p = vm->prog;
for (int i = 0; tokens[i]; i++) {
int valid_instruction = 0;
for(int token_idx = 0; token_idx < MAX_TOKENS; token_idx++)
{
for (int token_idx = 0; token_idx < MAX_TOKENS; token_idx++) {
/* If the token is empty, or non-existent, skip it */
if(!tokens[i][token_idx]) continue;
if (!tokens[i][token_idx])
continue;
/* Figure out if the source line we're on contains a valid instruction */
if(instr_to_opcode(tokens[i][token_idx]) != -1) valid_instruction = 1;
/* Check the source line for a valid instruction */
if (instr_to_opcode(tokens[i][token_idx]) != -1)
valid_instruction = 1;
/* Figure out if the token we're dealing with has a label delimiter */
char* label_delimiter = strchr(tokens[i][token_idx], ':');
if(label_delimiter == NULL) continue;
/* Check for a label delimiter*/
char *label_delimiter = strchr(
tokens[i][token_idx], ':');
if (label_delimiter == NULL)
continue;
*label_delimiter = 0;
/* If the label is "start," set the program to begin there */
if(strcmp(tokens[i][token_idx], "start") == 0) p->start = num_instructions;
/* If the label is "start," make it the entry point */
if (strcmp(tokens[i][token_idx], "start") == 0)
p->start = num_instr;
/* Check if the label already exists */
if(htab_find(p->label_htab, tokens[i][token_idx]) != -1)
{
int label_addr = tvm_htab_find(
p->label_htab, tokens[i][token_idx]);
if (label_addr != -1) {
printf("Label '%s' defined twice\n", tokens[i][token_idx]);
return 1;
}
else
{
/* Add that fucker to the hash table with the corresponding instruction index */
htab_add(p->label_htab, tokens[i][token_idx], num_instructions);
}
tvm_htab_add(
p->label_htab,
tokens[i][token_idx],
num_instr
);
}
if(valid_instruction) num_instructions++;
if (valid_instruction)
num_instr++;
}
return 0;
}
int parse_instructions(tvm_program_t *p, const char ***tokens, tvm_memory_t *pMemory)
/* This function takes the instruction tokens, and location of the
* instruction inside the line, parses the arguments, and returns a pointer
* to the heap where they're stored.
*/
static int **tvm_parse_args(
struct tvm_ctx *vm, const char **instr_tokens, int *instr_place)
{
int **args = calloc(sizeof(int *), MAX_ARGS);
for (int i = 0; i < MAX_ARGS; ++i) {
if (!instr_tokens[*instr_place+1 + i]
|| !strlen(instr_tokens[*instr_place+1 + i]))
continue;
char *newline = strchr(instr_tokens[*instr_place+1 + i], '\n');
if (newline)
*newline = 0;
/* Check to see if the token specifies a register */
int *regp = token_to_register(
instr_tokens[*instr_place+1 + i], vm->mem);
if (regp) {
args[i] = regp;
continue;
}
/* Check to see whether the token specifies an address */
if (instr_tokens[*instr_place+1 + i][0] == '[') {
char *end_symbol = strchr(
instr_tokens[*instr_place+1 + i], ']');
if (end_symbol) {
*end_symbol = 0;
args[i] = &((int *)vm->mem->mem_space)[
tvm_parse_value(instr_tokens[
*instr_place+1 + i] + 1)];
continue;
}
}
/* Check if the argument is a label */
int addr = tvm_htab_find(
vm->prog->label_htab, instr_tokens[*instr_place+1 + i]);
if (addr != -1) {
args[i] = tvm_add_value(vm, addr);
continue;
}
/* Fuck it, parse it as a value */
args[i] = tvm_add_value(
vm, tvm_parse_value(instr_tokens[*instr_place+1 + i]));
}
int args_set = 0;
for (int i = 0; i < MAX_ARGS; i++) {
if (args[i])
args_set = 1;
}
if (!args_set)
free(args);
return args;
}
/* This is a helper function that converts one instruction,
* from one line of code, to tvm bytecode
*/
static int tvm_parse_instr(
struct tvm_ctx *vm, const char **instr_tokens, int *instr_place)
{
for (int token_idx = 0; token_idx < MAX_TOKENS; token_idx++) {
/* Skip empty tokens */
if (!instr_tokens[token_idx])
continue;
int opcode = instr_to_opcode(instr_tokens[token_idx]);
if (opcode == -1)
continue;
if (instr_place)
*instr_place = token_idx;
vm->prog->num_instr++;
return opcode;
}
return -1;
}
int tvm_parse_program(
struct tvm_ctx *vm, const char ***tokens)
{
int line_idx;
for(line_idx = 0; tokens[line_idx]; line_idx++)
{
p->instr = (int *)realloc(p->instr, sizeof(int) * (line_idx + 2));
p->instr[line_idx] = 0;
p->args = (int ***)realloc(p->args, sizeof(int **) * (line_idx + 2));
p->args[line_idx] = (int **)calloc(MAX_ARGS, sizeof(int *));
for (line_idx = 0; tokens[line_idx]; line_idx++) {
int instr_place;
int token_idx;
for(token_idx = 0; token_idx < MAX_TOKENS; token_idx++)
{
int opcode = 0;
int opcode = tvm_parse_instr(
vm, tokens[line_idx], &instr_place);
/* Skip empty tokens */
if(!tokens[line_idx][token_idx]) continue;
int **args = tvm_parse_args(
vm, tokens[line_idx], &instr_place);
opcode = instr_to_opcode(tokens[line_idx][token_idx]);
if (opcode == -1 || !args)
continue;
/* If it *isn't* an opcode, skip trying to parse arguments */
if(opcode == -1) continue;
void *newptr;
int i, instr_idx = 0, num_instr = p->num_instructions;
p->instr[p->num_instructions++] = opcode;
newptr = realloc(
vm->prog->instr, sizeof(int) * (vm->prog->num_instr+1));
for(i = ++token_idx; i < (token_idx + 2); ++i)
{
if(!tokens[line_idx][i] || strlen(tokens[line_idx][i]) <= 0) continue;
if (newptr != NULL) {
vm->prog->instr = newptr;
vm->prog->instr[vm->prog->num_instr - 1] = opcode;
} else
return -1;
char *newline = strchr(tokens[line_idx][i], '\n');
if(newline) *newline = 0;
newptr = realloc(
vm->prog->args,
sizeof(int **) * (vm->prog->num_instr+1));
/* Check to see if the token specifies a register */
int *pRegister = token_to_register(tokens[line_idx][i], pMemory);
if(pRegister)
{
p->args[num_instr][i - token_idx] = pRegister;
continue;
}
if (newptr != NULL)
vm->prog->args = (int ***)newptr;
else
return -1;
/* Check to see whether the token specifies an address */
if(tokens[line_idx][i][0] == '[')
{
char *end_symbol = strchr(tokens[line_idx][i], ']');
if(end_symbol)
{
*end_symbol = 0;
p->args[num_instr][i - token_idx] = &((int *)pMemory->mem_space)[tvm_parse_value(tokens[line_idx][i] + 1)];
continue;
}
}
/* Check if the argument is a label */
instr_idx = htab_find(p->label_htab, tokens[line_idx][i]);
if(instr_idx >= 0)
{
p->args[num_instr][i - token_idx] = tvm_add_value(p, instr_idx);
continue;
}
/* Fuck it, parse it as a value */
p->args[num_instr][i - token_idx] = tvm_add_value(p, tvm_parse_value(tokens[line_idx][i]));
}
}
vm->prog->args[vm->prog->num_instr - 1] = (int **)args;
}
p->args[line_idx] = NULL;
p->instr[line_idx] = -0x1;
vm->prog->args[vm->prog->num_instr] = NULL;
vm->prog->instr[vm->prog->num_instr] = -0x1;
return 0;
}
int* token_to_register(const char *token, tvm_memory_t *pMemory)
int *token_to_register(const char *token, struct tvm_mem *mem)
{
for(int i = 0; tvm_register_map[i]; i++)
{
if(strcmp(token, tvm_register_map[i]) == 0)
return &pMemory->registers[i].i32;
for (int i = 0; tvm_register_map[i]; i++) {
if (strcmp(token, tvm_register_map[i]) == 0)
return &mem->registers[i].i32;
}
return NULL;
@ -141,15 +214,17 @@ int* token_to_register(const char *token, tvm_memory_t *pMemory)
int instr_to_opcode(const char *instr)
{
for(int i = 0; tvm_opcode_map[i]; i++)
if(strcmp(instr, tvm_opcode_map[i]) == 0)
for (int i = 0; tvm_opcode_map[i]; i++)
if (strcmp(instr, tvm_opcode_map[i]) == 0)
return i;
return -1;
}
int *tvm_add_value(tvm_program_t *p, const int val)
int *tvm_add_value(struct tvm_ctx *vm, const int val)
{
struct tvm_prog *p = vm->prog;
p->values = realloc(p->values, sizeof(int *) * (p->num_values + 1));
p->values[p->num_values] = (int *)calloc(1, sizeof(int));
@ -162,15 +237,19 @@ int tvm_parse_value(const char *str)
{
char *delimiter = strchr(str, '|'), base = 0;
if(delimiter)
{
if (delimiter) {
char *identifier = delimiter + 1;
switch(*identifier)
{
case 'h': base = 16; break;
case 'b': base = 2; break;
default: base = 0; break;
switch (*identifier) {
case 'h':
base = 16;
break;
case 'b':
base = 2;
break;
default:
base = 0;
break;
}
}

View file

@ -1,111 +1,145 @@
#include <tvm/tvm_preprocessor.h>
#include <tvm/tvm_tokens.h>
#include <tvm/tvm_file.h>
#include <string.h>
int tvm_preprocess(char *src, int *src_len, tvm_htab_t *defines)
static int process_includes(
char *src, int *src_len, struct tvm_htab_ctx *defines)
{
char* pp_directive_delimiter = NULL;
if((pp_directive_delimiter = strstr(src, "%include")))
{
char *strbegin = pp_directive_delimiter, *strend = strchr(strbegin, '\n');
char *pp_directive_delimiter = strstr(src, TOK_INCLUDE);
if(!strend || !strbegin) return 0;
if (!pp_directive_delimiter)
return 0;
int linelen = strend - strbegin;
char* temp_str = calloc(linelen + 1, sizeof(char));
memcpy(temp_str, strbegin, linelen);
char *strbegin = pp_directive_delimiter,
*strend = strchr(strbegin, '\n');
char *filename = (strchr(temp_str, ' ') + 1);
if (!strend || !strbegin)
return 0;
FILE* pFile = tvm_fopen(filename, ".vm", "r");
if(!pFile)
{
printf("Unable to open file \"%s\"\n", filename);
return -1;
}
int linelen = strend - strbegin;
char *temp_str = calloc(linelen + 1, sizeof(char));
free(temp_str);
memcpy(temp_str, strbegin, linelen);
size_t addition_len = tvm_flength(pFile);
char *addition_str = calloc(addition_len, sizeof(char));
tvm_fcopy(addition_str, addition_len, pFile);
fclose(pFile);
char *filename = (strchr(temp_str, ' ') + 1);
FILE *filp = tvm_fopen(filename, ".vm", "r");
size_t first_block_len = (strbegin - src);
size_t second_block_len = ((src + *src_len) - strend);
size_t new_src_len = (first_block_len + addition_len + second_block_len);
src = (char *)realloc((char *)src, sizeof(char) * new_src_len);
src[new_src_len] = 0;
memmove(&src[first_block_len + addition_len], strend, second_block_len);
memcpy(&src[first_block_len], addition_str, addition_len);
// Fuckin' hack
for(int i = 0; i < new_src_len; i++) if(src[i] == 0) src[i] = ' ';
*src_len = strlen(src);
return 1;
}
else if((pp_directive_delimiter = strstr(src, "%define ")))
{
char *begin = pp_directive_delimiter;
char *end = strchr(begin, '\n');
if(!end) return 0;
int offset = strlen("%define ");
if(begin + offset >= end)
{
printf("Define missing arguments.\n");
return -1;
}
int length = (end - (begin + offset));
char tempstr[length + 1];
memset(tempstr, 0, length + 1);
memcpy(tempstr, begin + offset, length);
char *keystr = tempstr;
char *valstr = strchr(tempstr, ' ');
/* If there is a value, seperate the key and value
with a null character. */
if(valstr)
{
*valstr = 0;
valstr += 1;
}
if(!keystr || !valstr)
{
printf("Define missing arguments.\n");
return -1;
}
if(htab_find(defines, keystr) < 0)
htab_add_ref(defines, keystr, valstr, strlen(valstr) + 1);
else
{
printf("Multiple definitions for %s.\n", keystr);
return -1;
}
/* Remove the define line so it is not processed again. */
size_t new_length = *src_len - (end - begin);
size_t first_block_len = begin - src;
size_t second_block_len = (src + *src_len) - end;
memmove(&src[first_block_len], end, second_block_len);
src = realloc(src, sizeof(char) * new_length);
*src_len = new_length;
return 1;
if (!filp) {
printf("Unable to open file \"%s\"\n", filename);
return -1;
}
return 0;
free(temp_str);
size_t addition_len = tvm_flength(filp);
char *addition_str = calloc(addition_len, sizeof(char));
tvm_fcopy(addition_str, addition_len, filp);
fclose(filp);
size_t first_block_len = (strbegin - src);
size_t second_block_len = ((src + *src_len) - strend);
size_t new_src_len = (
first_block_len + addition_len + second_block_len);
src = (char *)realloc((char *)src, sizeof(char) * new_src_len);
src[new_src_len] = 0;
memmove(&src[first_block_len + addition_len], strend, second_block_len);
memcpy(&src[first_block_len], addition_str, addition_len);
/* Fuckin' hack */
for (int i = 0; i < new_src_len; i++) {
if (src[i] == 0)
src[i] = ' ';
}
*src_len = strlen(src);
return 1;
}
static int process_defines(
char *src, int *src_len, struct tvm_htab_ctx *defines)
{
char *pp_directive_delimiter = strstr(src, TOK_DEFINE);
if (!pp_directive_delimiter)
return 0;
char *begin = pp_directive_delimiter;
char *end = strchr(begin, '\n');
if (!end)
return 0;
int offset = strlen(TOK_DEFINE) + 1;
if (begin + offset >= end) {
printf("Define missing arguments.\n");
return -1;
}
int length = (end - (begin + offset));
char tempstr[length + 1];
memset(tempstr, 0, length + 1);
memcpy(tempstr, begin + offset, length);
char *keystr = tempstr;
char *valstr = strchr(tempstr, ' ');
/* If there is a value, seperate the key and value
* with a null character.
*/
if (valstr) {
*valstr = 0;
valstr += 1;
}
if (!keystr || !valstr) {
printf("Define missing arguments.\n");
return -1;
}
if (tvm_htab_find(defines, keystr) < 0)
tvm_htab_add_ref(defines, keystr, valstr, strlen(valstr) + 1);
else {
printf("Multiple definitions for %s.\n", keystr);
return -1;
}
/* Remove the define line so it is not processed again. */
size_t new_length = *src_len - (end - begin);
size_t first_block_len = begin - src;
size_t second_block_len = (src + *src_len) - end;
memmove(&src[first_block_len], end, second_block_len);
src = realloc(src, sizeof(char) * new_length);
*src_len = new_length;
return 1;
}
static int preprocess_pass(
char *src, int *src_len, struct tvm_htab_ctx *defines)
{
int ret = 0;
ret += process_includes(src, src_len, defines);
ret += process_defines(src, src_len, defines);
return ret;
}
int tvm_preprocess(char *src, int *src_len, struct tvm_htab_ctx *defines)
{
int ret = 1;
while (ret > 0)
ret = preprocess_pass(src, src_len, defines);
return ret;
}

View file

@ -3,73 +3,35 @@
#include <tvm/tvm_preprocessor.h>
#include <tvm/tvm_lexer.h>
#include <tvm/tvm_parser.h>
#include <tvm/tvm.h>
tvm_program_t *program_create()
struct tvm_prog *tvm_prog_create()
{
tvm_program_t *p = (tvm_program_t *)calloc(1, sizeof(tvm_program_t));
p->label_htab = htab_create();
p->defines = htab_create();
struct tvm_prog *p = calloc(1, sizeof(struct tvm_prog));
p->label_htab = tvm_htab_create();
p->defines = tvm_htab_create();
return p;
}
void program_destroy(tvm_program_t *p)
void tvm_prog_destroy(struct tvm_prog *p)
{
htab_destroy(p->label_htab);
tvm_htab_destroy(p->label_htab);
if(p->values)
{
for(int i = 0; i < p->num_values; i++) free(p->values[i]);
if (p->values) {
for (int i = 0; i < p->num_values; i++)
free(p->values[i]);
free(p->values);
}
if(p->args)
{
for(int i = 0; p->args[i]; i++) free(p->args[i]);
if (p->args) {
for (int i = 0; p->args[i]; i++)
free(p->args[i]);
free(p->args);
}
if(p->instr) free(p->instr);
if (p->instr)
free(p->instr);
free(p);
}
int program_interpret(tvm_program_t *p, char *filename, tvm_memory_t *pMemory)
{
FILE *pFile = NULL;
int source_length = 0;
/* Attempt to open the file. If the file cannot be opened, try once more. */
if(filename)
for(int i = 0; i < 2; i++)
if(!pFile) pFile = tvm_fopen(filename, ".vm", "r");
if(!pFile)
{
printf("File was not found, or does not exist. Unable to interpret.\n");
return 1;
}
source_length = tvm_flength(pFile);
char *source = calloc(source_length, sizeof(char));
tvm_fcopy(source, source_length, pFile);
fclose(pFile);
int err = 0;
while((err = tvm_preprocess(source, &source_length, p->defines)) > 0);
/* The preprocessor encountered a problem. */
if (err < 0)
return 1;
tvm_lexer_t *lexer_ctx = lexer_create();
lex(lexer_ctx, source, p->defines);
free(source);
if(parse_labels(p, (const char ***)lexer_ctx->tokens) != 0) return 1;
if(parse_instructions(p, (const char ***)lexer_ctx->tokens, pMemory) != 0) return 1;
lexer_destroy(lexer_ctx);
return 0;
}

View file

@ -3,12 +3,14 @@
#include <tvm/tvm.h>
int main(int argc, char** argv)
int main(int argc, char **argv)
{
tvm_t* vm = tvm_create();
if(vm != NULL && tvm_interpret(vm, argv[1]) == 0) tvm_run(vm);
struct tvm_ctx *vm = tvm_vm_create();
tvm_destroy(vm);
if (vm != NULL && tvm_vm_interpret(vm, argv[1]) == 0)
tvm_vm_run(vm);
tvm_vm_destroy(vm);
return 0;
}

View file

@ -3,10 +3,10 @@
int main(int argc, char **argv)
{
tvm_t *vm = tvm_create();
if(vm != NULL && tvm_interpret(vm, argv[1]) == 0) tdb_shell(vm);
struct tvm_ctx *vm = tvm_vm_create();
if(vm != NULL && tvm_vm_interpret(vm, argv[1]) == 0) tdb_shell(vm);
tvm_destroy(vm);
tvm_vm_destroy(vm);
return 0;
}

View file

@ -1,5 +1,6 @@
#include "tdb.h"
#include <tvm/tvm.h>
#include <tvm/tvm_parser.h>
#include <stdio.h>
@ -12,7 +13,7 @@ const char *commands[] = {"q", "run", "break", "step", "continue", 0};
static void tokenize(char *str, char **tokens);
static int cmd_to_idx(char *cmd);
void tdb_shell(tvm_t *vm)
void tdb_shell(struct tvm_ctx *vm)
{
int run = 1, i;
int running = 0;
@ -21,11 +22,11 @@ void tdb_shell(tvm_t *vm)
char str[MAX_INPUT_LENGTH];
int num_breakpoints = 0;
tdb_breakpoint_t *breakpoints = NULL;
struct tdb_breakpoint *breakpoints = NULL;
for(i = 0; i < MAX_TOKENS; i++) tokens[i] = malloc(TOKEN_LENGTH);
vm->pMemory->registers[0x8].i32 = vm->pProgram->start;
vm->mem->registers[0x8].i32 = vm->prog->start;
while(run && !feof(stdin))
{
@ -45,18 +46,18 @@ void tdb_shell(tvm_t *vm)
case 0x0: run = 0; break;
case 0x1: if(running) printf("The program is already running.\n");
else { retcode = tdb_run(vm, breakpoints, num_breakpoints); running = 1; } break;
case 0x2: breakpoints = realloc(breakpoints, sizeof(tdb_breakpoint_t) * ++num_breakpoints);
case 0x2: breakpoints = realloc(breakpoints, sizeof(struct tdb_breakpoint) * ++num_breakpoints);
breakpoints[num_breakpoints - 1].address = tvm_parse_value(tokens[1]); break;
case 0x3: tvm_step(vm, &vm->pMemory->registers[0x8].i32);
vm->pMemory->registers[0x8].i32++;
printf("Advancing instruction pointer to %i\n", vm->pMemory->registers[0x8].i32); break;
case 0x4: tvm_step(vm, &vm->pMemory->registers[0x8].i32);
vm->pMemory->registers[0x8].i32++;
case 0x3: tvm_step(vm, &vm->mem->registers[0x8].i32);
vm->mem->registers[0x8].i32++;
printf("Advancing instruction pointer to %i\n", vm->mem->registers[0x8].i32); break;
case 0x4: tvm_step(vm, &vm->mem->registers[0x8].i32);
vm->mem->registers[0x8].i32++;
retcode = tdb_run(vm, breakpoints, num_breakpoints); break;
};
if(vm->pProgram->instr[vm->pMemory->registers[0x8].i32] == -0x1) printf("End of program reached\n");
if(retcode == 1) printf("Breakpoint hit at address: %i\n", vm->pMemory->registers[0x8].i32);
if(vm->prog->instr[vm->mem->registers[0x8].i32] == -0x1) printf("End of program reached\n");
if(retcode == 1) printf("Breakpoint hit at address: %i\n", vm->mem->registers[0x8].i32);
}
free(breakpoints);
@ -64,9 +65,9 @@ void tdb_shell(tvm_t *vm)
for(i = 0; i < MAX_TOKENS; i++) free(tokens[i]);
}
int tdb_run(tvm_t* vm, tdb_breakpoint_t* breakpoints, int num_breakpoints)
int tdb_run(struct tvm_ctx* vm, struct tdb_breakpoint* breakpoints, int num_breakpoints)
{
for(int *instr_idx = &vm->pMemory->registers[0x8].i32; vm->pProgram->instr[*instr_idx] != -0x1; ++(*instr_idx))
for(int *instr_idx = &vm->mem->registers[0x8].i32; vm->prog->instr[*instr_idx] != -0x1; ++(*instr_idx))
{
for(int i = 0; i < num_breakpoints; i++) if(breakpoints[i].address == *instr_idx) return 1; /* Breakpoint hit */
tvm_step(vm, instr_idx);

View file

@ -4,9 +4,9 @@
#include <tvm/tvm.h>
#include "tdb_breakpoint.h"
void tdb_shell(tvm_t *vm);
void tdb_shell(struct tvm_ctx *vm);
int tdb_run(tvm_t *vm, tdb_breakpoint_t *breakpoints, int num_breakpoints);
void tdb_step(tvm_t *vm);
int tdb_run(struct tvm_ctx *vm, struct tdb_breakpoint *breakpoints, int num_breakpoints);
void tdb_step(struct tvm_ctx *vm);
#endif

View file

@ -4,13 +4,13 @@
#define TDB_BREAKPOINT_LABEL 0x1
#define TDB_BREAKPOINT_ADDRESS 0x2
typedef struct tdb_breakpoint_s
struct tdb_breakpoint
{
int address;
char *label;
int type;
} tdb_breakpoint_t;
};
#endif