language

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

commit d63d34e130a52e7c988a9326e3ad84323f8a6dbd
parent bd666939dab1c914ac7cfaf2dcba9d2c74047b8f
Author: Paul Longtine <paullongtine@gmail.com>
Date:   Wed May  4 13:47:13 2016

Made last breaking change less breaking.

Diffstat:
 src/lc/bytecode.py                              |  8 +--
 src/lc/interpreter.py                           |  4 +-
 src/lc/test_files/class.ti                      | 18 +++++--
 src/vm/inc/ins_mdata.h                          |  8 +--
 src/vm/inc/rt.h                                 |  3 +-
 src/vm/src/ins_def.c                            | 25 +++++----
 src/vm/src/ns.c                                 |  1 +-
 src/vm/src/proc.c                               | 34 ++++++++++--
 src/vm/src/rt.c                                 |  2 +-
 src/vm/tests/cases/bc/bytecode                  | Bin 87 -> 0 bytes
 src/vm/tests/cases/bc/expected_output           | 72 ++++++++++++++++++++++----
 src/vm/tests/cases/program_fibb/Makefile        |  0
 src/vm/tests/cases/program_fibb/expected_output | 18 +-------
 src/vm/tests/cases/program_fibb/fibb            | Bin 94 -> 0 bytes
 src/vm/tests/cases/program_fibb/test            |  6 +--
 15 files changed, 137 insertions(+), 62 deletions(-)

