/*====================================================
* rapl_register_cmd.js "A Tcl like language implementation in Javascript named WebRAPL
* (Web Rapid Application Programming Language)"
*
* registration of base built in commands for RAPL
*
* Released under the same terms as Tcl itself.
* (BSD license found at <http://www.tcl.tk/software/tcltk/license.html>)
*
* Based on Picol by Salvatore Sanfilippo (<http://antirez.com/page/picol>)
* (c) Stéphane Arnold 2007
* Richard Suchenwirth 2007: cleanup, additions
* Arnulf Wiedemann 2011: a lot of additions for Tcl 8.6 commands
*/
RP.add("rapl-register-cmd", function(R, name) {
function registerCmds(interp) {
//---------------------------------- Commands in alphabetical order
/* ==================== command append ===================================== */
interp.registerCommand("::append", function (interp, args) {
args.shift();
this.requireMinArgc(args, 1, "append", "");
var var_name = args.shift().toString();
var create_it = 1;
/* FIXME !!! need handling for array names here */
var var_obj = interp.root_namespace.lookupVariableEx(interp, var_name, 0, "", 1, 1);
if (var_obj.isUndefined()) {
var_obj.setValue("");
}
var str = interp.getVarValue(var_name).toString();
for (var i = 0; i < args.length; i++) {
str += args[i].toString();
}
// interp.setVar(var_name, str);
var_obj.setValue(str, null);
return str;
});
/* ==================== command break ===================================== */
interp.registerCommand("::break", function (interp, args) {
interp.code = this.BREAK;
return;
});
/* ==================== command catch ===================================== */
interp.registerCommand("::catch", function (interp, args) {
args.shift();
this.requireMinArgc(args, 1, "catch", "");
var body = args.shift();
var var_obj = null;
if (args.length > 0) {
var result_var_name = args.shift();
var_obj = interp.root_namespace.lookupVariableEx(interp, result_var_name, 0, "", 1, 1);
}
try {
var res = this.eval(body);
if (var_obj != null) {
var_obj.setValue(res.toString());
}
} catch (e) {
if (var_obj != null) {
var_obj.setValue(e);
}
return 1;
}
return 0;
});
/* ==================== command continue ===================================== */
interp.registerCommand("::continue", function (interp, args) {
interp.code = this.CONTINUE;
return;
});
/* ==================== command clock format ===================================== */
interp.registerSubCommand("::clock", "format", function (interp, args) {
var now = new Date();
now.setTime(args[1]);
return now.toString();
});
/* ==================== command clock scan ===================================== */
interp.registerSubCommand("::clock", "scan", function (interp, args) {
return Date.parse(args[1]);
});
/* ==================== command clock seconds ===================================== */
interp.registerSubCommand("::clock", "seconds", function (interp, args) {
return (new Date()).valueOf();
});
/* ==================== command dom ===================================== */
if(typeof(jQuery) != 'undefined') {
interp.registerCommand("::dom", function (interp, args) {
var selector = args[1].toString();
var fn = args[2].toString();
args = args.slice(3);
for (var i in args) {
args[i] = args[i].toString();
}
var q = $(selector);
q[fn].apply(q,args);
return "dom " + selector;
});
}
/* ==================== command eval ===================================== */
interp.registerCommand("::eval",function (interp, args) {
this.requireMinArgc(args, 2, "eval", "");
for (var i = 1; i < args.length; i++) {
args[i] = args[i].toString();
}
if (args.length == 2) {
var code = args[1];
} else {
var code = args.slice(1).join(" ");
}
return interp.eval_statement.eval(code);
});
var sqrt = "";
sqrt = Math.sqrt; // "publish" other Math.* functions as needed
/* ==================== command expr ===================================== */
interp.registerCommand("::expr", function (interp, args) {
var result = null;
var retcode;
if (args.length == 2) {
result = new Array();
/* seems to be a braced expression argument */
retcode = interp.eval_expression.evalExpression(args[1], result);
// for being compatible with Tcl we need to return 0 or 1 instead of true or false!!
result = result[0];
if (result.toString() == "true") {
result = interp.objectify("1");
} else {
if (result.toString() == "false") {
result = interp.objectify("0");
} else {
result = interp.objectify(result);
}
}
interp.setResult(result);
return retcode;
}
var str = args.splice(0, args.length).join(' ');
retcode = interp.eval_expression.evalExpression(args[1], result);
// for being compatible with Tcl we need to return 0 or 1 instead of true or false!!
if (result == "true") {
result = interp.objectify("1");
} else {
if (result == "false") {
result = interp.objectify("0");
} else {
result = interp.objectify(result);
}
}
interp.setResult(result);
return retcode;
});
/* ==================== command file join ===================================== */
interp.registerSubCommand("::file", "join", function (interp, args) {
args.shift();
this.requireMinArgc(args, 1, "file join", "");
var path = args.shift();
for (var i = 0; i < args.length; i++) {
path += "/"+args[i].toString();
}
//print("file join!"+path+"!");
return path;
});
/* ==================== command for ===================================== */
interp.registerCommand("::for", function (interp, args) {
this.requireExactArgc(args, 5, "for", "");
interp.eval_statement.eval(args[1].toString());
if(interp.code != this.OK) return;
var cond = "::set _ "+args[2].toString();
var step = args[3].toString();
var body = args[4].toString();
interp.inLoop = true;
interp.code = this.OK;
while (true) {
test = interp.statement_parser.objectify(interp.eval_statement.eval(cond));
if (!test.toBoolean()) break;
interp.eval_statement.eval(body);
var ic = interp.code; // tested after step command
interp.eval_statement.eval(step);
if(ic == this.BREAK) break;
if(ic == this.CONTINUE) continue;
}
interp.inLoop = false;
if(interp.code == this.BREAK || interp.code == this.CONTINUE)
interp.code = this.OK;
return "";
});
/* ==================== command foreach ===================================== */
interp.registerCommand("::foreach", function (interp, args) {
args.shift();
this.requireExactArgc(args, 3, "foreach", "");
var var_list = args.shift()
var_list = var_list.toList();
var list = args.shift();
list = list.toList();
var body = args.shift();
var res = "";
interp.eval_statement.inLoop = true;
interp.eval_statement.code = this.OK;
var i = 0;
while (i < list.length) {
for (var j = 0; j < var_list.length; j++) {
var var_name = var_list[j];
var var_value = "";
if (i < list.length) {
var_value = list[i];
i++;
}
interp.setVar(var_name,interp.statement_parser.objectify(var_value));
}
res = interp.eval_statement.eval(body);
if(interp.eval_statement.code == this.BREAK) {
break;
}
if(interp.eval_statement.code == this.RETURN) {
break;
}
if(interp.eval_statement.code == this.CONTINUE) {
continue;
}
}
interp.eval_statement.inLoop = false;
if(interp.eval_statement.code == this.BREAK || interp.eval_statement.code == this.CONTINUE) {
interp.eval_statement.code = this.OK;
}
return res;
});
/* ==================== command format ===================================== */
interp.registerCommand("::format", function (interp, args) {
this.requireMinArgc(args, 2, "format", "");
throw "format not yet implemented";
});
/* ==================== command gets ===================================== */
interp.registerCommand("::gets", function (interp, args) {
this.requireArgcRange(args, 2, 3, "gets", "");
var reply = prompt(args[1],"");
if(args[2] != null) {
interp.setVar(args[2],interp.statement_parser.objectify(reply));
return reply.length;
} else return reply;
});
/* ==================== command if ===================================== */
interp.registerCommand("::if", function (interp, args) {
var idx = 1;
var bool = new Array();
var retcode;
var current = 1;
var falsebody = 0;
var err = false;
var argc = args.length;
if (args.length >= 3) {
while (1) {
/* Far not enough arguments given! */
if (current >= argc) {
err = true;
break;
}
if ((retval = interp.eval_expression.getBoolFromExpr(args[current++], bool)) != interp.OK) {
return retval;
}
bool = bool[0];
/* There lacks something, isn't it? */
if (current >= argc) {
err = true;
break;
}
if (args[current] == "then") {
current++;
}
/* Tsk tsk, no then-clause? */
if (current >= argc) {
err = true;
break;
}
if (bool) {
return interp.eval_statement.evalObj(args[current]);
}
/* Ok: no else-clause follows */
if (++current >= argc) {
interp.setResult(intp.string_obj_type.newEmptyStringObj());
return interp.OK;
}
falsebody = current++;
if (args[falsebody] == "else") {
/* IIICKS - else-clause isn't last cmd? */
if (current != argc - 1) {
err = true;
break
}
return interp.eval_statement.evalObj(args[current]);
} else {
if (args[falsebody] == "elseif") {
/* Ok: elseif follows meaning all the stuff
* again (how boring...)
*/
continue;
} else {
/* OOPS - else-clause is not last cmd? */
if (falsebody != argc - 1) {
err = true;
break;
}
return interp.eval_statement.evalObj(args[falsebody]);
}
}
}
if (!err) {
return interp.OK;
}
}
interp.wrongNumArgs(1, args, "condition ?then? trueBody ?elseif ...? ?else? falseBody");
return interp.ERROR;
});
/* ==================== command incr ===================================== */
interp.registerCommand("::incr", function (interp, args) {
var wide_value;
var increment = 1;
var int_obj_ptr;
if (args.length != 2 && args.length != 3) {
interp.wrongNumArgs(1, args, "varName ?increment?");
return interp.ERROR;
}
if (args.length == 3) {
increment = new Array()
if (interp.int_obj_type.getWide(args[2], increment) != interp.OK) {
return interp.ERROR;
}
increment = increment[0];
}
int_obj_ptr = interp.variable_obj_type.getVariable(args[1], interp.FUNCTION_FLAGS_UNSHARED);
if (!int_obj_ptr) {
/* Set missing variable to 0 */
wide_value = 0;
} else {
wide_value = new Array();
if (interp.int_obj_type.getWide(int_obj_ptr, wide_value) != interp.OK) {
return interp.ERROR;
}
}
if (!int_obj_ptr || int_obj_ptr.isShared()) {
int_obj_ptr = interp.int_obj_type.newIntObj(wide_value + increment);
if (interp.variable_obj_type.setVariable(args[1], int_obj_ptr) != interp.OK) {
int_obj_ptr.freeNewObj();
return interp.ERROR;
}
} else {
/* Can do it the quick way */
int_obj_ptr.invalidateStringRep();
interp.default_obj_type.wideValue(int_obj_ptr) = wide_value + increment;
/* The following step is required in order to invalidate the
* string repr of "FOO" if the var name is on the form of "FOO(IDX)"
*/
if (args[1].obj_type != interp.variable_obj_type) {
/* Note that this can't fail since GetVariable already succeeded */
interp.variable_obj_type.setVariable(args[1], int_obj_ptr);
}
}
interp.setResult(int_obj_ptr);
return interp.OK;
});
/* ==================== command interp alias ===================================== */
interp.registerSubCommand("::interp", "alias", function (interp, args) {
args.shift();
this.requireMinArgc(args, 2, "interp alias", "");
var src_path = args.shift().toString();
var src_cmd = args.shift().toString();
if (args.length == 0) {
/* return the target_cmd */
if (src_path != "") {
throw "interp alias interp other current interp not yet implemented, src_path must be empty!";
}
if (src_path == "") {
src_path = interp;
}
var result_str = "";
for (var i = 0; i < interp.aliases.length; i++) {
var my_alias = interp.aliases[i];
if (my_alias.src_path == src_path) {
if (my_alias.src_cmd == src_cmd) {
result_str = my_alias.target_cmd;
break;
}
}
}
return result_str;
}
if (args.length == 1) {
/* seems to be the unset, so the argument has to be empty */
var arg3 = args.shift();
if (src_path != "") {
throw "interp alias interp other current interp not yet implemented, src_path must be empty!";
}
if (src_path == "") {
src_path = interp;
}
var my_aliases = new Array();;
var found = false;
for (var i = 0; i < interp.aliases.length; i++) {
var my_alias = interp.aliases[i];
if ((my_alias.src_path != src_path) || (my_alias.src_cmd != src_cmd)) {
my_aliases.push(my_alias);
} else {
found = true;
}
}
if (found) {
interp.aliases = my_aliases;
} else {
if (src_path == interp) {
src_path = "{}";
} else {
throw "multiple interps not yet implemented!"
}
throw "could not unset alias: \""+src_path+" "+src_cmd+"\" does not exist";
}
return;
}
if (args.length < 2) {
throw "usage: interp alias srcPath srcCmd targetPath targetCmd ?arg ...?";
}
var target_path = args.shift().toString();
var target_cmd = args.shift().toString();
if ((src_path != "") || (target_path != "")) {
throw "interp alias interp other current interp not yet implemented, src_path and target_path must be empty!";
}
if (src_path == "") {
src_path = interp;
}
if (target_path == "") {
target_path = interp;
}
interp.aliases.push(new R.InterpAlias(src_path, src_cmd, target_path, target_cmd, args));
});
/* ==================== command interp aliases ===================================== */
interp.registerSubCommand("::interp", "aliases", function (interp, args) {
args.shift();
this.requireArgcRange(args, 0, 1, "interp aliases", "");
var src_path = null;
if (args.length > 0) {
src_path = args.shift().toString();
if (src_path != "") {
throw "interp alias interp other current interp not yet implemented, src_path must be empty!";
}
if (src_path == "") {
src_path = interp;
}
}
var result_str = "";
var sep = "";
for (var i = 0; i < interp.aliases.length; i++) {
var my_alias = interp.aliases[i];
if ((src_path == null) || (my_alias.src_path == src_path)) {
result_str += sep+my_alias.src_cmd;
sep = " ";
}
}
return result_str;
});
/* ==================== command join ===================================== */
interp.registerCommand("::join", function (interp, args) {
args.shift();
this.requireArgcRange(args, 1, 2, "join", "");
var lst = args.shift();
var join_str = " ";
if (args.length > 0) {
join_str = args.shift().toString();
}
var result = lst.getList(lst);
result = result.join(join_str);
return result;
});
/* ==================== command jsdebug ===================================== */
interp.registerCommand("::jsdebug", function (interp, args) {
args.shift();
var type = args.shift().toString();
switch(type) {
case "eval2_cmd_debug":
interp.eval_statement.eval2_cmd_debug = 1;
break;
case "expr_debug":
interp.eval_statement.expr_debug = 1;
break;
case "eval2_parser_debug":
interp.eval_statement.eval2_parser_debug = 1;
break;
case "expr_parser_debug":
interp.eval_statement.expr_parser_debug = 1;
break;
case "class_command_debug":
this.class_command_debug = 1;
break;
default:
throw "bad type for js_debug: \""+type+"\"";
}
print("set: "+type+"!");
});
/* ==================== command jseval ===================================== */
interp.registerCommand("::jseval", function (interp, args) {
args.shift();
var result = eval(args[0].toString());
return result;
});
/* ==================== command puts ===================================== */
interp.registerCommand("::puts", function (interp, args) {
if (args.length != 2 && args.length != 3) {
interp.wrongNumArgs(1, args, "?-nonewline? string");
return interp.ERROR;
}
if (args.length == 3) {
if (args[1] != "-nonewline") {
interp.setResultString("The second argument must be -nonewline", -1);
return interp.ERROR;
} else {
print(args[2]);
}
} else {
print(args[1]);
}
return interp.OK;
});
/* ==================== command proc ===================================== */
interp.registerCommand("::proc", function (interp, args) {
if (args.length != 4 && args.length != 5) {
interp.wrongNumArgs(1, args, "name arglist ?statics? body");
return interp.ERROR;
}
if (args.length == 4) {
return interp.command_obj_type.createProcedure(args[1], args[2], null, args[3]);
} else {
return interp.command_obj_type.createProcedure(args[1], args[2], args[3], argvs[4]);
}
});
/* ==================== command regexp ===================================== */
interp.registerCommand("::regexp", function (interp, args) {
args.shift();
this.requireMinArgc(args, 2, "regexp", "");
var re = new RegExp(args.shift().toString());
var str = args.shift().toString();
var res = re.exec(str);
if (res == null) {
return false;
}
for (var i = 0; i < res.length; i++) {
if (args.length > i) {
interp.setVar(args[i].toString(), res[i].toString());
}
}
return true;
});
/* ==================== command regsub ===================================== */
interp.registerCommand("::regsub", function (interp, args) {
this.requireMinArgc(args, 2, "regsub", "");
throw "regsub not yet implemented";
});
/* ==================== command rename ===================================== */
interp.registerCommand("::rename", function (interp, args) {
this.requireExactArgc(args, 3, "rename", "");
interp.renameCommand(args[1], args[2]);
});
/* ==================== command return ===================================== */
interp.registerCommand("::return", function (interp, args) {
//print("return!"+args+"!");
/* strip of the command name at the beginning */
args.shift();
this.requireMinArgc(args, 0, "return", "");
var errorcode = null;
var errorinfo = null;
var level = null;
var options = null;
var allowed_codes = new Object();
allowed_codes["ok"] = 0;
allowed_codes["error"] = 1;
allowed_codes["return"] = 2;
allowed_codes["break"] = 3;
allowed_codes["continue"] = 4;
allowed_codes["0"] = 0;
allowed_codes["1"] = 1;
allowed_codes["2"] = 2;
allowed_codes["3"] = 3;
allowed_codes["4"] = 4;
var allowed_options = new Object();
allowed_options["-code"] = 1;
allowed_options["-errorcode"] = 1;
allowed_options["-errorinfo"] = 1;
allowed_options["-level"] = 1;
allowed_options["-options"] = 1;
interp.eval_statement.code = this.RETURN;
var r = "";
if (args.length == 1) {
/* seems to be a return value only */
r = args.shift();
}
var options = this.GetOptions(allowed_options, "::return", args);
for (i = 0; i < this.numOptionFields; i++) {
args.shift();
}
if (args.length > 1) {
throw "usage: return ?option value ...? ?result?"
}
if (args.length > 0) {
r = args.shift();
}
if (typeof options["-errorcode"] != "undefined") {
errorcode = options["-errorcode"] ;
throw "return -errorcode not yet implemented"
}
if (typeof options["-code"] != "undefined") {
code = options["-code"];
if (typeof allowed_codes[code] == "undefined") {
throw "bad code \""+code+"\" for -code option in return"
}
interp.eval_statement.code = allowed_codes[code];
if (interp.code == this.ERROR) {
this.SetErrorCode(interp, r);
throw r;
}
}
if (typeof options["-errorinfo"] != "undefined") {
errorinfo = options["-errorinfo"] ;
throw "return -errorinfo not yet implemented"
}
if (typeof options["-level"] != "undefined") {
level = options["-level"];
throw "return -level not yet implemented"
}
if (typeof options["-options"] != "undefined") {
options = options["-options"];
throw "return -options not yet implemented"
}
return r;
});
/* ==================== command scan ===================================== */
interp.registerCommand("::scan", function (interp, args) {
this.requireMinArgc(args, 2, "scan", "");
throw "scan not yet implemented";
});
/* ==================== command set ===================================== */
interp.registerCommand("::set", function (interp, args) {
//print("::set!"+args+"!");
if ((args.length != 2) && (args.length != 3)) {
interp.wrongNumArgs(interp, 1, args, "varName ?newValue?");
return interp.ERROR;
}
if (args.length == 2) {
var obj_ptr;
obj_ptr = interp.variable_obj_type.getVariable(args[1], interp.FUNCTION_FLAGS_LEAVE_ERR_MSG);
if (obj_ptr == null) {
return interp.ERROR;
}
interp.setResult(obj_ptr);
return interp.OK;
}
/* args.length == 3 */
if (interp.variable_obj_type.setVariable(args[1], args[2]) != interp.OK) {
return interp.ERROR;
}
interp.setResult(args[2]);
return interp.OK;
});
/* ==================== command source ===================================== */
interp.registerCommand("::source", function (interp, args) {
args.shift();
this.requireExactArgc(args, 1, "source", "");
var source_file = args.shift();
return this.Source(interp, source_file);
});
/* ==================== command switch ===================================== */
interp.registerCommand("::switch", function (interp, args) {
var usage = 'wrong # args: should be "switch ?-switch ...? string {?pattern body ...? ?default body?}';
if (args.length < 3) {
throw usage;
}
var body_start_idx = 1;
var have_exact_opt = 0;
var have_glob_opt = 0;
var have_regexp_opt = 0;
var have_nocase_opt = 0;
var have_matchvar_opt = 0;
var have_indexvar_opt = 0;
var match_var = null;
var index_var = null;
var switch_string;
var body;
var obj;
var text;
var parser;
var pattern;
var token;
var match_body = null;
var have_match;
var default_body = null;
var re = new RegExp("^[-].*");
if (args.length > 3) {
for (body_start_idx = 1; body_start_idx < args.length; body_start_idx++) {
my_arg = args[body_start_idx].toString();
if (my_arg.match(re)) {
if (my_arg == "-exact") {
if (have_exact_opt != 0) {
throw 'bad option "-exact": -exact option already found'
}
if (have_glob_opt != 0) {
throw 'bad option "-exact": -glob option already found'
}
if (have_regexp_opt != 0) {
throw 'bad option "-exact": -regexp option already found'
}
have_exact_opt = 1;
}
if (my_arg == "-glob") {
if (have_exact_opt != 0) {
throw 'bad option "-glob": -exact option already found'
}
if (have_regexp_opt != 0) {
throw 'bad option "-glob": -regexp option already found'
}
if (have_glob_opt != 0) {
throw 'bad option "-glob": -glob option already found'
}
have_glob_opt = 1;
}
if (my_arg == "-regexp") {
if (have_regexp_opt != 0) {
throw 'bad option "-regexp": -regexp option already found'
}
if (have_exact_opt != 0) {
throw 'bad option "-regexp": -exact option already found'
}
if (have_glob_opt != 0) {
throw 'bad option "-regexp": -glob option already found'
}
have_regexp_opt = 1;
}
if (my_arg == "-nocase") {
if (have_nocase_opt != 0) {
throw 'bad option "-nocase": -nocase option already found'
}
have_nocase_opt = 1;
}
if (my_arg == "-matchvar") {
if (have_matchvar_opt != 0) {
throw 'bad option "-matchvar": -matchvar option already found'
}
if (have_regexp_opt == 0) {
throw '-matchvar option requires -regexp option'
}
have_matchvar_opt = 1;
if (body_start_idx > args.length-1) {
throw usage;
}
body_start_idx++;
matchvar = args[body_start_idx].toString();
}
if (my_arg == "-indexvar") {
if (have_indexvar_opt != 0) {
throw 'bad option "-indexvar": -indexvar option already found'
}
if (have_regexp_opt == 0) {
throw '-indexvar option requires -regexp option'
}
have_indexvar_opt = 1;
if (body_start_idx > args.length-1) {
throw usage;
}
body_start_idx++;
indexvar = args[body_start_idx].toString();
}
if (my_arg == "--") {
body_start_idx++;
break;
}
} else {
break;
}
}
if (body_start_idx == args.length-1) {
throw usage;
}
}
if ((have_exact_opt == 0) && (have_glob_opt == 0) && (have_regexp_opt == 0)) {
have_exact_opt = 1;
}
switch_string = args[body_start_idx].toString();
body_start_idx++;
if (body_start_idx > args.length-1) {
throw usage;
}
/* if we have one argument left, it must be a list, otherwise we have the
* list elements in the args array
*/
if (body_start_idx == args.length-1) {
parser = new R.Parser(args[args.length-1].toString());
body = new Array();
while (parser.type != interp.TOKEN_EOF) {
token = parser.getToken();
if (parser.type == interp.TOKEN_EOF) {
break;
}
if ((parser.type == interp.TOKEN_EOL) || (parser.type == interp.TOKEN_WORD_SEP)) {
continue;
}
text = parser.getText();
if (parser.type == interp.TOKEN_VAR) {
text = "$"+text;
}
if (parser.type == interp.TOKEN_CMD) {
text = "["+text+"]";
}
body.push(interp.empty_obj.newRaplStringObject(text, -1));
}
} else {
body = new Array();
for (var i = body_start_idx; i < args.length; i++) {
var had_special = 0;
if (had_special == 0) {
text = args[i].toString();
}
body.push(interp.empty_obj.newRaplStringObject(text, -1));
}
}
have_match = 0;
for (var i = 0; i < body.length; i++) {
pattern = body[i];
//print("pattern!"+pattern+"!"+switch_string+"!");
if (i > body.length-1) {
throw "need body for pattern"
}
if (have_glob_opt) {
pattern = pattern.toString();
var pat2 = ""
for (var j = 0; j < pattern.length; j++) {
if (pattern.charAt(j) == "*") {
pat2 += "." + pattern.charAt(j);
} else {
pat2 += pattern.charAt(j);
}
}
pattern = pat2;
if (switch_string.match(new RegExp(pattern)) != null) {
have_match = 1;
}
}
if (have_regexp_opt) {
if (new RegExp(pattern).test(switch_string)) {
have_match = 1;
}
}
if (have_exact_opt) {
if (switch_string == pattern) {
have_match = 1;
}
}
if (body[i] == "default") {
if (i > body.length-1) {
throw "bad switch body"
}
default_body = body[i+1];
}
if (have_match) {
if (i > body.length-1) {
throw "bad switch body"
}
while (body[i+1] == "-") {
i++;
if (i > body.length-2) {
throw "bad switch body"
}
i++;
}
i++;
match_body = body[i];
break;
}
if ((i < body.length-1) && (body[i+1] == "-")) {
i++;
continue;
} else {
/* skip the body for the pattern */
i++;
}
}
if (have_match == 0) {
if (default_body == null) {
return "";
}
match_body = default_body;
}
//print("+++match_body!"+match_body+"!");
//interp.eval_statement.eval2_cmd_debug = 1;
result = interp.eval_statement.eval(match_body.toString());
//print("switch RET!"+typeof result+"!"+(result instanceof RaplObject)+"!"+result.object_oid+"!"+typeof result.value+"!"+result.value.object_oid+"!");
//print("RV!"+result.value.toString()+"!");
//print("RESULT!"+result+"!");
return result;
});
/* ==================== sec_msec ===================================== */
function sec_msec () {
var t = new Date();
return t.getSeconds()*1000 + t.getMilliseconds();
}
/* ==================== command time ===================================== */
interp.registerCommand("::time", function (interp, args) {
this.requireArgcRange(args, 2, 3, "time", "");
args.shift();
var code = args.shift();
if (args.length > 0) {
var n = args.shift();
} else {
var n = 1;
}
var t0 = sec_msec();
var xx = interp.string_obj_type.newStringObj("10", -1);
var yy = interp.string_obj_type.newStringObj("a", -1);
for(var i = 0; i < n; i++) {
interp.eval_statement.evalObj(code);
// interp.setVar("a", xx);
// interp.variable_obj_type.setVariable(yy, xx);
}
print("TT!"+((sec_msec()-t0)*1000/n + " microseconds per iteration")+"!");
return (sec_msec()-t0)*1000/n + " microseconds per iteration";
});
/* ==================== command uplevel ===================================== */
interp.registerCommand("::uplevel", function (interp, args) {
args.shift();
this.requireMinArgc(args, 1, "uplevel", "");
var arg1 = args.shift();
var have_level = 0;
var have_integer_level = 0;
if (this.isLevel.test(arg1)) {
have_level = 1;
if (this.isInteger.test(arg1)) {
have_integer_level = 1;
} else {
arg1 = arg1.substring(1);
}
} else {
have_level = 1;
have_integer_level = 1;
arg1 = "1";
}
if (interp.eval_statement.level < arg1) {
throw "bad level \""+arg1+"\" interp level: "+interp.eval_statement.level;
}
for (var i = arg1; i > 0; i--) {
interp.uplevel_dist++;
}
var my_obj = interp.empty_obj.newRaplStringObject("", -1);
var my_args;
if (args.length == 1) {
var lst = my_obj.getList(args);
my_args = lst.getString();
} else {
my_args = args.getString();
}
//print("UPLEVEL!"+arg1+"!"+args+"!"+my_args+"!");
var res = interp.eval_statement.eval(my_args);
for (var i = arg1; i > 0; i--) {
interp.uplevel_dist--;
}
return interp.statement_parser.objectify(res);
});
/* ==================== command upvar ===================================== */
interp.registerCommand("::upvar", function (interp, args) {
//print("UPVAR!"+args+"!");
args.shift();
this.requireMinArgc(args, 2, "upvar", "");
var arg1 = args[0];
var have_level = 0;
var have_integer_level = 0;
if (this.isLevel.test((arg1))) {
have_level = 1;
args.shift();
if (this.isInteger.test(arg1)) {
have_integer_level = 1;
} else {
arg1 = arg1.substring(1);
}
} else {
have_level = 1;
have_integer_level = 1;
arg1 = "1";
}
arg1 = parseInt(arg1);
interp.upvar_dist = parseInt(arg1);
interp.in_upvar = 1;
if (interp.eval_statement.level < arg1) {
throw "bad level \""+arg1+"\" interp level: "+interp.eval_statement.level;
}
var my_flags = 0;
while (args.length > 0) {
if (args.length == 1) {
throw "must be an even number of references"
}
var create = 1;
var to_var = args.shift().toString();
var my_var = args.shift().toString();
//print("upvar to_var!"+to_var+"!my_var!"+my_var+"!arg1!"+arg1+"!intplv!"+interp.eval_statement.level+"!");
interp.eval_statement.level -= arg1;
var var_to_obj = interp.root_namespace.lookupVariableEx(interp, to_var, this.VAR_LOOKUP_LEAVE_ERR_MSG, "access", 0, 0);
interp.eval_statement.level += arg1;
if (var_to_obj == null) {
interp.code = this.ERROR;
return "";
}
var my_var_obj = interp.root_namespace.lookupSimpleVariable(interp, my_var, my_flags|this.VAR_LOOKUP_AVOID_RESOLVERS, create);
if (my_var_obj == null) {
this.VarErrMsg(interp, my_var, null, "create", interp.current_namespace.err_msg, -1);
this.SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME", my_name);
interp.code = this.ERROR;
return "";
}
if (var_to_obj == my_var_obj) {
this.SetResult(interp, "can't upvar from variable to itself");
this.SetErrorCode(interp, "TCL", "UPVAR", "SELF");
interp.code = this.ERROR;
return "";
}
my_var_obj.linkVar(var_to_obj);
}
interp.in_upvar = 0;
interp.code = this.OK;
return "";
});
/* ==================== command unset ===================================== */
interp.registerCommand("::unset", function (interp, args) {
this.requireExactArgc(args, 2, "unset", "");
interp.setVar(args[1], null);
});
/* ==================== command while ===================================== */
interp.registerCommand("::while", function (interp, args) {
args.shift();
this.requireExactArgc(args, 2, "while", "");
var cond = args.shift();
var body = args.shift();
var res = "";
interp.inLoop = true;
interp.code = this.OK;
while (true) {
var my_cond = interp.statement_parser.parse2ExprTree(cond.toString());
test = interp.statement_parser.objectify(interp.eval_statement.evalExprSubTree(my_cond, null, 0));
interp.eval_statement.eval("::set _ "+test.toString());
if (!test.toBoolean()){
break;
}
res = interp.eval_statement.eval(body);
if(interp.code == this.CONTINUE) {
continue;
}
if(interp.code != this.OK) {
break;
}
}
interp.inLoop = false;
if(interp.code == this.BREAK || interp.code == this.CONTINUE) {
interp.code = this.OK;
}
return interp.statement_parser.objectify(res);
});
/* ==================== command variable ===================================== */
interp.registerCommand("::variable", function (interp, args) {
args.shift();
this.requireArgcRange(args, 1, 2, "variable", "");
var create_it = 1;
var var_name = args.shift().toString();
var var_obj = interp.current_namespace.lookupVariableEx(interp, var_name, this.NAMESPACE_LOOKUP_NAMESPACE_ONLY, "", create_it, create_it);
if (args.length > 0) {
var val = args.shift().toString();
var_obj.setValue(val, null);
}
interp.eval_statement.code = this.OK;
return interp.statement_parser.objectify("");
});
/* ==================== command native ===================================== */
// native cmdname {function(interp, args) {...}}
interp.registerCommand("::native", function (interp, args) {
this.requireExactArgc(args, 3, "native", "");
var cmd = args[1].toList();
var func = eval(args[2].toString());
//print("in: "+args[2].toString()+", func: "+ func);
if (cmd.length == 1) {
interp.registerCommand(cmd[0].toString(), func);
return;
}
base = cmd[0].toString();
cmd.shift();
interp.registerSubCommand(base, cmd.join(" "), eval(args[2].toString()));
return;
});
/* ==================== command showLevelInfo ===================================== */
interp.registerCommand("::showLevelInfo", function (interp, args) {
args.shift();
this.requireMinArgc(args, 1, "showLevelInfo", "");
var txt = "";
if (args.length > 0) {
txt = args.shift();
}
for (var i = interp.eval_statement.level-1; i >= 0; i--) {
print("LEVEL_INFO!"+i+"!"+txt+"!"+interp.level_infos[i]+"!");
}
});
}
R.registerCmds = registerCmds;
}, "0.0.1", {});