commit 676ee856da06028ea3d77722dcc88594178844ea
parent 6898dc118663b89e6b74306502fe4c7d0817a9c2
Author: tomas <tomas@logand.com>
Date:   Sat, 23 Jan 2010 15:13:01 +0100
changes from 2009-07-14
Diffstat:
| M | wps.js | | | 182 | ++++++++++++++++++++++++++++++++----------------------------------------------- | 
| M | wps.wps | | | 68 | ++++++++++++++++++++++++++++++++++++++++++++------------------------ | 
2 files changed, 117 insertions(+), 133 deletions(-)
diff --git a/wps.js b/wps.js
@@ -37,16 +37,24 @@ function inDs(Ds, K) {
   return false;
 }
 
-function ps0(L, Os, Ds, Es) { // TODO Nd name dict name=>sym?
-  var N = L.length;
-  var I = 0;
-
-  // TODO white space ffeed + null???
-  function member(C, L) {return 0 <= L.indexOf(C);}
-  function peek() {return I < N && L[I];}
-  function xchar() {return I < N && L[I++];}
-  function skip() {while(I < N && member(L[I], " \t\n")) I++;}
+function member(C, L) {
+  return 0 <= L.indexOf(C);
+}
 
+function PsParser() {
+  var Self = this;
+  function init(L) {
+    Self.L = L;
+    Self.N = L.length;
+    Self.I = 0;
+    Self.D = 0;
+  }
+  function peek() {return Self.I < Self.N && Self.L[Self.I];}
+  function xchar() {return Self.I < Self.N && Self.L[Self.I++];}
+  function skip() { // TODO white space ffeed + null???
+    while(Self.I < Self.N && member(Self.L[Self.I], " \t\n"))
+      Self.I++;
+  }
   function comment() {
     while("%" == peek()) {
       while(peek() && "\n" != peek())
@@ -54,7 +62,6 @@ function ps0(L, Os, Ds, Es) { // TODO Nd name dict name=>sym?
       skip();
     }
   }
-
   function text() {
     // TODO hex text in <>
     // TODO ASCII base-85 <~ and ~>
@@ -90,7 +97,6 @@ function ps0(L, Os, Ds, Es) { // TODO Nd name dict name=>sym?
     }
     return L.join("");
   }
-
   function symbol() {
     // TODO 1e10 1E-5 real numbers
     // TODO radix numbers 8#1777 16#FFFE 2#1000
@@ -111,9 +117,6 @@ function ps0(L, Os, Ds, Es) { // TODO Nd name dict name=>sym?
     if(1 == L.length && member(L, "+-.")) N = false;
     return N ? (F ? parseFloat(L) : parseInt(L, 10)) : new Symbol(L);
   }
-
-  var D = 0;
-
   function token() {
     skip();
     switch(peek()) { // TODO read dict in <> <~~> <<>> immediate literal //
@@ -121,8 +124,8 @@ function ps0(L, Os, Ds, Es) { // TODO Nd name dict name=>sym?
       case "%": return comment();
       case "[": return new Symbol(xchar());
       case "]": return new Symbol(xchar());
-      case "{": D++; return new Symbol(xchar());
-      case "}": D--; return new Symbol(xchar());
+      case "{": Self.D++; return new Symbol(xchar());
+      case "}": Self.D--; return new Symbol(xchar());
       case "/": xchar(); var X = symbol(); return quote(X);
       case "(": return text();
       case "<":
@@ -138,38 +141,34 @@ function ps0(L, Os, Ds, Es) { // TODO Nd name dict name=>sym?
       default: return symbol();
     }
   }
+  PsParser.prototype.init = init;
+  PsParser.prototype.peek = peek;
+  PsParser.prototype.token = token;
+  return this;
+}
 
-  //function Xexec() {Es.push([false, Os.pop()]);};
-
+function Ps0(Os, Ds, Es) {
   function run(X, Z) {
     if(isSymbol(X) && !isQuoted(X)) { // executable name
       var K = symbolName(X);
       var D = inDs(Ds, K);
-      if(!D) {
+      if(!D)
         throw "bind error '" + K + "'";
-      }
       Es.push([false, D[K]]);
-      //if(V !== undefined) Es.push([false, V, Xexec]);
-      //else throw "Unknown operator '" + K + "' " + V;
     } else if(Z && isArray(X) && isQuoted(X)) { // proc from Es
       if(0 < X.length) {
         var F = X[0];
         var R = quote(X.slice(1));
-        //if(0 < R.length) Es.push([false, R, Xexec]);
         if(0 < R.length) Es.push([false, R]);
-        //run(F, true);
         run(F, false);
-        //Es.push([false, F]);
       }
     } else if("function" == typeof X) X(); // operator
     else Os.push(X);
   }
-
   function exec() {
     var X = Os.pop();
     run(X, false);
   }
-
   function step() {
     var C = Es.pop();
     var L = C.shift(); // TODO use for 'exit'
@@ -178,13 +177,14 @@ function ps0(L, Os, Ds, Es) { // TODO Nd name dict name=>sym?
       Os.push(C[I]);
     run(X, true);
   }
-
-  function parse() {
-    while(peek()) {
-      var T = token();
+  var PsP = new PsParser;
+  function parse(L) {
+    PsP.init(L);
+    while(PsP.peek()) {
+      var T = PsP.token();
       if(T || T === 0) {
         Os.push(T);
-        if(D <= 0 || isSymbol(T) &&
+        if(PsP.D <= 0 || isSymbol(T) &&
            (member(symbolName(T), "[]{}") ||
             "<<" == symbolName(T) || ">>" == symbolName(T))) {
           exec();
@@ -195,15 +195,19 @@ function ps0(L, Os, Ds, Es) { // TODO Nd name dict name=>sym?
     }
     return Os;
   }
-
-  return parse();
+  Ps0.prototype.run = run;
+  Ps0.prototype.exec = exec;
+  Ps0.prototype.step = step;
+  Ps0.prototype.parse = parse;
+  return this;
 }
 
-function wps(E, T) {
+function Wps() {
   var Os = [];
   var Sd = {};
   var Ds = [Sd];
   var Es = [];
+  var Ps = new Ps0(Os, Ds, Es);
 
   // trivial
   Sd[".true"] = function() {Os.push(true);};
@@ -293,8 +297,6 @@ function wps(E, T) {
   Sd["eq"] = function() {var Y = Os.pop(); var X = Os.pop(); Os.push(X == Y);};
   Sd["lt"] = function() {var Y = Os.pop(); var X = Os.pop(); Os.push(X < Y);};
 
-  //function Xexec() {Es.push([false, Os.pop()]);};
-  //Sd["exec"] = Xexec;
   Sd["exec"] = function() {Es.push([false, Os.pop()]);};
 
   Sd["ifelse"] = function() {
@@ -332,7 +334,7 @@ function wps(E, T) {
   Sd["get"] = function() { // dict key -- any
     var K = Os.pop();
     var D = Os.pop();
-    // TODO other datatypes http://www.capcode.de/help/get
+    // TODO other datatypes
     if(isSymbol(K)) Os.push(D[symbolName(K)]);
     else Os.push(D[K]);
   };
@@ -340,7 +342,7 @@ function wps(E, T) {
     var V = Os.pop();
     var K = Os.pop();
     var D = Os.pop();
-    // TODO other datatypes http://www.capcode.de/help/put
+    // TODO other datatypes
     if(isSymbol(K)) D[symbolName(K)] = V;
     else D[K] = V;
   };
@@ -378,8 +380,24 @@ function wps(E, T) {
     // savetype
   };
 
-  Sd["restore"] = function() {Os.pop();}; // TODO
-  Sd["save"] = function() {Os.push([]);}; // TODO
+  Sd["save"] = function() {
+    var X = Ds.slice();
+    for(var I = 0; I < X.length; I++) {
+      var A = X[I];
+      var B = {};
+      for(var J in A)
+        B[J] = A[J];
+      X[I] = B;
+    }
+    Os.push(X);
+  };
+  Sd["restore"] = function() {
+    var X = Os.pop();
+    while(0 < Ds.length)
+      Ds.pop();
+    while(0 < X.length)
+      Ds.unshift(X.pop());
+  };
 
   var Sb = true;
   Sd[".strictBind"] = function() {Sb = true === Os.pop();}; // bool --
@@ -409,30 +427,6 @@ function wps(E, T) {
     return X;
   }
 
-//   function bind(X) {
-//     if(isSymbol(X) && !isQuoted(X)) {
-//       var K = symbolName(X);
-//       var D = inDs(Ds, K);
-//       return !D ? X : bind(D[K]); // TODO .strictBind ???
-// //       if(!D) {
-// //         throw "bind error '" + K + "'";
-// //       }
-// //       return bind(D[K]);
-//     } else if(isArray(X) && isQuoted(X)) {
-//       var N = X.length;
-//       var A = [];
-//       for(var I = 0; I < N; I++) {
-//         var Xi = X[I];
-//         var Xb = bind(Xi);
-//         if(isArray(Xi))
-//           A = A.concat(isQuoted(Xi) ? quote([Xb]) : [Xb]);
-//         else
-//           A = A.concat(Xb);
-//       }
-//       return quote(A);
-//     }
-//     return X;
-//   }
   //////////////////////////////////////////////////////////
 
   // js ffi operators
@@ -448,54 +442,18 @@ function wps(E, T) {
   Sd[".math"] = function() { // -- Math
     Os.push(Math);
   };
-  Sd[".gc"] = function() { // -- gc
-    Os.push(E.getContext("2d"));
-  };
   Sd[".date"] = function() { // -- date
     Os.push(new Date());
   };
   Sd[".window"] = function() { // -- window
     Os.push(window);
   };
-  Sd[".callback"] = function() { // body -- callback // TODO refactor properly
+  Sd[".callback"] = function() { // body -- callback
     var X = Os.pop();
-    Os.push(function() { // TODO fix this mess
-              //alert(".callback");
-              //Es.push([false, X]); // TODO process event in ps0 ???
-  function run(X, Z) {
-    if(isSymbol(X) && !isQuoted(X)) { // executable name
-      var K = symbolName(X);
-      var D = inDs(Ds, K);
-      if(!D) {
-        throw "bind error '" + K + "'";
-      }
-      Es.push([false, D[K]]);
-      //if(V !== undefined) Es.push([false, V, Xexec]);
-      //else throw "Unknown operator '" + K + "' " + V;
-    } else if(Z && isArray(X) && isQuoted(X)) { // proc from Es
-      if(0 < X.length) {
-        var F = X[0];
-        var R = quote(X.slice(1));
-        //if(0 < R.length) Es.push([false, R, Xexec]);
-        if(0 < R.length) Es.push([false, R]);
-        //run(F, true);
-        run(F, false);
-        //Es.push([false, F]);
-      }
-    } else if("function" == typeof X) X(); // operator
-    else Os.push(X);
-  }
-  function step() {
-    var C = Es.pop();
-    var L = C.shift(); // TODO use for 'exit'
-    var X = C.pop();
-    for(var I = 0; I < C.length; I++)
-      Os.push(C[I]);
-    run(X, true);
-  }
-              run(X, true);
+    Os.push(function() {
+              Ps.run(X, true);
               while(0 < Es.length)
-                step();
+                Ps.step();
             });
   };
 
@@ -544,8 +502,14 @@ function wps(E, T) {
     Os.push("rgba(" + R + "," + G + "," + B + "," + A + ")");
   };
 
-  if(T.length)
-    for(var I = 0; I < T.length; I++)
-      ps0(T[I], Os, Ds, Es);
-  else ps0(T, Os, Ds, Es);
+  function parse() {
+    var T = arguments;
+    if(T.length)
+      for(var I = 0; I < T.length; I++)
+        Ps.parse(T[I]);
+    else Ps.parse(T);
+    return Os;
+  }
+  Wps.prototype.parse = parse;
+  return this;
 }
diff --git a/wps.wps b/wps.wps
@@ -134,6 +134,8 @@ systemdict/def{currentdict 2 index 2 index put pop pop}put
 
 %% html5
 
+/.setGc{.getElementById(2d)exch(getContext)1 .call/.$gc .xdef}.bdef
+/.gc{/.$gc load}.bdef
 /.gget{.gc exch get}.bdef
 /.gput{.gc 3 1 roll exch put}.bdef
 /.gcall0{.gc 3 1 roll .call pop}.bdef
@@ -221,41 +223,40 @@ systemdict/def{currentdict 2 index 2 index put pop pop}put
 /.deg2rad{.pi 180 div mul}.bdef
 /.rad2deg{180 .pi div mul}.bdef
 
-/.cx 0 def
-/.cy 0 def
-/.px 0 def
-/.py 0 def
-/.setPoint{/.cy .xdef/.cx .xdef}.bdef
-/.setPath{/.py .xdef/.px .xdef}.bdef
-/currentpoint{/.cx load /.cy load}.bdef
-/.getPath{/.px load /.py load}.bdef
+/.$cx 0 def
+/.$cy 0 def
+/.$px 0 def
+/.$py 0 def
+/.setPoint{/.$cy .xdef/.$cx .xdef}.bdef
+/.setPath{/.$py .xdef/.$px .xdef}.bdef
+/currentpoint{/.$cx load /.$cy load}.bdef
+/.getPath{/.$px load /.$py load}.bdef
 
 /identmatrix{pop [1 0 0 1 0 0]}.bdef % TODO fill
 /matrix{6 array identmatrix}.bdef
-/setmatrix{/.tm .xdef}.bdef
+/setmatrix{/.$tm .xdef}.bdef
 /defaultmatrix{pop matrix}.bdef % TODO fill
 /initmatrix{matrix defaultmatrix setmatrix}.bdef
-/currentmatrix{pop /.tm load}.bdef % TODO fill
+/currentmatrix{pop /.$tm load}.bdef % TODO fill
 initmatrix
 
 %/matrix load =
 %matrix =
 
-/.getTmd{/.tmd load}.bdef
-/.setTmd{/.tmd .xdef}.bdef
+/.getTmd{/.$tmd load}.bdef
+/.setTmd{/.$tmd .xdef}.bdef
 /.resetTmd{matrix .setTmd}.bdef
 .resetTmd
 
 /.update{ % m --
-  %dup .cx exch .cy exch % m .cx .cy m
-  currentpoint 2 index % m .cx .cy m
+  currentpoint 2 index % m .$cx .$cy m
   .xy .setPoint % m
-  dup .getTmd exch .mmul .setTmd % (.tmd x m)
-  dup currentmatrix exch .mmul setmatrix % = .tm x m
+  dup .getTmd exch .mmul .setTmd % (.$tmd x m)
+  dup currentmatrix exch .mmul setmatrix % = .$tm x m
 }.bdef
 
-/transform{dup type(arraytype)ne{.getTmd}if .xy}.bdef % TODO why .tmd not .tm?
-/itransform{dup type(arraytype)ne{.getTmd}if .minv .xy}.bdef % TODO why .tmd not .tm?
+/transform{dup type(arraytype)ne{.getTmd}if .xy}.bdef % TODO why .$tmd not .$tm?
+/itransform{dup type(arraytype)ne{.getTmd}if .minv .xy}.bdef % TODO why .$tmd not .$tm?
 
 /.scaleM{0 0 3 2 roll 0 0 6 array astore}.bdef % x y -- [x 0 0 y 0 0]
 /.scale3{pop .scaleM}.bdef
@@ -272,7 +273,6 @@ initmatrix
 /.rotate1{.deg2rad dup .rotateM .update .rotate}.bdef
 /rotate{dup type(arraytype)eq{.rotate2}{.rotate1}ifelse}.bdef
 
-
 %matrix concat – 	Replace CTM by matrix ´ CTM
 %matrix1 matrix2 matrix3 concatmatrix matrix3 	Fill matrix3 with matrix1 ´ matrix2
 
@@ -308,19 +308,17 @@ initmatrix
 
 /setgray{255 mul dup dup .rgb dup .setStrokeStyle .setFillStyle}.bdef
 /setrgbcolor{3{255 mul round 3 1 roll}repeat .rgb dup .setStrokeStyle .setFillStyle}.bdef
-/setfont{}.bdef % TODO C.font = N + "pt " + F.V;
+/setcmykcolor{setrgbcolor pop}.bdef % TODO
+/sethsbcolor{setrgbcolor}.bdef % TODO
 /clippath{0 0 .gcanvas(width)get .gcanvas(height)get .rect}.bdef % TODO
 /show{currentpoint 3 2 roll 3 copy .fillText .strokeText}.bdef % TODO
 
-%/rlineto{.getTmd .xy .py add exch .px add exch .getTmd .minv .xy lineto}.bdef
-/rlineto{.getTmd .xy /.py load add exch /.px load add exch .getTmd .minv .xy lineto}.bdef
+/rlineto{.getTmd .xy /.$py load add exch /.$px load add exch .getTmd .minv .xy lineto}.bdef
 /curveto{2 copy .setPoint 2 copy .setPath .resetTmd .bezierCurveTo}.bdef
 
 /currentflat{42}.bdef % TODO
 /setflat{pop}.bdef % TODO
 
-/showpage{}.bdef % TODO
-
 /arc{.deg2rad exch .deg2rad exch true .arc}.bdef % TODO currentpoint
 /arcn{.deg2rad exch .deg2rad exch false .arc}.bdef % TODO currentpoint
 
@@ -330,7 +328,29 @@ initmatrix
 
 /stroke{.stroke newpath currentpoint .moveTo}.bdef
 
+/showpage{}.bdef % TODO
 /grestoreall{}.bdef % TODO
+/readonly{}.bdef % TODO
+/currentfile{(url?)}.bdef % TODO
+/eexec{pop}.bdef % TODO
+/findfont{}.bdef % TODO
+/scalefont{pop}.bdef % TODO
+/setfont{pop}.bdef % TODO C.font = N + "pt " + F.V;
+/stopped{}.bdef % TODO
+/loop{}.bdef % TODO !!!
+/string{}.bdef % TODO
+/cvi{}.bdef % TODO
+/pathbbox{}.bdef % TODO
+/urx{}.bdef % TODO
+/ury{}.bdef % TODO
+/llx{}.bdef % TODO
+/lly{}.bdef % TODO
+/pagewidth{}.bdef % TODO
+/pageheight{}.bdef % TODO
+/inwidth{}.bdef % TODO
+/inheight{}.bdef % TODO
+/usertime{}.bdef % TODO
+/srand{}.bdef % TODO
 
 %% PDF