2018-03-03 22:05:33 +01:00
|
|
|
import {HacknetNode} from "./HacknetNode.js";
|
2017-08-30 19:44:29 +02:00
|
|
|
import {NetscriptFunctions} from "./NetscriptFunctions.js";
|
2018-03-03 22:05:33 +01:00
|
|
|
import {NetscriptPort} from "./NetscriptPort.js";
|
|
|
|
|
2016-11-17 23:25:40 +01:00
|
|
|
/* Environment
|
2017-08-30 19:44:29 +02:00
|
|
|
* NetScript program environment
|
2016-11-17 23:25:40 +01:00
|
|
|
*/
|
2017-06-28 11:47:42 +02:00
|
|
|
function Environment(workerScript,parent) {
|
|
|
|
if (parent){
|
2017-10-02 04:35:22 +02:00
|
|
|
//Create a copy of parent's variables
|
|
|
|
//this.vars = parent.vars;
|
|
|
|
this.vars = Object.assign({}, parent.vars);
|
2017-06-28 11:47:42 +02:00
|
|
|
} else {
|
|
|
|
this.vars = NetscriptFunctions(workerScript);
|
|
|
|
}
|
2016-11-17 23:25:40 +01:00
|
|
|
this.parent = parent;
|
2016-12-06 17:59:20 +01:00
|
|
|
this.stopFlag = false;
|
2016-11-17 23:25:40 +01:00
|
|
|
}
|
|
|
|
Environment.prototype = {
|
|
|
|
//Create a "subscope", which is a new new "sub-environment"
|
|
|
|
//The subscope is linked to this through its parent variable
|
|
|
|
extend: function() {
|
2017-09-29 17:02:33 +02:00
|
|
|
return new Environment(null, this);
|
2016-11-17 23:25:40 +01:00
|
|
|
},
|
2017-08-30 19:44:29 +02:00
|
|
|
|
2016-11-17 23:25:40 +01:00
|
|
|
//Finds the scope where the variable with the given name is defined
|
|
|
|
lookup: function(name) {
|
|
|
|
var scope = this;
|
|
|
|
while (scope) {
|
2017-10-02 04:35:22 +02:00
|
|
|
if (Object.prototype.hasOwnProperty.call(scope.vars, name)) {
|
2016-11-17 23:25:40 +01:00
|
|
|
return scope;
|
2017-10-02 04:35:22 +02:00
|
|
|
}
|
2016-11-17 23:25:40 +01:00
|
|
|
scope = scope.parent;
|
|
|
|
}
|
2017-10-02 04:35:22 +02:00
|
|
|
return null;
|
2016-11-17 23:25:40 +01:00
|
|
|
},
|
2017-08-30 19:44:29 +02:00
|
|
|
|
2016-11-17 23:25:40 +01:00
|
|
|
//Get the current value of a variable
|
|
|
|
get: function(name) {
|
2017-05-30 00:37:38 +02:00
|
|
|
if (name in this.vars) {
|
2016-11-17 23:25:40 +01:00
|
|
|
return this.vars[name];
|
2017-05-30 00:37:38 +02:00
|
|
|
}
|
2016-11-17 23:25:40 +01:00
|
|
|
throw new Error("Undefined variable " + name);
|
|
|
|
},
|
2017-08-30 19:44:29 +02:00
|
|
|
|
2016-11-17 23:25:40 +01:00
|
|
|
//Sets the value of a variable in any scope
|
|
|
|
set: function(name, value) {
|
|
|
|
var scope = this.lookup(name);
|
2017-10-02 04:35:22 +02:00
|
|
|
|
|
|
|
//If scope has a value, then this variable is already set in a higher scope, so
|
|
|
|
//set is there. Otherwise, create a new variable in the local scope
|
|
|
|
if (scope !== null) {
|
|
|
|
return scope.vars[name] = value;
|
|
|
|
} else {
|
|
|
|
return this.vars[name] = value;
|
2017-05-30 00:37:38 +02:00
|
|
|
}
|
2016-11-17 23:25:40 +01:00
|
|
|
},
|
2017-08-30 19:44:29 +02:00
|
|
|
|
2017-07-13 18:54:29 +02:00
|
|
|
setArrayElement: function(name, idx, value) {
|
2017-09-15 16:06:59 +02:00
|
|
|
if (!(idx instanceof Array)) {
|
|
|
|
throw new Error("idx parameter is not an Array");
|
|
|
|
}
|
2017-07-13 18:54:29 +02:00
|
|
|
var scope = this.lookup(name);
|
|
|
|
if (!scope && this.parent) {
|
|
|
|
throw new Error("Undefined variable " + name);
|
|
|
|
}
|
|
|
|
var arr = (scope || this).vars[name];
|
|
|
|
if (!(arr.constructor === Array || arr instanceof Array)) {
|
|
|
|
throw new Error("Variable is not an array: " + name);
|
|
|
|
}
|
2017-09-15 16:06:59 +02:00
|
|
|
var res = arr;
|
|
|
|
for (var iterator = 0; iterator < idx.length-1; ++iterator) {
|
|
|
|
var i = idx[iterator];
|
|
|
|
if (!(res instanceof Array) || i >= res.length) {
|
|
|
|
throw new Error("Out-of-bounds array access");
|
|
|
|
}
|
|
|
|
res = res[i];
|
|
|
|
}
|
2018-03-03 22:05:33 +01:00
|
|
|
|
|
|
|
//Cant assign to ports or HacknetNodes
|
|
|
|
if (res[idx[idx.length-1]] instanceof HacknetNode) {
|
|
|
|
throw new Error("Cannot assign a Hacknet Node handle to a new value");
|
|
|
|
}
|
|
|
|
if (res[idx[idx.length-1]] instanceof NetscriptPort) {
|
|
|
|
throw new Error("Cannot assign a Netscript Port handle to a new value");
|
|
|
|
}
|
2017-09-15 16:06:59 +02:00
|
|
|
return res[idx[idx.length-1]] = value;
|
2017-07-13 18:54:29 +02:00
|
|
|
},
|
2017-08-30 19:44:29 +02:00
|
|
|
|
2016-11-17 23:25:40 +01:00
|
|
|
//Creates (or overwrites) a variable in the current scope
|
|
|
|
def: function(name, value) {
|
|
|
|
return this.vars[name] = value;
|
2017-08-30 19:44:29 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export {Environment};
|