language

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

commit 311d2f46d11b199f72b6cb042012c93e5ad18528
parent 2a7d35da30a50d524edbea346756d3dfeeab80f4
Author: Paul Longtine <paullongtine@gmail.com>
Date:   Thu Feb 25 19:54:05 2016

Implemented the program counter, more outlining and pondering and head bashing in terms of the runtime management

Diffstat:
 doc/SPECIFICATION                     |  4 ++-
 src/vm/inc/bc.h                       |  6 +++-
 src/vm/inc/ins_mdata.h                | 10 ++---
 src/vm/inc/pc.h                       | 44 ++++++++++++++++++++++-
 src/vm/inc/rt.h                       | 39 ++++++++++----------
 src/vm/inc/threads.h                  |  7 +----
 src/vm/src/bc.c                       | 28 +++++++++++++-
 src/vm/src/pc.c                       | 57 +++++++++++++++++++++++++++++-
 src/vm/src/rt.c                       | 72 +++++++++++++++++++++++++++++++++---
 src/vm/tests/cases/bc/test.c          |  1 +-
 src/vm/tests/cases/pc/Makefile        | 30 +++++++++++++++-
 src/vm/tests/cases/pc/bytecode        | Bin 0 -> 22 bytes
 src/vm/tests/cases/pc/expected_output |  3 ++-
 src/vm/tests/cases/pc/test.c          | 26 +++++++++++++-
 src/vm/tests/cases/stk/Makefile       |  1 +-
 15 files changed, 289 insertions(+), 39 deletions(-)

