language

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

commit 1432b7f51653fdf3c317735633cee91517f103d6
parent 2e807b0bc8404bfecca4a04c263ff24c65f9bbef
Author: Paul Longtine <paullongtine@gmail.com>
Date:   Tue Apr 26 13:53:39 2016

Fixed wrongness, spec objects, etc

Diffstat:
 doc/SPECIFICATION                               | 68 +++++++++++++-------------
 src/lc/bytecode.py                              |  8 +--
 src/lc/helper.py                                | 14 ++++-
 src/lc/interpreter.py                           | 33 +++++++------
 src/lc/lexer.py                                 | 23 ++++-----
 src/lc/test_files/fibb.ti                       | 21 ++++----
 src/lc/test_files/if.ti                         |  1 +-
 src/lc/test_files/test.ti                       |  9 +++-
 src/vm/Makefile                                 |  5 +-
 src/vm/inc/bc.h                                 |  4 ++-
 src/vm/src/bc.c                                 | 29 +++++++++++-
 src/vm/src/ins_def.c                            |  5 +-
 src/vm/src/proc.c                               |  9 +--
 src/vm/src/var_ops.c                            |  3 +-
 src/vm/tests/bytecodes/fibb                     | Bin 87 -> 0 bytes
 src/vm/tests/bytecodes/funtest                  | Bin 45 -> 0 bytes
 src/vm/tests/cases/bc/expected_output           | 48 +++++++++---------
 src/vm/tests/cases/bc/test.c                    | 31 +------------
 src/vm/tests/cases/program_fibb/Makefile        |  0
 src/vm/tests/cases/program_fibb/expected_output | 16 ++++++-
 src/vm/tests/cases/program_fibb/fibb            | Bin 0 -> 87 bytes
 src/vm/tests/cases/program_fibb/test            |  6 ++-
 22 files changed, 202 insertions(+), 131 deletions(-)

