language

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

commit 6cc46e9726906b259c377a1fcfd0ed507630b9a2
parent 5697d91cdc11f8af8bbba5d817e38e2c0aaf2b1d
Author: Paul Longtine <paullongtine@gmail.com>
Date:   Sat Apr  9 23:54:21 2016

Very wobbly, but it does compile code now! and run the code!

Diffstat:
 doc/SPECIFICATION            |  14 +-
 src/lc/bytecode.py           | 110 +++++++++++++++-
 src/lc/interpreter.py        | 226 ++++++++++++++++++++++++--------
 src/lc/main.py               |  32 ++++-
 src/lc/memonic.py            |   4 +-
 src/lc/parser.py             | 306 ++++++++++++++++++++++++++++----------------
 src/lc/test_files/fibb.ti    |  10 +-
 src/lc/test_files/if.ti      |  14 ++-
 src/lc/test_files/simple.ti  |   4 +-
 src/lc/test_files/testing.ti |  23 +---
 src/vm/Makefile              |   2 +-
 src/vm/inc/var.h             |   8 +-
 src/vm/inc/var_ops.h         |   2 +-
 src/vm/src/ins_def.c         |  46 ++-----
 src/vm/src/stk.c             |   2 +-
 src/vm/src/var.c             |   4 +-
 src/vm/src/var_ops.c         |  19 +++-
 17 files changed, 590 insertions(+), 236 deletions(-)