diff --git a/doc/SPECIFICATION b/doc/SPECIFICATION @@ -209,6 +209,10 @@ FF DEFUN A<ref> S<type> D<args> - Un-funs everything. no, no- it defines a return value, D<args> is the args. FE DECLASS A<ref> D<args> - Defines a class. + +F1 NEW A<ref> - Instantiates class + +F0 LSIZE W<size> - Dictates local scope size for function/class ------------------------------------------------------------------------------- 0 - SPECIAL BYTES ------------------------------------------------------------------------------- diff --git a/src/vm/inc/bc.h b/src/vm/inc/bc.h @@ -10,13 +10,17 @@ #include "fh.h" #include "helper.h" +typedef unsigned short int bc_addr; + /* 'Bytecode Container' */ typedef struct bc_cont { byte_t op; byte_t* args[3]; byte_t mdata; + bc_addr real_addr; struct bc_cont* next; + struct bc_cont* prev; } bc_cont; #include "is.h" @@ -41,6 +45,8 @@ byte_t* get_byte_arg(FILE*); byte_t* get_word_arg(FILE*); byte_t* get_dync_arg(FILE*); +bc_cont* bc_scan(bc_cont*, int); + /* Initiates the first pass to take a raw binary file and translate it into a * basic datastructure */ diff --git a/src/vm/inc/ins_mdata.h b/src/vm/inc/ins_mdata.h @@ -1,8 +1,6 @@ #ifndef INS_MDATA_H #define INS_MDATA_H -#include "ins_def.h" - #define INS_MDATA_DEF() \ /* NULL */ INS_MDATA[0x00] = encode(0, A_NULL, A_NULL, A_NULL); \ /* POP */ INS_MDATA[0x10] = encode(1, A_BYTE, A_NULL, A_NULL); \ @@ -53,10 +51,10 @@ /* PUSH */ INS_MDATA[0x80] = encode(0, A_NULL, A_NULL, A_NULL); \ /* DEL */ INS_MDATA[0x81] = encode(0, A_NULL, A_NULL, A_NULL); \ /* GET */ INS_MDATA[0x82] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* GETP */ INS_MDATA[0x83] = encode(0, A_WORD, A_NULL, A_NULL); \ -/* CALLM */ INS_MDATA[0x84] = encode(0, A_WORD, A_NULL, A_NULL); \ +/* GETP */ INS_MDATA[0x83] = encode(1, A_WORD, A_NULL, A_NULL); \ +/* CALLM */ INS_MDATA[0x84] = encode(1, A_WORD, A_NULL, A_NULL); \ \ -/* DECLASS */ INS_MDATA[0xFE] = encode(0, A_WORD, A_DYNC, A_NULL); \ -/* DEFUN */ INS_MDATA[0xFF] = encode(0, A_WORD, A_BYTE, A_DYNC); +/* DECLASS */ INS_MDATA[0xFE] = encode(2, A_WORD, A_DYNC, A_NULL); \ +/* DEFUN */ INS_MDATA[0xFF] = encode(3, A_WORD, A_BYTE, A_DYNC); #endif diff --git a/src/vm/inc/pc.h b/src/vm/inc/pc.h @@ -0,0 +1,44 @@ +/* `pc.h` - Program counter + */ + +#ifndef PC_H +#define PC_H + +#include <stdlib.h> +#include <stdio.h> + +#include "bc.h" +#include "is.h" +#include "fh.h" +#include "helper.h" + +typedef unsigned short int pc_addr; + +typedef struct pc_t { + bc_cont* root; + bc_cont* line; + pc_addr address; +} pc_t; + +/* Initalizes program counter + * char* is filename of file containing bytecode + */ +pc_t* pc_new(char*); + +/* Frees memory assosiated with pc_t* instance + */ +void pc_del(pc_t*); + +/* Updates program counter on changes + */ +void pc_update(pc_t*); + +/* Increment program counter by amount in pc_addr + */ +void pc_inc(pc_t*, pc_addr); + +/* Branch + */ +void pc_branch(pc_t*, pc_addr); + +#endif // PC_H diff --git a/src/vm/inc/rt.h b/src/vm/inc/rt.h @@ -6,43 +6,46 @@ #include <stdlib.h> #include <stdio.h> +#include <pthread.h> #include "bc.h" #include "stk.h" #include "var.h" -#include "threads.h" +#include "pc.h" #include "helper.h" -typedef struct rt_info { +typedef struct rt_pool { int thread_count; rt_worker** threads; - bc_cont* code; - ns_t* vars; -} rt_info; + ns_cont* gvars; +} rt_pool; typedef struct rt_worker { - thrd_state state; - thread_t* thread_ctx; + pthread_t* thread_ctx; + rt_t runtime_ctx; + pc_t* pc; } rt_worker -typedef struct rt_context { +typedef struct rt_t { stk_t* stack; stk_t* argstk; ns_t* vars; - ns_addr func; -} rt_context; + ns_cont* gvars; + ns_addr entry; +} rt_t; -/* Initializes runtime environment, spawns main thread and - * - */ -rt_info* rt_init(char); +rt_pool* rt_pool_init(int); + +void rt_pool_kill(rt_pool*); + +rt_worker* rt_worker_new(void); -ns_t* rt_init_ns(bc_cont*); +void rt_worker_del(rt_worker*); -rt_worker* rt_spawnthread(rt_info*, ns_addr); +rt_t* rt_ctx_new(char); -void rt_runthread(rt_info*, rt_worker*); +void rt_ctx_del(rt_t*); -void* rt_workerfun(void*); +void *rt_worker_run(void*); #endif // RT_H diff --git a/src/vm/inc/threads.h b/src/vm/inc/threads.h @@ -1,7 +0,0 @@ -/* `threads.h` handles threading implementation, provides wrapper for - * cross-platform threading implementation - * - * Currently, this header will support a context for win32 threads and pthreads - */ - -#include <pthreads.h> diff --git a/src/vm/src/bc.c b/src/vm/src/bc.c @@ -21,6 +21,7 @@ bc_cont* bc_cont_new(void) bc_cont* bc_cont_push(bc_cont* head) { head->next = bc_cont_new(); + head->next->prev = head; return head->next; } @@ -77,6 +78,25 @@ byte_t* get_dync_arg(FILE* f) return read_until_null(f); } +bc_cont* bc_scan(bc_cont* ptr, int scanto) +{ + while (scanto != 0) + { + if (scanto > 0 && ptr->next != NULL) + { + ptr = ptr->next; + scanto--; + } else + if (scanto < 0 && ptr->next != NULL) + { + ptr = ptr->prev; + scanto++; + } + } + + return ptr; +} + bc_cont* bc_read(char* fname) { FILE* f; @@ -87,7 +107,8 @@ bc_cont* bc_read(char* fname) fsize = read_size(f); bc_cont *root = bc_cont_new(); - bc_cont *ptr = root; + bc_cont *ptr = root; + bc_addr addr = 0; /* Loop through file byte-by-byte */ while (ftell(f)<fsize) @@ -96,9 +117,14 @@ bc_cont* bc_read(char* fname) get_opcode(byte, ptr); get_args(f, ptr); + ptr->real_addr = addr; + ptr = bc_cont_push(ptr); + + addr++; } fclose(f); + return root; } diff --git a/src/vm/src/pc.c b/src/vm/src/pc.c @@ -0,0 +1,57 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "pc.h" + +#include "bc.h" +#include "is.h" +#include "fh.h" +#include "helper.h" + +pc_t* pc_new(char* fname) +{ + N_ASSERT(fname); + + pc_t* pc = (pc_t*)malloc(sizeof(pc_t)); + M_ASSERT(pc); + + pc->root = bc_read(fname); + N_ASSERT(pc->root); + + pc->line = pc->root; + + pc->address = pc->root->real_addr; + + return pc; +} + +void pc_del(pc_t* pc) +{ + N_ASSERT(pc); + N_ASSERT(pc->root); + bc_cont_del(pc->root); + + free(pc); +} + +void pc_update(pc_t* pc) +{ + N_ASSERT(pc); + + pc->line = bc_scan(pc->line, pc->address - pc->line->real_addr); +} + +void pc_inc(pc_t* pc, pc_addr addr) +{ + N_ASSERT(pc); + + pc->address = pc->address + addr; +} + + +void pc_branch(pc_t* pc, pc_addr addr) +{ + N_ASSERT(pc); + + pc->address = addr; +} diff --git a/src/vm/src/rt.c b/src/vm/src/rt.c @@ -1,28 +1,90 @@ #include <stdlib.h> +#include <pthreads.h> #include "rt.h" #include "bc.h" #include "stk.h" #include "var.h" -#include "threads.h" +#include "pc.h" #include "helper.h" -rt_info* rt_init(char* fname) +rt_pool* rt_pool_init(int depth) { } -ns_t* rt_init_ns(bc_cont* bytecode) +void rt_pool_kill(rt_pool* pool) { } -void rt_runthread(rt_info* ctx, ns_addr func) + +rt_worker* rt_worker_new(char* fname, ns_addr func, ns_cont* gscope, stk_t* args) +{ + rt_worker* worker = (rt_worker*)malloc(sizeof(rt_worker)); + M_ASSERT(worker); + + worker->pc = pc_new(fname); + + worker->runtime_ctx = rt_ctx_init(func, args, gscope, 1024); + + pthread_create(&worker->thread_ctx, NULL, rt_worker_run, worker); + + return worker; +} + +void rt_worker_del(rt_worker* worker) +{ + N_ASSERT(worker); + N_ASSERT(worker->thread_ctx); + pthread_cancel(worker->thread_ctx); + + N_ASSERT(worker->runtime_ctx); + rt_ctx_del(worker->runtime_ctx); + + N_ASSERT(worker->pc); + pc_del(worker->pc); + + free(worker); +} + +rt_t* rt_ctx_new(ns_addr func, stk_t* args, ns_cont* gscope, int size) { + rt_t* ctx = (rt_t*)malloc(sizeof(rt_t)); + M_ASSERT(ctx); + ctx->stack = stk_new(); + ctx->argstk = args; + ctx->vars = ns_new(size); + ctx->gvars = gscope; + ctx->entry = func; + + return ctx; } -void* rt_worker(void* arg) +void rt_ctx_del(rt_t* ctx) { + N_ASSERT(ctx); + + N_ASSERT(ctx->stack); + if (ctx->stack != NULL) + stk_del(ctx->stack); + + N_ASSERT(ctx->argstk); + if (ctx->argstk != NULL) + stk_del(ctx->stack); + + N_ASSERT(ctx->ns); + if (ctx->ns != NULL) + ns_del(ctx->ns); +} + +void *rt_worker_run(void* ctx) +{ + rt_worker* c; + c = (rt_worker*)ctx; + + //TODO actually make this run the function that runs opcodes n' what not + return 0; } diff --git a/src/vm/tests/cases/bc/test.c b/src/vm/tests/cases/bc/test.c @@ -36,7 +36,6 @@ void print_op(bc_cont* op) int main(int argc, char** argv) { - if (argc < 2) return -1; init(); // start testing diff --git a/src/vm/tests/cases/pc/Makefile b/src/vm/tests/cases/pc/Makefile @@ -0,0 +1,30 @@ +SRC_DIR = ../../../src +INC_DIR = ../../../inc + +CC = gcc +CFLAGS = -std=c99 -Wall -I$(INC_DIR) + +DEPS = i$(INC_DIR)/is_mdata.h \ + helper.h \ + fh.h \ + is.h \ + bc.h \ + pc.h + +OBJ = test.o \ + $(SRC_DIR)/fh.o \ + $(SRC_DIR)/is.o \ + $(SRC_DIR)/bc.o \ + $(SRC_DIR)/pc.o + +OUT = test + +%.o: %.c $(DEPS) + $(CC) $(CFLAGS) -c -o $@ $< + +$(OUT): $(OBJ) + $(CC) $(CFLAGS) -o $@ $^ + +clean: + rm *.o + rm $(OUT) diff --git a/src/vm/tests/cases/pc/bytecode b/src/vm/tests/cases/pc/bytecode Binary files differ diff --git a/src/vm/tests/cases/pc/expected_output b/src/vm/tests/cases/pc/expected_output @@ -0,0 +1,3 @@ +OP: ff +OP: 24 +OP: 10 diff --git a/src/vm/tests/cases/pc/test.c b/src/vm/tests/cases/pc/test.c @@ -0,0 +1,26 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "pc.h" +#include "fh.h" +#include "is.h" +#include "bc.h" + +int main(int argc, char *argv[]) +{ + init(); + + pc_t* pc = pc_new("bytecode"); + + while (pc->line->next != NULL) + { + pc_inc(pc, 1); + + printf("OP: %x\n", pc->line->op); + + pc_update(pc); + } + + pc_del(pc); + return 0; +} diff --git a/src/vm/tests/cases/stk/Makefile b/src/vm/tests/cases/stk/Makefile @@ -23,4 +23,3 @@ $(OUT): $(OBJ) clean: rm *.o rm $(OUT) - rm $(SRC_DIR)/*.o