xref: /inferno-os/appl/lib/ecmascript/pprint.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.ForsythPPrint: adt
2*37da2899SCharles.Forsyth{
3*37da2899SCharles.Forsyth	ex:	ref Exec;
4*37da2899SCharles.Forsyth	code:	ref Code;
5*37da2899SCharles.Forsyth	stack:	array of string;
6*37da2899SCharles.Forsyth	sp:	int;
7*37da2899SCharles.Forsyth};
8*37da2899SCharles.Forsyth
9*37da2899SCharles.Forsythmkpprint(ex: ref Exec, code: ref Code): ref PPrint
10*37da2899SCharles.Forsyth{
11*37da2899SCharles.Forsyth	return ref PPrint(ex, code, array[4] of string, 0);
12*37da2899SCharles.Forsyth}
13*37da2899SCharles.Forsyth
14*37da2899SCharles.Forsythfuncprint(ex: ref Exec, func: ref Ecmascript->Obj): string
15*37da2899SCharles.Forsyth{
16*37da2899SCharles.Forsyth	params := func.call.params;
17*37da2899SCharles.Forsyth	(nil, name) := str->splitr(func.val.str, ".");
18*37da2899SCharles.Forsyth	s := "function " + name + "(";
19*37da2899SCharles.Forsyth	sep := "";
20*37da2899SCharles.Forsyth	for(i := 0; i < len params; i++){
21*37da2899SCharles.Forsyth		s += sep + params[i];
22*37da2899SCharles.Forsyth		sep = ", ";
23*37da2899SCharles.Forsyth	}
24*37da2899SCharles.Forsyth	s += "){";
25*37da2899SCharles.Forsyth	if(func.host != nil)
26*37da2899SCharles.Forsyth		s += "[host code]";
27*37da2899SCharles.Forsyth	else
28*37da2899SCharles.Forsyth		s += "\n" + pprint(ex, func.call.code, "	");
29*37da2899SCharles.Forsyth	s += "}";
30*37da2899SCharles.Forsyth	return s;
31*37da2899SCharles.Forsyth}
32*37da2899SCharles.Forsyth
33*37da2899SCharles.Forsythpprint(ex: ref Exec, code: ref Code, indent: string): string
34*37da2899SCharles.Forsyth{
35*37da2899SCharles.Forsyth	pp := ref PPrint(ex, code, array[4] of string, 0);
36*37da2899SCharles.Forsyth#for(i:=0; i < code.npc; i++) sys->print("%d: %d\n", i, int code.ops[i]);
37*37da2899SCharles.Forsyth	s := pstmt(pp, 0, code.npc, indent);
38*37da2899SCharles.Forsyth
39*37da2899SCharles.Forsyth	if(pp.sp != 0)
40*37da2899SCharles.Forsyth		fatal(ex, "pprint stack not balanced");
41*37da2899SCharles.Forsyth
42*37da2899SCharles.Forsyth	return s;
43*37da2899SCharles.Forsyth}
44*37da2899SCharles.Forsyth
45*37da2899SCharles.Forsythpstmt(pp: ref PPrint, pc, epc: int, indent: string): string
46*37da2899SCharles.Forsyth{
47*37da2899SCharles.Forsyth	e, e1, e2: string;
48*37da2899SCharles.Forsyth	c, apc: int;
49*37da2899SCharles.Forsyth
50*37da2899SCharles.Forsyth	code := pp.code;
51*37da2899SCharles.Forsyth	s := "";
52*37da2899SCharles.Forsyth	while(pc < epc){
53*37da2899SCharles.Forsyth		op := int code.ops[pc++];
54*37da2899SCharles.Forsyth		while(op == Llabel){
55*37da2899SCharles.Forsyth			(pc, c) = getconst(code.ops, pc);
56*37da2899SCharles.Forsyth			s += code.strs[c] + ":\n";
57*37da2899SCharles.Forsyth			op = int code.ops[pc++];
58*37da2899SCharles.Forsyth		}
59*37da2899SCharles.Forsyth		s += indent;
60*37da2899SCharles.Forsyth		case op{
61*37da2899SCharles.Forsyth		Lbreak or
62*37da2899SCharles.Forsyth		Lcontinue or
63*37da2899SCharles.Forsyth		Lreturn =>
64*37da2899SCharles.Forsyth			s += tokname(op);
65*37da2899SCharles.Forsyth			if(op == Lreturn){
66*37da2899SCharles.Forsyth				(pc, e) = pexp(pp, pc, code.npc);
67*37da2899SCharles.Forsyth				s += " " + e;
68*37da2899SCharles.Forsyth			}
69*37da2899SCharles.Forsyth			s += ";\n";
70*37da2899SCharles.Forsyth		Lbreaklab or
71*37da2899SCharles.Forsyth		Lcontinuelab =>
72*37da2899SCharles.Forsyth			s += tokname(op);
73*37da2899SCharles.Forsyth			(pc, c) = getconst(code.ops, pc);
74*37da2899SCharles.Forsyth			s += " " + code.strs[c] + ";\n";
75*37da2899SCharles.Forsyth		'{' =>
76*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, pc);
77*37da2899SCharles.Forsyth			s += "{\n" + pstmt(pp, pc, apc, indent+"	") + indent + "}\n";
78*37da2899SCharles.Forsyth			pc = apc;
79*37da2899SCharles.Forsyth		Lif or
80*37da2899SCharles.Forsyth		Lwith or
81*37da2899SCharles.Forsyth		Lwhile =>
82*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, pc);
83*37da2899SCharles.Forsyth			(pc, e) = pexp(pp, pc, apc);
84*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, pc);
85*37da2899SCharles.Forsyth			s += tokname(op) + "(" + e + "){\n";
86*37da2899SCharles.Forsyth			s += pstmt(pp, pc, apc, indent+"	");
87*37da2899SCharles.Forsyth			if(op == Lif){
88*37da2899SCharles.Forsyth				(pc, apc) = getjmp(code.ops, apc);
89*37da2899SCharles.Forsyth				if(pc != apc)
90*37da2899SCharles.Forsyth					s += indent + "}else{\n";
91*37da2899SCharles.Forsyth				s += pstmt(pp, pc, apc, indent+"	");
92*37da2899SCharles.Forsyth			}
93*37da2899SCharles.Forsyth			s += indent + "}\n";
94*37da2899SCharles.Forsyth			pc = apc;
95*37da2899SCharles.Forsyth		Ldo =>
96*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, pc);
97*37da2899SCharles.Forsyth			e = pstmt(pp, pc, apc, indent+"	");
98*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, apc);
99*37da2899SCharles.Forsyth			(pc, e1) = pexp(pp, pc, apc);
100*37da2899SCharles.Forsyth			s += "do{\n" + e + indent + "}(while(" + e1 + ");\n";
101*37da2899SCharles.Forsyth			pc = apc;
102*37da2899SCharles.Forsyth		Lfor or
103*37da2899SCharles.Forsyth		Lforvar or
104*37da2899SCharles.Forsyth		Lforin or
105*37da2899SCharles.Forsyth		Lforvarin =>
106*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, pc);
107*37da2899SCharles.Forsyth			(pc, e) = pexp(pp, pc, apc);
108*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, pc);
109*37da2899SCharles.Forsyth			(pc, e1) = pexp(pp, pc, apc);
110*37da2899SCharles.Forsyth			s += "for(";
111*37da2899SCharles.Forsyth			if(op == Lforvar || op == Lforvarin)
112*37da2899SCharles.Forsyth				s += "var ";
113*37da2899SCharles.Forsyth			s += e;
114*37da2899SCharles.Forsyth			if(op == Lfor || op == Lforvar){
115*37da2899SCharles.Forsyth				(pc, apc) = getjmp(code.ops, pc);
116*37da2899SCharles.Forsyth				(pc, e2) = pexp(pp, pc, apc);
117*37da2899SCharles.Forsyth				s += "; " + e1 + "; " + e2;
118*37da2899SCharles.Forsyth			}else
119*37da2899SCharles.Forsyth				s += " in " + e1;
120*37da2899SCharles.Forsyth			s += "){\n";
121*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, pc);
122*37da2899SCharles.Forsyth			s += pstmt(pp, pc, apc, indent+"	");
123*37da2899SCharles.Forsyth			s += indent + "}\n";
124*37da2899SCharles.Forsyth			pc = apc;
125*37da2899SCharles.Forsyth		';' =>
126*37da2899SCharles.Forsyth			s += ";\n";
127*37da2899SCharles.Forsyth		Lvar =>
128*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, pc);
129*37da2899SCharles.Forsyth			(pc, e) = pexp(pp, pc, apc);
130*37da2899SCharles.Forsyth			s += "var " + e + ";\n";
131*37da2899SCharles.Forsyth		Lswitch =>
132*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, pc);
133*37da2899SCharles.Forsyth			(pc, e) = pexp(pp, pc, apc);
134*37da2899SCharles.Forsyth			s += "switch (" + e + ") {\n";
135*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, pc);
136*37da2899SCharles.Forsyth			(pc, e) = pcaseblk(pp, pc, apc, indent);
137*37da2899SCharles.Forsyth			s  += e + indent + "}\n";
138*37da2899SCharles.Forsyth			pc = apc;
139*37da2899SCharles.Forsyth		Lthrow =>
140*37da2899SCharles.Forsyth			(pc, e) = pexp(pp, pc, code.npc);
141*37da2899SCharles.Forsyth			s += "throw " + e + "\n";
142*37da2899SCharles.Forsyth		Ltry =>
143*37da2899SCharles.Forsyth			s += "try\n";
144*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, pc);
145*37da2899SCharles.Forsyth			s += pstmt(pp, pc, apc, indent+"	");
146*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, apc);
147*37da2899SCharles.Forsyth			if(pc != apc){
148*37da2899SCharles.Forsyth				(pc, c) = getconst(code.ops, ++pc);
149*37da2899SCharles.Forsyth				s += "catch(" + code.strs[c] + ")\n";
150*37da2899SCharles.Forsyth				s += pstmt(pp, pc, apc, indent+"	");
151*37da2899SCharles.Forsyth			}
152*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, apc);
153*37da2899SCharles.Forsyth			if(pc != apc){
154*37da2899SCharles.Forsyth				s += "finally\n";
155*37da2899SCharles.Forsyth				s += pstmt(pp, pc, apc, indent+"	");
156*37da2899SCharles.Forsyth			}
157*37da2899SCharles.Forsyth			pc = apc;
158*37da2899SCharles.Forsyth		* =>
159*37da2899SCharles.Forsyth			(pc, e) = pexp(pp, pc-1, code.npc);
160*37da2899SCharles.Forsyth			s += e + ";\n";
161*37da2899SCharles.Forsyth		}
162*37da2899SCharles.Forsyth	}
163*37da2899SCharles.Forsyth	return s;
164*37da2899SCharles.Forsyth}
165*37da2899SCharles.Forsyth
166*37da2899SCharles.Forsythpexp(pp: ref PPrint, pc, epc: int): (int, string)
167*37da2899SCharles.Forsyth{
168*37da2899SCharles.Forsyth	c, apc: int;
169*37da2899SCharles.Forsyth	s, f, a, a1, a2: string;
170*37da2899SCharles.Forsyth
171*37da2899SCharles.Forsyth	code := pp.code;
172*37da2899SCharles.Forsyth	savesp := pp.sp;
173*37da2899SCharles.Forsythout:	while(pc < epc){
174*37da2899SCharles.Forsyth		case op := int code.ops[pc++]{
175*37da2899SCharles.Forsyth		Lthis =>
176*37da2899SCharles.Forsyth			s = "this";
177*37da2899SCharles.Forsyth		Lid or
178*37da2899SCharles.Forsyth		Lnum or
179*37da2899SCharles.Forsyth		Lstr or
180*37da2899SCharles.Forsyth		Lregexp =>
181*37da2899SCharles.Forsyth			(pc, c) = getconst(code.ops, pc);
182*37da2899SCharles.Forsyth			if(op == Lnum)
183*37da2899SCharles.Forsyth				s = string code.nums[c];
184*37da2899SCharles.Forsyth			else{
185*37da2899SCharles.Forsyth				s = code.strs[c];
186*37da2899SCharles.Forsyth				if(op == Lstr)
187*37da2899SCharles.Forsyth					s = "\""+escstr(code.strs[c])+"\"";
188*37da2899SCharles.Forsyth			}
189*37da2899SCharles.Forsyth		'*' or
190*37da2899SCharles.Forsyth		'/' or
191*37da2899SCharles.Forsyth		'%' or
192*37da2899SCharles.Forsyth		'+' or
193*37da2899SCharles.Forsyth		'-' or
194*37da2899SCharles.Forsyth		Llsh or
195*37da2899SCharles.Forsyth		Lrsh or
196*37da2899SCharles.Forsyth		Lrshu or
197*37da2899SCharles.Forsyth		'<' or
198*37da2899SCharles.Forsyth		'>' or
199*37da2899SCharles.Forsyth		Lleq or
200*37da2899SCharles.Forsyth		Lgeq or
201*37da2899SCharles.Forsyth		Lin or
202*37da2899SCharles.Forsyth		Linstanceof or
203*37da2899SCharles.Forsyth		Leq or
204*37da2899SCharles.Forsyth		Lneq or
205*37da2899SCharles.Forsyth		Lseq or
206*37da2899SCharles.Forsyth		Lsne or
207*37da2899SCharles.Forsyth		'&' or
208*37da2899SCharles.Forsyth		'^' or
209*37da2899SCharles.Forsyth		'|' or
210*37da2899SCharles.Forsyth		'=' or
211*37da2899SCharles.Forsyth		'.' or
212*37da2899SCharles.Forsyth		',' or
213*37da2899SCharles.Forsyth		'[' =>
214*37da2899SCharles.Forsyth			a2 = ppop(pp);
215*37da2899SCharles.Forsyth			a1 = ppop(pp);
216*37da2899SCharles.Forsyth			s = tokname(op);
217*37da2899SCharles.Forsyth			if(a1[0] == '='){
218*37da2899SCharles.Forsyth				s += "=";
219*37da2899SCharles.Forsyth				a1 = a1[1:];
220*37da2899SCharles.Forsyth			}
221*37da2899SCharles.Forsyth			if(op == '[')
222*37da2899SCharles.Forsyth				s = a1 + "[" + a2 + "]";
223*37da2899SCharles.Forsyth			else{
224*37da2899SCharles.Forsyth				if(op != '.'){
225*37da2899SCharles.Forsyth					if(op != ',')
226*37da2899SCharles.Forsyth						s = " " + s;
227*37da2899SCharles.Forsyth					s = s + " ";
228*37da2899SCharles.Forsyth				}
229*37da2899SCharles.Forsyth				s = a1 + s + a2;
230*37da2899SCharles.Forsyth			}
231*37da2899SCharles.Forsyth		Ltypeof or
232*37da2899SCharles.Forsyth		Ldelete or
233*37da2899SCharles.Forsyth		Lvoid or
234*37da2899SCharles.Forsyth		Lnew or
235*37da2899SCharles.Forsyth		Linc or
236*37da2899SCharles.Forsyth		Ldec or
237*37da2899SCharles.Forsyth		Lpreadd or
238*37da2899SCharles.Forsyth		Lpresub or
239*37da2899SCharles.Forsyth		'~' or
240*37da2899SCharles.Forsyth		'!' or
241*37da2899SCharles.Forsyth		Lpostinc or
242*37da2899SCharles.Forsyth		Lpostdec =>
243*37da2899SCharles.Forsyth			a = ppop(pp);
244*37da2899SCharles.Forsyth			s = tokname(op);
245*37da2899SCharles.Forsyth			if(op == Lpostinc || op == Lpostdec)
246*37da2899SCharles.Forsyth				s = a + s;
247*37da2899SCharles.Forsyth			else{
248*37da2899SCharles.Forsyth				if(op == Ltypeof || op == Ldelete || op == Lvoid || op == Lnew)
249*37da2899SCharles.Forsyth					s += " ";
250*37da2899SCharles.Forsyth				s += a;
251*37da2899SCharles.Forsyth			}
252*37da2899SCharles.Forsyth		'(' =>
253*37da2899SCharles.Forsyth			s = "(";
254*37da2899SCharles.Forsyth		')' =>
255*37da2899SCharles.Forsyth			s = ppop(pp);
256*37da2899SCharles.Forsyth			if(ppop(pp) != "(")
257*37da2899SCharles.Forsyth				fatal(pp.ex, "unbalanced () in pexp");
258*37da2899SCharles.Forsyth			s = "(" + s + ")";
259*37da2899SCharles.Forsyth		Lgetval or
260*37da2899SCharles.Forsyth		Las =>
261*37da2899SCharles.Forsyth			continue;
262*37da2899SCharles.Forsyth		Lasop =>
263*37da2899SCharles.Forsyth			s = "=" + ppop(pp);
264*37da2899SCharles.Forsyth		Lcall or
265*37da2899SCharles.Forsyth		Lnewcall =>
266*37da2899SCharles.Forsyth			(pc, c) = getconst(code.ops, pc);
267*37da2899SCharles.Forsyth			a = "";
268*37da2899SCharles.Forsyth			sep := "";
269*37da2899SCharles.Forsyth			for(sp := pp.sp-c; sp < pp.sp; sp++){
270*37da2899SCharles.Forsyth				a += sep + pp.stack[sp];
271*37da2899SCharles.Forsyth				sep = ", ";
272*37da2899SCharles.Forsyth			}
273*37da2899SCharles.Forsyth			pp.sp -= c;
274*37da2899SCharles.Forsyth			f = ppop(pp);
275*37da2899SCharles.Forsyth			if(op == Lnewcall)
276*37da2899SCharles.Forsyth				f = "new " + f;
277*37da2899SCharles.Forsyth			s = f + "(" + a + ")";
278*37da2899SCharles.Forsyth		';' =>
279*37da2899SCharles.Forsyth			break out;
280*37da2899SCharles.Forsyth		Landand or
281*37da2899SCharles.Forsyth		Loror or
282*37da2899SCharles.Forsyth		'?' =>
283*37da2899SCharles.Forsyth			s = ppop(pp);
284*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, pc);
285*37da2899SCharles.Forsyth			(pc, a1) = pexp(pp, pc, apc);
286*37da2899SCharles.Forsyth			s += " " + tokname(op) + " " + a1;
287*37da2899SCharles.Forsyth			if(op == '?'){
288*37da2899SCharles.Forsyth				(pc, apc) = getjmp(code.ops, pc);
289*37da2899SCharles.Forsyth				(pc, a2) = pexp(pp, pc, apc);
290*37da2899SCharles.Forsyth				s += " : "+ a2;
291*37da2899SCharles.Forsyth			}
292*37da2899SCharles.Forsyth		* =>
293*37da2899SCharles.Forsyth			fatal(pp.ex, "pexp: unknown op " + tokname(op));
294*37da2899SCharles.Forsyth		}
295*37da2899SCharles.Forsyth		ppush(pp, s);
296*37da2899SCharles.Forsyth	}
297*37da2899SCharles.Forsyth
298*37da2899SCharles.Forsyth	if(savesp == pp.sp)
299*37da2899SCharles.Forsyth		return (pc, "");
300*37da2899SCharles.Forsyth
301*37da2899SCharles.Forsyth	if(savesp != pp.sp-1)
302*37da2899SCharles.Forsyth		fatal(pp.ex, "unbalanced stack in pexp");
303*37da2899SCharles.Forsyth	return (pc, ppop(pp));
304*37da2899SCharles.Forsyth}
305*37da2899SCharles.Forsyth
306*37da2899SCharles.Forsythpcaseblk(pp: ref PPrint, pc, epc: int, indent: string): (int, string)
307*37da2899SCharles.Forsyth{
308*37da2899SCharles.Forsyth	code := pp.code;
309*37da2899SCharles.Forsyth	defpc, clausepc, nextpc, apc: int;
310*37da2899SCharles.Forsyth	s, a: string;
311*37da2899SCharles.Forsyth
312*37da2899SCharles.Forsyth	(pc, defpc) = getjmp(code.ops, pc);
313*37da2899SCharles.Forsyth	clausepc = pc;
314*37da2899SCharles.Forsyth	(pc, nextpc) = getjmp(code.ops, pc);
315*37da2899SCharles.Forsyth	for (; pc < epc; (clausepc, (pc, nextpc)) = (nextpc, getjmp(code.ops, nextpc))) {
316*37da2899SCharles.Forsyth		if (clausepc == defpc) {
317*37da2899SCharles.Forsyth			s += indent + "default:\n";
318*37da2899SCharles.Forsyth		} else {
319*37da2899SCharles.Forsyth			(pc, apc) = getjmp(code.ops, pc);
320*37da2899SCharles.Forsyth			(pc, a) = pexp(pp, pc, apc);
321*37da2899SCharles.Forsyth			s += indent + "case " + a + ":\n";
322*37da2899SCharles.Forsyth		}
323*37da2899SCharles.Forsyth		s += pstmt(pp, pc, nextpc, indent+"\t");
324*37da2899SCharles.Forsyth	}
325*37da2899SCharles.Forsyth	return (epc, s);
326*37da2899SCharles.Forsyth}
327*37da2899SCharles.Forsyth
328*37da2899SCharles.Forsythppush(pp: ref PPrint, s: string)
329*37da2899SCharles.Forsyth{
330*37da2899SCharles.Forsyth	if(pp.sp >= len pp.stack){
331*37da2899SCharles.Forsyth		st := array[2 * len pp.stack] of string;
332*37da2899SCharles.Forsyth		st[:] = pp.stack;
333*37da2899SCharles.Forsyth		pp.stack = st;
334*37da2899SCharles.Forsyth	}
335*37da2899SCharles.Forsyth	pp.stack[pp.sp++] = s;
336*37da2899SCharles.Forsyth}
337*37da2899SCharles.Forsyth
338*37da2899SCharles.Forsythppop(pp: ref PPrint): string
339*37da2899SCharles.Forsyth{
340*37da2899SCharles.Forsyth	if(pp.sp == 0)
341*37da2899SCharles.Forsyth		fatal(pp.ex, "popping too far off the pstack");
342*37da2899SCharles.Forsyth	return pp.stack[--pp.sp];
343*37da2899SCharles.Forsyth}
344*37da2899SCharles.Forsyth
345*37da2899SCharles.Forsythunescmap :=	array[128] of
346*37da2899SCharles.Forsyth{
347*37da2899SCharles.Forsyth	'\'' =>		byte '\'',
348*37da2899SCharles.Forsyth	'"' =>		byte '"',
349*37da2899SCharles.Forsyth	'\\' =>		byte '\\',
350*37da2899SCharles.Forsyth	'\b' =>		byte 'b',
351*37da2899SCharles.Forsyth	'\u000c' =>	byte 'f',
352*37da2899SCharles.Forsyth	'\n' =>		byte 'n',
353*37da2899SCharles.Forsyth	'\r' =>		byte 'r',
354*37da2899SCharles.Forsyth	'\t' =>		byte 't',
355*37da2899SCharles.Forsyth
356*37da2899SCharles.Forsyth	* =>		byte 0
357*37da2899SCharles.Forsyth};
358*37da2899SCharles.Forsyth
359*37da2899SCharles.Forsythescstr(s: string): string
360*37da2899SCharles.Forsyth{
361*37da2899SCharles.Forsyth	n := len s;
362*37da2899SCharles.Forsyth	sb := "";
363*37da2899SCharles.Forsyth	for(i := 0; i < n; i++){
364*37da2899SCharles.Forsyth		c := s[i];
365*37da2899SCharles.Forsyth		if(c < 128 && (e := int unescmap[c])){
366*37da2899SCharles.Forsyth			sb[len sb] = '\\';
367*37da2899SCharles.Forsyth			sb[len sb] = e;
368*37da2899SCharles.Forsyth		}else if(c > 128 || c < 32){
369*37da2899SCharles.Forsyth			sb += "\\u0000";
370*37da2899SCharles.Forsyth			for(j := 1; j <= 4; j++){
371*37da2899SCharles.Forsyth				sb[len sb - j] = "0123456789abcdef"[c & 16rf];
372*37da2899SCharles.Forsyth				c >>= 4;
373*37da2899SCharles.Forsyth			}
374*37da2899SCharles.Forsyth		}else
375*37da2899SCharles.Forsyth			sb[len sb] = c;
376*37da2899SCharles.Forsyth	}
377*37da2899SCharles.Forsyth	return sb;
378*37da2899SCharles.Forsyth}
379