diff --git a/src/lc/bytecode.py b/src/lc/bytecode.py @@ -64,8 +64,10 @@ class NewClass(): return([ self.args.action(), OP_NEW, + self.label.action(s=True), self.label.action(), OP_DEC, + self.label.action(s=True), 0x06, self.toset.action(), OP_STV, @@ -81,8 +83,8 @@ class VariableNew(): def action(self): return([ OP_DEC, - self.typed.action(), self.label.action(s=True), + self.typed.action(), self.label.action() ]) @@ -147,7 +149,7 @@ class FunctionCall(): return([ self.arguements.action(), OP_CALL, - self.label.action(s=True) + self.label.action(s=True), self.label.action() ]) @@ -211,5 +213,3 @@ class Opcode(): def action(self): return(self.opcode) - - diff --git a/src/lc/interpreter.py b/src/lc/interpreter.py @@ -44,7 +44,7 @@ class Label(AbstractToken): break if self.expr == 0: - print("UNDEFINED REFERENCE TO VARIABLE '{}'".format(self.data)) + print("Undefined variable '{}'".format(self.data)) def action(self, s=False): if s: @@ -271,7 +271,7 @@ class Interpreter(): for scope in range(0, self.scope): if t in self.names[scope]: - print("Can't do that") + print("Can't instantiate name that's already in use!") self.names[self.scope].append(t) diff --git a/src/lc/test_files/class.ti b/src/lc/test_files/class.ti @@ -1,3 +1,14 @@ +class Counter: +{ + int val = 0; + int inc = 1; + + func increment -> int: + { + val = val + inc; + return val; + } +} class ObjectFibb: { @@ -5,6 +16,8 @@ class ObjectFibb: int b = 1; int c = 0; + Counter counter = new Counter(); + func next -> void: { if c == 0: @@ -27,12 +40,11 @@ class ObjectFibb: func run (int count) -> void: { - int x = 0; - while x < count: + counter.val = 0; + while counter.increment() < count: { next(); display(); - x = x + 1; } } } diff --git a/src/vm/inc/ins_mdata.h b/src/vm/inc/ins_mdata.h @@ -34,7 +34,7 @@ /* 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(2, A_BYTE, A_NAME, A_BYTE); \ +/* 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); \ /* CTV */ INS_MDATA[0x23] = encode(3, A_BYTE, A_NAME, A_DYNC); \ @@ -89,7 +89,7 @@ /* MODO */ INS_MDATA[0x84] = encode(1, A_BYTE, A_BYTE, A_BYTE); \ \ /* RETURN */ INS_MDATA[0xF0] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ -/* NEW */ INS_MDATA[0xF1] = encode(1, A_NAME, A_BYTE, A_BYTE); \ +/* NEW */ INS_MDATA[0xF1] = encode(2, A_BYTE, A_NAME, A_BYTE); \ /* ENDCLASS */ INS_MDATA[0xF2] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ /* DENS */ INS_MDATA[0xFD] = encode(1, A_BYTE, A_BYTE, A_BYTE); \ /* DECLASS */ INS_MDATA[0xFE] = encode(2, A_NAME, A_DYNC, A_BYTE); \ @@ -118,7 +118,7 @@ /* 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, BTOI); \ +/* DEC */ INS_ADATA[0x20] = encode(3, BTOI, BTOT, BTOI); \ /* LOV */ INS_ADATA[0x21] = encode(2, BTOI, BTOI, BTOI); \ /* STV */ INS_ADATA[0x22] = encode(2, BTOI, BTOI, BTOI); \ /* CTV */ INS_ADATA[0x23] = encode(3, BTOI, BTOI, DTOV); \ @@ -173,7 +173,7 @@ /* MODO */ INS_ADATA[0x84] = encode(1, BTOI, BTOI, BTOI); \ \ /* RETURN */ INS_ADATA[0xF0] = encode(0, BTOI, BTOI, BTOI); \ -/* NEW */ INS_ADATA[0xF1] = encode(1, BTOI, BTOI, BTOI); \ +/* NEW */ INS_ADATA[0xF1] = encode(2, BTOI, BTOI, BTOI); \ /* ENDCLASS */ INS_MDATA[0xF2] = encode(0, BTOI, BTOI, BTOI); \ /* DENS */ INS_ADATA[0xFD] = encode(1, BTOI, BTOI, BTOI); \ /* DECLASS */ INS_ADATA[0xFE] = encode(2, BTOI, DTOL, BTOI); \ diff --git a/src/vm/inc/rt.h b/src/vm/inc/rt.h @@ -16,10 +16,13 @@ #include "helper.h" /* Runtime context structure + * db - Debug flag * pc - `pc.h` program counter instance * stack - `stk.h` stack instance[0] * argstk- `stk.h` stack instance[1] * vars - `ns.h` namespace instance + * varctx- `ns.h` namespace context instance + * names - `ns.h` namespace instance * * [0] This is the stack register used at runtime to push/pop variable * containers. diff --git a/src/vm/src/ins_def.c b/src/vm/src/ins_def.c @@ -170,8 +170,8 @@ void _ins_def_ROT_THREE(rt_t* ctx, bc_cont* line) void _ins_def_DEC (rt_t* ctx, bc_cont* line) { - int type = var_data_get_G_INT(line->varg[0]); - int scope = var_data_get_G_INT(line->varg[1]); + int scope = var_data_get_G_INT(line->varg[0]); + b_type type = var_data_get_TYPE(line->varg[1]); int name = var_data_get_G_INT(line->varg[2]); proc_decvar(ctx, type, scope, name); @@ -548,6 +548,8 @@ void _ins_def_CALL (rt_t* ctx, bc_cont* line) // Call the function proc_function_call(ctx, scope, name); + + pc_inc(ctx->pc, 1); } void _ins_def_GETN (rt_t* ctx, bc_cont* line) @@ -596,6 +598,7 @@ void _ins_def_CALLM (rt_t* ctx, bc_cont* line) var_data_func* func = var_data_get_FUNC(var); // Push current namespace context ns_ctx_push(ctx->varctx, ctx->vars); + if (ctx->db) printf("PUSHED NAMESPACE CONTEXT\n"); // Set current namespace to objects namespace ctx->vars = object->names; // Call the function @@ -606,6 +609,9 @@ void _ins_def_CALLM (rt_t* ctx, bc_cont* line) proc_run_to_return(ctx); // Pop the namespace context ctx->vars = ns_ctx_pop(ctx->varctx); + if (ctx->db) printf("POPPED NAMESPACE CONTEXT\n"); + + pc_inc(ctx->pc, 1); } void _ins_def_INDEXO (rt_t* ctx, bc_cont* line) { @@ -624,22 +630,20 @@ void _ins_def_RETURN (rt_t* ctx, bc_cont* line) // Pop the namespace and get the return value var_cont* return_value = ns_pop(ctx->vars); - + if (ctx->db) printf("RETURN VALUE TYPE (%i)\n", return_value->type); // Push the return value to the stack stk_push(ctx->stack, return_value); // Return to the callee pc_return(ctx->pc); - - // And increment the program counter - pc_inc(ctx->pc, 1); } void _ins_def_NEW (rt_t* ctx, bc_cont* line) { - int name = var_data_get_G_INT(line->varg[0]); + int scope = var_data_get_G_INT(line->varg[0]); + int name = var_data_get_G_INT(line->varg[0]); // Get the object builder - var_cont* var = proc_getvar(ctx, 1, name); + var_cont* var = proc_getvar(ctx, scope, name); var_data_objbldr* builder = var_data_get_OBJBLDR(var); // Init a new namespace of proper size @@ -647,6 +651,7 @@ void _ins_def_NEW (rt_t* ctx, bc_cont* line) // Push current namespace to namespace context ns_ctx_push(ctx->varctx, ctx->vars); + if (ctx->db) printf("NEW: PUSHED NEW NAMESPACE CONTEXT\n"); // Set the current namespace to new namespace ctx->vars = new_ns; @@ -673,6 +678,7 @@ void _ins_def_NEW (rt_t* ctx, bc_cont* line) } void _ins_def_ENDCLASS (rt_t* ctx, bc_cont* line) { + if (ctx->db) printf("NEW: CREATING NEW OBJECT\n"); var_cont* new = var_new(OBJECT); var_data_object* data = var_data_alloc_OBJECT(object_del); @@ -686,6 +692,7 @@ void _ins_def_ENDCLASS (rt_t* ctx, bc_cont* line) stk_poplevel(&ctx->stack); stk_poplevel(&ctx->argstk); + if (ctx->db) printf("NEW: POPPED NAMESPACE\n"); ctx->vars = ns_ctx_pop(ctx->varctx); stk_push(ctx->stack, new); @@ -697,7 +704,7 @@ void _ins_def_DENS (rt_t* ctx, bc_cont* line) { int name = var_data_get_G_INT(line->varg[0]); - ns_t* ns = ns_init(0xFF); + ns_t* ns = ns_init(0xFFFF); var_data_object* namespace = var_data_alloc_OBJECT(rt_ns_del); namespace->ref = (void*)ns; diff --git a/src/vm/src/ns.c b/src/vm/src/ns.c @@ -210,7 +210,6 @@ void ns_dec(ns_t* ns, b_type type, int scope, ns_addr address) * b_type - Type of variable * ns_addr - Variable name */ - void ns_cont_dec(ns_cont* container, b_type type, ns_addr address) { N_ASSERT(container, "ns_cont_dec\n"); diff --git a/src/vm/src/proc.c b/src/vm/src/proc.c @@ -47,10 +47,14 @@ void proc_run(rt_t* ctx) } } +/* Runs exection loop until a return is reached + */ void proc_run_to_return(rt_t* ctx) { N_ASSERT(ctx, "proc_run\n"); + if (ctx->db) printf("START proc_run_to_return\n"); + int n; for (n = 0; pc_safe(ctx->pc); pc_update(ctx->pc)) { @@ -61,19 +65,30 @@ void proc_run_to_return(rt_t* ctx) printf("\n"); } + if (ctx->pc->line->op == 0x7F) + { + if (ctx->db) printf("FUNCTION CALL proc_run_to_return\n"); + n++; + } + INS_DEF[ctx->pc->line->op](ctx, ctx->pc->line); // Break when the function returns - if (ctx->pc->line->op == 0x7F) - n++; - else if (ctx->pc->line->op == 0xF0) + + if (ctx->pc->line->op == 0xF0) { if (n > 0) + { + if (ctx->db) printf("FUNCTION CALL RETURN proc_run_to_return\n"); n--; - else + } else + { + if (ctx->db) printf("RETURNING FROM proc_run_to_return\n"); break; + } } } + if (ctx->db) printf("END proc_run_to_return\n"); } /* Calls runtime context elements to free memory and terminate @@ -163,9 +178,12 @@ var_cont* proc_getvar(rt_t* ctx, int scope, ns_addr name) return rv; } +/* Call a function + */ void proc_function_call(rt_t* ctx, int scope, ns_addr name) { N_ASSERT(ctx, "proc_function_call\n"); + if (ctx->db) printf("FUNCTION CALL (%i)\n", name); int x = (scope & 0xFE) >> 1; @@ -174,6 +192,7 @@ void proc_function_call(rt_t* ctx, int scope, ns_addr name) if (x != 0) { ns_ctx_push(ctx->varctx, ctx->vars); + var_cont* ns_var = ns_get(ctx->names, 1, x); var_data_object* var_d = var_data_get_OBJECT(ns_var); ns_t* ns = (ns_t*) var_d->ref; @@ -185,14 +204,21 @@ void proc_function_call(rt_t* ctx, int scope, ns_addr name) proc_function_call_handle(ctx, func); + pc_update(ctx->pc); + proc_run_to_return(ctx); if (x != 0) { ctx->vars = ns_ctx_pop(ctx->varctx); } + + if (ctx->db) printf("RETURN (%i)\n", name); } +/* Handles arguements and namespace procedures for a given + * function call + */ void proc_function_call_handle(rt_t* ctx, var_data_func* func) { // Push a new namespace of specified size diff --git a/src/vm/src/rt.c b/src/vm/src/rt.c @@ -26,7 +26,7 @@ rt_t* rt_ctx_new(char* fname, stk_t* args) ctx->pc = pc_new(fname); ctx->stack = stk_new(); ctx->argstk = args; - ctx->vars = ns_init(0xFF); + ctx->vars = ns_init(0xFFFF); ctx->varctx = ns_ctx_init(); ctx->names = ns_init(0x7F); diff --git a/src/vm/tests/cases/bc/bytecode b/src/vm/tests/cases/bc/bytecode Binary files differ diff --git a/src/vm/tests/cases/bc/expected_output b/src/vm/tests/cases/bc/expected_output @@ -1,24 +1,76 @@ -20 1, 7, 0 3, -23 1, 0 3, 7 ff +fe 0 1, 20 1, 7, 0 1, -23 1, 0 1, 7 0 +24 7 0 +22 1, 0 1, 20 1, 7, 0 2, -23 1, 0 2, 7 1 -60 +24 7 1 +22 1, 0 2, +ff 0 3, 7, 21 1, 0 2, -21 1, 0 3, -50 -61 21 1, 0 1, -21 1, 0 2, 40 +22 1, 0 1, +21 1, 0 1, +22 0, 0 0, +f0 +f2 +fe 0 2, +20 1, 7, 0 1, +24 7 0 +22 1, 0 1, +20 1, 7, 0 2, +24 7 1 22 1, 0 2, +20 1, 7, 0 3, +24 7 0 +22 1, 0 3, +f1 0, 0 0, +20 0, 6, 0 4, +22 1, 0 4, +ff 0 5, 0, +24 7 0 +21 1, 0 3, +54 +72 21 1, 0 2, -2 21 1, 0 1, +40 +22 1, 0 2, +24 7 1 +22 1, 0 3, +7e 21 1, 0 2, +21 1, 0 1, 40 22 1, 0 1, +24 7 0 +22 1, 0 3, +f0 +ff 0 6, 0, +21 1, 0 2, +2 21 1, 0 1, 2 +f0 +ff 0 7, 0, 7 +24 7 0 +21 1, 0 4, +81 0 1, +60 +21 0, 0 1, +21 1, 0 4, +82 0 3, +51 +61 +7f 1, 0 5, +7f 1, 0 6, 6f +f0 +f2 +f1 1, 0 2, +20 1, 6, 0 3, +22 1, 0 3, +24 7 f +e +21 1, 0 3, +82 0 7, diff --git a/src/vm/tests/cases/program_fibb/Makefile b/src/vm/tests/cases/program_fibb/Makefile diff --git a/src/vm/tests/cases/program_fibb/expected_output b/src/vm/tests/cases/program_fibb/expected_output @@ -1,18 +0,0 @@ -1 -1 -2 -3 -5 -8 -13 -21 -34 -55 -89 -144 -233 -377 -610 -987 -1597 -2584 diff --git a/src/vm/tests/cases/program_fibb/fibb b/src/vm/tests/cases/program_fibb/fibb Binary files differ diff --git a/src/vm/tests/cases/program_fibb/test b/src/vm/tests/cases/program_fibb/test @@ -1,6 +0,0 @@ -#!/bin/bash -pushd ../../.. &>/dev/null -make &>/dev/null -popd &>/dev/null - -../../../toi fibb