language

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

commit 898e8d534b78c5085b37e37e376dd0f91471e404
parent 311d2f46d11b199f72b6cb042012c93e5ad18528
Author: Paul Longtine <paullongtine@gmail.com>
Date:   Fri Feb 26 14:15:32 2016

Added proc.(h|c), made runtime less thready, almost close to actually getting stuff to run, provided instruction definitions

Diffstat:
 doc/SPECIFICATION      |  14 +--
 src/vm/inc/ins_def.h   |  74 +++++++++++++++-
 src/vm/inc/ins_mdata.h |   7 ++-
 src/vm/inc/is.h        |   6 +-
 src/vm/inc/pc.h        |   2 +-
 src/vm/inc/proc.h      |  29 ++++++-
 src/vm/inc/rt.h        |  20 ++--
 src/vm/src/ins_def.c   | 227 +++++++++++++++++++++++++++++++++++++++++++++++++-
 src/vm/src/main.c      |  21 +++++-
 src/vm/src/pc.c        |  17 ++++-
 src/vm/src/proc.c      |  55 ++++++++++++-
 src/vm/src/rt.c        |  56 ++++++------
 src/vm/tests/run.sh    |   4 +-
 13 files changed, 488 insertions(+), 44 deletions(-)

diff --git a/doc/SPECIFICATION b/doc/SPECIFICATION @@ -210,20 +210,22 @@ FF DEFUN A<ref> S<type> D<args> - Un-funs everything. no, no- it defines a FE DECLASS A<ref> D<args> - Defines a class. +F2 LSIZE W<size> - Dictates local scope size for function/class + F1 NEW A<ref> - Instantiates class -F0 LSIZE W<size> - Dictates local scope size for function/class +F0 RETURN - Returns from function ------------------------------------------------------------------------------- 0 - SPECIAL BYTES ------------------------------------------------------------------------------- -00 NULL - Terminator byte +00 NULL - Terminator byte -01 SYNC - Updates global namespace with global namespace cache of current - thread +01 SYNC S<level> - Updates global namespace with global namespace cache of + current thread -0E ARGB - Builds arguement stack +0E ARGB - Builds arguement stack -0F LIBC A<ref> - Library call +0F LIBC A<ref> - Library call ------------------------------------------------------------------------------- General Architecture Overview diff --git a/src/vm/inc/ins_def.h b/src/vm/inc/ins_def.h @@ -7,9 +7,79 @@ #include <stdlib.h> #include <stdio.h> +#include "proc.h" #include "rt.h" +#include "bc.h" +#include "stk.h" +#include "var.h" +#include "pc.h" #include "helper.h" -void _ins_def_INSTRUCTIONNAME(rt_worker*, rt_context*); +// This array is populated by init_ins_def( void ); +void INS_DEF[0xFF]; -#endif INS_DEF_H +void init_ins_def( void ); + +void _ins_def_NULL (rt_t*, byte_t*); +void _ins_def_SYNC (rt_t*, byte_t*); +void _ins_def_ARGB (rt_t*, byte_t*); +void _ins_def_LIBC (rt_t*, byte_t*); + +void _ins_def_POP (rt_t*, byte_t*); +void _ins_def_ROT (rt_t*, byte_t*); +void _ins_def_DUP (rt_t*, byte_t*); +void _ins_def_ROT_THREE(rt_t*, byte_t*); + +void _ins_def_DEC (rt_t*, byte_t*); +void _ins_def_LOV (rt_t*, byte_t*); +void _ins_def_STV (rt_t*, byte_t*); +void _ins_def_LOC (rt_t*, byte_t*); +void _ins_def_CTS (rt_t*, byte_t*); + +void _ins_def_TYPEOF (rt_t*, byte_t*); +void _ins_def_CAST (rt_t*, byte_t*); + +void _ins_def_ADD (rt_t*, byte_t*); +void _ins_def_SUB (rt_t*, byte_t*); +void _ins_def_MULT (rt_t*, byte_t*); +void _ins_def_DIV (rt_t*, byte_t*); +void _ins_def_POW (rt_t*, byte_t*); +void _ins_def_BRT (rt_t*, byte_t*); +void _ins_def_SIN (rt_t*, byte_t*); +void _ins_def_COS (rt_t*, byte_t*); +void _ins_def_TAN (rt_t*, byte_t*); +void _ins_def_ISIN (rt_t*, byte_t*); +void _ins_def_ICOS (rt_t*, byte_t*); +void _ins_def_ITAN (rt_t*, byte_t*); +void _ins_def_MOD (rt_t*, byte_t*); +void _ins_def_OR (rt_t*, byte_t*); +void _ins_def_XOR (rt_t*, byte_t*); +void _ins_def_NAND (rt_t*, byte_t*); + +void _ins_def_GTHAN (rt_t*, byte_t*); +void _ins_def_LTHAN (rt_t*, byte_t*); +void _ins_def_EQ (rt_t*, byte_t*); +void _ins_def_NOT (rt_t*, byte_t*); + +void _ins_def_STARTL (rt_t*, byte_t*); +void _ins_def_CLOOP (rt_t*, byte_t*); +void _ins_def_BREAK (rt_t*, byte_t*); +void _ins_def_DONE (rt_t*, byte_t*); + +void _ins_def_GOTO (rt_t*, byte_t*); +void _ins_def_JUMPF (rt_t*, byte_t*); +void _ins_def_CALL (rt_t*, byte_t*); + +void _ins_def_PUSH (rt_t*, byte_t*); +void _ins_def_DEL (rt_t*, byte_t*); +void _ins_def_GET (rt_t*, byte_t*); +void _ins_def_GETP (rt_t*, byte_t*); +void _ins_def_CALLM (rt_t*, byte_t*); + +void _ins_def_RETURN (rt_t*, byte_t*); +void _ins_def_NEW (rt_t*, byte_t*); +void _ins_def_LSIZE (rt_t*, byte_t*); +void _ins_def_DECLASS (rt_t*, byte_t*); +void _ins_def_DEFUN (rt_t*, byte_t*); + +#endif //INS_DEF_H diff --git a/src/vm/inc/ins_mdata.h b/src/vm/inc/ins_mdata.h @@ -3,6 +3,10 @@ #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); \ +/* ARGB */ INS_MDATA[0x02] = encode(0, A_NULL, A_NULL, A_NULL); \ +/* LIBC */ INS_MDATA[0x0F] = encode(1, A_WORD, A_NULL, A_NULL); \ + \ /* POP */ INS_MDATA[0x10] = encode(1, A_BYTE, A_NULL, A_NULL); \ /* ROT */ INS_MDATA[0x11] = encode(0, A_NULL, A_NULL, A_NULL); \ /* DUP */ INS_MDATA[0x12] = encode(0, A_NULL, A_NULL, A_NULL); \ @@ -54,6 +58,9 @@ /* GETP */ INS_MDATA[0x83] = encode(1, A_WORD, A_NULL, A_NULL); \ /* CALLM */ INS_MDATA[0x84] = encode(1, A_WORD, A_NULL, A_NULL); \ \ +/* RETURN */ INS_MDATA[0xF0] = encode(0, A_NULL, A_NULL, A_NULL); \ +/* NEW */ INS_MDATA[0xF1] = encode(1, A_WORD, A_NULL, A_NULL); \ +/* LSIZE */ INS_MDATA[0xF2] = encode(1, A_WORD, A_NULL, A_NULL); \ /* DECLASS */ INS_MDATA[0xFE] = encode(2, A_WORD, A_DYNC, A_NULL); \ /* DEFUN */ INS_MDATA[0xFF] = encode(3, A_WORD, A_BYTE, A_DYNC); diff --git a/src/vm/inc/is.h b/src/vm/inc/is.h @@ -13,8 +13,6 @@ #include "fh.h" #include "bc.h" -#include "ins_mdata.h" - #define A_NULL 0 #define A_BYTE 1 #define A_WORD 2 @@ -23,8 +21,10 @@ #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 -byte_t INS_MDATA[256]; +byte_t INS_MDATA[0xFF]; /* Takes an opcode, fills metadata about that opcode (given that it exists) in * the `bc_cont` structure diff --git a/src/vm/inc/pc.h b/src/vm/inc/pc.h @@ -37,6 +37,8 @@ void pc_update(pc_t*); */ void pc_inc(pc_t*, pc_addr); +int pc_safe(pc_t*); + /* Branch */ void pc_branch(pc_t*, pc_addr); diff --git a/src/vm/inc/proc.h b/src/vm/inc/proc.h @@ -0,0 +1,29 @@ +/* `proc.h` - Provide running process to evaluate bytecode + */ + +#ifndef PROC_H +#define PROC_H + +#include <stdlib.h> +#include <stdio.h> + +#include "rt.h" +#include "bc.h" +#include "stk.h" +#include "var.h" +#include "pc.h" +#include "helper.h" + +rt_t* proc_init(char*); + +void proc_run(rt_t*); + +void proc_clean(rt_t*); + +var_cont* proc_callfun(rt_t*, var_cont*); + +void proc_setvar(rt_t*, int, ns_addr, var_cont*); + +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 @@ -6,7 +6,6 @@ #include <stdlib.h> #include <stdio.h> -#include <pthread.h> #include "bc.h" #include "stk.h" @@ -14,38 +13,47 @@ #include "pc.h" #include "helper.h" +#ifdef THREADING +#include <pthread.h> + typedef struct rt_pool { int thread_count; rt_worker** threads; ns_cont* gvars; } rt_pool; + typedef struct rt_worker { pthread_t* thread_ctx; rt_t runtime_ctx; - pc_t* pc; } rt_worker +#endif // THREADING + typedef struct rt_t { + pc_t* pc; stk_t* stack; stk_t* argstk; ns_t* vars; ns_cont* gvars; - ns_addr entry; } rt_t; +#ifdef THREADING + rt_pool* rt_pool_init(int); void rt_pool_kill(rt_pool*); +void *rt_worker_run(void*); + rt_worker* rt_worker_new(void); void rt_worker_del(rt_worker*); -rt_t* rt_ctx_new(char); +#endif //THREADING -void rt_ctx_del(rt_t*); +rt_t* rt_ctx_new(char*, stk_t*, ns_cont*); -void *rt_worker_run(void*); +void rt_ctx_del(rt_t*); #endif // RT_H diff --git a/src/vm/src/ins_def.c b/src/vm/src/ins_def.c @@ -5,8 +5,233 @@ #include "rt.h" #include "helper.h" -void _ins_def_INSTRUCTIONNAME(rt_worker* thread, rt_context* ctx) +void init_ins_def( void ) { + INS_DEF[0x00] = _ins_def_NULL; + INS_DEF[0x01] = _ins_def_SYNC; + INS_DEF[0x02] = _ins_def_ARGB; + INS_DEF[0x0F] = _ins_def_LIBC; + INS_DEF[0x10] = _ins_def_POP; + INS_DEF[0x11] = _ins_def_ROT; + INS_DEF[0x12] = _ins_def_DUP; + INS_DEF[0x13] = _ins_def_ROT_THREE; + + INS_DEF[0x20] = _ins_def_DEC; + INS_DEF[0x21] = _ins_def_LOV; + INS_DEF[0x22] = _ins_def_STV; + INS_DEF[0x23] = _ins_def_LOC; + INS_DEF[0x24] = _ins_def_CTS; + + INS_DEF[0x30] = _ins_def_TYPEOF; + INS_DEF[0x31] = _ins_def_CAST; + + INS_DEF[0x40] = _ins_def_ADD; + INS_DEF[0x41] = _ins_def_SUB; + INS_DEF[0x42] = _ins_def_MULT; + INS_DEF[0x43] = _ins_def_DIV; + INS_DEF[0x44] = _ins_def_POW; + INS_DEF[0x45] = _ins_def_BRT; + INS_DEF[0x46] = _ins_def_SIN; + INS_DEF[0x47] = _ins_def_COS; + INS_DEF[0x48] = _ins_def_TAN; + INS_DEF[0x49] = _ins_def_ISIN; + INS_DEF[0x4A] = _ins_def_ICOS; + INS_DEF[0x4B] = _ins_def_ITAN; + INS_DEF[0x4C] = _ins_def_MOD; + INS_DEF[0x4D] = _ins_def_OR; + INS_DEF[0x4E] = _ins_def_XOR; + INS_DEF[0x4F] = _ins_def_NAND; + + INS_DEF[0x50] = _ins_def_GTHAN; + INS_DEF[0x51] = _ins_def_LTHAN; + INS_DEF[0x52] = _ins_def_EQ; + INS_DEF[0x53] = _ins_def_NOT; + + INS_DEF[0x60] = _ins_def_STARTL; + INS_DEF[0x61] = _ins_def_CLOOP; + INS_DEF[0x6E] = _ins_def_BREAK; + INS_DEF[0x6F] = _ins_def_DONE; + + INS_DEF[0x70] = _ins_def_GOTO; + INS_DEF[0x71] = _ins_def_JUMPF; + INS_DEF[0x7F] = _ins_def_CALL; + + INS_DEF[0x80] = _ins_def_PUSH; + INS_DEF[0x81] = _ins_def_DEL; + INS_DEF[0x82] = _ins_def_GET; + INS_DEF[0x83] = _ins_def_GETP; + INS_DEF[0x84] = _ins_def_GETM; + + INS_DEF[0xF0] = _ins_def_RETURN; + INS_DEF[0xF1] = _ins_def_NEW; + INS_DEF[0xF2] = _ins_def_LSIZE; + INS_DEF[0xFE] = _ins_def_DECLASS; + INS_DEF[0xFF] = _ins_def_DEFUN; } +void _ins_def_NULL (rt_t*, byte_t*) +{ +} +void _ins_def_SYNC (rt_t*, byte_t*) +{ +} +void _ins_def_ARGB (rt_t*, byte_t*) +{ +} +void _ins_def_LIBC (rt_t*, byte_t*) +{ +} + +void _ins_def_POP (rt_t*, byte_t*) +{ +} +void _ins_def_ROT (rt_t*, byte_t*) +{ +} +void _ins_def_DUP (rt_t*, byte_t*) +{ +} +void _ins_def_ROT_THREE(rt_t*, byte_t*) +{ +} + +void _ins_def_DEC (rt_t*, byte_t*) +{ +} +void _ins_def_LOV (rt_t*, byte_t*) +{ +} +void _ins_def_STV (rt_t*, byte_t*) +{ +} +void _ins_def_LOC (rt_t*, byte_t*) +{ +} +void _ins_def_CTS (rt_t*, byte_t*) +{ +} + +void _ins_def_TYPEOF (rt_t*, byte_t*) +{ +} +void _ins_def_CAST (rt_t*, byte_t*) +{ +} + +void _ins_def_ADD (rt_t*, byte_t*) +{ +} +void _ins_def_SUB (rt_t*, byte_t*) +{ +} +void _ins_def_MULT (rt_t*, byte_t*) +{ +} +void _ins_def_DIV (rt_t*, byte_t*) +{ +} +void _ins_def_POW (rt_t*, byte_t*) +{ +} +void _ins_def_BRT (rt_t*, byte_t*) +{ +} +void _ins_def_SIN (rt_t*, byte_t*) +{ +} +void _ins_def_COS (rt_t*, byte_t*) +{ +} +void _ins_def_TAN (rt_t*, byte_t*) +{ +} +void _ins_def_ISIN (rt_t*, byte_t*) +{ +} +void _ins_def_ICOS (rt_t*, byte_t*) +{ +} +void _ins_def_ITAN (rt_t*, byte_t*) +{ +} +void _ins_def_MOD (rt_t*, byte_t*) +{ +} +void _ins_def_OR (rt_t*, byte_t*) +{ +} +void _ins_def_XOR (rt_t*, byte_t*) +{ +} +void _ins_def_NAND (rt_t*, byte_t*) +{ +} + +void _ins_def_GTHAN (rt_t*, byte_t*) +{ +} +void _ins_def_LTHAN (rt_t*, byte_t*) +{ +} +void _ins_def_EQ (rt_t*, byte_t*) +{ +} +void _ins_def_NOT (rt_t*, byte_t*) +{ +} + +void _ins_def_STARTL (rt_t*, byte_t*) +{ +} +void _ins_def_CLOOP (rt_t*, byte_t*) +{ +} +void _ins_def_BREAK (rt_t*, byte_t*) +{ +} +void _ins_def_DONE (rt_t*, byte_t*) +{ +} + +void _ins_def_GOTO (rt_t*, byte_t*) +{ +} +void _ins_def_JUMPF (rt_t*, byte_t*) +{ +} +void _ins_def_CALL (rt_t*, byte_t*) +{ +} + +void _ins_def_PUSH (rt_t*, byte_t*) +{ +} +void _ins_def_DEL (rt_t*, byte_t*) +{ +} +void _ins_def_GET (rt_t*, byte_t*) +{ +} +void _ins_def_GETP (rt_t*, byte_t*) +{ +} +void _ins_def_CALLM (rt_t*, byte_t*) +{ +} + +void _ins_def_RETURN (rt_t*, byte_t*) +{ +} +void _ins_def_NEW (rt_t*, byte_t*) +{ +} +void _ins_def_LSIZE (rt_t*, byte_t*) +{ +} +void _ins_def_DECLASS (rt_t*, byte_t*) +{ +} +void _ins_def_DEFUN (rt_t*, byte_t*) +{ +} diff --git a/src/vm/src/main.c b/src/vm/src/main.c @@ -1,6 +1,27 @@ #include <stdio.h> +#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 "helper.h" + + int main(int argc, char** argv) { + ASSERT(argc < 0, "C'mon, man! Gimme some args"); + init(); + init_ins_def(); + + rt_t* runtime = proc_init(argv[0]); + + proc_run(runtime); + + proc_clean(runtime); + return 0; } diff --git a/src/vm/src/pc.c b/src/vm/src/pc.c @@ -48,6 +48,23 @@ void pc_inc(pc_t* pc, pc_addr addr) pc->address = pc->address + addr; } +int pc_safe(pc_t* pc) +{ + N_ASSERT(pc); + + int rv = 0; + + if (pc->address >= pc->root->real_addr) + { + rv = 0; + } else + if (pc->address < pc->root->real_addr) + { + rv = 1; + } + + return rv; +} void pc_branch(pc_t* pc, pc_addr addr) { diff --git a/src/vm/src/proc.c b/src/vm/src/proc.c @@ -0,0 +1,55 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "proc.h" + +#include "rt.h" +#include "ins_def.h" +#include "bc.h" +#include "stk.h" +#include "var.h" +#include "pc.h" +#include "helper.h" + +rt_t* proc_init(char* fname) +{ + N_ASSERT(fname); + rt_t* ctx = rt_ctx_new(fname, stk_new(), ns_cont_new(1024)); + + return ctx; +} + +void proc_run(rt_t* ctx) +{ + N_ASSERT(ctx); + + for (pc_branch(ctx->pc, 0); pc_safe(ctx->pc); pc_update(ctx->pc)) + { + ins_def_is_valid(ctx->pc->line); + INS_DEF[ctx->pc->line->op](ctx, ctx->pc->line->args); + } +} + +void proc_clean(rt_t* ctx) +{ + N_ASSERT(ctx); + rt_ctx_del(ctx); +} + +var_cont* proc_callfun(rt_t* ctx, var_cont* func) +{ + N_ASSERT(ctx); + +} + +void proc_setvar(rt_t* ctx, int scope, ns_addr name, var_cont* var) +{ + +} + +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 @@ -1,5 +1,4 @@ #include <stdlib.h> -#include <pthreads.h> #include "rt.h" #include "bc.h" @@ -8,6 +7,9 @@ #include "pc.h" #include "helper.h" +#ifdef THREADING + +#include <pthread.h> rt_pool* rt_pool_init(int depth) { @@ -18,16 +20,22 @@ void rt_pool_kill(rt_pool* pool) } +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 -rt_worker* rt_worker_new(char* fname, ns_addr func, ns_cont* gscope, stk_t* args) + return 0; +} + + +rt_worker* rt_worker_new(char* fname, ns_addr func, ns_cont* gs, 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; @@ -48,16 +56,22 @@ void rt_worker_del(rt_worker* worker) free(worker); } -rt_t* rt_ctx_new(ns_addr func, stk_t* args, ns_cont* gscope, int size) +#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->vars = ns_new(size); - ctx->gvars = gscope; - ctx->entry = func; + ctx->gvars = gvars; + return ctx; } @@ -67,24 +81,14 @@ void rt_ctx_del(rt_t* ctx) N_ASSERT(ctx); N_ASSERT(ctx->stack); - if (ctx->stack != NULL) - stk_del(ctx->stack); + stk_del(ctx->stack); N_ASSERT(ctx->argstk); - if (ctx->argstk != NULL) - stk_del(ctx->stack); + stk_del(ctx->argstk); 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; + ns_del(ctx->ns); + + N_ASERT(ctx->pc); + pc_del(ctx->pc); } diff --git a/src/vm/tests/run.sh b/src/vm/tests/run.sh @@ -5,3 +5,7 @@ cd cases ../tools/test.sh $1 ../tools/clean.sh $1 + +cd .. + +rm ../src/*.o