/*====================================================
* rapl_variable.js "A Tcl like language implementation in Javascript named WebRAPL
* (Web Rapid Application Programming Language)"
*
* handling of variables for RAPL
*
* Released under the same terms as Tcl itself.
* (BSD license found at <http://www.tcl.tk/software/tcltk/license.html>)
*
* Arnulf Wiedemann 2011
*/
RP.add("rapl-variable", function(R, name) {
/* =============================== Variable ================================== */
function Variable(interp, name, type_str, call_frame, ns_ptr) {
R.log('constructor called', '2.life', 'Variable', true);
// kweight
var varbl = this;
var constructor = varbl.constructor;
Variable.superclass.constructor.apply(varbl, arguments);
R.Base.variable_oid++
varbl.oid = R.Base.variable_oid;
varbl.interp = interp;
varbl.type = 0;
varbl.link = null;
varbl.name = name;
varbl.value = null;
varbl.protection = varbl.PROTECTION_PUBLIC;
varbl.init_value = null;
varbl.config_code = null;
varbl.class_name = null;
varbl.state = varbl.VARIABLE_STATE_COMPLETE;
varbl.variable_traces = new Array();
varbl.no_trace = false;
varbl.namespace = null;
varbl.call_frame = null;
varbl.link_frame_ptr = null;
varbl.obj_ptr = null;
if (ns_ptr != null) {
varbl.namespace = ns_ptr;
} else {
varbl.call_frame = call_frame;
}
if (type_str == null) {
throw "bad type_str in Variable";
}
var types = type_str.split(" ");
for (var i = 0; i < types.length; i++) {
var my_type = types[i];
try {
var my_type_val = varbl.getVariableTypeFromString(my_type);
} catch(e) {
throw "bad type in Variable: '"+my_type+"'";
}
varbl.type |= my_type_val;
}
if (varbl.type == 0) {
throw "need type(s) for a variable";
}
if (typeof name == "undefined") {
throw "bad name in RaplVariable";
}
R.log('constructor end', '2.life', 'Variable', true);
}
R.extend(Variable, R.Base, {
my_name: "Variable",
/* ==================== toString ===================================== */
toString: function () {
var varbl = this;
return varbl.getProtectionString(varbl.protection)+" "+varbl.name;
},
/* ==================== toDebugString ===================================== */
toDebugString: function () {
var varbl = this;
var str = varbl.mySelf()+"\n";
str += " name: "+varbl.name+"\n";
str += " protection: "+varbl.getProtectionString(varbl.protection)+"\n";
str += " type: "+varbl.getVariableTypeString(varbl.type)+"\n";
if (varbl.value != null) {
str += varbl.value.toDebugString();
} else {
str += " value: "+"<null>"+"\n";
}
if (varbl.obj_ptr != null) {
str += " obj_ptr: "+varbl.obj_ptr.toDebugString();
} else {
str += " obj_ptr: "+"<null>"+"\n";
}
if (varbl.namespace != null) {
str += " namespace: "+varbl.namespace.full_name+"\n";
} else {
str += " namespace: "+"<null>"+"\n";
}
if (varbl.call_frame != null) {
str += " call_frame: "+varbl.call_frame.toDebugString()+"\n";
} else {
str += " call_frame: "+"<null>"+"\n";
}
if (varbl.link_frame_ptr != null) {
str += " link_frame: "+varbl.link_frame_ptr.toDebugString()+"\n";
} else {
str += " link_frame: "+"<null>"+"\n";
}
return str;
},
/* ==================== setProtection =================================== */
setProtection: function(val) {
this.protection = val;
},
/* ==================== getProtection =================================== */
getProtection: function() {
return this.protection;
},
/* ==================== setInitValue =================================== */
setInitValue: function(val) {
this.init_value = val;
this.setValue(val, null);
},
/* ==================== getInitValue =================================== */
getInitValue: function() {
return this.init_value;
},
/* ==================== setConfigCode =================================== */
setConfigCode: function(script) {
this.config_code = script;
},
/* ==================== getConfigCode =================================== */
getConfigCode: function() {
return this.config_code;
},
/* ==================== setClassName =================================== */
setClassName: function(class_name) {
this.class_name = class_name;
},
/* ==================== getClassName =================================== */
getClassName: function() {
return this.class_name;
},
/* ==================== setState =================================== */
setState: function(state) {
this.state = state;
},
/* ==================== getState =================================== */
getState: function() {
return this.state;
},
/* ==================== isUndefined =================================== */
isUndefined: function() {
if (this.type & this.VAR_UNDEFINED) {
return 1;
}
return 0;
},
/* ==================== isArray =================================== */
isArray: function() {
if (this.type & this.VAR_ARRAY) {
return 1;
}
return 0;
},
/* ==================== arrayNames =================================== */
arrayNames: function() {
if (!this.isArray) {
throw "variable \""+this.name+"\" is no array";
}
var names = new Array();
for (var z in this.value.value) {
names.push(z);
}
return names;
},
/* ==================== linkVar ===================================== */
linkVar: function(link) {
this.link = link;
if (this.type & this.VAR_UNDEFINED) {
this.type -= this.VAR_UNDEFINED;
}
this.type |= Tcl.VAR_LINK;
},
/* ==================== getVariableParts ===================================== */
getVariableParts: function(name) {
},
/* ==================== getVariableValue ===================================== */
getVariableValue: function() {
this.interp.variable_obj_type.handleVariableTrace(null, this.TRACE_OP_READ, "read");
return this.value;
},
/* ==================== addVariableTrace ===================================== */
addVariableTrace: function(trace_obj) {
this.variable_traces.push(trace_obj);
},
/* ==================== removeVariableTrace ===================================== */
removeVariableTrace: function(trace_obj) {
throw "removeVariableTrace not yet implemented";
},
/* ==================== setValue ===================================== */
setValue: function(val, part) {
print("VARIABLE setValue called!");
//print("SETV!"+typeof val+"!"+val.mySelf()+"!"+val.toDebugString()+"!");
var varbl = this;
//print("SETV2!"+varbl.toDebugString()+"!"+varbl.mySelf()+"!");
//print("var setValue!"+varbl.name+"!val!"+val+"!part!"+part+"!lv!"+varbl.interp.eval_statement.level+"!");
if (part != null) {
if (varbl.type & varbl.VAR_UNDEFINED) {
varbl.type &= ~varbl.VAR_UNDEFINED;
varbl.type |= varbl.VAR_ARRAY;
varbl.value = varbl.interp.string_obj_type.newStringObj(val, -1);
varbl.obj_ptr = varbl.value;
varbl.value.setValue(val, part);
} else {
if (!(varbl.type & varbl.VAR_ARRAY)) {
varbl.type |= varbl.VAR_ARRAY;
varbl.value = varbl.interp.string_obj_type.newStringObj(val, -1);
varbl.obj_ptr = varbl.value;
} else {
varbl.value.setValue(val, part);
}
}
} else {
varbl.type &= ~varbl.VAR_UNDEFINED;
if (varbl.type & varbl.VAR_ARRAY) {
varbl.type &= ~varbl.VAR_ARRAY;
}
if ((varbl.type & varbl.VAR_ARRAY)) {
throw "variable is of type array, need part: "+varbl.name+"!";
} else {
//print("RaplVariable setValue!"+varbl.name+"!"+typeof val+"!"+(val instanceof RaplObject)+"!"+typeof val.dict_keys+"!");
if (varbl.value != null) {
// varbl.value.setValue(val, part);
if ((typeof val != "object") && !(val instanceof R.RaplObject)) {
varbl.value = varbl.interp.string_obj_type.newStringObj(val, -1);
varbl.obj_ptr = varbl.value;
} else {
//print("SETV22!"+typeof val+"!"+(val instanceof R.RaplObject)+"!"+val.toDebugString()+"!");
varbl.value = val;
varbl.obj_ptr = varbl.value;
}
} else {
if ((typeof val != "object") && !(val instanceof R.RaplObject)) {
varbl.value = varbl.interp.string_obj_type.newStringObj(val, -1);
varbl.obj_ptr = varbl.value;
} else {
varbl.value = val;
varbl.obj_ptr = varbl.value;
}
}
}
}
if (varbl == varbl.value) {
throw "RaplVariable !"+varbl.variable_oid+"!"+varbl.name+" has same value as this!"
}
if (varbl.value != null) {
if (typeof arguments[2] != "undefined") {
print("WARNING VARSETV!"+varbl.name+"!arguments[2]!"+arguments[2]+"!");
}
}
varbl.interp.variable_obj_type.handleVariableTrace(part, varbl.TRACE_OP_WRITE, "write");
},
/* ==================== lappendValue ===================================== */
lappendValue: function(val, part) {
var varbl = this;
if (part != null) {
if (varbl.type & varbl.VAR_UNDEFINED) {
varbl.type &= ~varbl.VAR_UNDEFINED;
varbl.type |= varbl.VAR_ARRAY;
varbl.value = varbl.interp.empty_obj.newRaplStringObject(val, -1);
varbl.obj_ptr = varbl.value;
varbl.value.lappendValue(val, part);
} else {
if (!(varbl.type & varbl.VAR_ARRAY)) {
varbl.type |= varbl.VAR_ARRAY;
varbl.value = varbl.interp.empty_obj.newRaplStringObject(val, -1);
varbl.obj_ptr = varbl.value;
} else {
varbl.value.lappendValue(val, part);
varbl.obj_ptr = varbl.value;
}
}
} else {
varbl.type &= ~varbl.VAR_UNDEFINED;
if ((varbl.type & varbl.VAR_ARRAY)) {
throw "variable is of type array, need part"
} else {
if (varbl.value != null) {
varbl.value.lappendValue(val, part);
varbl.obj_ptr = varbl.value;
} else {
varbl.value = varbl.interp.empty_obj.newRaplStringObject(val, -1);
varbl.obj_ptr = varbl.value;
}
}
}
varbl.interp.variable_obj_type.handleVariableTrace(part, varbl.TRACE_OP_WRITE, "write");
},
/* ==================== getValue ===================================== */
getValue: function(part, value_type) {
var varbl = this;
this.interp.variable_obj_type.handleVariableTrace(part, varbl.TRACE_OP_READ, "read");
if (varbl.type & varbl.VAR_UNDEFINED) {
throw "getValue: variable \""+varbl.name+"\" is undefined"
}
//print("RaplVariable getValue!"+varbl.name+"!"+typeof varbl.value+"!"+(varbl.value instanceof R.RaplObject)+"!"+typeof varbl.value.dict_keys+"!");
var result = varbl.value.getValue(varbl.name, part, value_type, null);
//print("var getValue!"+varbl.name+"!val!"+result+"!lv!"+varbl.interp.eval_statement.level+"!");
print("GETV22!"+result.toDebugString()+"!");
return result;
},
/* ==================== getTypeString ===================================== */
getTypeString: function() {
var result = "";
var sep = "";
for (var z in this.variable_types) {
if (this.type & z) {
result += this.getVariableTypeString(this.type & z);
result += sep;
sep = " | ";
}
}
return result;
}
});
Variable.prototype.constructor = Variable;
R.Variable = Variable;
}, "0.0.1", {});