1
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
function debugprint_recursive( object, indent ) {
30
31
if( indent == null ) indent = "";
32
33
console.log( "DEC[" + object.declaration + "]\tINST[" + object.instruction + "]\tARG[" + object.argtext + "]" );
34
for( var i = 0; i < object.children.length; i++ ) {
35
indent += "\t";
36
debugprint_recursive( object.children[ i ], indent );
37
indent = indent.substr( 0, indent.length - 1 );
38
}
39
}
40
41
42
43
function Instruction( declaration, instruction, argtext, blocktext, comment, tp ) {
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
this.declaration = declaration;
67
this.instruction = instruction;
68
this.argtext = argtext;
69
this.blocktext = blocktext;
70
this.comment = comment;
71
this.tp = tp;
72
73
this.children = new Array();
74
75
76
if( this.blocktext != null ) this.analyze( this.blocktext );
77
78
}
[There are deleted line(s).]
[Instruction.prototype.analyze = function( text ) {
/*
text を受け取り、内容を解析して階層構造を見い出し、childrenへ収める。
返り値はなし。
流れ:
//1. 不要なタブと改行を削除する。
//2. 括弧で囲まれた部分を退避する。(すると入れ子構造がなくなり4項目の取得が行いやすくなる)
//3. そのテキストを解析。各行の形状別に4項目を取得
//4. 4項目のうち argtext と blocktext について、退避した括弧部分を展開
//5. 4項目から新しいinstructionを生成する(階層構造となる)
*/
]
79
80
Instruction.prototype.analyze = function( text ) {
81
82
text = text.replace( /(if|while|for)(\(.*?\)\s*)([^\{\s][\s\S]+)/g, function( m, a, b, c ) { return a + b + "{" + c + "}" } );
83
84
85
86
text = text.replace( /^\t+/mg, " " );
87
text = text.replace( /\n/g, ";" );
88
89
90
91
92
93
var res = escapeBrackets( text, "{", "}", "_block_#_;", true );
94
var blocks = res.contents;
95
96
var res = escapeBrackets( res.text, "(", ")", "_kakko_#_" );
97
var kakkos = res.contents;
98
99
100
var text2 = res.text;
101
text2 = text2.replace( /;\s+/mg, ";" );
102
text2 = text2.replace( /^\s+/gm, "" );
103
104
105
106
var lines = text2.split( /;/ );
107
for( var i = 0; i < lines.length; i++ ) {
108
var line = lines[ i ];
109
110
if( line.match( /^\s*$/ ) ) continue;
111
112
113
var declaration = null;
114
var instruction = null;
115
var argtext = null;
116
var blocktext = null;
117
var comment = null;
118
var commentN = null;
119
var tp = null;
120
121
122
if( line.match( /\/\// ) ) {
123
line = RegExp.leftContext;
124
comment = RegExp.rightContext;
125
comment = comment.replace( /^\s+|\s+$/g, "" );
126
}
127
if( i + 1 < lines.length && lines[ i + 1 ].match( /\/\// ) ) {
128
commentN = RegExp.rightContext;
129
commentN = commentN.replace( /^\s+|\s+$/g, "" );
130
}
131
132
133
134
135
136
137
if( line.match( /(var\s+|)(.+=)(.+)/ ) ) {
138
139
tp = 1;
140
declaration = RegExp.$1;
141
instruction = RegExp.$2;
142
argtext = RegExp.$3;
143
144
} else if( line.match( /(var\s+)(.+)/ ) ) {
145
146
tp = 2;
147
declaration = RegExp.$1;
148
instruction = RegExp.$2;
149
150
} else if( line.match( /(function\s+|)(.+)\((.*)\)(.+)/ ) ) {
151
152
tp = 3;
153
declaration = RegExp.$1;
154
instruction = RegExp.$2;
155
argtext = RegExp.$3;
156
blocktext = RegExp.$4;
157
158
} else if( line.match( /(.+)\((.*)\)/ ) && commentN == "stepin" ) {
159
160
tp = 4.5;
161
instruction = "if";
162
argtext = "true";
163
blocktext = eval( RegExp.$1 ).toString().match( /\{([\s\S]*)\}/ )[ 1 ];
164
165
} else if( line.match( /(.+)\((.*)\)/ ) ) {
166
167
tp = 4;
168
instruction = RegExp.$1;
169
argtext = RegExp.$2;
170
171
} else if( line.match( /(.*)\s(.*)/ ) ) {
172
173
tp = 5;
174
instruction = RegExp.$1;
175
blocktext = RegExp.$2;
176
177
} else if( comment != null ) {
178
179
} else {
180
181
console.log( "syntax error: " + ": [" + line + "]" );
182
continue;
183
184
}
185
186
187
if( argtext != null )
188
while( argtext.match( /_kakko_(\d+)_/ ) ) {
189
argtext = RegExp.leftContext + kakkos[ RegExp.$1 ] + RegExp.rightContext;
190
}
191
192
if( blocktext != null ) {
193
194
195
while( blocktext.match( /_kakko_(\d+)_/ ) ) {
196
blocktext = RegExp.leftContext + kakkos[ RegExp.$1 ] + RegExp.rightContext;
197
}
198
199
if( blocktext.match( /_block_(\d+)_/ ) ) {
200
blocktext = blocks[ RegExp.$1 ];
201
}
202
}
203
204
205
if( declaration != null ) declaration = declaration.replace( /^\s+|\s+$/, "" );
206
207
208
this.children.push( new Instruction( declaration, instruction, argtext, blocktext, comment, tp ) );
209
}
210
}
211
212
Instruction.prototype.exec = function() {
213
var envs = new Array();
214
var env = {
215
object : this,
216
counter : 0,
217
next : null,
218
parentEnv : null,
219
intoBlk : true,
220
};
221
222
owner = this;
223
224
var func = function() {
225
226
227
loop1: while( 1 ) {
228
229
if( ! env.object.commentProcessed && env.object.comment && env.object.comment.match( /anm(\d+)/ ) ) {
230
env.object.commentProcessed = true;
231
var ms = Number( RegExp.$1 );
232
setTimeout( func, ms );
233
break loop1;
234
}
235
else if( ! env.object.commentProcessed && env.object.comment && env.object.comment.match( /suspend/ ) ) {
236
env.object.commentProcessed = true;
237
owner.resume = func;
238
break loop1;
239
}
240
241
env.object.commentProcessed = false;
242
243
244
switch( env.object.instruction ) {
245
246
case "if":
247
env.intoBlk = eval( env.object.argtext );
248
249
if( env.next && env.next.instruction == "else" ) {
250
env.next.elseCancel = env.intoBlk;
251
}
252
break;
253
case "else":
254
break;
255
256
case "for":
257
if( typeof env.forInit === "undefined" ) {
258
if( env.object.argtext.match( /(.*);(.*);(.*)/ ) ) {
259
env.forInit = RegExp.$1;
260
env.forCond = RegExp.$2;
261
env.forAdd = RegExp.$3;
262
} else {
263
console.log( "syntax erro on for: " + env.object.argtext );
264
}
265
env.forInit = env.forInit.replace( /var\s+/, "env." );
266
eval( env.forInit );
267
} else {
268
with( env ) eval( env.forAdd );
269
}
270
with( env ) env.intoBlk = eval( env.forCond );
271
break;
272
273
default:
274
var script = "";
275
if( env.object.declaration == "function" ) {
276
script += "env.parentEnv.";
277
script += env.object.instruction + " = function( ";
278
script += env.object.argtext + " ) { ";
279
script += env.object.blocktext + " }";
280
env.intoBlk = false;
281
} else if( env.object.declaration == "var" ) {
282
script += "env.parentEnv.";
283
script += env.object.instruction;
284
if( env.object.argtext == null ) {
285
script += " = null";
286
} else {
287
script += env.object.argtext;
288
}
289
env.intoBlk = false;
290
} else if( env.object.instruction != null ) {
291
script += env.object.instruction;
292
if( env.object.instruction.substr( -1 ) == "=" ) {
293
294
script += env.object.argtext;
295
} else if( env.object.argtext != null ) {
296
script += "(" + env.object.argtext + ")";
297
}
298
299
} else {
300
301
break;
302
}
303
304
305
var allWith = "";
306
for( var j = 1; j < envs.length - 1; j++ ) {
307
allWith += "with( envs[ " + j + " ] ) ";
308
}
309
if( env.parentEnv ) allWith += "with( env.parentEnv ) ";
310
311
eval( allWith + script );
312
}
313
314
315
while( env.object.elseCancel || ! env.intoBlk || env.counter == env.object.children.length ) {
316
317
if( envs.length == 0 ) break loop1;
318
319
if( env.object.instruction == "for" && env.intoBlk ) {
320
env.counter = 0;
321
continue loop1;
322
}
323
324
325
env = envs.pop();
326
}
327
328
329
envs.push( env );
330
env = {
331
object : env.object.children[ env.counter++ ],
332
next : env.object.children[ env.counter ],
333
counter : 0,
334
intoBlk : true,
335
parentEnv : env,
336
}
337
338
}
339
340
};
341
342
343
func();
344
345
};
346
function escapeBrackets( text, startBracket, endBracket, identifier, swDelBracket ) {
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
var res = {
382
text : "",
383
contents : new Array()
384
};
385
386
var level = 0;
387
var buffer = "";
388
var tail = text;
389
var bracketSearchKey = "[" + startBracket + endBracket + "]";
390
391
while( tail.match( bracketSearchKey ) ) {
392
var bracket = RegExp.lastMatch;
393
var left = RegExp.leftContext;
394
tail = RegExp.rightContext;
395
396
397
if( level > 0 )
398
buffer += left;
399
else
400
res.text += left;
401
402
403
if( bracket == endBracket ) {
404
level --;
405
406
if( level == 0 ) {
407
var id = identifier.replace( "#", res.contents.length );
408
res.text += id;
409
res.contents.push( buffer );
410
buffer = "";
411
}
412
}
413
414
415
416
if( level > 0 )
417
buffer += bracket;
418
else if( ! swDelBracket )
419
res.text += bracket;
420
421
422
if( bracket == startBracket ) {
423
level ++;
424
}
425
}
426
res.text += tail;
427
428
return res;
429
}
430
console.log( "batch.js is loaded." );