このファイル: /home/web6047/www/cgi-bin/prj/20190503-javascript/vsync - snapshot 20190602/Scr.js
1
console.log( "Scr.js loading.." );
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
var cl = console.log;
44
var HereDocument = /[^]*\/\*\s([^]*)\*\/\}$/;
45
var FunctionCodeRE = /[^]*?\{\s([^]*)\}$/;
46
47
first = true;
48
49
50
function Scr( arg ) {
51
52
53
54
55
56
57
58
59
60
if( typeof arg === "object" ) {
61
62
63
text = arg.block;
64
this.selfBlock = arg;
65
this.blockScope = new Object();
66
this.functionScope = Scr.functionScopeStack[ Scr.functionScopeStack.length - 1 ];
67
68
} else {
69
70
71
if( typeof arg === "function" )
72
text = arg.toString().match( FunctionCodeRE )[ 1 ];
73
else
74
text = arg;
75
76
this.selfBlock = {
77
typ : "main",
78
ini : null,
79
cnd : null,
80
add : null,
81
};
82
this.blockScope = new Object();
83
this.functionScope = this.blockScope;
84
Scr.functionScopeStack.push( this.blockScope );
85
}
86
87
88
89
90
var forEscapes;
91
if( forEscapes = text.match( /for\([\s\S]*?;[\s\S]*?;[\s\S]*?\)/g ) ) {
92
text = text.replace( /for\([\s\S]*?;[\s\S]*?;[\s\S]*?\)/g, "_forEscape_" );
93
}
94
95
96
text = text.replace( /;/g, ";\n" );
97
98
99
if( forEscapes )
100
for( var i = 0; i < forEscapes.length; i++ ) {
101
text = text.replace( /_forEscape_/, forEscapes[ i ] );
102
}
103
104
105
106
107
108
109
110
var tail = text;
111
text = "";
112
while( tail.match( /\b(if\(|else\s|while\(|for\()/ ) ) {
113
text += RegExp.leftContext + RegExp.lastMatch;
114
tail = RegExp.rightContext;
115
116
117
var isElse = RegExp.lastMatch.match( /^else\s$/ );
118
119
120
if( isElse && tail.match( /^\s*if\(/ ) ) continue;
121
122
if( ! isElse ) {
123
124
var res = Scr.getToPairBracket( tail );
125
text += res[ 1 ] + ")";
126
tail = res[ 2 ].substr( 1 );
127
}
128
129
130
if( tail.match( /^\s*[^{\s].*;/ ) ) {
131
tail = RegExp.rightContext;
132
text += "{" + RegExp.lastMatch + "}";
133
}
134
}
135
text += tail;
136
137
text = text.replace( /[{}]/g, function( s ) { return "\n" + s + "\n" } );
138
text = text.replace( /^\s+/mg, "" );
139
text = text.replace( /\/\/.*$/gm, "" );
140
text = text.replace( /\n$/, "" );
141
142
143
if( first ) {
144
first = false;
145
cl( "\n=====" + text.replace( /^/mg, "\t" ) + "\n====\n" );
146
}
147
148
this.lines = text.split( /\n/ );
149
150
151
this.programCounter = 0;
152
this.isEnd = false;
153
this.isDelayed = false;
154
155
156
this.subBlockLV = -1;
157
this.subBlock = null;
158
this.resultOfIf = null;
159
this.isGettingSubBlock = false;
160
161
}
162
Scr.getToPairBracket = function( string ) {
163
var result = [
164
string,
165
"",
166
""
167
];
168
var tail = string;
169
var level = 0;
170
while( tail.match( /[\(\)]/ ) ) {
171
result[ 1 ] += RegExp.leftContext;
172
tail = RegExp.rightContext;
173
var got = RegExp.lastMatch;
174
175
if( got == "(" ) {
176
level++;
177
} else {
178
179
level--;
180
181
if( level == -1 ) {
182
result[ 2 ] = got + tail;
183
return result;
184
}
185
}
186
result[ 1 ] += got;
187
}
188
return result;
189
}
190
Scr.prototype.execBlock = function( subBlock ) {
191
192
Scr.stack.push( this );
193
194
scr = new Scr( subBlock );
195
196
setTimeout( scr.exec.bind( scr ), 0 );
197
}
198
Scr.prototype.eval = function( script ) {
199
with( this.functionScope )
200
with( this.blockScope )
201
return eval( script );
202
}
203
Scr.prototype.exec = function() {
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
while( ! this.isEnd ) {
229
230
231
var isEnableElse = this.resultOfIf == false;
232
this.resultOfIf = null;
233
234
var line = this.lines[ this.programCounter ];
235
236
237
this.programCounter ++;
238
239
240
if( this.programCounter > this.lines.length ) {
241
242
switch( this.selfBlock.typ ) {
243
case "main":
244
case "if":
245
case "else":
246
case "else if":
247
248
this.isEnd = true;
249
break;
250
case "for":
251
252
if( this.selfBlock.add ) this.eval( this.selfBlock.add );
253
254
case "while":
255
256
if( this.eval( this.selfBlock.cnd ) ) {
257
258
this.programCounter = 0;
259
} else {
260
261
this.isEnd = true;
262
}
263
break;
264
}
265
continue;
266
}
267
268
269
270
271
if( this.isGettingSubBlock ) {
272
if( line == "{" ) {
273
this.subBlockLV ++;
274
} else if( line == "}" ) {
275
this.subBlockLV --;
276
277
if( this.subBlockLV == 0 ) {
278
this.isGettingSubBlock = false;
279
280
281
if( this.subBlock.typ == "for" ) this.eval( this.subBlock.ini );
282
283
284
var subBlockIsIf = this.subBlock.typ.match( /^(?:if|else if)$/ );
285
if( this.eval( this.subBlock.cnd ) ) {
286
287
if( subBlockIsIf ) this.resultOfIf = true;
288
this.execBlock( this.subBlock );
289
break;
290
} else {
291
292
if( subBlockIsIf ) this.resultOfIf = false;
293
continue;
294
}
295
}
296
}
297
298
299
this.subBlock.block += line + "\n";
300
continue;
301
302
}
303
304
305
306
307
if( line.match( /^delay\(/ ) ) {
308
309
310
this.isDelayed = true;
311
break;
312
313
} else if( line.match( /^(if|while)\(([\s\S]*)\)/ ) ) {
314
315
316
this.subBlock = {
317
typ : RegExp.$1,
318
cnd : RegExp.$2,
319
}
320
continue;
321
322
} else if( line.match( /^for\(\s*([\s\S]*)\s*;\s*([\s\S]*)\s*;\s*([\s\S]*\s*)\)/ ) ) {
323
324
325
this.subBlock = {
326
typ : "for",
327
ini : RegExp.$1,
328
cnd : RegExp.$2,
329
add : RegExp.$3,
330
}
331
332
333
if( this.subBlock.ini.match( /^var / ) ) {
334
this.subBlock.ini = this.subBlock.ini.replace( /^var\s+/, "window." );
335
} else {
336
this.subBlock.ini = "window." + this.subBlock.ini;
337
}
338
this.subBlock.cnd = "window." + this.subBlock.cnd;
339
this.subBlock.add = "window." + this.subBlock.add;
340
341
continue;
342
} else if( line.match( /^else\s+if\(([\s\S]*)\)/ ) ) {
343
344
345
this.subBlock = {
346
typ : "else if",
347
cnd : isEnableElse.toString() + " && ( " + RegExp.$1 + ")",
348
}
349
continue;
350
351
} else if( line.match( /^else\s*$/ ) ) {
352
353
354
this.subBlock = {
355
typ : "else",
356
cnd : isEnableElse.toString(),
357
}
358
continue;
359
360
} else if( line == "{" ) {
361
362
363
this.subBlock.block = "";
364
this.subBlockLV = 1;
365
this.isGettingSubBlock = true;
366
continue;
367
368
} else {
369
370
371
372
373
line = line.replace( /;$/, "" );
374
if( line.match( /^([a-z0-9$_\.]*_)\(([\s\S]*)\)$/ ) ) {
375
376
377
378
var funcName = RegExp.$1;
379
var funcOpt = RegExp.$2;
380
381
funcName = funcName.replace( /_$/, "" );
382
cl( funcName );
383
var source = window[ funcName ].toString().match( FunctionCodeRE )[ 1 ];
384
this.execBlock( source );
385
break;
386
387
} else {
388
389
390
var recursive = function( string ) {
391
var right = string;
392
string = "";
393
394
while( right.match( /([a-z0-9$_\.]*)\(([\s\S]*)\)/ ) ) {
395
var left = RegExp.leftContext;
396
right = RegExp.rightContext;
397
var center = RegExp.lastMatch;
398
var funcName = RegExp.$1;
399
var funcOpt = RegExp.$2;
400
401
string += left + this.eval( funcName + "(" + recursive( funcOpt ) + ")" );
402
}
403
string += right;
404
return string;
405
}.bind( this );
406
407
var line2 = recursive( line );
408
line2 = line2.replace( /^var\s+/, "scr.functionScope." );
409
line2 = line2.replace( /^let\s+/, "scr.blockScope." );
410
411
this.eval( line2 );
412
413
}
414
}
415
}
416
417
418
if( this.isEnd ) {
419
if( Scr.stack.length > 0 ) {
420
421
scr = Scr.stack.pop();
422
setTimeout( scr.exec.bind( scr ), 0 );
423
} else {
424
console.log( "all end." );
425
}
426
return;
427
}
428
429
430
if( this.isDelayed ) {
431
this.isDelayed = false;
432
this.timerID = setTimeout( function() { this.exec(); }.bind( this ), 100 );
433
return;
434
}
435
436
};
437
438
439
440
441
Scr.stack = new Array();
442
Scr.functionScopeStack = new Array();