language

Some fools attempt at an interpreted language
Log | Files | Refs

commit 6b96af5a7c6930d2e2b1c395ff97efd03a0ff948
parent 898e8d534b78c5085b37e37e376dd0f91471e404
Author: Paul Longtine <paullongtine@gmail.com>
Date:   Fri Feb 26 23:21:22 2016

Elaborated documentation, restructured a bit

Diffstat:
 src/vm/inc/bc.h        | 11 ++++++-
 src/vm/inc/ins_def.h   |  3 ++-
 src/vm/inc/ins_mdata.h | 18 ++++++++++-
 src/vm/inc/is.h        | 25 ++------------
 src/vm/inc/ns.h        | 53 ++++++++++++++++++++++++++----
 src/vm/inc/proc.h      | 27 +++++++++++++++-
 src/vm/inc/rt.h        | 43 +++++++++++++++++--------
 src/vm/src/bc.c        | 21 ++++++++++++-
 src/vm/src/ins_def.c   |  3 ++-
 src/vm/src/is.c        | 22 ++++++++++---
 src/vm/src/main.c      | 18 +++-------
 src/vm/src/ns.c        | 89 ++++++++++++++++++++++++++++++++++++++++++---------
 src/vm/src/proc.c      | 28 ++++++++++++++++-
 src/vm/src/rt.c        | 77 ++++++++++++++++++++++++--------------------
 14 files changed, 333 insertions(+), 105 deletions(-)

