language

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

commit a12dcb90a2c27546091e0cd87cae811f68a00788
parent a7391e100eb493de0c5d3b513a15430526f2576c
Author: Paul Longtine <paullongtine@gmail.com>
Date:   Thu Mar  3 22:20:00 2016

Stuff.

Diffstat:
 doc/SPECIFICATION              |  23 ++---
 src/vm/inc/bc.h                |  38 ++------
 src/vm/inc/helper.h            |   2 +-
 src/vm/inc/ins_mdata.h         | 141 +++++++++++++++---------------
 src/vm/inc/ns.h                |   2 +-
 src/vm/inc/pc.h                |  16 +--
 src/vm/inc/var.h               |  76 ++++++++++------
 src/vm/src/bc.c                |  85 ++++++------------
 src/vm/src/ins_def.c           |  20 ++--
 src/vm/src/pc.c                |  25 ++++-
 src/vm/src/proc.c              |   7 +-
 src/vm/src/var.c               | 196 ++++++++++++++++++++++++++++++++++--------
 src/vm/testing                 | Bin 13 -> 0 bytes
 src/vm/tests/bytecodes/testing | Bin 0 -> 14 bytes
 14 files changed, 391 insertions(+), 240 deletions(-)

diff --git a/doc/SPECIFICATION b/doc/SPECIFICATION @@ -107,6 +107,7 @@ be assigned or re-assigned to variables. Keywords: TOS - 'Top Of Stack' The top element S<[variable]> - Static Arguement. (1 byte) + N<[variable]> - Name, word in length A<[variable]> - Address Arguement. Address width will vary on file size, decided on compile time. (for now, a word) D<[variable]> - Dynamic bytecode arguement. Arguements terminated with NULL @@ -121,10 +122,10 @@ Keywords: ------------------------------------------------------------------------------- 2 - Variable management ------------------------------------------------------------------------------- -20 DEC S<scope> S<type> A<ref> - declare variable of type -21 LOV S<scope> A<ref> - loads reference variable on to stack -22 STV S<scope> A<ref> - stores TOS to reference variable -23 LOC S<scope> A<ref> D<data> - loads constant into variable +20 DEC S<scope> S<type> N<ref> - declare variable of type +21 LOV S<scope> N<ref> - loads reference variable on to stack +22 STV S<scope> N<ref> - stores TOS to reference variable +23 LOC S<scope> N<ref> D<data> - loads constant into variable 24 CTS D<data> - loads constant into stack ------------------------------------------------------------------------------- 3 - Type management @@ -180,8 +181,8 @@ to TOS These instructions dictate code flow. ------------------------------------------------------------------------------- 70 GOTO A<addr> - Goes to address -71 JUMPF S<n> - Goes forward <n> lines -7F CALL A<ref> - Calls function, pushes return value on to STACK. +71 JUMPF A<n> - Goes forward <n> lines +7F CALL N<ref> - Calls function, pushes return value on to STACK. ------------------------------------------------------------------------------- 8 - Manipulating High-order Object Variables @@ -196,21 +197,21 @@ to TOS 82 GET - Gets key, TOS must be a keyed datastructure, and TOS1 must be a string that is a key in TOS. -83 GETP A<ref> - Get property of <ref> in object contained in TOS. pushes +83 GETP N<ref> - Get property of <ref> in object contained in TOS. pushes to stack -84 CALLM A<ref> - Call method of <ref> in object contained in TOS. Uses +84 CALLM N<ref> - Call method of <ref> in object contained in TOS. Uses arguement stack ------------------------------------------------------------------------------- F - Functions/classes ------------------------------------------------------------------------------- -FF DEFUN A<ref> S<type> D<args> - Un-funs everything. no, no- it defines a +FF DEFUN N<ref> S<type> D<args> - Un-funs everything. no, no- it defines a function. D<ref> is its name, S<type> is the return value, D<args> is the args. -FE DECLASS A<ref> D<args> - Defines a class. +FE DECLASS N<ref> D<args> - Defines a class. -F1 NEW A<ref> - Instantiates class +F1 NEW N<ref> - Instantiates class F0 RETURN - Returns from function ------------------------------------------------------------------------------- diff --git a/src/vm/inc/bc.h b/src/vm/inc/bc.h @@ -7,39 +7,26 @@ #include <stdlib.h> #include <stdio.h> -#include "var.h" #include "fh.h" #include "helper.h" +#include "var.h" -typedef unsigned short int bc_addr; +typedef unsigned int bc_addr; /* 'Bytecode Container' */ typedef struct bc_cont { - bc_addr real_addr; - byte_t op; - byte_t mdata; - byte_t adata; - byte_t* args[3]; - void* targ[3]; - int sarg[3]; + bc_addr real_addr; + byte_t op; + byte_t mdata; + byte_t adata; + byte_t* args[3]; + var_cont* varg[3]; + int sarg[3]; struct bc_cont* next; struct bc_cont* prev; } bc_cont; -typedef struct bc_targ_int { - int i; -} bc_targ_int; - -typedef struct bc_targ_list { - int size; - b_type* i; -} bc_targ_list; - -typedef struct bc_targ_var_cont { - var_cont* i; -} bc_targ_var_cont; - #include "is.h" /* Handles allocation for new `bc_cont` instances @@ -61,17 +48,14 @@ void bc_cont_del(bc_cont*); */ void get_args(FILE*, bc_cont*); byte_t* get_byte_arg(FILE*, int*); -byte_t* get_word_arg(FILE*, int*); +byte_t* get_name_arg(FILE*, int*); +byte_t* get_addr_arg(FILE*, int*); byte_t* get_dync_arg(FILE*, int*); /* Process arguements into typed & readable data * bc_cont* - bytecode container */ void process_args(bc_cont*); -void arg_to_int(void**, byte_t*); -void arg_to_addr(void**, byte_t*); -void arg_to_arglist(void**, int, byte_t*); -void arg_to_var(void**, int, byte_t*); /* Scan to +/- int in bytecode chain * bc_cont* - bytecode container [0] diff --git a/src/vm/inc/helper.h b/src/vm/inc/helper.h @@ -4,6 +4,8 @@ #ifndef HELPER_H #define HELPER_H +#include <stdio.h> + #define ASSERT(condition, message)\ if (!(condition)) \ { \ diff --git a/src/vm/inc/ins_mdata.h b/src/vm/inc/ins_mdata.h @@ -9,9 +9,12 @@ #define encode(n, a0, a1, a2) \ ( n << 6 | a0 << 4 | a1 << 2 | a2 ); -#define A_NULL 0 -#define A_BYTE 1 -#define A_WORD 2 +#define NAMELEN 2 +#define ADDRLEN 2 + +#define A_BYTE 0 +#define A_NAME 1 +#define A_ADDR 2 #define A_DYNC 3 /* This definition is ran in `is.c` @@ -19,69 +22,69 @@ * 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); \ -/* ARGB */ INS_MDATA[0x02] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* LIBC */ INS_MDATA[0x0F] = encode(1, A_WORD, A_NULL, A_NULL); \ +/* NULL */ INS_MDATA[0x00] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* SYNC */ INS_MDATA[0x01] = encode(1, A_BYTE, A_BYTE, A_BYTE); \ +/* ARGB */ INS_MDATA[0x02] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* LIBC */ INS_MDATA[0x0F] = encode(1, A_ADDR, A_BYTE, A_BYTE); \ \ -/* 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); \ -/* ROT_THREE */ INS_MDATA[0x13] = encode(0, A_NULL, A_NULL, A_NULL); \ +/* POP */ INS_MDATA[0x10] = encode(1, A_BYTE, A_BYTE, A_BYTE); \ +/* ROT */ INS_MDATA[0x11] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* DUP */ INS_MDATA[0x12] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* ROT_THREE */ INS_MDATA[0x13] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ \ -/* DEC */ INS_MDATA[0x20] = encode(3, A_BYTE, A_BYTE, A_WORD); \ -/* LOV */ INS_MDATA[0x21] = encode(2, A_BYTE, A_WORD, A_NULL); \ -/* STV */ INS_MDATA[0x22] = encode(2, A_BYTE, A_WORD, A_NULL); \ -/* LOC */ INS_MDATA[0x23] = encode(3, A_BYTE, A_WORD, A_DYNC); \ -/* CTS */ INS_MDATA[0x24] = encode(1, A_DYNC, A_NULL, A_NULL); \ +/* DEC */ INS_MDATA[0x20] = encode(3, A_BYTE, A_BYTE, A_NAME); \ +/* LOV */ INS_MDATA[0x21] = encode(2, A_BYTE, A_NAME, A_BYTE); \ +/* STV */ INS_MDATA[0x22] = encode(2, A_BYTE, A_NAME, A_BYTE); \ +/* LOC */ INS_MDATA[0x23] = encode(3, A_BYTE, A_NAME, A_DYNC); \ +/* CTS */ INS_MDATA[0x24] = encode(1, A_DYNC, A_BYTE, A_BYTE); \ \ -/* TYPEOF */ INS_MDATA[0x30] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* CAST */ INS_MDATA[0x31] = encode(1, A_BYTE, A_NULL, A_NULL); \ +/* TYPEOF */ INS_MDATA[0x30] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* CAST */ INS_MDATA[0x31] = encode(1, A_BYTE, A_BYTE, A_BYTE); \ \ -/* ADD */ INS_MDATA[0x40] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* SUB */ INS_MDATA[0x41] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* MULT */ INS_MDATA[0x42] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* DIV */ INS_MDATA[0x43] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* POW */ INS_MDATA[0x44] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* BRT */ INS_MDATA[0x45] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* SIN */ INS_MDATA[0x46] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* COS */ INS_MDATA[0x47] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* TAN */ INS_MDATA[0x48] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* ISIN */ INS_MDATA[0x49] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* ICOS */ INS_MDATA[0x4A] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* ITAN */ INS_MDATA[0x4B] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* MOD */ INS_MDATA[0x4C] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* OR */ INS_MDATA[0x4D] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* XOR */ INS_MDATA[0x4E] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* NAND */ INS_MDATA[0x4F] = encode(0, A_NULL, A_NULL, A_NULL); \ +/* ADD */ INS_MDATA[0x40] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* SUB */ INS_MDATA[0x41] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* MULT */ INS_MDATA[0x42] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* DIV */ INS_MDATA[0x43] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* POW */ INS_MDATA[0x44] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* BRT */ INS_MDATA[0x45] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* SIN */ INS_MDATA[0x46] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* COS */ INS_MDATA[0x47] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* TAN */ INS_MDATA[0x48] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* ISIN */ INS_MDATA[0x49] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* ICOS */ INS_MDATA[0x4A] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* ITAN */ INS_MDATA[0x4B] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* MOD */ INS_MDATA[0x4C] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* OR */ INS_MDATA[0x4D] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* XOR */ INS_MDATA[0x4E] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* NAND */ INS_MDATA[0x4F] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ \ -/* GTHAN */ INS_MDATA[0x50] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* LTHAN */ INS_MDATA[0x51] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* EQ */ INS_MDATA[0x52] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* NOT */ INS_MDATA[0x53] = encode(0, A_NULL, A_NULL, A_NULL); \ +/* GTHAN */ INS_MDATA[0x50] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* LTHAN */ INS_MDATA[0x51] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* EQ */ INS_MDATA[0x52] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* NOT */ INS_MDATA[0x53] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ \ -/* STARTL */ INS_MDATA[0x60] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* CLOOP */ INS_MDATA[0x61] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* BREAK */ INS_MDATA[0x6E] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* DONE */ INS_MDATA[0x6F] = encode(0, A_NULL, A_NULL, A_NULL); \ +/* STARTL */ INS_MDATA[0x60] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* CLOOP */ INS_MDATA[0x61] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* BREAK */ INS_MDATA[0x6E] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* DONE */ INS_MDATA[0x6F] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ \ -/* GOTO */ INS_MDATA[0x70] = encode(1, A_WORD, A_NULL, A_NULL); \ -/* JUMPF */ INS_MDATA[0x71] = encode(1, A_BYTE, A_NULL, A_NULL); \ -/* CALL */ INS_MDATA[0x7F] = encode(1, A_WORD, A_NULL, A_NULL); \ +/* GOTO */ INS_MDATA[0x70] = encode(1, A_ADDR, A_BYTE, A_BYTE); \ +/* JUMPF */ INS_MDATA[0x71] = encode(1, A_BYTE, A_BYTE, A_BYTE); \ +/* CALL */ INS_MDATA[0x7F] = encode(1, A_ADDR, A_BYTE, A_BYTE); \ \ -/* 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(1, A_WORD, A_NULL, A_NULL); \ -/* CALLM */ INS_MDATA[0x84] = encode(1, A_WORD, A_NULL, A_NULL); \ +/* PUSH */ INS_MDATA[0x80] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* DEL */ INS_MDATA[0x81] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* GET */ INS_MDATA[0x82] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* GETP */ INS_MDATA[0x83] = encode(1, A_NAME, A_BYTE, A_BYTE); \ +/* CALLM */ INS_MDATA[0x84] = encode(1, A_NAME, A_BYTE, A_BYTE); \ \ -/* RETURN */ INS_MDATA[0xF0] = encode(0, A_NULL, A_NULL, A_NULL); \ -/* NEW */ INS_MDATA[0xF1] = 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); +/* RETURN */ INS_MDATA[0xF0] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* NEW */ INS_MDATA[0xF1] = encode(1, A_NAME, A_BYTE, A_BYTE); \ +/* DECLASS */ INS_MDATA[0xFE] = encode(2, A_NAME, A_DYNC, A_BYTE); \ +/* DEFUN */ INS_MDATA[0xFF] = encode(3, A_NAME, A_BYTE, A_DYNC); #define BTOI 0 -#define WTOA 1 +#define BTOT 1 #define DTOL 2 #define DTOV 3 @@ -93,21 +96,21 @@ /* NULL */ INS_ADATA[0x00] = encode(0, BTOI, BTOI, BTOI); \ /* SYNC */ INS_ADATA[0x01] = encode(1, BTOI, BTOI, BTOI); \ /* ARGB */ INS_ADATA[0x02] = encode(0, BTOI, BTOI, BTOI); \ -/* LIBC */ INS_ADATA[0x0F] = encode(1, WTOA, BTOI, BTOI); \ +/* LIBC */ INS_ADATA[0x0F] = encode(1, BTOI, BTOI, BTOI); \ \ /* POP */ INS_ADATA[0x10] = encode(1, BTOI, BTOI, BTOI); \ /* ROT */ INS_ADATA[0x11] = encode(0, BTOI, BTOI, BTOI); \ /* DUP */ INS_ADATA[0x12] = encode(0, BTOI, BTOI, BTOI); \ /* ROT_THREE */ INS_ADATA[0x13] = encode(0, BTOI, BTOI, BTOI); \ \ -/* DEC */ INS_ADATA[0x20] = encode(3, BTOI, BTOI, WTOA); \ -/* LOV */ INS_ADATA[0x21] = encode(2, BTOI, WTOA, BTOI); \ -/* STV */ INS_ADATA[0x22] = encode(2, BTOI, WTOA, BTOI); \ -/* LOC */ INS_ADATA[0x23] = encode(3, BTOI, WTOA, BTOI); \ -/* CTS */ INS_ADATA[0x24] = encode(1, BTOI, BTOI, BTOI); \ +/* DEC */ INS_ADATA[0x20] = encode(3, BTOI, BTOI, BTOI); \ +/* LOV */ INS_ADATA[0x21] = encode(2, BTOI, BTOI, BTOI); \ +/* STV */ INS_ADATA[0x22] = encode(2, BTOI, BTOI, BTOI); \ +/* LOC */ INS_ADATA[0x23] = encode(3, BTOI, BTOI, BTOI); \ +/* CTS */ INS_ADATA[0x24] = encode(1, DTOV, BTOI, BTOI); \ \ /* TYPEOF */ INS_ADATA[0x30] = encode(0, BTOI, BTOI, BTOI); \ -/* CAST */ INS_ADATA[0x31] = encode(1, BTOI, BTOI, BTOI); \ +/* CAST */ INS_ADATA[0x31] = encode(1, BTOT, BTOI, BTOI); \ \ /* ADD */ INS_ADATA[0x40] = encode(0, BTOI, BTOI, BTOI); \ /* SUB */ INS_ADATA[0x41] = encode(0, BTOI, BTOI, BTOI); \ @@ -136,19 +139,19 @@ /* BREAK */ INS_ADATA[0x6E] = encode(0, BTOI, BTOI, BTOI); \ /* DONE */ INS_ADATA[0x6F] = encode(0, BTOI, BTOI, BTOI); \ \ -/* GOTO */ INS_ADATA[0x70] = encode(1, WTOA, BTOI, BTOI); \ +/* GOTO */ INS_ADATA[0x70] = encode(1, BTOI, BTOI, BTOI); \ /* JUMPF */ INS_ADATA[0x71] = encode(1, BTOI, BTOI, BTOI); \ -/* CALL */ INS_ADATA[0x7F] = encode(1, WTOA, BTOI, BTOI); \ +/* CALL */ INS_ADATA[0x7F] = encode(1, BTOI, BTOI, BTOI); \ \ /* PUSH */ INS_ADATA[0x80] = encode(0, BTOI, BTOI, BTOI); \ /* DEL */ INS_ADATA[0x81] = encode(0, BTOI, BTOI, BTOI); \ /* GET */ INS_ADATA[0x82] = encode(0, BTOI, BTOI, BTOI); \ -/* GETP */ INS_ADATA[0x83] = encode(1, WTOA, BTOI, BTOI); \ -/* CALLM */ INS_ADATA[0x84] = encode(1, WTOA, BTOI, BTOI); \ +/* GETP */ INS_ADATA[0x83] = encode(1, BTOI, BTOI, BTOI); \ +/* CALLM */ INS_ADATA[0x84] = encode(1, BTOI, BTOI, BTOI); \ \ /* RETURN */ INS_ADATA[0xF0] = encode(0, BTOI, BTOI, BTOI); \ -/* NEW */ INS_ADATA[0xF1] = encode(1, WTOA, BTOI, BTOI); \ -/* DECLASS */ INS_ADATA[0xFE] = encode(2, WTOA, BTOI, BTOI); \ -/* DEFUN */ INS_ADATA[0xFF] = encode(3, WTOA, BTOI, BTOI); +/* NEW */ INS_ADATA[0xF1] = encode(1, BTOI, BTOI, BTOI); \ +/* DECLASS */ INS_ADATA[0xFE] = encode(2, BTOI, DTOL, BTOI); \ +/* DEFUN */ INS_ADATA[0xFF] = encode(3, BTOI, BTOT, DTOL); #endif diff --git a/src/vm/inc/ns.h b/src/vm/inc/ns.h @@ -9,7 +9,7 @@ #include "var.h" #include "helper.h" -typedef int ns_addr; +typedef unsigned int ns_addr; typedef struct ns_cont { ns_addr size; diff --git a/src/vm/inc/pc.h b/src/vm/inc/pc.h @@ -19,23 +19,27 @@ typedef struct pc_stk { struct pc_stk* next; } pc_stk; +/* pc_t structure + * + * bc_cont* root - First instruction + * bc_cont* line - Current instruction + * pc_stk* stk - Address stack + */ typedef struct pc_t { bc_cont* root; bc_cont* line; pc_stk* stk; } pc_t; -/* Initalizes program counter - * char* is filename of file containing bytecode +/* Initalizes program counter, returns pc_t* instance + * char* - filename of file containing bytecode */ pc_t* pc_new(char*); - -pc_stk* pc_stk_new(void); +pc_stk* pc_stk_new(ns_addr); /* Frees memory assosiated with pc_t* instance */ void pc_del(pc_t*); - void pc_stk_del(pc_stk*); /* Updates program counter on changes @@ -46,7 +50,7 @@ void pc_update(pc_t*); */ void pc_inc(pc_t*, pc_addr); -/* Branch +/* Branch to addr */ void pc_branch(pc_t*, pc_addr); diff --git a/src/vm/inc/var.h b/src/vm/inc/var.h @@ -1,24 +1,28 @@ -/* types.h -> Provide implemenation of types +/* var.h -> Provide implemenation of types */ -#ifndef TYPES_H -#define TYPES_H +#ifndef VAR_H +#define VAR_H #include <stdlib.h> #include <stdio.h> #include "helper.h" +typedef unsigned int bc_addr; +typedef unsigned int ns_addr; + typedef enum { VOID, + ADDR, + TYPE, + PLIST, FUNC, OBJECT, G_INT, G_FLOAT, G_CHAR, - U_CHAR, G_STR, - U_STR, S_ARRAY, D_ARRAY, K_ARRAY, @@ -27,12 +31,20 @@ typedef enum { typedef struct var_cont { b_type type; - void* data; + void* data; } var_cont; -typedef struct var_data_void { - void* v; -} var_data_void; +typedef struct var_data_type { + b_type v; +} var_data_type; + +typedef struct var_data_func { + bc_addr loc; + bc_addr end; + b_type type; + ns_addr size; + b_type* param; +} var_data_func; typedef struct var_data_int { int v; @@ -45,41 +57,57 @@ typedef struct var_data_float { typedef struct var_data_char { char v; } var_data_char; -/* -typedef char var_data_u_char; -*/ + typedef struct var_data_str { char* v; } var_data_str; -/* -typedef struct var_data_u_str { - var_data_u_char* str; -} var_data_u_str; -*/ + +typedef struct var_data_plist { + b_type* v; +} var_data_plist; + +#include "bc.h" /* Initialze variable with type */ var_cont* var_new(b_type); -void* var_data_alloc(b_type); +void* var_data_alloc_TYPE(b_type); +void* var_data_alloc_FUNC(b_type); void* var_data_alloc_G_INT(int); void* var_data_alloc_G_FLOAT(double); void* var_data_alloc_G_CHAR(char); void* var_data_alloc_G_STR(size_t); +void* var_data_alloc_PLIST(size_t); /* Frees variable */ void var_del(var_cont*); void var_data_free(void*, b_type); +void var_data_free_FUNC(void*); +void var_data_free_G_STR(void*); +void var_data_free_PLIST(void*); + /* Sets variable - * void** -> pointer to allocated space of memory that agrees with b_type + * void* -> pointer to allocated space of memory that agrees with b_type */ void var_set(var_cont*, void*, b_type); -int var_data_get_G_INT(var_cont*); -double var_data_get_G_FLOAT(var_cont*); -char var_data_get_G_CHAR(var_cont*); -char* var_data_get_G_STR(var_cont*); +b_type var_data_get_TYPE(var_cont*); +var_data_func* var_data_get_FUNC(var_cont*); +int var_data_get_G_INT(var_cont*); +double var_data_get_G_FLOAT(var_cont*); +char var_data_get_G_CHAR(var_cont*); +char* var_data_get_G_STR(var_cont*); +b_type* var_data_get_PLIST(var_cont*); + +void bytes_to_int(var_cont**, int, byte_t*); + +void byte_to_type(var_cont**, byte_t); + +void raw_to_plist(var_cont**, int, byte_t*); + +void raw_to_var(var_cont**, int, byte_t*); -#endif // TYPES_H +#endif // var_H diff --git a/src/vm/src/bc.c b/src/vm/src/bc.c @@ -3,9 +3,9 @@ #include "bc.h" -#include "var.h" #include "is.h" #include "fh.h" +#include "var.h" #include "helper.h" /* Handles allocation for new `bc_cont` instances @@ -19,9 +19,9 @@ bc_cont* bc_cont_new(void) new->args[1] = NULL; new->args[2] = NULL; - new->targ[0] = NULL; - new->targ[1] = NULL; - new->targ[2] = NULL; + new->varg[0] = NULL; + new->varg[1] = NULL; + new->varg[2] = NULL; new->sarg[0] = 0; new->sarg[1] = 0; @@ -58,9 +58,9 @@ void bc_cont_del(bc_cont* root) if (root->args[1] != NULL) free(root->args[1]); if (root->args[2] != NULL) free(root->args[2]); - if (root->targ[0] != NULL) free(root->targ[0]); - if (root->targ[1] != NULL) free(root->targ[1]); - if (root->targ[2] != NULL) free(root->targ[2]); + if (root->varg[0] != NULL) var_del(root->varg[0]); + if (root->varg[1] != NULL) var_del(root->varg[1]); + if (root->varg[2] != NULL) var_del(root->varg[2]); free(root); } @@ -82,9 +82,13 @@ void get_args(FILE* f, bc_cont* ins) { ins->args[x] = get_byte_arg(f, &ins->sarg[x]); } else - if (arg_types[x] == A_WORD) + if (arg_types[x] == A_NAME) + { + ins->args[x] = get_name_arg(f, &ins->sarg[x]); + } else + if (arg_types[x] == A_ADDR) { - ins->args[x] = get_word_arg(f, &ins->sarg[x]); + ins->args[x] = get_addr_arg(f, &ins->sarg[x]); } else if (arg_types[x] == A_DYNC) { @@ -97,10 +101,15 @@ byte_t* get_byte_arg(FILE* f, int* size) *size = 1; return read_bytes(f, 1); } -byte_t* get_word_arg(FILE* f, int* size) +byte_t* get_name_arg(FILE* f, int* size) { - *size = 2; - return read_bytes(f, 2); + *size = NAMELEN; + return read_bytes(f, NAMELEN); +} +byte_t* get_addr_arg(FILE* f, int* size) +{ + *size = ADDRLEN; + return read_bytes(f, ADDRLEN); } byte_t* get_dync_arg(FILE* f, int* size) { @@ -130,63 +139,28 @@ void process_args(bc_cont* ins) unencode(ins->adata, &num_args, arg_types); - for (int x = 0; x < num_args; x++) + int x; + for (x = 0; x < num_args; x++) { if (arg_types[x] == BTOI) { - arg_to_int(&ins->targ[x], ins->args[x]); + bytes_to_int(&ins->varg[x], ins->sarg[x], ins->args[x]); } else - if (arg_types[x] == WTOA) + if (arg_types[x] == BTOT) { - arg_to_addr(&ins->targ[x], ins->args[x]); + byte_to_type(&ins->varg[x], ins->args[x][0]); } else if (arg_types[x] == DTOL) { - arg_to_arglist(&ins->targ[x], ins->sarg[x], ins->args[x]); + raw_to_plist(&ins->varg[x], ins->sarg[x], ins->args[x]); } else if (arg_types[x] == DTOV) { - arg_to_var(&ins->targ[x], ins->sarg[x], ins->args[x]); + raw_to_var(&ins->varg[x], ins->sarg[x], ins->args[x]); } } } -void arg_to_int(void** ptr, byte_t* byte) -{ - *ptr = (bc_targ_int*)malloc(sizeof(bc_targ_int)); - M_ASSERT(*ptr); - - bc_targ_int* v = *ptr; - - v->i = (int)byte[0]; -} - -void arg_to_addr(void** ptr, byte_t* word) -{ - *ptr = (bc_targ_int*)malloc(sizeof(bc_targ_int)); - M_ASSERT(*ptr); - - bc_targ_int* v = *ptr; - - v->i = (int)(word[0] << 8 | word[1]); -} - -void arg_to_arglist(void** ptr, int n, byte_t* bytes) -{ - *ptr = (bc_targ_list*)malloc(sizeof(bc_targ_list)); - M_ASSERT(*ptr); - -// bc_targ_list* v = *ptr; -} - -void arg_to_var(void** ptr, int n, byte_t* bytes) -{ - *ptr = (bc_targ_var_cont*)malloc(sizeof(bc_targ_list)); - M_ASSERT(*ptr); - -// bc_targ_var_cont* v = *ptr; -} - /* Scan to +/- int in bytecode chain * bc_cont* - bytecode container [0] * int - +/- up/down [1] @@ -236,8 +210,11 @@ bc_cont* bc_read(char* fname) while (ftell(f)<fsize) { byte = read_byte(f); + get_opcode(byte, ptr); + get_args(f, ptr); + process_args(ptr); ptr->real_addr = addr; diff --git a/src/vm/src/ins_def.c b/src/vm/src/ins_def.c @@ -300,11 +300,13 @@ void _ins_def_DECLASS (rt_t* ctx, bc_cont* line) } void _ins_def_DEFUN (rt_t* ctx, bc_cont* line) { - bc_targ_int* name = line->targ[0]; - bc_targ_int* type = line->targ[1]; - bc_targ_list* args = line->targ[2]; + int name = var_data_get_G_INT(line->varg[0]); + b_type type = var_data_get_TYPE(line->varg[1]); + b_type* args = var_data_get_PLIST(line->varg[2]); - proc_decvar(ctx, FUNC, 1, name->i); + var_data_func* data = var_data_alloc_FUNC(type); + + data->loc = line->real_addr + 1; int nsize; @@ -320,9 +322,13 @@ void _ins_def_DEFUN (rt_t* ctx, bc_cont* line) nsize++; } } + + data->size = nsize; + data->type = type; + data->param = args; + proc_decvar(ctx, 1, name, FUNC); - - printf("Namespace size for thingy: %i\n", nsize); - printf("Name: %i\n", name->i); + var_cont* var = proc_getvar(ctx, 1, name); + var_set(var, data, FUNC); } diff --git a/src/vm/src/pc.c b/src/vm/src/pc.c @@ -8,6 +8,9 @@ #include "fh.h" #include "helper.h" +/* Initalizes program counter, returns pc_t* instance + * char* - filename of file containing bytecode + */ pc_t* pc_new(char* fname) { N_ASSERT(fname); @@ -15,7 +18,7 @@ pc_t* pc_new(char* fname) pc_t* pc = (pc_t*)malloc(sizeof(pc_t)); M_ASSERT(pc); - pc->stk = pc_stk_new(); + pc->stk = pc_stk_new(0); pc->root = bc_read(fname); @@ -26,16 +29,20 @@ pc_t* pc_new(char* fname) return pc; } -pc_stk* pc_stk_new() +pc_stk* pc_stk_new(ns_addr address) { pc_stk* new = (pc_stk*)malloc(sizeof(pc_stk)); M_ASSERT(new); + new->address = address; + new->next = NULL; return new; } +/* Frees memory assosiated with pc_t* instance + */ void pc_del(pc_t* pc) { N_ASSERT(pc); @@ -60,13 +67,16 @@ void pc_stk_del(pc_stk* stk) free(stk); } - +/* Updates program counter on changes + */ void pc_update(pc_t* pc) { N_ASSERT(pc); pc->line = bc_scan(pc->line, (pc->stk->address - pc->line->real_addr) ); } +/* Increment program counter by +-addr + */ void pc_inc(pc_t* pc, pc_addr addr) { N_ASSERT(pc); @@ -74,22 +84,27 @@ void pc_inc(pc_t* pc, pc_addr addr) pc->stk->address = pc->stk->address + addr; } -void pc_branch(pc_t* pc, pc_addr addr) +/* Branch to addr + */ +void pc_branch(pc_t* pc, pc_addr address) { N_ASSERT(pc); - pc_stk* new = pc_stk_new(); + pc_stk* new = pc_stk_new(address); new->next = pc->stk; pc->stk = new; } +/* Return from branch + */ void pc_return(pc_t* pc) { N_ASSERT(pc); pc_stk* tmp = pc->stk; pc->stk = pc->stk->next; + free(tmp); } diff --git a/src/vm/src/proc.c b/src/vm/src/proc.c @@ -96,7 +96,10 @@ 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) { - return 0; -} + var_cont* rv; + + rv = ns_get(ctx->vars, scope, name); + return rv; +} diff --git a/src/vm/src/var.c b/src/vm/src/var.c @@ -2,8 +2,34 @@ #include <stdio.h> #include "var.h" + +#include "bc.h" #include "helper.h" +void* var_data_alloc_TYPE(b_type type) +{ + var_data_type* rv = (var_data_type*)malloc(sizeof(var_data_type)); + M_ASSERT(rv); + + rv->v = type; + + return rv; +} + +void* var_data_alloc_FUNC(b_type type) +{ + var_data_func* rv = (var_data_func*)malloc(sizeof(var_data_func)); + M_ASSERT(rv); + + rv->type = type; + rv->loc = 0; + rv->end = 0; + rv->size = 0; + rv->param = NULL; + + return rv; +} + void* var_data_alloc_G_INT(int value) { var_data_int* rv = (var_data_int*)malloc(sizeof(var_data_int)); @@ -21,7 +47,7 @@ void* var_data_alloc_G_FLOAT(double value) rv->v = value; - return (void**)rv; + return rv; } void* var_data_alloc_G_CHAR(char value) @@ -44,23 +70,12 @@ void* var_data_alloc_G_STR(size_t size) return rv; } -void* var_data_alloc(b_type type) +void* var_data_alloc_PLIST(size_t size) { - void* rv = NULL; - - if (type == G_INT) - rv = var_data_alloc_G_INT(0); - - if (type == G_FLOAT) - rv = var_data_alloc_G_FLOAT(0.0); + var_data_plist* rv = (var_data_plist*)malloc(sizeof(var_data_plist)); + M_ASSERT(rv); - if (type == G_CHAR) - rv = var_data_alloc_G_CHAR(0); - - if (type == G_STR) - { - rv = var_data_alloc_G_STR(1); - } + rv->v = (b_type*)malloc(sizeof(b_type)*size); return rv; } @@ -77,37 +92,57 @@ var_cont* var_new(b_type type) return new; } -void var_data_free(void* data, b_type type) +void var_del(var_cont* var) { - N_ASSERT(data); + N_ASSERT(var); - if (type == G_INT) - free(data); + if (var->data != NULL) + var_data_free(var->data, var->type); - if (type == G_FLOAT) - free(data); + free(var); +} - if (type == G_CHAR) - free(data); +void var_data_free(void* data, b_type type) +{ + N_ASSERT(data); + + if (type == FUNC) + { + var_data_free_FUNC(data); + } if (type == G_STR) { - var_data_str* d = data; - if (d->v != NULL) - free(d->v); + var_data_free_G_STR(data); + } - free(data); + if (type == PLIST) + { + var_data_free_PLIST(data); } + + if (data != NULL) + free(data); } -void var_del(var_cont* var) +void var_data_free_FUNC(void* data) { - N_ASSERT(var); - - if (var->data != NULL) - var_data_free(var->data, var->type); + var_data_func* d = data; + if (d->param != NULL) + free(d->param); +} - free(var); +void var_data_free_G_STR(void* data) +{ + var_data_str* d = data; + if (d->v != NULL) + free(d->v); +} +void var_data_free_PLIST(void* data) +{ + var_data_plist* d = data; + if (d->v != NULL) + free(d->v); } void var_set(var_cont* var, void* data, b_type type) @@ -124,6 +159,26 @@ void var_set(var_cont* var, void* data, b_type type) var->data = data; } +b_type var_data_get_TYPE(var_cont* var) +{ + N_ASSERT(var); + ASSERT( var->type == TYPE, "TypeError" ); + + var_data_type* t = var->data; + + return t->v; +} + +var_data_func* var_data_get_FUNC(var_cont* var) +{ + N_ASSERT(var); + ASSERT( var->type == FUNC, "TypeError" ); + + var_data_func* t = var->data; + + return t; +} + int var_data_get_G_INT(var_cont* var) { N_ASSERT(var); @@ -171,3 +226,76 @@ char* var_data_get_G_STR(var_cont* var) return t->v; } + +b_type* var_data_get_PLIST(var_cont* var) +{ + N_ASSERT(var); + ASSERT( var->type == PLIST, "TypeError" ); + + N_ASSERT(var->data); + + var_data_plist* t = var->data; + + return t->v; +} + +/* Lovely little function to take bytes and turn it into an integer. + * int - sizeof(bytes) + * byte_t* - array of bytes + */ +void bytes_to_int(var_cont** rv, int size, byte_t* bytes) +{ + *rv = var_new(G_INT); + + int i, + data; + + data = 0; + for ( i = 0; i < size; i++) + { + data = (data << 8 | bytes[i]); + } + + var_set(*rv, var_data_alloc_G_INT(data), G_INT); +} + +void byte_to_type(var_cont** rv, byte_t byte) +{ + *rv = var_new(TYPE); + + var_set(*rv, var_data_alloc_TYPE((b_type)byte), TYPE); +} + +/* Converts array of bytes of size n into parameter list + * + * int - sizeof(bytes) + * byte_t* - array of bytes + */ +void raw_to_plist(var_cont** rv, int n, byte_t* bytes) +{ + *rv = var_new(PLIST); + + var_set(*rv, var_data_alloc_PLIST(n), PLIST); + + b_type* var = var_data_get_PLIST(*rv); + + int i; + + for (i = 0; i < n; i++) + { + var[i] = (b_type)bytes[i]; + } +} + +/* Raw variable to var_cont + * + * int - sizeof(bytes) + * byte_t* - array of bytes + */ +void raw_to_var(var_cont** rv, int n, byte_t* bytes) +{ + *rv = var_new(VOID); + + // TODO: implement. +} + diff --git a/src/vm/testing b/src/vm/testing Binary files differ diff --git a/src/vm/tests/bytecodes/testing b/src/vm/tests/bytecodes/testing Binary files differ