diff --git a/doc/SPECIFICATION b/doc/SPECIFICATION @@ -87,7 +87,7 @@ In this definition, the namespace will provide the following key mechanisms: * Implicitly move in/out of scopes Scopes are handled by referencing to either the Global Scope or the Local Scope. -The Local Scope is denoted by '1' in the scope arguement when refering to names, +The Local Scope is denoted by '0' in the scope arguement when refering to names, and this scope is initialized when evaluating any new block of code. When a diff erent block of code is called, a new scope is added as a new Namespace level. Namespace levels act as context switches within function contexts. For example, @@ -97,20 +97,20 @@ function calls, you can traverse n instances of previous namespaces. For example, take this namespace level graphic, where each Level is a namespace instance: - Level 0: Global namespace, denoted by '0'. - Level 1: Namespace level, where Local Level is at 1, denoted by '1'. + Level 0: Global namespace, denoted by '1'. + Level 1: Namespace level, where Local Level is at 1, denoted by '0'. When a function is called, another namespace level is created and the local level increases, like so: - Level 0: Global namespace, denoted by '0'. + Level 0: Global namespace, denoted by '1'. Level 1: Namespace level. - Level 2: Namespace level, where Local Level is at 2, denoted by '1'. + Level 2: Namespace level, where Local Level is at 2, denoted by '0'. -Global scope names (denoted by a '0' in the scope arguement) are persistient +Global scope names (denoted by a '1' in the scope arguement) are persistient through the runtime as they handle all function definitions, objects, and names declared in the global scope. The "Local Level" is at where references -that have a scope arguement of '1' refer to when accessing names. +that have a scope arguement of '0' refer to when accessing names. VARIABLE DEFINITION diff --git a/src/lc/bytecode.py b/src/lc/bytecode.py @@ -1,8 +1,114 @@ +from memonic import * + +class VariableNew(): + def __init__(self, label, typed): + self.label = label + self.typed = typed + + def action(self): + return([ + OP_DEC, + self.label.action(scope=True), + self.typed.action(), + self.label.action() + ]) + +class VariableAssignment(): + def __init__(self, label, expression): + self.label = label + self.expr = expression + + def action(self): + return([ + self.expr.action(), + OP_STV, + self.label.action(scope=True), + self.label.action() + ]) + +class VariableGet(): + def __init__(self, label): + self.label = label + + def action(self): + return([ + OP_LOV, + self.label.action(scope=True), + self.label.action() + ]) + +class FunctionDef(): + def __init__(self, label, args, typed): + self.label = label + self.args = args + self.typed = typed + + def action(self): + tmp = self.args.action() if self.args != None else 0x0 + return([ + OP_DEFUN, + self.label.action(), + self.typed.action(), + tmp + ]) + class FunctionCall(): def __init__(self, label, arguements): self.label = label self.arguements = arguements + + def action(self): + return([ + self.arguements.action(), + OP_CALL, + self.label.action() + ]) + +class ForLoop(): + def __init__(self, expression): + self.expr = expression + + def action(self): + return([0]) + +class SerializeableType(): + def __init__(self, value): + pass -class IntegerConstant(): +class StringConstant(SerializeableType): def __init__(self, value): - self.value = int(value[0][0]) + self.value = value[1:-1] + + def action(self): + return([ + len(value), + 0x00, + value + ]) + +class IntegerConstant(SerializeableType): + def __init__(self, value): + self.value = int(value[0]) + if self.value > 0xFF: + print("ONE BYTE PLEASE THIS IS A PROTOTYPE!!") + + def action(self): + return([ + OP_CTS, + 0x02, + 0x00, + 0x06, + self.value + ]) + +class BinaryOp(): + def __init__(self, expr1, op): + self.vals = [expr1] + self.op = op + + def action(self): + return([ + self.vals[0].action(), + self.vals[1].action(), + self.op.action() + ]) diff --git a/src/lc/interpreter.py b/src/lc/interpreter.py @@ -42,10 +42,23 @@ class AbstractToken(): class Label(AbstractToken): def update(self): - self.expr.append(self.data) - - def action(self): - pass + 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.expr = 0 + + for i in self.i.names: + if self.data in i: + self.expr = i.index(self.data) + 1 + break + + def action(self, scope=False): + if scope: + return(self.scope) + else: + return([0x00, self.expr]) class Arguements(AbstractToken): def update(self): @@ -57,8 +70,10 @@ class Arguements(AbstractToken): self.expr.append(Expression(self.i, t)) def action(self): + rv = [] for i in self.expr: - i.action() + rv.append([i.action(), OP_ARGB]) + return rv class Type(AbstractToken): def update(self): @@ -71,10 +86,10 @@ class Type(AbstractToken): if n == None: print("INVALID TYPE") - self.expr.append(n) + self.expr = n def action(self): - pass + return(self.expr) class Parameters(AbstractToken): def update(self): @@ -83,16 +98,37 @@ class Parameters(AbstractToken): if x != "(" and x != ")" and x != ",": tmp.append(x) elif x == "," or 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 = [] def action(self): - pass + types = map(lambda x: x[0].action(), self.expr) + return([ + len(types), + 0x0, + types + ]) + class Expression(AbstractToken): def update(self): + self.operators = [ + ["+", Opcode(OP_ADD)], + ["-", Opcode(OP_SUB)], + ["*", Opcode(OP_MULT)], + ["/", Opcode(OP_DIV)], + ["==", Opcode(OP_EQ)], + [">", Opcode(OP_GTHAN)], + ["<", Opcode(OP_LTHAN)], + [">=", Opcode(OP_GTHAN_EQ)], + ["=<", Opcode(OP_LTHAN_EQ)] + ] + + self.operator_names = map(lambda x: x[0], self.operators) + self.func_call = Statement( "func_call", expression=[ @@ -100,7 +136,21 @@ class Expression(AbstractToken): self.i.p.paramlist_def, ], init=(lambda x,y: FunctionCall(Label(x,y[0]), - Arguements(x,y[1]))) + Arguements(x,y[1:]))) + ) + self.subexpr = Statement( + "subexpr", + expression=[ + self.i.p.paramlist_def + ], + init=(lambda x,y: Expression(x, y[1:-1])) + ) + self.string = Statement( + "string", + expression=[ + AtomicSymbol("^\0") + ], + init=(lambda x,y: StringConstant(y)) ) self.integer = Statement( "integer", @@ -114,64 +164,75 @@ class Expression(AbstractToken): expression=[ self.i.p.label_def ], - init=(lambda x,y: Label(x, y)) + init=(lambda x,y: VariableGet(Label(x, y))) ) self.identifiers = [ self.func_call, + self.subexpr, + self.string, self.integer, self.label ] - self.operators = [ - ["+", OP_ADD], - ["-", OP_SUB], - ["*", OP_MULT], - ["/", OP_DIV], - ["==", OP_EQ], - [">", OP_GTHAN], - ["<", OP_LTHAN], - [">=", OP_GTHAN_EQ], - ["=<", OP_LTHAN_EQ] - ] - self.operator_names = map(lambda x: x[0], self.operators) - self.group_char = [["[", "("], ["]", ")"]] - t = token_split(self.data, self.group_char, self.operator_names) if len(t) == 0: t = self.data - - subexpr = [] - for n,x in enumerate(t): - if x[-1] in self.operator_names: - subexpr.append( - self.operators[ self.operator_names.index(x[-1]) ][1]) - d = x[:-1] + if len(t) > 2: + print("Expression Error ({})".format(self.data)) + return False + + next_op = False + for thing in t: + if thing[-1] in self.operator_names: + ex = thing[:-1] + op = thing[-1] else: - d = x - - if d[0] == "(": - subexpr.append(Expression(self.i, d[1:-1])) + ex = thing + op = None + + obj = None + for i in self.identifiers: + r = i.match(ex) + if r: + obj = i.action(self.i, ex) + + if obj == None: + print("Unknown Expression Error ({})".format(ex)) + break + + if next_op: + self.expr[-1].vals.append(obj) + next_op = False else: - for o in self.identifiers: - r = o.match(d) - if r: - subexpr.append(o.action(self.i, r)) - if len(subexpr) == 3: - self.expr.append(subexpr) - self.subexpr = [] + if op in self.operator_names: + index = self.operator_names.index(op) + self.expr.append(BinaryOp(obj, self.operators[index][1])) + next_op = True + else: + self.expr.append(obj) - if len(subexpr) > 0: - self.expr.append(subexpr) - print(self.expr) + def action(self): + return([ + self.expr[0].action() + ]) +class Opcode(): + def __init__(self, opcode): + self.opcode = opcode + def action(self): - pass + return([self.opcode]) + +class Directive(): + def __init__(self, function, conditional): + self.action = function + self.cond = conditional class Interpreter(): def __init__(self, filename): @@ -181,14 +242,79 @@ class Interpreter(): self.line = (None, None) - self.contex = {} + self.ln = 0 + + self.names = [[]] + self.scope = 0 + + self.cur_directives = [] + + self.directives = [self.cur_directives] #initalizes values n' stuff - for self.line in self.program: - self.line.append(self.line[0].action(self)) + for self.ln, self.line in enumerate(self.program): + t = self.line[0].action(self) + for i in t: + if i != False: + self.line[2].append(i) + + def nxt(self): + if len(self.program) >= self.ln + 1: + return self.program[self.ln] + return self.program[self.ln + 1] + + def new_name(self, index): + self.name_dec(self.line[1][index]) + return False + + def name_dec(self, token): + f = lambda y, x: y(y, x[0]) if type(x) is list else x + t = f(f, token) + + for scope in range(0, self.scope): + if t in self.names[scope]: + print("Can't do that") + + self.names[self.scope].append(t) + + def inc_scope(self): + self.names.append([]) + self.scope += 1 + return False + + def dec_scope(self): + self.names.pop() + self.scope -= 1 + return False + + def push_directives(self): + self.directives.append(self.cur_directives) + self.cur_directives = [] + return False + + def pop_directives(self): + t = self.directives.pop() + for x in t: + if x.cond(self): + self.cur_directives.append(x) + else: + r = x.action(self) + for i in r: + if i != False: + self.line[2].append(i) + + return False + def add_directive(self, directive, cond=(lambda x: False)): + d = Directive(directive, cond) + self.cur_directives.append(d) + return False + + def op(self, opcode): + return(Opcode(opcode)) + def eval_label(self, index): - return(Label(self, self.line[1][index][0])) + return(Label(self, self.line[1][index])) def eval_args(self, index): return(Arguements(self, self.line[1][index])) diff --git a/src/lc/main.py b/src/lc/main.py @@ -1,9 +1,33 @@ from interpreter import * +def tobytearray(l, n, ba): + for i in l: + if type(i) is list: + n += 1 + ba = tobytearray(i, n, ba) + else: + print((" "*n)+hex(i)) + ba.append(i) + + return(ba) + + if __name__ == "__main__": import sys - t = Interpreter(sys.argv[1]) - for l in t.program: + if len(sys.argv) != 3: + print("useage: {} input_file output_file".format(sys.argv[0])) + sys.exit(1) + + itr = Interpreter(sys.argv[1]) + + out = file(sys.argv[2], "w") + + rv = [] + for l in itr.program: for e in l[2]: - #print("{} : {}".format(e, e.expr)) - pass + rv.append(e.action()) + + program = bytearray() + program = tobytearray(rv, 0, program) + + out.write(program) diff --git a/src/lc/memonic.py b/src/lc/memonic.py @@ -46,8 +46,8 @@ OP_AND = 0x57 OP_STARTL = 0x60 OP_CLOOP = 0x61 -OP_BREAK = 0x62 -OP_ENDL = 0x63 +OP_BREAK = 0x6E +OP_ENDL = 0x6F OP_GOTO = 0x70 OP_JUMPF = 0x71 diff --git a/src/lc/parser.py b/src/lc/parser.py @@ -1,4 +1,7 @@ from lexer import * +from memonic import * +from bytecode import * + class Parser(): def __init__(self, file_name): self.splitters = [ @@ -25,6 +28,8 @@ class Parser(): ] self.known_tokens = [ + "return", + "print", "if", "else", "for", @@ -49,10 +54,13 @@ class Parser(): "stack" ] - self.int_def = AtomicSymbol("[0-9]+") + self.int_def = AtomicSymbol("^[0-9]+$") + self.str_def = AtomicSymbol("^\0+") self.type_def = InclusiveSymbol(self.defined_types) self.label_def = ExclusiveSymbol(self.defined_types + + [self.int_def] + + [self.str_def] + self.known_tokens ) self.paramlist_def = GroupingSymbol( [ @@ -82,142 +90,222 @@ class Parser(): ]) self.statement_codeblock_begin = Statement( - "codeblock_begin", - expression=[ - AtomicSymbol("{") - ], - init=(lambda x: []) - ) + "codeblock_begin", + expression=[ + AtomicSymbol("{") + ], + init=(lambda x: [x.push_directives()]) + ) self.statement_codeblock_end = Statement( - "codeblock_end", - expression=[ - AtomicSymbol("}") - ], - init=(lambda x: []) - ) + "codeblock_end", + expression=[ + AtomicSymbol("}") + ], + init=(lambda x: [x.pop_directives()]) + ) + + self.statement_return = Statement( + "return", + expression=[ + AtomicSymbol("return"), + self.expr_def, + AtomicSymbol(";") + ], + init=(lambda x: [ + x.eval_expr(1), + x.op(OP_STV), + x.op(0x00), + x.op(0x00), + x.op(0x00) + ]) + ) + + self.statement_print = Statement( + "print", + expression=[ + AtomicSymbol("print"), + self.expr_def, + AtomicSymbol(";") + ], + init=(lambda x: [ + x.eval_expr(1), + x.op(OP_PRINT) + ]) + ) self.statement_if = Statement( - "if", - expression=[ - AtomicSymbol("if"), - self.expr_def, - AtomicSymbol(":") - ], - init=(lambda x: [x.eval_expr(1)]) - ) + "if", + expression=[ + AtomicSymbol("if"), + self.expr_def, + AtomicSymbol(":") + ], + init=(lambda x: [ + x.eval_expr(1), + x.op(OP_IFDO), + x.add_directive(lambda x: [x.op(OP_DONE)], + cond=( + lambda x: x.nxt()[0].name in ["else", "else_if"])) + ]) + ) + + self.statement_else_if = Statement( + "else_if", + expression=[ + AtomicSymbol("else"), + AtomicSymbol("if"), + self.expr_def, + AtomicSymbol(":") + ], + init=(lambda x: [ + x.op(OP_ELSE), + x.eval_expr(2), + x.op(OP_IFDO), + x.add_directive(lambda x: [x.op(OP_DONE)], + cond=( + lambda x: x.nxt()[0].name in ["else", "else_if"])) + ]) + ) self.statement_else = Statement( - "else", - expression=[ - AtomicSymbol("else"), - AtomicSymbol(":") - ], - init=(lambda x: []) - ) + "else", + expression=[ + AtomicSymbol("else"), + AtomicSymbol(":") + ], + init=(lambda x: [ + x.op(OP_ELSE), + x.add_directive(lambda x: [x.op(OP_DONE)]) + ]) + ) self.statement_for = Statement( - "for", - expression=[ - AtomicSymbol("for"), - self.expr_def, - AtomicSymbol(":") - ], - init=(lambda x: [x.eval_expr(1)]) - ) + "for", + expression=[ + AtomicSymbol("for"), + self.expr_def, + AtomicSymbol(":") + ], + init=(lambda x: [ + ForLoop(x.eval_expr(1)) + ]) + ) self.statement_while = Statement( - "while", - expression=[ - AtomicSymbol("while"), - self.expr_def, - AtomicSymbol(":") - ], - init=(lambda x: [x.eval_expr(1)]) - ) + "while", + expression=[ + AtomicSymbol("while"), + self.expr_def, + AtomicSymbol(":") + ], + init=(lambda x: [ + x.op(OP_STARTL), + x.eval_expr(1), + x.op(OP_CLOOP), + x.add_directive(lambda x: [x.op(OP_ENDL)]) + ]) + ) self.statement_func = Statement( - "function", - expression=[ - AtomicSymbol("func"), - self.label_def, - self.paramlist_def, - AtomicSymbol("-"), - AtomicSymbol(">"), - self.type_def, - AtomicSymbol(":") - ], - init=( - lambda x: [ - x.eval_label(1), - x.eval_param(2), - x.eval_type(5) - ]) - ) + "function", + expression=[ + AtomicSymbol("func"), + self.label_def, + self.paramlist_def, + AtomicSymbol("-"), + AtomicSymbol(">"), + self.type_def, + AtomicSymbol(":") + ], + init=( + lambda x: [ + x.new_name(1), + x.inc_scope(), + FunctionDef(x.eval_label(1), + x.eval_param(2), + x.eval_type(5)), + x.add_directive(lambda x: [x.op(OP_RETURN), + x.dec_scope()]) + ]) + ) + + self.statement_proc = Statement( + "procedure", + expression=[ + AtomicSymbol("func"), + self.label_def, + AtomicSymbol("-"), + AtomicSymbol(">"), + self.type_def, + AtomicSymbol(":") + ], + init=( + lambda x: [ + x.new_name(1), + x.inc_scope(), + FunctionDef(x.eval_label(1), + None, + x.eval_type(4)), + x.add_directive(lambda x: [x.op(OP_RETURN), + x.dec_scope()]) + ]) + ) self.statement_inst = Statement( - "instantiation", - expression=[ - self.type_def, - self.label_def, - AtomicSymbol("="), - self.expr_def, - AtomicSymbol(";") - ], - init=(lambda x: [ - x.eval_type(0), - x.eval_label(1), - x.eval_expr(3) - ]) - ) + "instantiation", + expression=[ + self.type_def, + self.label_def, + AtomicSymbol("="), + self.expr_def, + AtomicSymbol(";") + ], + init=(lambda x: [ + x.new_name(1), + VariableNew(x.eval_label(1), + x.eval_type(0)), + VariableAssignment(x.eval_label(1), + x.eval_expr(3)) + ]) + ) self.statement_assign = Statement( - "assignment", - expression=[ - self.label_def, - AtomicSymbol("="), - self.expr_def, - AtomicSymbol(";") - ], - init=(lambda x: [ - x.eval_label(0), - x.eval_expr(2) - ]) - ) - - self.statement_call = Statement( - "func_call", - expression=[ - self.label_def, - self.paramlist_def, - AtomicSymbol(";") - ], - init=(lambda x: [ - x.eval_label(0), - x.eval_args(1) - ]) - ) + "assignment", + expression=[ + self.label_def, + AtomicSymbol("="), + self.expr_def, + AtomicSymbol(";") + ], + init=(lambda x: [ + VariableAssignment(x.eval_label(0), + x.eval_expr(2)) + ]) + ) self.statement_expression = Statement( - "expression", - expression=[ - self.expr_def, - AtomicSymbol(";") - ], - init=(lambda x: [x.eval_expr(0)]) - ) + "expression", + expression=[ + self.expr_def, + AtomicSymbol(";") + ], + init=(lambda x: [x.eval_expr(0)]) + ) self.active_tokens = [ self.statement_codeblock_begin, self.statement_codeblock_end, + self.statement_return, + self.statement_print, self.statement_if, self.statement_else, self.statement_for, self.statement_while, self.statement_func, + self.statement_proc, self.statement_inst, self.statement_assign, - self.statement_call, self.statement_expression ] data="" @@ -236,7 +324,7 @@ class Parser(): for a in self.active_tokens: r = a.match(l) if r: - rv.append([a,r]) + rv.append([a,r,[]]) break return rv diff --git a/src/lc/test_files/fibb.ti b/src/lc/test_files/fibb.ti @@ -0,0 +1,10 @@ +int a = 0; +int b = 1; + +while a > 254: +{ + 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 @@ -0,0 +1,14 @@ +func test (int y) -> int: +{ + int z = 2; + return y * z; +} + +int x = 3; + +if 3 == x: +{ + x = x + 1; +} + +print test(x); diff --git a/src/lc/test_files/simple.ti b/src/lc/test_files/simple.ti @@ -1,4 +0,0 @@ -func testing (int i, int x) -> int: -{ - return(0); -} diff --git a/src/lc/test_files/testing.ti b/src/lc/test_files/testing.ti @@ -1,23 +0,0 @@ -func test (int x, int y, int z) -> int: -{ - int c = (x * y) + z; - if c > 3: - { - c = c - 3; - } - return(c); -} - -int x = 3; - -string y = "strings"; - -if x == 3: -{ - print("Potatoes are good for \"the\" soul."); -} - -int z = test(3, test(2*3, 2, 6), 1 * 2); - -print(y); -print(z); diff --git a/src/vm/Makefile b/src/vm/Makefile @@ -2,7 +2,7 @@ SRC_DIR = src INC_DIR = inc CC = gcc -CFLAGS = -std=c99 -Wall -Wconversion -I$(INC_DIR) +CFLAGS = -std=c99 -Wall -I$(INC_DIR) DEPS = $(INC_DIR)/is_mdata.h \ helper.h \ diff --git a/src/vm/inc/var.h b/src/vm/inc/var.h @@ -26,7 +26,9 @@ typedef enum { S_ARRAY,// A D_ARRAY,// B H_TABLE,// C - G_FIFO // D + G_FIFO, // D + G_IO, // E + G_PTR // F } b_type; typedef struct var_cont { @@ -52,6 +54,10 @@ typedef struct var_data_func { b_type* param; } var_data_func; +typedef struct var_data_ptr { + var_cont* v; +} var_data_ptr; + typedef struct var_data_int { int v; } var_data_int; diff --git a/src/vm/inc/var_ops.h b/src/vm/inc/var_ops.h @@ -10,6 +10,8 @@ #include "var.h" #include "helper.h" +void var_pprint(var_cont*); + var_cont* var_add_float(var_cont*, var_cont*); var_cont* var_add_int(var_cont*, var_cont*); var_cont* var_add(var_cont*, var_cont*); diff --git a/src/vm/src/ins_def.c b/src/vm/src/ins_def.c @@ -70,6 +70,7 @@ void init_ins_def( void ) INS_DEF[0x70] = _ins_def_GOTO; INS_DEF[0x71] = _ins_def_JUMPF; + INS_DEF[0x72] = _ins_def_IFDO; INS_DEF[0x73] = _ins_def_ELSE; INS_DEF[0x7E] = _ins_def_DONE; INS_DEF[0x7F] = _ins_def_CALL; @@ -105,21 +106,7 @@ void _ins_def_PRINT (rt_t* ctx, bc_cont* line) { var_cont* var = stk_pop(ctx->stack); - if (var->type == G_STR) - { - char* str = var_data_get_G_STR(var); - printf("%s\n", str); - } else - if (var->type == G_INT) - { - int val = var_data_get_G_INT(var); - printf("%i\n", val); - } else - if (var->type == G_FLOAT) - { - double val = var_data_get_G_FLOAT(var); - printf("%f\n", val); - } + var_pprint(var); pc_inc(ctx->pc, 1); } @@ -132,6 +119,7 @@ void _ins_def_ARGB (rt_t* ctx, bc_cont* line) var_cont* var = stk_at(ctx->stack, 0); stk_push(ctx->argstk, var); + pc_inc(ctx->pc, 1); } void _ins_def_LIBC (rt_t* ctx, bc_cont* line) @@ -221,6 +209,7 @@ void _ins_def_CTS (rt_t* ctx, bc_cont* line) var_cont* new = var_data_cpy(line->varg[0]); stk_push(ctx->stack, new); + pc_inc(ctx->pc, 1); } @@ -362,9 +351,7 @@ void _ins_def_GTHAN_EQ (rt_t* ctx, bc_cont* line) var_cont* A = stk_pop(ctx->stack); var_cont* B = stk_pop(ctx->stack); - var_cont* C = (var_gthan(A, B) || var_eq(A, B)); - - stk_push(ctx->stack, C); + // TODO pc_inc(ctx->pc, 1); } @@ -373,9 +360,7 @@ void _ins_def_LTHAN_EQ (rt_t* ctx, bc_cont* line) var_cont* A = stk_pop(ctx->stack); var_cont* B = stk_pop(ctx->stack); - var_cont* C = (var_lthan(A, B) || var_eq(A, B)); - - stk_push(ctx->stack, C); + // TODO pc_inc(ctx->pc, 1); } @@ -475,6 +460,9 @@ void _ins_def_IFDO (rt_t* ctx, bc_cont* line) break; } } + } else + { + pc_inc(ctx->pc, 1); } } void _ins_def_ELSE (rt_t* ctx, bc_cont* line) @@ -545,13 +533,13 @@ void _ins_def_CALLM (rt_t* ctx, bc_cont* line) 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); - // Pop a level in the stack and arguement stack stk_poplevel(&ctx->stack); stk_poplevel(&ctx->argstk); + // Pop the namespace and get the return value + var_cont* return_value = ns_pop(ctx->vars); + // Push the return value to the stack stk_push(ctx->stack, return_value); @@ -573,7 +561,7 @@ void _ins_def_DEFUN (rt_t* ctx, bc_cont* line) { 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]); + b_type* args = var_data_get_PLIST(line->varg[2]); size_t alen = line->sarg[2]; // Create a new variable for the new function @@ -586,8 +574,8 @@ void _ins_def_DEFUN (rt_t* ctx, bc_cont* line) data->loc = line->real_addr + 1; int nsize; - /* Determine the namespace size by finding variable declarations in the functions body, - Along with determining the end of the function. + /* Determine the namespace size by finding variable declarations in the + functions body, Along with determining the end of the function. */ for (nsize = 0; pc_safe(ctx->pc); pc_update(ctx->pc)) { @@ -606,10 +594,10 @@ void _ins_def_DEFUN (rt_t* ctx, bc_cont* line) nsize++; } } - // Set all the values. data->end = ctx->pc->line->real_addr; // This is the end! - data->size = nsize + alen + 1; // How many names will this function have? + data->size = nsize + alen + 1; // How many names will this + // function have? data->type = type; // Return type data->paramlen = alen; // Set the arguement length data->param = args; // Set the parameter list diff --git a/src/vm/src/stk.c b/src/vm/src/stk.c @@ -121,7 +121,6 @@ var_cont* stk_pop(stk_t* stack) stack->stack->ptr = stack->stack->ptr - 1; var_cont* rv = stack->stack->data[stack->stack->ptr]; - return rv; } @@ -140,6 +139,7 @@ void stk_push(stk_t* stack, var_cont* data) } stack->stack->data[stack->stack->ptr] = data; + stack->stack->ptr = stack->stack->ptr + 1; } diff --git a/src/vm/src/var.c b/src/vm/src/var.c @@ -2,7 +2,6 @@ #include <stdio.h> #include "var.h" - #include "bc.h" #include "helper.h" @@ -407,8 +406,7 @@ var_cont* raw_to_var(int n, byte_t* bytes) } else if (type == G_STR) { - - rv= raw_to_str(n, 1, bytes); + rv = raw_to_str(n, 1, bytes); } else { printf("Type {%x} is not a seralizeable type\n", type); diff --git a/src/vm/src/var_ops.c b/src/vm/src/var_ops.c @@ -6,6 +6,25 @@ #include "var.h" #include "helper.h" +void var_pprint(var_cont* var) +{ + if (var->type == G_STR) + { + var_data_str* data = var->data; + for (int i = 0; i < data->size; i++) printf("%c", data->v[i]); + } else + if (var->type == G_INT) + { + int val = var_data_get_G_INT(var); + printf("%i\n", val); + } else + if (var->type == G_FLOAT) + { + double val = var_data_get_G_FLOAT(var); + printf("%f\n", val); + } +} + var_cont* var_add_float(var_cont* A, var_cont* B) { var_cont* var = var_new(G_FLOAT);