diff --git a/src/vm/inc/bc.h b/src/vm/inc/bc.h @@ -30,10 +30,14 @@ typedef struct bc_cont { bc_cont* bc_cont_new(void); /* Pushes new bc_cont to the chain. + * bc_cont* - bytecode container + * + * -> bc_cont* - push new bytecode container on chain */ bc_cont* bc_cont_push(bc_cont*); /* Deallocates all the things, assuming the arguement is the root. + * bc_cont* - bytecode container, root node (hopefully) */ void bc_cont_del(bc_cont*); @@ -45,10 +49,17 @@ byte_t* get_byte_arg(FILE*); byte_t* get_word_arg(FILE*); byte_t* get_dync_arg(FILE*); +/* Scan to +/- int in bytecode chain + * bc_cont* - bytecode container [0] + * int - +/- up/down [1] + * + * -> bc_cont* - Bytecode @param[0]'s location +/- @param[1] + */ bc_cont* bc_scan(bc_cont*, int); /* Initiates the first pass to take a raw binary file and translate it into a * basic datastructure + * char* -> filename */ bc_cont* bc_read(char*); diff --git a/src/vm/inc/ins_def.h b/src/vm/inc/ins_def.h @@ -18,6 +18,9 @@ // This array is populated by init_ins_def( void ); void INS_DEF[0xFF]; +/* Initializes INS_DEF with pointers to each instructions function + * Populates INS_DEF + */ void init_ins_def( void ); void _ins_def_NULL (rt_t*, byte_t*); diff --git a/src/vm/inc/ins_mdata.h b/src/vm/inc/ins_mdata.h @@ -1,6 +1,24 @@ #ifndef INS_MDATA_H #define INS_MDATA_H +#define A_NULL 0 +#define A_BYTE 1 +#define A_WORD 2 +#define A_DYNC 3 + + +/* Macro used below. + * It should be self-explainitory + * i.e. encode( 3, 2, 1, 0 ) = 0b11100100 + * 11,10,01,00 = 0xE4 + */ +#define encode(n, a0, a1, a2) \ + ( n << 6 | a0 << 4 | a1 << 2 | a2 ); + +/* This definition is ran in `is.c` + * + * INS_MDATA[ <opcode> ] = encode( <number of arguements>, <type..3> ) + */ #define INS_MDATA_DEF() \ /* NULL */ INS_MDATA[0x00] = encode(0, A_NULL, A_NULL, A_NULL); \ /* SYNC */ INS_MDATA[0x01] = encode(1, A_BYTE, A_NULL, A_NULL); \ diff --git a/src/vm/inc/is.h b/src/vm/inc/is.h @@ -5,22 +5,6 @@ be handled by this file. */ -#ifndef IS_H -#define IS_H - -#include <stdlib.h> - -#include "fh.h" -#include "bc.h" - -#define A_NULL 0 -#define A_BYTE 1 -#define A_WORD 2 -#define A_DYNC 3 - -#define encode(n, a0, a1, a2) \ - ( n << 6 | a0 << 4 | a1 << 2 | a2 ); - #include "ins_mdata.h" // This array is populated by inc/is_mdata.h @@ -28,12 +12,15 @@ byte_t INS_MDATA[0xFF]; /* Takes an opcode, fills metadata about that opcode (given that it exists) in * the `bc_cont` structure + * byte_t - opcode + * bc_cont* - Bytecode instruction */ 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 + * byte_t - un-expanded metadata + * int* - is number of params [0] + * int* - int[3] detailing param types [1] * * For example, given a byte 11011011, it would break down into the following: * @param[1] = 3, @@ -43,8 +30,6 @@ void get_mdata(byte_t, int*, int*); /* Sets up the datastructure to quickly queue for data. */ -void init(void); - void init_mdata(void); #endif // IS_H diff --git a/src/vm/inc/ns.h b/src/vm/inc/ns.h @@ -23,8 +23,13 @@ typedef struct ns_t { } ns_t; /* Initializes namespace of size + * ns_addr - name limit */ ns_t* ns_init(ns_addr); + +/* Initialize namespace container of size + * ns_addr - name limit + */ ns_cont* ns_cont_init(ns_addr); /* Cleans up memory @@ -33,6 +38,8 @@ void ns_del(ns_t*); void ns_cont_del(ns_cont*); /* Pushes namespace of size + * ns_t* - namespace instance + * ns_addr - name limit */ void ns_push(ns_t*, ns_addr); @@ -41,27 +48,59 @@ void ns_push(ns_t*, ns_addr); void ns_pop(ns_t*); /* Declares a variable, at root or last namespace - * int = namespace level - * * 0 -> current namespace - * * 1 -> global namespace + * ns_t* - Namespace instance + * b_type - Type of variable + * int - Mux value [0] + * ns_addr - Variable name + * + * @param[0] = namespace level + * 0 -> current namespace + * 1 -> global namespace */ void ns_dec(ns_t*, b_type, int, ns_addr); + +/* Declares a variable, at namespace + * ns_t* - Namespace instance + * b_type - Type of variable + * ns_addr - Variable name + */ void ns_cont_dec(ns_cont*, b_type, ns_addr); /* Sets variable to value, at root or last namespace - * int = namespace level + * ns_t* - namespace instance + * int - mux value [0] + * ns_addr - Variable name + * var_cont* - Variable + * + * @param[0] = namespace level * * 0 -> current namespace * * 1 -> global namespace */ void ns_set(ns_t*, int, ns_addr, var_cont*); + +/* Sets variable to value, at root or last namespace + * ns_cont* - Namespace instance + * var_cont* - Variable + * ns_addr - Variable name + */ void ns_cont_set(ns_cont*, var_cont*, ns_addr); /* Gets variable from address - * int = namespace level - * * 0 -> current namespace - * * 1 -> global namespace + + * ns_t* - namespace instance + * int - mux value [0] + * ns_addr - Variable name + * + * @param[0] = namespace level + * 0 -> current namespace + * 1 -> global namespace */ var_cont* ns_get(ns_t*, int, ns_addr); + +/* Gets variable from address + * ns_t* - namespace instance + * ns_addr - Variable name + */ var_cont* ns_cont_get(ns_cont*, ns_addr); #endif // NS_H diff --git a/src/vm/inc/proc.h b/src/vm/inc/proc.h @@ -14,16 +14,43 @@ #include "pc.h" #include "helper.h" +/* Initializes process, returns runtime context. + * char* - Filename of valid bytecode + */ rt_t* proc_init(char*); +/* Starts execution loop for a runtime context + */ void proc_run(rt_t*); +/* Calls runtime context elements to free memory and terminate + * rt_t* - Runtime context + */ void proc_clean(rt_t*); +/* Function call subroutine. + * rt_t* - Runtime context + * var_cont* - Variable in type of function + * + * This function is used to support an interface to multithreaded instances + */ var_cont* proc_callfun(rt_t*, var_cont*); +/* Set a variable subroutine + * rt_t* - Runtime context + * int - Scope + * ns_addr - Name of variable + * var_cont* - Variable container + * + * This function is used to support an interface to multithreaded instances + */ void proc_setvar(rt_t*, int, ns_addr, var_cont*); +/* Get a variable subroutine + * rt_t* - Runtime context + * int - Scope + * ns_addr - Name of variable + */ var_cont* proc_getvar(rt_t*, int, ns_addr); #endif //PROC_H diff --git a/src/vm/inc/rt.h b/src/vm/inc/rt.h @@ -13,6 +13,36 @@ #include "pc.h" #include "helper.h" +/* Runtime context structure + * pc - `pc.h` program counter instance + * stack - `stk.h` stack instance[0] + * argstk- `stk.h` stack instance[1] + * vars - `ns.h` namespace instance + * gvars - `ns.h` namespace container instance + * + * [0] This is the stack register used at runtime to push/pop variable containers. + * [1] Function calls implement this stack to load variables as arguements. + */ +typedef struct rt_t { + pc_t* pc; + stk_t* stack; + stk_t* argstk; + ns_t* vars; + ns_cont* gvars; +} rt_t; + +/* Creates new runtime context. + * char* - Filename + * stk_t* - Arguement stack + * ns_cont*- Copy of the global namespace + */ +rt_t* rt_ctx_new(char*, stk_t*, ns_cont*); + +/* Destroys runtime context. This can be *very* slow. + */ +void rt_ctx_del(rt_t*); + + #ifdef THREADING #include <pthread.h> @@ -30,14 +60,6 @@ typedef struct rt_worker { #endif // THREADING -typedef struct rt_t { - pc_t* pc; - stk_t* stack; - stk_t* argstk; - ns_t* vars; - ns_cont* gvars; -} rt_t; - #ifdef THREADING rt_pool* rt_pool_init(int); @@ -51,9 +73,4 @@ rt_worker* rt_worker_new(void); void rt_worker_del(rt_worker*); #endif //THREADING - -rt_t* rt_ctx_new(char*, stk_t*, ns_cont*); - -void rt_ctx_del(rt_t*); - #endif // RT_H diff --git a/src/vm/src/bc.c b/src/vm/src/bc.c @@ -6,6 +6,8 @@ #include "fh.h" #include "helper.h" +/* Handles allocation for new `bc_cont` instances + */ bc_cont* bc_cont_new(void) { bc_cont *new = (bc_cont*)malloc(sizeof(bc_cont)); @@ -18,6 +20,8 @@ bc_cont* bc_cont_new(void) return new; } +/* Handles allocation for new `bc_cont` instances + */ bc_cont* bc_cont_push(bc_cont* head) { head->next = bc_cont_new(); @@ -25,6 +29,11 @@ bc_cont* bc_cont_push(bc_cont* head) return head->next; } +/* Pushes new bc_cont to the chain. + * bc_cont* - bytecode container + * + * -> bc_cont* - push new bytecode container on chain + */ void bc_cont_del(bc_cont* root) { if (root->next != NULL) @@ -39,6 +48,9 @@ void bc_cont_del(bc_cont* root) free(root); } +/* Deallocates all the things, assuming the arguement is the root. + * bc_cont* - bytecode container, root node (hopefully) + */ void get_args(FILE* f, bc_cont* ins) { int num_args, @@ -78,6 +90,12 @@ byte_t* get_dync_arg(FILE* f) return read_until_null(f); } +/* Scan to +/- int in bytecode chain + * bc_cont* - bytecode container [0] + * int - +/- up/down [1] + * + * -> bc_cont* - Bytecode @param[0]'s location +/- @param[1] + */ bc_cont* bc_scan(bc_cont* ptr, int scanto) { while (scanto != 0) @@ -97,6 +115,9 @@ bc_cont* bc_scan(bc_cont* ptr, int scanto) return ptr; } +/* Initiates the first pass to take a raw binary file and translate it into a + * basic datastructure + */ bc_cont* bc_read(char* fname) { FILE* f; diff --git a/src/vm/src/ins_def.c b/src/vm/src/ins_def.c @@ -5,6 +5,9 @@ #include "rt.h" #include "helper.h" +/* Initializes INS_DEF with pointers to each instructions function + * Populates INS_DEF + */ void init_ins_def( void ) { INS_DEF[0x00] = _ins_def_NULL; diff --git a/src/vm/src/is.c b/src/vm/src/is.c @@ -6,12 +6,26 @@ #include "ins_mdata.h" +/* Takes an opcode, fills metadata about that opcode (given that it exists) in + * the `bc_cont` structure + * byte_t - opcode + * bc_cont* - Bytecode instruction + */ void get_opcode(byte_t byte, bc_cont* ins) { ins->op = byte; ins->mdata = INS_MDATA[byte]; } +/* Fills in metadata in @param byte_t. + * byte_t - un-expanded metadata + * int* - is number of params [0] + * int* - int[3] detailing param types [1] + * + * 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 byte, int* n, int* at) { *n = (byte & (3 << 6)) >> 6; @@ -20,12 +34,10 @@ void get_mdata(byte_t byte, int* n, int* at) at[2] = (byte & 3) ; } -void init(void) -{ - init_mdata(); -} - +/* Sets up the datastructure to quickly queue for data. + */ void init_mdata(void) { INS_MDATA_DEF(); } + diff --git a/src/vm/src/main.c b/src/vm/src/main.c @@ -3,25 +3,21 @@ #include "proc.h" #include "rt.h" #include "ins_def.h" -#include "is.h" -#include "bc.h" -#include "stk.h" -#include "var.h" -#include "pc.h" +#include "ins_mdata.h" #include "helper.h" - int main(int argc, char** argv) { - ASSERT(argc < 0, "C'mon, man! Gimme some args"); - init(); + ASSERT(argc < 0, "C'mon, man! Gimme some args\n"); + + init_mdata(); // Initalize the instruction definitions init_ins_def(); - rt_t* runtime = proc_init(argv[0]); + rt_t* runtime = proc_init(argv[0]); // Initalize process - proc_run(runtime); + proc_run(runtime); // Execute runtime - proc_clean(runtime); + proc_clean(runtime); // Once `proc_run` returns, try to clean what sort of mess it made. return 0; } diff --git a/src/vm/src/ns.c b/src/vm/src/ns.c @@ -4,6 +4,9 @@ #include "var.h" #include "helper.h" +/* Initialize namespace container of size + * ns_addr - name limit + */ ns_cont* ns_cont_init(ns_addr size) { ns_cont* new = (ns_cont*)malloc(sizeof(ns_cont)); @@ -24,6 +27,9 @@ ns_cont* ns_cont_init(ns_addr size) return new; } +/* Initializes namespace of size + * ns_addr - name limit + */ ns_t* ns_init(ns_addr size) { ns_t* ns = (ns_t*)malloc(sizeof(ns_t)); @@ -35,6 +41,8 @@ ns_t* ns_init(ns_addr size) return ns; } +/* Cleans up memory + */ void ns_cont_del(ns_cont* container) { N_ASSERT(container); @@ -51,6 +59,8 @@ void ns_cont_del(ns_cont* container) free(container); } +/* Cleans up memory + */ void ns_del(ns_t* ns) { N_ASSERT(ns); @@ -62,6 +72,10 @@ void ns_del(ns_t* ns) free(ns); } +/* Pushes namespace of size + * ns_t* - namespace instance + * ns_addr - name limit + */ void ns_push(ns_t* ns, ns_addr size) { N_ASSERT(ns); @@ -80,6 +94,8 @@ void ns_push(ns_t* ns, ns_addr size) } } +/* Pops last namespace level + */ void ns_pop(ns_t* ns) { N_ASSERT(ns); @@ -93,15 +109,16 @@ void ns_pop(ns_t* ns) } } -void ns_cont_dec(ns_cont* ns, b_type type, ns_addr address) -{ - N_ASSERT(ns); - - SIZE_ASSERT( ns->size > address ); - - ns->names[ address ] = var_new(type); -} - +/* Declares a variable, at root or last namespace + * ns_t* - Namespace instance + * b_type - Type of variable + * int - Mux value [0] + * ns_addr - Variable name + * + * @param[0] = namespace level + * 0 -> current namespace + * 1 -> global namespace + */ void ns_dec(ns_t* ns, b_type type, int scope, ns_addr address) { N_ASSERT(ns); @@ -111,15 +128,31 @@ void ns_dec(ns_t* ns, b_type type, int scope, ns_addr address) ns_cont_dec(scoped_ns, type, address); } -void ns_cont_set(ns_cont* ns, var_cont* var, ns_addr address) +/* Declares a variable, at namespace + * ns_t* - Namespace instance + * b_type - Type of variable + * ns_addr - Variable name + */ + +void ns_cont_dec(ns_cont* ns, b_type type, ns_addr address) { N_ASSERT(ns); - N_ASSERT(var); + SIZE_ASSERT( ns->size > address ); - var_set(ns->names[ address ], var->data, var->type); + ns->names[ address ] = var_new(type); } +/* Sets variable to value, at root or last namespace + * ns_t* - namespace instance + * int - mux value [0] + * ns_addr - Variable name + * var_cont* - Variable + * + * @param[0] = namespace level + * * 0 -> current namespace + * * 1 -> global namespace + */ void ns_set(ns_t* ns, int scope, ns_addr address, var_cont* var) { N_ASSERT(ns); @@ -130,14 +163,30 @@ void ns_set(ns_t* ns, int scope, ns_addr address, var_cont* var) ns_cont_set(scoped_ns, var, address); } -var_cont* ns_cont_get(ns_cont* ns, ns_addr address) +/* Sets variable to value, at root or last namespace + * ns_cont* - Namespace instance + * var_cont* - Variable + * ns_addr - Variable name + */ +void ns_cont_set(ns_cont* ns, var_cont* var, ns_addr address) { N_ASSERT(ns); + N_ASSERT(var); SIZE_ASSERT( ns->size > address ); - return ns->names[ address ]; + var_set(ns->names[ address ], var->data, var->type); } +/* Gets variable from address + + * ns_t* - namespace instance + * int - mux value [0] + * ns_addr - Variable name + * + * @param[0] = namespace level + * 0 -> current namespace + * 1 -> global namespace + */ var_cont* ns_get(ns_t* ns, int scope, ns_addr address) { N_ASSERT(ns); @@ -146,3 +195,15 @@ var_cont* ns_get(ns_t* ns, int scope, ns_addr address) return ns_cont_get(scoped_ns, address); } + +/* Gets variable from address + * ns_t* - namespace instance + * ns_addr - Variable name + */ +var_cont* ns_cont_get(ns_cont* ns, ns_addr address) +{ + N_ASSERT(ns); + SIZE_ASSERT( ns->size > address ); + + return ns->names[ address ]; +} diff --git a/src/vm/src/proc.c b/src/vm/src/proc.c @@ -11,6 +11,9 @@ #include "pc.h" #include "helper.h" +/* Initializes process, returns runtime context. + * char* - Filename of valid bytecode + */ rt_t* proc_init(char* fname) { N_ASSERT(fname); @@ -19,6 +22,9 @@ rt_t* proc_init(char* fname) return ctx; } +/* Starts execution loop for a runtime context + * rt_t* - Runtime context + */ void proc_run(rt_t* ctx) { N_ASSERT(ctx); @@ -30,23 +36,45 @@ void proc_run(rt_t* ctx) } } +/* Calls runtime context elements to free memory and terminate + * rt_t* - Runtime context + */ void proc_clean(rt_t* ctx) { N_ASSERT(ctx); rt_ctx_del(ctx); } +/* Function call subroutine. + * rt_t* - Runtime context + * var_cont* - Variable in type of function + * + * This function is used to support an interface to multithreaded instances + */ var_cont* proc_callfun(rt_t* ctx, var_cont* func) { N_ASSERT(ctx); } +/* Set a variable subroutine + * rt_t* - Runtime context + * int - Scope + * ns_addr - Name of variable + * var_cont* - Variable container + * + * This function is used to support an interface to multithreaded instances + */ void proc_setvar(rt_t* ctx, int scope, ns_addr name, var_cont* var) { } +/* Get a variable subroutine + * rt_t* - Runtime context + * int - Scope + * ns_addr - Name of variable + */ var_cont* proc_getvar(rt_t* ctx, int scope, ns_addr name) { diff --git a/src/vm/src/rt.c b/src/vm/src/rt.c @@ -7,6 +7,48 @@ #include "pc.h" #include "helper.h" +/* Creates new runtime context. + * char* - Filename + * stk_t* - Arguement stack (non-null) + * ns_cont*- Copy of the global namespace + */ +rt_t* rt_ctx_new(char* fname, stk_t* args, ns_cont* gvars) +{ + N_ASSERT(fname); + N_ASSERT(args); + N_ASSERT(gvars); + rt_t* ctx = (rt_t*)malloc(sizeof(rt_t)); + M_ASSERT(ctx); + + ctx->pc = pc_new(fname); + ctx->stack = stk_new(); + ctx->vars = ns_new(1024); + ctx->argstk = args; + ctx->gvars = gvars; + + + return ctx; +} + +/* Destroys runtime context. This can be *very* slow. + */ +void rt_ctx_del(rt_t* ctx) +{ + N_ASSERT(ctx); + + N_ASSERT(ctx->stack); + stk_del(ctx->stack); + + N_ASSERT(ctx->argstk); + stk_del(ctx->argstk); + + N_ASSERT(ctx->ns); + ns_del(ctx->ns); + + N_ASERT(ctx->pc); + pc_del(ctx->pc); +} + #ifdef THREADING #include <pthread.h> @@ -57,38 +99,3 @@ void rt_worker_del(rt_worker* worker) } #endif // SINGLE_THREAD - -rt_t* rt_ctx_new(char* fname, stk_t* args, ns_cont* gvars) -{ - N_ASSERT(fname); - N_ASSERT(args); - N_ASSERT(gvars); - rt_t* ctx = (rt_t*)malloc(sizeof(rt_t)); - M_ASSERT(ctx); - - ctx->pc = pc_new(fname); - ctx->stack = stk_new(); - ctx->vars = ns_new(1024); - ctx->argstk = args; - ctx->gvars = gvars; - - - return ctx; -} - -void rt_ctx_del(rt_t* ctx) -{ - N_ASSERT(ctx); - - N_ASSERT(ctx->stack); - stk_del(ctx->stack); - - N_ASSERT(ctx->argstk); - stk_del(ctx->argstk); - - N_ASSERT(ctx->ns); - ns_del(ctx->ns); - - N_ASERT(ctx->pc); - pc_del(ctx->pc); -}