Check-in [3d61c6fe53]
Overview
SHA1:3d61c6fe53bb2dc412187dd18ec9a28fdbe70911
Date: 2013-11-20 20:58:57
User: suchenwi
Comment:added [catch]
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | folders | manifest
Tags And Properties
Context
2013-11-23
21:28
[4f3db7f982] added several file commands, fixed backslash substitutions (user: suchenwi, tags: trunk)
2013-11-20
20:58
[3d61c6fe53] added [catch] (user: suchenwi, tags: trunk)
2013-11-19
20:21
[c9965b6d9d] now passing all 105 tests (user: suchenwi, tags: trunk)
Changes

Modified tcl053.js from [7793cfca8e] to [368d355e33].

    98     98       }
    99     99       this.eval = function (code) {
   100    100         try {
   101    101   	return this.eval2(code);
   102    102         } catch (e) {
   103    103   	var msg = code.substr(0,128);
   104    104   	if(msg.length >= 125) msg += "...";
   105         -	puts(e);
   106    105   	var msg = e+'\n        while executing\n"'+msg+'"';
   107    106   	for(var i = this.level; i > 0; i--)
   108    107   	  msg += '\n        invoked from within\n"'+this.levelcall[i]+'"'
   109    108   	this.setVar("::errorInfo", msg);
          109  +	throw e;
   110    110         }
   111    111       }
   112    112       this.eval2 = function(code) {
   113    113         this.code  = this.OK;
   114    114         var parser = new TclParser(code);
   115    115         var args   = [];
   116    116         var first  = true;
................................................................................
   179    179   	for (var i = 2; i < args.length; i++) str += args[i].toString();
   180    180           interp.setVar(vname, str);
   181    181           return str;
   182    182         });
   183    183       this.registerCommand("break", function (interp, args) {
   184    184           interp.code = interp.BRK;
   185    185           return;
          186  +      });
          187  +    this.registerCommand("catch", function (interp, args) {
          188  +	this.arity(args, 2, 3);
          189  +	var code = args[1].toString();
          190  +	var res;
          191  +	var rc   = 0;
          192  +	try {res = interp.eval(code);} catch(e) {res = e; rc = 1;}
          193  +	if(args.length == 3) interp.setVar(args[2], res);
          194  +	return rc;
   186    195         });
   187    196       this.registerCommand("cd", function (interp, args) {
   188    197   	this.arity(args, 1, 2);
   189    198   	var dir = process.env.HOME;
   190    199   	if (args.length == 2) dir = args[1].toString();
   191    200   	process.chdir(dir);
   192    201   	return;
................................................................................
   674    683           var r = args[1];
   675    684           interp.code = interp.RET;
   676    685           return r;
   677    686       });
   678    687       this.registerCommand("set", function (interp, args) {
   679    688           this.arity(args, 2, 3);
   680    689           var name = args[1];
   681         -        if (args.length == 3) interp.setVar(name, args[2]);
          690  +	var val  = eval(args[2]);
          691  +        if (args.length == 3) interp.setVar(name, val);
   682    692           return interp.getVar(name);
   683    693       });
   684    694       this.registerCommand("source", function (interp, args) {
   685    695           this.arity(args, 2);
   686    696           interp.script = args[1].toString();
   687    697           try {
   688    698   	  var data = fs.readFileSync(interp.script).toString();
   689    699           } catch(e) {
   690         -	  throw 'couldn\' read file "'+interp.script+'": no such file or directory';}
          700  +	  throw 'couldn\' read file "'+interp.script
          701  +	    +'": no such file or directory';}
   691    702   	var res    = interp.eval(data);
   692    703   	interp.script = "";
   693    704   	return res;
   694    705         });
   695    706       this.registerCommand("split", function (interp, args) {
   696    707           this.arity(args, 2, 3);
   697    708           var str = args[1].toString();
   698         -        var sep = " ";
   699         -        if (args.length == 3) sep = args[2].toString();
   700         -	var res = [], e;
          709  +        var sep = (args.length == 3)? args[2].toString() : " ";
          710  +	var res = [], element;
   701    711           var tmp = str.split(sep);
   702    712   	for(var i in tmp) {
   703         -	  e = tmp[i];
   704         -	  if(e == "") e = "{}";
   705         -	  res.push(e);
          713  +	  element = tmp[i];
          714  +	  if(element == "") element = "{}";
          715  +	  res.push(element);
   706    716   	}
   707    717   	return res.join(" ");
   708    718         });
   709    719       this.registerSubCommand("string", "compare", function (interp, args) {
   710    720           this.arity(args, 3);
   711    721   	var a = args[1].toString();
   712    722   	var b = args[2].toString();
................................................................................
   816    826   	  return;
   817    827           }
   818    828           base = cmd[0].toString();
   819    829           cmd.shift();
   820    830           interp.registerSubCommand(base, cmd.join(" "), eval(args[2].toString()));
   821    831           return;
   822    832         });
   823         -    this.math = function (name, a, b) {
   824         -      switch (name) {
   825         -      case "+":  return a + b;
   826         -      case "-":  return a - b;
   827         -      case "*":  return a * b;
   828         -      case "/":  return a / b;
   829         -      case "%":  return a % b;
   830         -      case "<":  return a < b? "1":"0";
   831         -      case ">":  return a > b? "1":"0";
   832         -      case "==": return a == b? "1":"0";
   833         -      case "!=": return a != b? "1":"0";
   834         -      default:   throw "Unknown operator: '"+name+"'";
   835         -      }
   836         -    }
   837         -    var ops = ["+","-","*","/","%","<",">","==","!="];
   838         -    for (var i in ops)
   839         -      this.registerCommand(ops[i],function (interp, args) {
   840         -	  this.arity(args, 3);
   841         -	  var name = args[0].toString();
   842         -	  var a    = interp.objectify(args[1]);
   843         -	  var b    = interp.objectify(args[2]);
   844         -	  if (name == '==') 
   845         -	    return new TclObject(a.toString() == b.toString()?"1":"0","BOOL");
   846         -	  if (name == '!=') 
   847         -	    return new TclObject(a.toString() != b.toString()?"1":"0","BOOL");
   848         -	  
   849         -	  var x = a.getNumber();
   850         -	  var y = b.getNumber();
   851         -	  if (a.isInteger() && b.isInteger())
   852         -	    return new TclObject(interp.math(name, x, y),"INTEGER");
   853         -	  if (a.isReal() && b.isReal())
   854         -	    return new TclObject(interp.math(name, x, y),"REAL");
   855         -	  return new TclObject(interp.math(name, args[1].toString(), 
   856         -					   args[2].toString()));
   857         -        });
   858    833       this.mkList = function(x) {
   859    834         var list = [];
   860    835         for (var name in x) {list.push(name);}
   861    836         return list;
   862    837       }
   863    838       this.objectify = function (text) {
   864    839         if (text == null) text = "";
................................................................................
  1150   1125     this.SEP = 0;
  1151   1126     this.STR = 1;
  1152   1127     this.EOL = 2;
  1153   1128     this.EOF = 3;
  1154   1129     this.ESC = 4;
  1155   1130     this.CMD = 5;
  1156   1131     this.VAR = 6;
  1157         -  this.text  = text;
  1158         -  this.start = 0;
  1159         -  this.end   = 0;
         1132  +  this.text        = text;
         1133  +  this.start       = 0;
         1134  +  this.end         = 0;
  1160   1135     this.insidequote = false;
  1161         -  this.index = 0;
  1162         -  this.len = text.length;
  1163         -  this.type = this.EOL;
  1164         -  this.cur = this.text.charAt(0);
  1165         -  this.getText = function () {
         1136  +  this.index       = 0;
         1137  +  this.len         = text.length;
         1138  +  this.type        = this.EOL;
         1139  +  this.cur         = this.text.charAt(0);
         1140  +  this.getText     = function () {
  1166   1141       return this.text.substring(this.start,this.end+1);
  1167   1142     }
  1168   1143     this.parseString = function () {
  1169   1144       var newword = (this.type==this.SEP ||
  1170   1145   		   this.type == this.EOL || this.type == this.STR);
  1171   1146       if (newword && this.cur == "{") return this.parseBrace();
  1172   1147       else if (newword && this.cur == '"') {
................................................................................
  1176   1151       this.start = this.index;
  1177   1152       while (true) {
  1178   1153         if (this.len == 0) {
  1179   1154   	this.end = this.index-1;
  1180   1155   	this.type = this.ESC;
  1181   1156   	return this.OK;
  1182   1157         }
  1183         -      if (this.cur == "\\") {
  1184         -	//if (this.len >= 2) this.feedSequence();
  1185         -      }
  1186         -      else if ("$[ \t\n\r;".indexOf(this.cur)>=0) {
         1158  +      /*if (this.cur == "\\") { // works not :(
         1159  +	if (this.len >= 2) this.feedSequence();
         1160  +	}
         1161  +	else*/ if ("$[ \t\n\r;".indexOf(this.cur)>=0) {
  1187   1162   	if ("$[".indexOf(this.cur)>=0 || !this.insidequote) {
  1188   1163   	  this.end = this.index-1;
  1189   1164   	  this.type = this.ESC;
  1190   1165   	  return this.OK;
  1191   1166   	}
  1192   1167         }
  1193   1168         else if (this.cur == '"' && this.insidequote) {
  1194         -	this.end    = this.index-1;
         1169  +	this.end  = this.index-1;
  1195   1170   	this.type = this.ESC;
  1196   1171   	this.feedchar();
  1197   1172   	this.insidequote = false;
  1198   1173   	return this.OK;
  1199   1174         }
  1200   1175         this.feedchar();
  1201   1176       }
................................................................................
  1207   1182       while (true) {
  1208   1183         if (this.len == 0) {
  1209   1184   	this.end  = this.index;
  1210   1185   	this.type = this.EOL;
  1211   1186   	return;
  1212   1187         }
  1213   1188         switch (this.cur) {
  1214         -      case "\\":
         1189  +	/*case "\\":
  1215   1190   	if (this.len >= 2) this.feedSequence();
  1216         -	break;
         1191  +	break;*/
  1217   1192         case " ": case "\t": case "\n": case "\r":
  1218   1193   	if (level > 0) break;
  1219   1194   	this.end  = this.index - 1;
  1220   1195   	this.type = this.SEP;
  1221   1196   	this.feedchar();
  1222   1197   	return;
  1223   1198         case '{': level++; break;
................................................................................
  1250   1225       while (true) {
  1251   1226         if (this.len == 0) break;
  1252   1227         if (this.cur == "[" && blevel == 0)
  1253   1228   	level++;
  1254   1229         else if (this.cur == "]" && blevel == 0) {
  1255   1230   	level--;
  1256   1231   	if (level == 0) break;
  1257         -      } else if (this.cur == "\\") {
  1258         -	this.feedSequence();
         1232  +	//} else if (this.cur == "\\") {
         1233  +	//this.feedSequence();
  1259   1234         } else if (this.cur == "{") {
  1260   1235   	blevel++;
  1261   1236         } else if (this.cur == "}") {
  1262   1237   	if (blevel != 0) blevel--;
  1263   1238         }
  1264   1239         this.feedchar();
  1265   1240       }
................................................................................
  1279   1254       this.setPos(this.end+1);
  1280   1255       return this.OK;
  1281   1256     }
  1282   1257     this.parseBrace = function () {
  1283   1258       var level = 1;
  1284   1259       this.feedcharstart();
  1285   1260       while (true) {
  1286         -      if (this.len > 1 && this.cur == "\\") {
         1261  +      /*if (this.len > 1 && this.cur == "\\") {
  1287   1262   	this.feedSequence();
  1288         -      } else if (this.len == 0 || this.cur == "}") {
         1263  +	} else*/
         1264  +      if (this.len == 0 || this.cur == "}") {
  1289   1265   	level--;
  1290   1266   	if (level == 0 || this.len == 0) {
  1291   1267   	  this.end = this.index-1;
  1292   1268   	  if (this.len > 0) this.feedchar();
  1293   1269   	  this.type = this.STR;
  1294   1270   	  return this.OK;
  1295   1271   	}
................................................................................
  1323   1299         }
  1324   1300         if (this.cur == "#" && this.type == this.EOL) {
  1325   1301   	this.parseComment();
  1326   1302   	continue;
  1327   1303         }
  1328   1304         return this.parseString();
  1329   1305       }
         1306  +    puts("unreachable?");
  1330   1307       return this.OK; // unreached
  1331   1308     }
  1332   1309     this.feedSequence = function () {
  1333   1310       //return;
  1334   1311       if (this.cur != "\\") throw "Invalid escape sequence";
  1335   1312       var cur = this.steal(1);
  1336         -    //puts("enter feedSequence, text: "+this.text+" cur: "+cur);
         1313  +    puts("enter feedSequence, text: "+this.text+" cur: "+cur);
  1337   1314       var specials = {};
  1338   1315       specials.a = "\a";
  1339   1316       specials.b = "\b";
  1340   1317       specials.f = "\f";
  1341   1318       specials.n = "\n";
  1342   1319       specials.r = "\r";
  1343   1320       specials.t = "\t";
................................................................................
  1346   1323       case 'u':
  1347   1324         var hex = this.steal(4);
  1348   1325         if (hex != Tcl.isHexSeq.exec(hex))
  1349   1326   	throw "Invalid unicode escape sequence: "+hex;
  1350   1327         cur = String.fromCharCode(parseInt(hex,16));
  1351   1328         break;
  1352   1329       case 'x':
  1353         -      var hex = this.steal(2);
  1354         -      puts("enter case x, hex: '"+hex+"'");
         1330  +      /*
         1331  +      var hex = cur; //this.steal(2);
         1332  +      puts("enter case x, hex: '"+hex+"' cur: '"+cur+'"');
  1355   1333         if (hex != Tcl.isHexSeq.exec(hex))
  1356   1334   	throw "Invalid unicode escape sequence: "+hex;
  1357   1335         cur = String.fromCharCode(parseInt(hex,16));
  1358   1336         //puts("hex: "+hex.toString()+" cur: "+cur);
         1337  +      */
  1359   1338         break;
  1360   1339       case "a": case "b": case "f": case "n":
  1361   1340       case "r": case "t": case "v":
  1362   1341         cur = specials[cur];
  1363   1342         break;
  1364   1343       default:
  1365   1344         if ("0123456789".indexOf(cur) >= 0) {

Modified test_tcljs.tcl from [c15ca09a61] to [da8fb3dc27].

    27     27   e.g. {append x bar}     -> foobar
    28     28   
    29     29   proc sum args {expr [join $args +]}
    30     30   e.g. {sum 1 2 3} -> 6
    31     31   #native sum2 {function (interp, args) {return eval(args.join("+"));}}
    32     32   #e.g. {sum2 2 3 4} -> 9
    33     33   
           34  +e.g. {catch foo msg} -> 1
           35  +e.g. {set msg} -> {invalid command name "foo"}
           36  +e.g. {catch {expr 7*6}} -> 0
           37  +e.g. {catch {expr 7*6} msg; set msg} -> 42
           38  +
    34     39   e.g. {concat {a b} {c d}} -> {a b c d}
    35     40   
    36     41   e.g. {set d [dict create a 1 b 2 c 3]} -> {a 1 b 2 c 3}
    37     42   e.g. {dict exists $d c} -> 1
    38     43   e.g. {dict exists $d x} -> 0
    39     44   e.g. {dict get $d b}    -> 2
    40     45   e.g. {dict keys $d}     -> {a b c}
................................................................................
    70     75   e.g. {set x 0xFF; expr {$x+0}} -> 255
    71     76   e.g. {expr 0376}               -> 254
    72     77   e.g. {set x 0375; expr $x}     -> 253
    73     78   e.g. {expr {$x}}   -> 253
    74     79   e.g. {expr 6 * 7}  -> 42
    75     80   e.g. {expr 1 == 2} -> 0
    76     81   e.g. {expr 1 < 2}  -> 1
           82  +e.g. {expr 1 > 2}  -> 0
           83  +e.g. {expr 1 != 2} -> 1
           84  +e.g. {expr 1 <= 2} -> 1
           85  +e.g. {expr 1 >= 2} -> 0
    77     86   e.g. {expr !0}     -> 1
    78     87   e.g. {expr !42}    -> 0
    79     88   e.g. {set x 3}     -> 3
    80     89   e.g. {expr $x+1}   -> 4
    81     90   e.g. {expr {$x+1}} -> 4
    82     91   e.g. {set x a; set y b; expr {$x == $y}} -> 0
    83     92   e.g. {expr {$x != $y}} -> 1
           93  +e.g. {expr 43 % 5}     -> 3 
           94  +e.g. {set x -44; expr {-$x}} -> 44
           95  +e.g. {expr 1<<3} -> 8
    84     96   
    85     97   set forres ""
    86     98   e.g. {for {set i 0} {$i < 5} {incr i} {append forres $i}; set forres} -> 01234
    87     99   e.g. {foreach i {a b c d e} {append foreachres $i}; set foreachres}   -> abcde
    88    100   
    89    101   e.g. {format %x 255} -> ff
    90    102   e.g. {format %X 254} -> FE
................................................................................
   121    133   e.g. {llength $x}         -> 4
   122    134   e.g. {lindex $x 2}        -> c
   123    135   e.g. {lrange $x 1 2}      -> {b c}
   124    136   e.g. {lreverse {a b c}}   -> {c b a}
   125    137   e.g. {lsearch $x b}       -> 1
   126    138   e.g. {lsearch $x y}       -> -1
   127    139   e.g. {lsort {z x y}}      -> {x y z}
          140  +
          141  +e.g. {proc f args {expr [join $args +]}} -> ""
          142  +e.g. {f 1}     -> 1
          143  +e.g. {f 1 2}   -> 3
          144  +e.g. {f 1 2 3} -> 6
   128    145   
   129    146   e.g. {regexp {X[ABC]Y} XAY}    -> 1
   130    147   e.g. {regexp {X[ABC]Y} XDY}    -> 0
   131    148   e.g. {regsub {[A-C]+} uBAAD x} -> uxD 
   132    149   
   133    150   e.g. {split "a b  c d"}     -> {a b {} c d}
   134    151   e.g. {split " a b  c d"}     -> {{} a b {} c d}
................................................................................
   146    163   e.g. {string length ""}       -> 0
   147    164   e.g. {string length foo}      -> 3
   148    165   e.g. {string range hello 1 3} -> ell
   149    166   e.g. {string tolower Tcl}     -> tcl
   150    167   e.g. {string toupper Tcl}     -> TCL
   151    168   e.g. {string trim " foo "}    -> foo
   152    169   
   153         -#e.g. {set x a.\x62.c} -> a.b.c ;# severe malfunction, breaks test suite operation :(
          170  +e.g. {set x a.\x62.c} -> a.b.c ;# severe malfunction, breaks test suite operation :(
   154    171   
   155    172   puts "total $total tests, passed $passed, failed $fail"
   156    173   #----------- clean up variables used in tests
   157    174   foreach var [info vars] {
   158    175       set pos [lsearch $vars $var] ;# expr can't substitute commands yet
   159    176       set neq [string compare $var vars]
   160    177       if {$var != "vars" && $pos < 0} {unset $var}
   161    178   }
   162    179   unset vars var pos neq
   163    180   puts "vars now: [info vars]"
   164    181   puts "[llength [info commands]] commands implemented"