jweinst1
5/19/2016 - 6:25 PM

virtual machine reader for json language prototype

virtual machine reader for json language prototype

//bool comparison functions

var BoolFuncs = {
    "==":function(a, b){
        return a.value === b.value;
    },
    "!=":function(a, b){
        return a.value !== b.value;
    },
    "<":function(a, b){
        return a.value < b.value;
    },
    ">":function(a, b){
        return a.value > b.value;
    },
    "<=":function(a, b){
        return a.value <= b.value;
    },
    ">=":function(a, b){
        return a.value >= b.value;
    },
    "&&":function(a, b){
        return a.value && b.value;
    },
    "||":function(a, b){
        return a.value || b.value;
    }
};

//processes, or mini functions that facilitate operations
//dest is always the destination of where the resulting value is stored.
var procfuncs = {
    //math funcs
    "+":function(a, b, dest){
        dest.value = a.value + b.value;
    },
    "-":function(a, b, dest){
        dest.value = a.value - b.value;
    },
    "*":function(a, b, dest){
        dest.value = a.value * b.value;
    },
    "/":function(a, b, dest){
        dest.value = a.value / b.value;
    },
    "//":function(a, b, dest){
        dest.value = Math.floor(a.value / b.value);
    },
    "%":function(a, b, dest){
        dest.value = a.value % b.value;
    },
    "**":function(a, b, dest){
        dest.value = Math.pow(a.value, b.value);
    },
    //concat oper, for strings or arrays
    "+~":function(a, b, dest){
        dest.value = a.concat(b);
    },
    //pushes or appends onto arrays
    "push":function(a, b, dest){
        a.value.push(b.value);
    },
    //pop operator only uses one operand, but needs both to be called
    "pop":function(a, b, dest){
        dest.value = a.value.pop();
    },
    //indexing operator
    "get":function(a, b, dest){
        dest.value = a.value[b.value];
    },
    //setitem oper for objects or arrays
    "set":function(a, b, dest){
        dest.value[a.value] = b.value;
    },
    //takes the length of a string or array
    "len":function(a, b, dest){
        dest.value = a.value.length;
    },
    //printing oper, must be called with a, b and dest
    "print":function(a, b, dest){
        console.log(a.value);
    }
};

//class to implement variable collection and storage
var Vardict = (function(){
    //private object to hold values in the dictionary
    function Valobj(value){
        this.value = value;
    }
    function Vardict(){

    }
    Vardict.prototype.init = function(key, value){
        this[key] = new Valobj(value);
    };
    Vardict.prototype.del = function(key){
        delete this[key];
    };
    Vardict.prototype.check = function(key){
        return key in this;
    };
    //declares variable without assigning value
    Vardict.prototype.declare = function(key){
        this[key] = null;
    };
    //gets the entire value with it's object reference
    //if key does not exist in object, creates a key that is null valued
    Vardict.prototype.get = function(key){
        if(this.check(key)){
            return this[key];
        }
        else{
            this.init(key, null);
            return this[key];
        }
    };
    //gets only the value associated with the reference
    Vardict.prototype.getValue = function(key){
        if(this.check(key)){
            return this[key].value;
        }
        else{
            return false;
        }
    };
    //modifies the value of a preexisting object
    Vardict.prototype.set = function(key, value){
        if(this.check(key)){
            this[key].value = value;
        }
        else {
            return false;
        }
    };
    return Vardict;
})();


//main class for virtual machine
var VirtualMachine = (function(){
    //private object to hold values in the dictionary
    function Valobj(value){
        this.value = value;
    }
    function VirtualMachine(){
        this.variables = new Vardict();
        this.endstate = false;
        this.comps = BoolFuncs;
        this.procs = procfuncs;
        this.beginstate = true;
    }
    //loads variables from a variable object, as a preprocessor arrangement
    VirtualMachine.prototype.loadVars = function(obj){
        for(var key in obj){
            this.variables.init(key, obj[key]);
        }
    };
    //method that turns values into value object for easy referencing.
    VirtualMachine.prototype.setupVars = function(obj){
        for(var key in obj){
            //loads an object from memory if its already a variable
            if(typeof obj[key] === 'string' && obj[key][0] === "@"){
                obj[key] = this.variables.get(obj[key]);
            }
            //strings that don't start with @ will not be loaded
            else if(key !== "op") {
                obj[key] = new Valobj(obj[key]);
            }
        }
    };
    //evaluates one process
    VirtualMachine.prototype.assembleProc = function(obj){
        if("a" in obj && "b" in obj && "dest" in obj && "op"in obj){
            this.procs[obj.op](obj.a, obj.b, obj.dest);
        }
        else{
            throw "Process Error, invalid keys";
        }
    };
    //evaluates if a condition object is true
    VirtualMachine.prototype.assembleCond = function(obj){
        if("a" in obj && "b" in obj && "op"in obj){
            if(!(obj.op in this.comps)) throw "OPER ERROR";
            return this.comps[obj.op](obj.a, obj.b);
        }
    };
    //determines if an object is a block
    VirtualMachine.prototype.isBlock = function(obj){
        return "type" in obj && obj.type === "block" && "stmts" in obj;
    };
    //determines if an object is a conditional
    VirtualMachine.prototype.isConditional = function(obj){
        return "type" in obj && obj.type === "cond" && "exps" in obj && "t" in obj && "f" in obj;
    };
    //determines if an object is a loop statement
    VirtualMachine.prototype.isLoop = function(obj){
        return "type" in obj && obj.type === "loop" && "cond" in obj && "stmts" in obj;
    };
    VirtualMachine.prototype.isEnd = function(obj){
        return "type" in obj && obj.type === "end";
    };
    return VirtualMachine;
})();

var a = new VirtualMachine();
//sample program object
var b = {
    "vars":{
        "@foo":4
    },
    "program":{
        "type":"loop",
        "cond":{
            "op":">=",
            "a":"@foo",
            "b":10
        },
        "stmts":[
            {
                "op":"+",
                "a":"@foo",
                "b":1,
                "dest":"@foo"
            },
            {
                "op":"print",
                "a":"@foo",
                "b":"@foo",
                "dest":"@foo"
            }
        ],
        "next":{
            "type":"end"
        }
    }
};