commit bf52ab078dec3dcff68cca5e4117d64a3749f727 parent 1e9622851c7963ef4a11565a46b0e770ced3a2ff Author: Paul Longtine <paullongtine@gmail.com> Date: Thu Dec 17 13:28:26 2015 Added stack implementation, started implementing types Diffstat: src/vm/inc/bc.h | 31 ++++++++------- src/vm/inc/fh.h | 16 +++++++- src/vm/inc/is.h | 18 +++++++-- src/vm/inc/stk.h | 56 +++++++++++++++++++++++++++- src/vm/inc/types.h | 39 +++++++++++++++++++- src/vm/src/bc.c | 10 ++--- src/vm/src/fh.c | 7 +-- src/vm/src/stk.c | 84 +++++++++++++++++++++++++++++++++++++++++- src/vm/src/types.c | 25 ++++++++++++- src/vm/tests/bc/Makefile | 1 +- src/vm/tests/bc/expected_output | 4 ++- src/vm/tests/bc/test | Bin 13990 -> 0 bytes src/vm/tests/stk/Makefile | 25 ++++++++++++- src/vm/tests/stk/expected_output | 4 ++- src/vm/tests/stk/test.c | 47 +++++++++++++++++++++++- 15 files changed, 340 insertions(+), 27 deletions(-)
diff --git a/src/vm/inc/bc.h b/src/vm/inc/bc.h @@ -1,6 +1,6 @@ /* - `bc` handles bytecode objects. -*/ + * `bc` handles bytecode objects. + */ #ifndef BC_H #define BC_H @@ -11,8 +11,8 @@ #include "fh.h" /* - 'Bytecode Container' -*/ + * 'Bytecode Container' + */ typedef struct bc_cont { byte_t op; byte_t* args[3]; @@ -23,30 +23,33 @@ typedef struct bc_cont { #include "is.h" /* - Handles allocation for new `bc_cont` instances -*/ + * Handles allocation for new `bc_cont` instances + */ bc_cont* bc_cont_new(void); +/* + * Pushes new bc_cont to the chain. + */ bc_cont* bc_cont_push(bc_cont*); /* - Deallocates all the things, assuming the arguement is the root. -*/ + * Deallocates all the things, assuming the arguement is the root. + */ void bc_cont_del(bc_cont*); /* - Given a file object, and an instance of `bc_cont` with proper metadata, this - function will read arguements -*/ + * Given a file object, and an instance of `bc_cont` with proper metadata, this + * function will read arguements into bc_cont. + */ void get_args(FILE*, bc_cont*); byte_t* get_byte_arg(FILE*); byte_t* get_word_arg(FILE*); byte_t* get_dync_arg(FILE*); /* - Initiates the first pass to take a raw binary file and translate it into a - basic datastructure -*/ + * Initiates the first pass to take a raw binary file and translate it into a + * basic datastructure + */ bc_cont* bc_read(char* fname); #endif // BC_H diff --git a/src/vm/inc/fh.h b/src/vm/inc/fh.h @@ -1,6 +1,6 @@ /* - 'fh.h' is here to provide useful functions to mess about with files. -*/ + * 'fh.h' is here to provide useful functions to mess about with files. + */ #ifndef FH_H #define FH_H @@ -10,12 +10,24 @@ typedef unsigned char byte_t; +/* + * Reads passed file descriptor until NULL, returns array of byte_t + */ byte_t* read_until_null(FILE*); +/* + * Reads n bytes, n passed as @param long, returns array of byte_t + */ byte_t* read_bytes(FILE*, long); +/* + * Reads a byte, returns byte_t + */ byte_t read_byte(FILE*); +/* + * Determines filesize, returns size as long + */ long read_size(FILE*); #endif // FH_H diff --git a/src/vm/inc/is.h b/src/vm/inc/is.h @@ -27,13 +27,25 @@ byte_t INS_MDATA[256]; /* - Takes an opcode, fills metadata about that opcode (given that it exists) in the - `bc_cont` structure -*/ + * Takes an opcode, fills metadata about that opcode (given that it exists) in the + * `bc_cont` structure + */ void get_opcode(byte_t, bc_cont*); +/* + * Fills in metadata in @param byte_t. + * @param[1] is number of params, + * @param[2] is an array[3] detailing param types + * + * For example, given a byte 11011011, it would break down into the following: + * @param[1] = 3, + * @param[2] = { 01, 10, 11 } + */ void get_mdata(byte_t, int*, int*); +/* + * Sets up the datastructure to quickly queue for data. + */ void init(void); void init_mdata(void); diff --git a/src/vm/inc/stk.h b/src/vm/inc/stk.h @@ -0,0 +1,56 @@ +/* + stk.h -> Provide implementation of a stack +*/ + +#ifndef STK_H +#define STK_H + +#include <stdlib.h> +#include <stdio.h> + +#include "types.h" + +typedef struct stk_t { + struct stk_t* next; + var_cont* data; +} stk_t; + +/* + * Create a new stack instance + */ +stk_t* stk_new(void); + +/* + * Delete a stack + */ +void stk_del(stk_t*); + +/* + * Pop the first element of the stack + * + * @param stk_t* + * stack instance pointer + */ +var_cont* stk_pop(stk_t**); + +/* + * Pushes @param var_cont* to the stack + */ +void stk_push(stk_t**, var_cont*); + +/* + * Returns the data at location in the stack + */ +var_cont* stk_at(stk_t*, int); + +/* + * Rotates the top two elements of the stack + */ +void stk_rot_top(stk_t**); + +/* + * Rotates the top three elements of the stack + */ +void stk_rot_three(stk_t**); + +#endif // STK_H diff --git a/src/vm/inc/types.h b/src/vm/inc/types.h @@ -0,0 +1,39 @@ +/* + * types.h -> Provide implemenation of types + */ + +#include <stdlib.h> +#include <stdio.h> + +#ifndef TYPES_H +#define TYPES_H + +typedef enum { + VOID, + FUNC, + OBJECT, + G_INT, + G_FLOAT, + G_CHAR, + G_STRING, + S_ARRAY, + D_ARRAY, + A_ARRAY +} b_type; + +typedef struct var_cont { + b_type type; + void* data; +} var_cont; + +/* + * Initialze variable with type + */ +var_cont* var_new(b_type); + +/* + * Frees variable + */ +void var_del(var_cont*); + +#endif // TYPES_H diff --git a/src/vm/src/bc.c b/src/vm/src/bc.c @@ -31,9 +31,11 @@ void bc_cont_del(bc_cont* root) { bc_cont_del(root->next); } - free(root->args[0]); - free(root->args[1]); - free(root->args[2]); + + if (root->args[0] != NULL) free(root->args[0]); + if (root->args[1] != NULL) free(root->args[1]); + if (root->args[2] != NULL) free(root->args[2]); + free(root); } @@ -78,8 +80,6 @@ byte_t* get_dync_arg(FILE* f) bc_cont* bc_read(char* fname) { - /* initialize datastructures for instructionstuffs, - begin to read file byte-by-byte */ FILE* f; byte_t byte; long fsize; diff --git a/src/vm/src/fh.c b/src/vm/src/fh.c @@ -6,8 +6,8 @@ byte_t* read_until_null(FILE* f) { long f_pos_i = ftell(f); - - // This bit needs to be refactored. + + // This bit gets the length in bytes it needs to read into a buffer byte_t byte = read_byte(f); while (byte != 0) { @@ -16,7 +16,8 @@ byte_t* read_until_null(FILE* f) long bytes = (ftell(f) - f_pos_i); - fseek(f, 0-bytes, SEEK_CUR); + // Seek backwards + fseek(f, -bytes, SEEK_CUR); return read_bytes(f, bytes); } diff --git a/src/vm/src/stk.c b/src/vm/src/stk.c @@ -0,0 +1,84 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "stk.h" +#include "types.h" + +stk_t* stk_new( void ) +{ + stk_t* new = (stk_t*)malloc(sizeof(stk_t)); + if (new == NULL) + { + fprintf(stderr, "Could not allocate memory\n"); + exit(1); + } + + return new; +} + +void stk_del(stk_t* root) +{ + if (root->next != NULL) + { + stk_del(root->next); + } + + if (root->data != NULL) + var_del(root->data); + + free(root); +} + +var_cont* stk_pop(stk_t** root) +{ + if ((*root)->next == NULL) + return 0; + + stk_t* new = (*root)->next; + var_cont* data = (*root)->data; + + free(*root); + + *root = new; + + return data; +} + +void stk_push(stk_t** root, var_cont* data) +{ + stk_t* new = stk_new(); + new->data = data; + new->next = *root; + *root = new; +} + +var_cont* stk_at(stk_t* root, int n) +{ + n--; + if (n >= 0) + { + return stk_at(root->next, n); + } + else + { + return root->data; + } +} + +void stk_rot_top(stk_t** root) +{ + stk_t* tmp = (*root)->next; + (*root)->next = tmp->next; + tmp->next = *root; + *root = tmp; +} + +void stk_rot_three(stk_t** root) +{ + stk_t* tmp2 = (*root)->next->next; + stk_t* tmp1 = (*root)->next; + (*root)->next = tmp2->next; + tmp2->next = tmp1; + tmp1->next = *root; + *root = tmp2; +} diff --git a/src/vm/src/types.c b/src/vm/src/types.c @@ -0,0 +1,25 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "types.h" + +var_cont* var_new(b_type type) +{ + var_cont* new = (var_cont*)malloc(sizeof(var_cont)); + if (new == NULL) + { + fprintf(stderr, "Could not allocate memory"); + exit(1); + } + new->type = type; + new->data = NULL; + return new; +} + +void var_del(var_cont* var) +{ + if (var == NULL) + return; + + free(var); +} diff --git a/src/vm/tests/bc/Makefile b/src/vm/tests/bc/Makefile @@ -23,5 +23,6 @@ $(OUT): $(OBJ) $(CC) $(CFLAGS) -o $@ $^ clean: + rm *.o rm $(SRC_DIR)/*.o rm $(OUT) diff --git a/src/vm/tests/bc/expected_output b/src/vm/tests/bc/expected_output @@ -0,0 +1,4 @@ +1: +2: 33 +3: 44, 12 34 +4: 12 34 56 78 90 0 0 0 diff --git a/src/vm/tests/bc/test b/src/vm/tests/bc/test Binary files differ diff --git a/src/vm/tests/stk/Makefile b/src/vm/tests/stk/Makefile @@ -0,0 +1,25 @@ +SRC_DIR = ../../src +INC_DIR = ../../inc + +CC = gcc +CFLAGS = -std=c99 -Wall -I$(INC_DIR) + +DEPS = i$(INC_DIR)/stk.h \ + types.h \ + +OBJ = test.o \ + $(SRC_DIR)/stk.o \ + $(SRC_DIR)/types.o + +OUT = test + +%.o: %.c $(DEPS) + $(CC) $(CFLAGS) -c -o $@ $< + +$(OUT): $(OBJ) + $(CC) $(CFLAGS) -o $@ $^ + +clean: + rm *.o + rm $(SRC_DIR)/*.o + rm $(OUT) diff --git a/src/vm/tests/stk/expected_output b/src/vm/tests/stk/expected_output @@ -0,0 +1,4 @@ +5, 4, 3, 2 +4, 3, 2, 1 +3, 4, 2, 1 +2, 3, 4, 1 diff --git a/src/vm/tests/stk/test.c b/src/vm/tests/stk/test.c @@ -0,0 +1,47 @@ +#include <stdio.h> + +#include "stk.h" +#include "types.h" + + +void printstk(stk_t* stk) +{ + var_cont* test0 = stk_at(stk, 0); + var_cont* test1 = stk_at(stk, 1); + var_cont* test2 = stk_at(stk, 2); + var_cont* test3 = stk_at(stk, 3); + printf("%i, %i, %i, %i\n", + test0->type, test1->type, test2->type, test3->type); +} + +int main(int argc, char* argv[]) +{ + stk_t* new = stk_new(); + new->data = var_new(0); + + stk_push(&new, var_new(1)); + stk_push(&new, var_new(2)); + stk_push(&new, var_new(3)); + stk_push(&new, var_new(4)); + stk_push(&new, var_new(5)); + + printstk(new); + + stk_pop(&new); + + printstk(new); + + stk_rot_top(&new); + + printstk(new); + + stk_rot_top(&new); + + stk_rot_three(&new); + + printstk(new); + + stk_del(new); + + return 0; +}