PageRenderTime 56ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/examples/jsonrpc/public/services/phpolait/jsolait/lib/lang.js

http://pyjamas.googlecode.com/
JavaScript | 377 lines | 377 code | 0 blank | 0 comment | 51 complexity | 29d7231b0a4d2340abfdc900eff45600 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. Module("lang", "0.3.7", function(mod){
  2. var ISODate = function(d){
  3. if(/^(\d{4})(\d{2})(\d{2})T(\d{2}):(\d{2}):(\d{2})/.test(d)){
  4. return new Date(Date.UTC(RegExp.$1, RegExp.$2-1, RegExp.$3, RegExp.$4, RegExp.$5, RegExp.$6));
  5. }else{
  6. throw new mod.Exception("Not an ISO date: " + d);
  7. }
  8. }
  9. mod.JSONParser=Class("JSONParser", function(publ, supr){
  10. publ.init=function(){
  11. this.libs = {};
  12. var sys = {"ISODate" : ISODate};
  13. this.addLib(sys, "sys", ["ISODate"]);
  14. }
  15. publ.addLib = function(obj, name, exports){
  16. if(exports == null){
  17. this.libs[name] = obj;
  18. }else{
  19. for(var i=0;i<exports.length;i++){
  20. this.libs[name + "." + exports[i]] = obj[exports[i]];
  21. }
  22. }
  23. }
  24. var EmptyValue = {};
  25. var SeqSep = {};
  26. var parseValue = function(tkns, libs){
  27. var tkn = tkns.nextNonWS();
  28. switch(tkn.type){
  29. case mod.tokens.STR:
  30. case mod.tokens.NUM:
  31. return eval(tkn.value);
  32. case mod.tokens.NAME:
  33. return parseName(tkn.value);
  34. case mod.tokens.OP:
  35. switch(tkn.value){
  36. case "[":
  37. return parseArray(tkns, libs);
  38. break;
  39. case "{":
  40. return parseObj(tkns, libs);
  41. break;
  42. case "}": case "]":
  43. return EmptyValue;
  44. case ",":
  45. return SeqSep;
  46. default:
  47. throw new mod.Exception("expected '[' or '{' but found: '" + tkn.value + "'");
  48. }
  49. }
  50. return EmptyValue;
  51. }
  52. var parseArray = function(tkns, libs){
  53. var a = [];
  54. while(! tkns.finished()){
  55. var v = parseValue(tkns, libs);
  56. if(v == EmptyValue){
  57. return a;
  58. }else{
  59. a.push(v);
  60. v = parseValue(tkns, libs);
  61. if(v == EmptyValue){
  62. return a;
  63. }else if(v != SeqSep){
  64. throw new mod.Exception("',' expected but found: '" + v + "'");
  65. }
  66. }
  67. }
  68. throw new mod.Exception("']' expected");
  69. }
  70. var parseObj = function(tkns, libs){
  71. var obj = {};
  72. var nme ="";
  73. while(! tkns.finished()){
  74. var tkn = tkns.nextNonWS();
  75. if(tkn.type == mod.tokens.STR){
  76. var nme = eval(tkn.value);
  77. tkn = tkns.nextNonWS();
  78. if(tkn.value == ":"){
  79. var v = parseValue(tkns, libs);
  80. if(v == SeqSep || v == EmptyValue){
  81. throw new mod.Exception("value expected");
  82. }else{
  83. obj[nme] = v;
  84. v = parseValue(tkns, libs);
  85. if(v == EmptyValue){
  86. return transformObj(obj, libs);
  87. }else if(v != SeqSep){
  88. throw new mod.Exception("',' expected");
  89. }
  90. }
  91. }else{
  92. throw new mod.Exception("':' expected but found: '" + tkn.value + "'");
  93. }
  94. }else if(tkn.value == "}"){
  95. return transformObj(obj, libs);
  96. }else{
  97. throw new mod.Exception("String expected");
  98. }
  99. }
  100. throw new mod.Exception("'}' expected.")
  101. }
  102. var transformObj = function(obj, libs){
  103. var o2;
  104. if(obj.jsonclass != null){
  105. var clsName = obj.jsonclass[0];
  106. var params = obj.jsonclass[1]
  107. if(libs[clsName]){
  108. o2 = libs[clsName].apply(this, params);
  109. for(var nme in obj){
  110. if(nme != "jsonclass"){
  111. if(typeof obj[nme] != "function"){
  112. o2[nme] = obj[nme];
  113. }
  114. }
  115. }
  116. }else{
  117. throw new mod.Exception("jsonclass not found: " + clsName);
  118. }
  119. }else{
  120. o2 = obj;
  121. }
  122. return o2;
  123. }
  124. var parseName = function(name){
  125. switch(name){
  126. case "null":
  127. return null;
  128. case "true":
  129. return true;
  130. case "false":
  131. return false;
  132. default:
  133. throw new mod.Exception("'null', 'true', 'false' expected but found: '" + name + "'");
  134. }
  135. }
  136. publ.jsonToObj = function(data){
  137. var t = new mod.Tokenizer(data);
  138. return parseValue(t, this.libs);
  139. }
  140. publ.objToJson=function(obj){
  141. if(obj == null){
  142. return "null";
  143. }else{
  144. return obj.toJSON();
  145. }
  146. }
  147. })
  148. mod.parser = new mod.JSONParser();
  149. mod.jsonToObj=function(src){
  150. return mod.parser.jsonToObj(src);
  151. }
  152. mod.objToJson=function(obj){
  153. return mod.parser.objToJson(obj);
  154. }
  155. mod.tokens = {};
  156. mod.tokens.WSP = 0;
  157. mod.tokens.OP =1;
  158. mod.tokens.STR = 2;
  159. mod.tokens.NAME = 3;
  160. mod.tokens.NUM = 4;
  161. mod.tokens.ERR = 5;
  162. mod.tokens.NL = 6;
  163. mod.tokens.COMMENT = 7;
  164. mod.tokens.DOCCOMMENT = 8;
  165. mod.tokens.REGEXP = 9;
  166. mod.Token=Class(function(publ, supr){
  167. publ.init=function(type, value, pos, err){
  168. this.type = type;
  169. this.value = value;
  170. this.pos = pos;
  171. this.err= err;
  172. }
  173. })
  174. mod.Tokenizer=Class("Tokenizer", function(publ, supr){
  175. publ.init=function(s){
  176. this._working = s;
  177. this._pos = 0;
  178. }
  179. publ.finished=function(){
  180. return this._working.length == 0;
  181. }
  182. publ.nextNonWS = function(nlIsWS){
  183. var tkn = this.next();
  184. while((tkn.type == mod.tokens.WSP) || (nlIsWS && (tkn.type == mod.tokens.NL))){
  185. tkn = this.next();
  186. }
  187. return tkn;
  188. }
  189. publ.next = function(){
  190. if(this._working ==""){
  191. throw new mod.Exception("Empty");
  192. }
  193. var s1 = this._working.charAt(0);
  194. var s2 = s1 + this._working.charAt(1);
  195. var s3 = s2 + this._working.charAt(2);
  196. var rslt=[];
  197. switch(s1){
  198. case '"': case "'":
  199. try{
  200. s1 = extractQString(this._working);
  201. rslt= new mod.Token(mod.tokens.STR, s1, this._pos);
  202. }catch(e){
  203. rslt= new mod.Token(mod.tokens.ERR, s1, this._pos, e);
  204. }
  205. break;
  206. case "\n": case "\r":
  207. rslt =new mod.Token(mod.tokens.NL, s1, this._pos);
  208. break;
  209. case "-":
  210. s1=this._working.match(/-\d+\.\d+|-\d+/)[0];
  211. if(/^-\d|-\d\.\d/.test(s1)){
  212. rslt = new mod.Token(mod.tokens.NUM, s1, this._pos);
  213. break;
  214. }
  215. case "{": case "}": case "[": case "]": case "(": case ")":
  216. case ":": case ",": case ".": case ";":
  217. case "*": case "-": case "+":
  218. case "=": case "<": case ">": case "!":
  219. case "|": case "&":
  220. switch(s2){
  221. case "==": case "!=": case "<>": case "<=": case ">=":case "||": case "&&":
  222. rslt = new mod.Token(mod.tokens.OP, s2, this._pos);
  223. break;
  224. default:
  225. rslt = new mod.Token(mod.tokens.OP, s1, this._pos);
  226. }
  227. break;
  228. case "/":
  229. if(s2 == "//" || s3 =="///"){
  230. s1 = extractSLComment(this._working);
  231. rslt = new mod.Token(s1.charAt(2) != "/" ? mod.tokens.COMMENT:mod.tokens.DOCCOMMENT, s1, this._pos);
  232. }else if(s2 == "/*" || s3 =="/**"){
  233. try{
  234. s1 = extractMLComment(this._working);
  235. rslt = new mod.Token(s3 !="/**" ? mod.tokens.COMMENT: mod.tokens.DOCCOMMENT, s1, this._pos);
  236. }catch(e){
  237. rslt= new mod.Token(mod.tokens.ERR, s3 != "/**" ? s2 : s3, this._pos, e);
  238. }
  239. }else{
  240. try{
  241. s1 = extractRegExp(this._working);
  242. rslt = new mod.Token(mod.tokens.REGEXP, s1, this._pos);
  243. }catch(e){
  244. rslt = new mod.Token(mod.tokens.OP, s1, this._pos, e);
  245. }
  246. }
  247. break;
  248. case " ":
  249. var i = 0;
  250. var s="";
  251. while(this._working.charAt(i) == " "){
  252. s+=" ";
  253. i++;
  254. }
  255. rslt = new mod.Token(mod.tokens.WSP, s, this._pos);
  256. break;
  257. default:
  258. s1=this._working.match(/\d+\.\d+|\d+|\w+/)[0];
  259. if(/^\d|\d\.\d/.test(s1)){
  260. rslt = new mod.Token(mod.tokens.NUM, s1, this._pos);
  261. }else{
  262. rslt =new mod.Token(mod.tokens.NAME, s1, this._pos);
  263. }
  264. }
  265. this._working=this._working.slice(rslt.value.length);
  266. this._pos += rslt.value.length;
  267. return rslt;
  268. }
  269. var searchQoute = function(s, q){
  270. if(q=="'"){
  271. return s.search(/[\\']/);
  272. }else{
  273. return s.search(/[\\"]/);
  274. }
  275. }
  276. var extractQString=function(s){
  277. if(s.charAt(0) == "'"){
  278. var q="'";
  279. }else{
  280. var q='"';
  281. }
  282. s=s.slice(1);
  283. var rs="";
  284. var p= searchQoute(s, q);
  285. while(p >= 0){
  286. if(p >=0){
  287. if(s.charAt(p) == q){
  288. rs += s.slice(0, p+1);
  289. s = s.slice(p+1);
  290. return q + rs;
  291. }else{
  292. rs+=s.slice(0, p+2);
  293. s = s.slice(p+2);
  294. }
  295. }
  296. p = searchQoute(s, q);
  297. }
  298. throw new mod.Exception("End of String expected.");
  299. }
  300. var extractSLComment=function(s){
  301. var p = s.search(/\n/);
  302. if(p>=0){
  303. return s.slice(0,p+1);
  304. }else{
  305. return s;
  306. }
  307. }
  308. var extractMLComment=function(s){
  309. var p = s.search(/\*\//);
  310. if(p>=0){
  311. return s.slice(0,p+2);
  312. }else{
  313. throw new mod.Exception("End of comment expected.");
  314. }
  315. }
  316. var extractRegExp=function(s){
  317. var p=0;
  318. for(var i=0;i<s.length;i++){
  319. if(s.charAt(i) == "/"){
  320. p=i;
  321. }
  322. if(s.charAt(i) == "\n"){
  323. i = s.length;
  324. }
  325. }
  326. return s.slice(0,p+1);
  327. }
  328. })
  329. Object.prototype.toJSON = function(){
  330. var v=[];
  331. for(attr in this){
  332. if(typeof this[attr] != "function"){
  333. v.push('"' + attr + '": ' + mod.objToJson(this[attr]));
  334. }
  335. }
  336. return "{" + v.join(", ") + "}";
  337. }
  338. String.prototype.toJSON = function(){
  339. var s = '"' + this.replace(/(["\\])/g, '\\$1') + '"';
  340. s = s.replace(/(\n)/g,"\\n");
  341. return s;
  342. }
  343. Number.prototype.toJSON = function(){
  344. return this.toString();
  345. }
  346. Boolean.prototype.toJSON = function(){
  347. return this.toString();
  348. }
  349. Date.prototype.toJSON= function(){
  350. var padd=function(s, p){
  351. s=p+s
  352. return s.substring(s.length - p.length)
  353. }
  354. var y = padd(this.getUTCFullYear(), "0000");
  355. var m = padd(this.getUTCMonth() + 1, "00");
  356. var d = padd(this.getUTCDate(), "00");
  357. var h = padd(this.getUTCHours(), "00");
  358. var min = padd(this.getUTCMinutes(), "00");
  359. var s = padd(this.getUTCSeconds(), "00");
  360. var isodate = y + m + d + "T" + h + ":" + min + ":" + s;
  361. return '{"jsonclass":["sys.ISODate", ["' + isodate + '"]]}';
  362. }
  363. Array.prototype.toJSON = function(){
  364. var v = [];
  365. for(var i=0;i<this.length;i++){
  366. v.push(mod.objToJson(this[i])) ;
  367. }
  368. return "[" + v.join(", ") + "]";
  369. }
  370. mod.test=function(){
  371. try{
  372. print(mod.jsonToObj("['sds', -12377,-1212.1212, 12, '-2312']").toJSON());
  373. }catch(e){
  374. print(e.toTraceString());
  375. }
  376. }
  377. })