diff --git a/doc/SPECIFICATION b/doc/SPECIFICATION @@ -147,6 +147,16 @@ structures. This is set in place to prevent accidental deallocation of variable containers that are not copied, but instead passed as references to these structures. + FUNCTION DEFINITION + +Functions in this virtual machine are a pointer to a set of instructions in a +program with metadata about parameters defined. + + OBJECT DEFINITION + +In this paradigm, objects are units that encapsulate a seperate namespace and +collection of methods. + BYTECODE SPEC Bytecode is organised in the following manner: @@ -206,8 +216,8 @@ Hex | Memnonic | arguments - description Types are in the air at this moment. I'll detail what types there are when the time comes ------------------------------------------------------------------------------- -30 TYPEOF - pushes type of TOS on to the stack TBI -31 CAST S<type> - Tries to cast TOS to <type> TBI +30 TYPEOF - pushes type of TOS on to the stack TBI +31 CAST S<type> - Tries to cast TOS to <type> TBI ------------------------------------------------------------------------------- 4 - Binary Ops OPS take the two top elements of the stack, preform an operation and push @@ -217,18 +227,18 @@ the result on the stack. 41 SUB - subtracts 42 MULT - multiplies 43 DIV - divides -44 POW - power, TOS^TOS1 TBI -45 BRT - base root, TOS root TOS1 TBI -46 SIN - sine TBI -47 COS - cosine TBI -48 TAN - tangent TBI -49 ISIN - inverse sine TBI -4A ICOS - inverse consine TBI -4B ITAN - inverse tangent TBI -4C MOD - modulus TBI -4D OR - or's TBI -4E XOR - xor's TBI -4F NAND - and's TBI +44 POW - power, TOS^TOS1 TBI +45 BRT - base root, TOS root TOS1 TBI +46 SIN - sine TBI +47 COS - cosine TBI +48 TAN - tangent TBI +49 ISIN - inverse sine TBI +4A ICOS - inverse consine TBI +4B ITAN - inverse tangent TBI +4C MOD - modulus TBI +4D OR - or's TBI +4E XOR - xor's TBI +4F NAND - and's TBI ------------------------------------------------------------------------------- 5 - Conditional Expressions @@ -268,27 +278,21 @@ to TOS 7E DONE - End of block 7F CALL N<ref> - Calls function, pushes return value on to STACK. ------------------------------------------------------------------------------- -8 - Generic object interface - - For arrays, key-value arrays, etc +8 - Generic object interface. Expects object on TOS ------------------------------------------------------------------------------- -80 NEW - Call 'new' method of <ref> TBI - -81 DEL - Call 'delete' method of <ref> TBI +80 GETN N<name> - Returns variable assosiated with name in object TBI -82 INDEX - Call 'get' method of <ref> TBI +81 CALLM N<name> - Calls method in object TBI -83 GETP N<ref> - Get property of <ref> in object contained in TOS. pushes TBI - to stack +82 INDEXO - Index an object, uses arguement stack TBI -84 CALLM N<ref> - Call method of <ref> in object contained in TOS. Uses TBI - arguement stack +83 MODO S<OP> - Modify an object based on op. [+, -, *, /, %, ^ .. etc] TBI ------------------------------------------------------------------------------- F - Functions/classes ------------------------------------------------------------------------------- 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. + function. D<ref> is its name, S<type> is + the return value, D<args> is the args. FE DECLASS N<ref> D<args> - Defines a class. TBI @@ -298,10 +302,9 @@ F0 RETURN - Returns from function ------------------------------------------------------------------------------- 0 - SPECIAL BYTES ------------------------------------------------------------------------------- -00 NULL - +00 NULL - No-op -01 SYNC S<level> - Updates global namespace with global namespace cache of TBI - current thread +01 LC N<name> - Calls OS function library, i.e. I/O, opening files, etc TBI 02 PRINT - Prints whatever is on the TOS. TBI @@ -309,8 +312,9 @@ F0 RETURN - Returns from function 0E ARGB - Builds arguement stack -0F LIBC A<ref> - Library call TBI - +0F PC S<ref> - Primitive call, calls a subroutine A<ref>. A list of TBI + primitive subroutines providing methods to tweak + objects this bytecode set cannot touch. Uses argstack. _______________________________________________________________________________ COMPILER/TRANSLATOR/ASSEMBLER SHINDIGS -------------------------------------------------------------------------------- diff --git a/src/lc/bytecode.py b/src/lc/bytecode.py @@ -9,7 +9,7 @@ class VariableNew(): def action(self): return([ OP_DEC, - self.label.action(scope=True), + self.label.action(s=True), self.typed.action(), self.label.action() ]) @@ -23,7 +23,7 @@ class VariableAssignment(): return([ self.expr.action(), OP_STV, - self.label.action(scope=True), + self.label.action(s=True), self.label.action() ]) @@ -34,7 +34,7 @@ class VariableGet(): def action(self): return([ OP_LOV, - self.label.action(scope=True), + self.label.action(s=True), self.label.action() ]) @@ -114,8 +114,8 @@ class BinaryOp(): def action(self): return([ - self.vals[0].action(), self.vals[1].action(), + self.vals[0].action(), self.op.action() ]) diff --git a/src/lc/helper.py b/src/lc/helper.py @@ -13,13 +13,20 @@ def token_split(tokenstring, esc_chars, split_chars, include_splitter=True): tokens = [] tmp = [] capturing = False + depth = 0 for x in tokenstring: if x in esc_chars[0]: - capturing = esc_chars[0].index(x) + if capturing: + depth += 1 + else: + capturing = esc_chars[0].index(x) tmp.append(x) elif x in esc_chars[1]: if esc_chars[1][capturing] == x: - capturing = False + if depth > 0: + depth -= 1 + elif depth == 0: + capturing = False tmp.append(x) elif include_splitter or not x in split_chars or capturing: tmp.append(x) @@ -32,6 +39,9 @@ def token_split(tokenstring, esc_chars, split_chars, include_splitter=True): return tokens +# This here takes a number and chops it up into a series of byte-width numbers +# i.e 42 -> [42], 256 -> [1, 0] +# def int_to_bytes(number): rv = [] c = 0 diff --git a/src/lc/interpreter.py b/src/lc/interpreter.py @@ -23,28 +23,28 @@ class Label(AbstractToken): f = lambda y, x: y(y, x[0]) if type(x) is list else x self.data = f(f, self.data) - self.scope = 0 if self.i.scope > 0 else 1 + self.scope = 0 self.expr = 0 - for i in self.i.names: + for n, i in enumerate(self.i.names): if self.data in i: self.expr = i.index(self.data) + 1 + self.scope = 0 if n > 0 else 1 break - def action(self, scope=False): - if scope: + def action(self, s=False): + if s: return(self.scope) else: return(int_to_word(self.expr)) class Arguements(AbstractToken): def update(self): - tokens = token_split(self.data[1:-1], + tokens = token_split(self.data[1:], [["[", "("], ["]", ")"]], [","], include_splitter = False) - for t in tokens: - self.expr.append(Expression(self.i, t)) + self.expr.insert(0, Expression(self.i, t)) def action(self): rv = [] @@ -72,15 +72,21 @@ class Parameters(AbstractToken): def update(self): tmp = [] for x in self.data: - if x != "(" and x != ")" and x != ",": + if x != ",": tmp.append(x) - elif x == "," or x == ")": + elif x == ",": self.i.name_dec(tmp[1:]) t = Type(self.i, tmp[:-1]) l = Label(self.i, tmp[1:]) self.expr.append([t, l]) tmp = [] + if len(tmp) > 0: + self.i.name_dec(tmp[1:]) + t = Type(self.i, tmp[:-1]) + l = Label(self.i, tmp[1:]) + self.expr.append([t, l]) + def action(self): types = list(map(lambda x: x[0].action(), self.expr)) return([ @@ -100,10 +106,10 @@ class Expression(AbstractToken): ["/", Opcode(OP_DIV)], ["==", Opcode(OP_EQ)], ["!=", Opcode(OP_NEQ)], - [">", Opcode(OP_LTHAN)], - ["<", Opcode(OP_GTHAN)], - [">=", Opcode(OP_LTHAN_EQ)], - ["=<", Opcode(OP_GTHAN_EQ)] + [">", Opcode(OP_GTHAN)], + ["<", Opcode(OP_LTHAN)], + [">=", Opcode(OP_GTHAN_EQ)], + ["=<", Opcode(OP_LTHAN_EQ)] ] self.operator_names = list(map(lambda x: x[0], self.operators)) @@ -150,7 +156,6 @@ class Expression(AbstractToken): t = token_split(self.data, self.group_char, self.operator_names) - if len(t) == 0: t = self.data if len(t) > 2: diff --git a/src/lc/lexer.py b/src/lc/lexer.py @@ -80,7 +80,6 @@ class GroupingSymbol(PolySymbol): rv = [] r = self.symbols[0].match(tokenstring, index) if r[0]: - rv.extend(r[1]) index = r[0] ignore = 0 while index < len(tokenstring): @@ -89,17 +88,19 @@ class GroupingSymbol(PolySymbol): ignore += 1 rv.extend(r[1]) index = r[0] - r = self.symbols[1].match(tokenstring, index) - if r[0]: - index = r[0] - rv.extend(r[1]) - if not ignore > 0: - break - else: - ignore -= 1 else: - rv.append(tokenstring[index]) - index += 1 + r = self.symbols[1].match(tokenstring, index) + if r[0]: + if ignore > 0: + ignore -= 1 + rv.extend(r[1]) + index = r[0] + else: + index = r[0] + break + else: + rv.append(tokenstring[index]) + index += 1 return [index, rv] if len(rv) > 0 else [False, None] diff --git a/src/lc/test_files/fibb.ti b/src/lc/test_files/fibb.ti @@ -1,10 +1,15 @@ -int a = 0; -int b = 1; - -while a < 100000000: +func fibo(int limit) -> void: { - a = a + b; - print b; - b = a + b; - print a; + string thing = "starting this shit yo"; + print thing; + int a = 0; + int b = 1; + + while a < limit: + { + a = a + b; + print b; + b = a + b; + print a; + } } diff --git a/src/lc/test_files/if.ti b/src/lc/test_files/if.ti @@ -1,3 +1,4 @@ include extern; +include test; print some_external_function(3); diff --git a/src/lc/test_files/test.ti b/src/lc/test_files/test.ti @@ -0,0 +1,9 @@ +include fibb; + +func testing(int x, int y, int z) -> int: +{ + int rv = (x * y) * z; + return rv; +} + +fibo(testing(2333, 3, 3)); diff --git a/src/vm/Makefile b/src/vm/Makefile @@ -1,9 +1,9 @@ SRC_DIR = src INC_DIR = inc +DST_DIR = /usr/bin/ CC = gcc CFLAGS = -std=c99 -Wall -I$(INC_DIR) -DEBUG = -D DEBUG DEPS = $(INC_DIR)/is_mdata.h \ helper.h \ @@ -43,3 +43,6 @@ $(OUT): $(OBJ) clean: rm $(SRC_DIR)/*.o rm $(OUT) + +install: + mv $(OUT) $(DST_DIR) diff --git a/src/vm/inc/bc.h b/src/vm/inc/bc.h @@ -70,4 +70,8 @@ bc_t* bc_init(char*); */ void bc_del(bc_t*); +/* Thing for pretty printing + */ +void bc_print_op(bc_cont*); + #endif // BC_H diff --git a/src/vm/src/bc.c b/src/vm/src/bc.c @@ -226,3 +226,32 @@ void bc_del(bc_t* program) free(program); } + +/* Thing for pretty printing + */ +void bc_print_op(bc_cont* op) +{ + int num_args, + arg_types[3]; + + unencode(op->mdata, &num_args, arg_types); + + printf("%x\t", op->op); + for (int i = 0; i < num_args && num_args != 0; i++) + { + if (arg_types[i] == A_BYTE) + { + printf("%x, ", op->args[i][0]); + } else + if (arg_types[i] == A_NAME) + { + printf("%x %x, ", op->args[i][0], op->args[i][1]); + } else + if (arg_types[i] == A_DYNC) + { + for (int x = 0; x < op->sarg[i]; x++) + printf("%x ", op->args[i][x]); + } + } +} + diff --git a/src/vm/src/ins_def.c b/src/vm/src/ins_def.c @@ -189,8 +189,11 @@ void _ins_def_STV (rt_t* ctx, bc_cont* line) int name = var_data_get_G_INT(line->varg[1]); var_cont* var = stk_pop(ctx->stack); + var_cont* ovr = proc_getvar(ctx, scope, name); + var_cont* set = var_data_cpy(var); + set->ownership = ovr->ownership; - proc_setvar(ctx, scope, name, var); + proc_setvar(ctx, scope, name, set); pc_inc(ctx->pc, 1); } diff --git a/src/vm/src/proc.c b/src/vm/src/proc.c @@ -34,10 +34,11 @@ void proc_run(rt_t* ctx) for (n = 0; pc_safe(ctx->pc); pc_update(ctx->pc)) { -#ifdef DEBUG - printf("LINE[%i]: %x\n", ctx->pc->address, ctx->pc->line->op); -#endif - +/* + printf("[%i]:\t", ctx->pc->address); + bc_print_op(ctx->pc->line); + printf("\n"); +*/ INS_DEF[ctx->pc->line->op](ctx, ctx->pc->line); n++; diff --git a/src/vm/src/var_ops.c b/src/vm/src/var_ops.c @@ -43,6 +43,7 @@ var_cont* var_add_float(var_cont* A, var_cont* B) var_cont* var_add_int(var_cont* A, var_cont* B) { var_cont* var = var_new(G_INT); + int AV = var_data_get_G_INT(A); int BV = var_data_get_G_INT(B); @@ -173,7 +174,7 @@ var_cont* var_div_float(var_cont* A, var_cont* B) double AV = var_data_get_G_FLOAT(A); double BV = var_data_get_G_FLOAT(B); - double S = AV * BV; + double S = AV / BV; var_data_float* data = var_data_alloc_G_FLOAT(S); diff --git a/src/vm/tests/bytecodes/fibb b/src/vm/tests/bytecodes/fibb Binary files differ diff --git a/src/vm/tests/bytecodes/funtest b/src/vm/tests/bytecodes/funtest Binary files differ diff --git a/src/vm/tests/cases/bc/expected_output b/src/vm/tests/cases/bc/expected_output @@ -1,24 +1,24 @@ -20: 1, 6, 3 0, -23: 1, 3 0, 6 ff -20: 1, 6, 1 0, -23: 1, 1 0, 6 0 -20: 1, 6, 2 0, -23: 1, 2 0, 6 1 -60: -21: 1, 2 0, -21: 1, 3 0, -50: -61: -21: 1, 1 0, -21: 1, 2 0, -40: -22: 1, 2 0, -21: 1, 2 0, -2: -21: 1, 1 0, -21: 1, 2 0, -40: -22: 1, 1 0, -21: 1, 1 0, -2: -6f: +20 1, 6, 0 3, +23 1, 0 3, 6 ff +20 1, 6, 0 1, +23 1, 0 1, 6 0 +20 1, 6, 0 2, +23 1, 0 2, 6 1 +60 +21 1, 0 2, +21 1, 0 3, +50 +61 +21 1, 0 1, +21 1, 0 2, +40 +22 1, 0 2, +21 1, 0 2, +2 +21 1, 0 1, +21 1, 0 2, +40 +22 1, 0 1, +21 1, 0 1, +2 +6f diff --git a/src/vm/tests/cases/bc/test.c b/src/vm/tests/cases/bc/test.c @@ -7,34 +7,6 @@ #include "var.h" #include "bc.h" -void print_op(bc_cont* op) -{ - int num_args, - arg_types[3]; - - unencode(op->mdata, &num_args, arg_types); - - printf("%x: ", op->op); - for (int i = 0; i < num_args && num_args != 0; i++) - { - if (arg_types[i] == A_BYTE) - { - printf("%x, ", op->args[i][0]); - } else - if (arg_types[i] == A_NAME) - { - printf("%x %x, ", op->args[i][1], op->args[i][0]); - } else - if (arg_types[i] == A_DYNC) - { - for (int x = 0; x < op->sarg[i]; x++) - printf("%x ", op->args[i][x]); - } - } - - printf("\n"); -} - int main(int argc, char** argv) { init_mdata(); @@ -45,7 +17,8 @@ int main(int argc, char** argv) int i; for (i = 0; i < bc->size; i++) { - print_op(bc->heap[i]); + bc_print_op(bc->heap[i]); + printf("\n"); } bc_del(bc); 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 @@ -0,0 +1,16 @@ +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 +144 +233 +377 +610 +987 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 @@ -0,0 +1,6 @@ +#!/bin/bash +pushd ../../.. &>/dev/null +make &>/dev/null +popd &>/dev/null + +../../../toi fibb