View difference between Paste ID: QY5Xbmd1 and xevgUAj1
SHOW: | | - or go back to the newest paste.
1
// My Server Language - Fast Line
2
Versions msl_fl_version[]={
3
	"0.0.0.5", "16.10.2013 05:06",
4
	"0.0.0.4", "15.10.2013 17:24",
5
	"0.0.0.3", "14.10.2013 16:22",
6
	"0.0.0.2", "14.10.2013 01:08",
7
	"0.0.0.1", "13.10.2013 21:05"	
8
};
9
10
11
12
// Values
13
class msl_value : public OMatrixT<msl_value>{
14
public:
15
	// prev, next, up first, up end
16
	msl_value *_p, *_n;//, *_a, *_e;
17
	MString key, val;
18
19
	msl_value(){ _p=0; _n=0; }
20
21
	msl_value* New(){
22
		msl_value *p=new msl_value;
23
		if(!p) return 0;
24
25
		OMAdd(p);
26
		return p;
27
	}
28
29
	msl_value* Find(VString key){
30
		if(!this) return 0;
31
		
32
		for(msl_value*p=_a; p; p=p->_n){
33
			if(p->key==key) return p;
34
		}
35
36
		return 0;
37
	}
38
39
	msl_value* Set(VString key, VString val){
40
		msl_value *p=Find(key);
41
		if(p){
42
			p->val=val;
43
		} else{
44
			p=New();
45
			if(p){
46
				p->key=key; p->val=val;
47
			}
48
		}
49
		return p;
50
	}
51
52
	VString Get(VString key){
53
		msl_value *p=Find(key);
54
		if(p)
55
			return p->val;
56
		else
57
			return VString();
58
	}
59
60
	msl_value* SGet(VString key){
61
		msl_value *p=Find(key);
62
		if(!p){
63
			p=New();
64
			if(p){
65
				p->key=key; p->val.sz=0xffffffff;
66
			}
67
		}
68
		return p;
69
	}
70
71
	void Del(VString key){
72
		msl_value *p=Find(key);
73
		if(p){
74
			OMDel(p); delete p;
75
		}
76
		return ;
77
	}
78
79
	void Copy(msl_value *val){
80
		Clear();
81
		this->val=val->val;
82
		
83
		for(msl_value*p=val->_a; p; p=p->_n){
84
			Set(p->key, p->val)->Copy(p);			
85
		}
86
		return ;
87
	}
88
89
	void Move(msl_value &val){
90
		Clear();
91
		_a=val._a; _e=val._e; val._a=0; val._e=0;
92
		this->val-=val.val;		
93
		return ;
94
	}
95
96
	~msl_value(){ Clear(); }
97
	void Clear(){ OMClear(); }
98
99
};
100
101
// Function Arguments
102
class msl_fl_farg{
103
public:
104
	msl_value val;
105
	//VString val;
106
};
107
108
class msl_fl_fargs{
109
	MString _args; // memory buffer
110
	msl_fl_farg *args; // 
111
	int asz, usz; // all sz & use sz
112
113
	int UpSize(){
114
		// reserv memory
115
		_args.Reserv(sizeof(msl_fl_farg)*(asz+16));
116
		// if error
117
		if(!_args){
118
			asz=0; usz=0;
119
			return 0;
120
		}
121
		// update
122
		asz+=16;
123
		args=(msl_fl_farg*)_args.data;
124
125
		return 1;
126
	}
127
128
public:
129
	// constructor & destructor
130
	msl_fl_fargs(){ args=0; asz=0; usz=0; }
131
	~msl_fl_fargs(){ }
132
133
	// vals[id];
134
	msl_fl_farg &operator[](const int i){
135
		if(i>usz){ globalerror("msl_fl_fargs epic fail"); }
136
		return args[i]; 
137
	}
138
139
	// add value
140
	msl_fl_farg* Add(msl_value &val){
141
		if(usz>=asz){ if(!UpSize()) return 0; }
142
		// add
143
		args[usz].val.Move(val);
144
		return &args[usz++];
145
	}
146
147
	int Sz(){ return usz; }
148
	
149
};
150
151
//#include "omatrix-msl_value.h"
152
153
// Hints:
154
// msl_value. Механизм балансировки возвращаемых значений.  Чтобы не копировать лишний раз структуру с данными.
155
156
157
// spaces
158
// Do() - all process operations
159
// Set () - set
160
// Get () - get
161
162
//#define MSL_DOOPT_ERROR 0
163
//#define MSL_DOOPT_STOPIT (MSL_DOOPT_ERROR)
164
165
class msl_fl{
166
	HLString output; // result
167
168
	int do_opt, do_opt_stopit, do_opt_ifw, do_opt_active;
169
170
	msl_value global;
171
172
	public:
173
174
	// init
175
	msl_fl(){ do_opt=0; do_opt_stopit=0; }
176
177
	~msl_fl(){	}
178
	
179
	// process
180
	void Do(VString code){
181
		unsigned char *line=code, *pline=line, *to=code.endu();
182
		// stop it & active
183
		do_opt_stopit=0; do_opt_active=1; do_opt_ifw=0;
184
		// value;
185
		msl_value outval;
186
187
		while(line<to && !do_opt_stopit){
188
			if(*line=='<' && line+1<to && *(line+1)=='?'){
189
				// set result
190
				SetOutput(VString(pline, line-pline));
191
				// *line='<?...' skip this 2 sumbols
192
				line+=2;
193
194
				//while(!do_opt_stopit){
195
					// do msl
196
				//	DoCode(line, to, outval, ';');
197
				//	if(line>=to || *line!=';') break;
198
				//	line++;
199
				//}
200
				DoCodeMulti(line, to, outval);
201
202
				// if(line='?>')
203
				if(line+1>=to || *line!='?' || *(line+1)!='>'){
204
					// oh no
205
					SetError("No find '?>'");
206
					// exit
207
					return ;
208
				} else{
209
					// *line='?>...' skip this 2 sumbols
210
					line+=2; pline=line;
211
				}
212
			}
213
			line++;
214
		}
215
		// set result
216
		SetOutput(VString(pline, line-pline));
217
		return ;
218
	}
219
220
	// do code; code; code
221
	void DoCodeMulti(unsigned char*&line, unsigned char *to, msl_value &outval, unsigned char ecode=1){
222
		while(!do_opt_stopit){
223
			// do msl
224
			DoCode(line, to, outval, ';', ecode);
225
			if(line>=to || *line!=';') break;
226
			line++;
227
		}
228
		return ;
229
	}
230
231
	void DoCode(unsigned char*&line, unsigned char *to, msl_value &outval, unsigned char ecode=1, unsigned char ecodet=1){
232
		msl_value *value=0;
233
		unsigned char *pline=0;
234
235
236
		while(line<to && !do_opt_stopit){
237
238
			// skip space 
239
			while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
240
241
			// $value
242
			if(*line=='$'){
243
				if(value){ SetError("double $value"); return ; }
244
				value=DoCodeValue(++line, to);
245
				//outval.val=value->val;
246
				continue;
247
			}else
248
			// function
249
			if(*line>='a' && *line<='z' || *line>='A' && *line<='Z' || *line=='_'){
250
				
251
				DoCodeFunction(line, to);
252
				continue;
253
			}
254
			// ecode
255
			else if(*line==ecode || *line==ecodet){
256
				if(value) outval.val=value->val;
257
				return ;
258
			}
259
			// string
260
			else if(*line=='"' || *line=='\''){
261
				pline=++line; 
262
				if(*line=='"')
263
					while(line<to && *line!='"') line++;
264
				else
265
					while(line<to && *line!='\'') line++;
266
				if(line>=to){ SetError("closed \" or ' not found"); }
267
				outval.val=VString(pline, line-pline);
268
				line++;
269
				continue;
270
			}
271
			// numbers
272
			else if(*line>='0' && *line<='9'){
273
				pline=line; 
274
				while(line<to && *line>='0' && *line<='9') line++;
275
				outval.val=VString(pline, line-pline);
276
				continue;				
277
			}
278
			// operator=
279
			else if(*line=='='){				
280
				if(!value){ SetError("need $value="); return ; }
281
				
282
				msl_value val;
283
				DoCode(++line, to, val, ecode, ecodet);
284
				
285
				// move
286
				value->Clear();
287
				value->val=val.val;
288
				value->_a=val._a; value->_e=val._e; val._a=0; val._e=0;
289
				// set outval
290
				outval.Copy(value);
291
				continue;			
292
			}
293
			// operator--
294
			else if(*line=='-' && line+1<to && *(line+1)=='-'){
295
				if(!value){ SetError("need $value--"); return ; }
296
				// $val--
297
				value->val=itos(value->val.toi()-1);
298
				// set outval
299
				outval.Copy(value);
300
				line+=2;
301
				continue;
302
			}
303
			// '?>' end do code
304
			else if(*line=='?' && line+1<to && *(line+1)=='>'){
305
				return ;
306
			}
307
			// what the sumbol?
308
			else{				
309
				SetError(HLString()+"Unknown sumbol: '"+VString(line, 1)+"'.");
310
				return ;
311
			}
312
313
			// skip space
314
			while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
315
			line++;
316
		}
317
318
		return ;
319
	}
320
321
	msl_value* DoCodeValue(unsigned char*&line, unsigned char *to){
322
		unsigned char *pline=line;
323
324
		while(line<to && *line>='a' && *line<='z' || *line>='A' && *line<='Z' || *line=='_') line++;
325
		if(line>=to){
326
			SetError(HLString()+"EOF.");
327
			return 0;
328
		}
329
		
330
		// Get existing or create new
331
		msl_value *val;
332
		
333
		if(do_opt_active)
334
			val=global.SGet(VString(pline, line-pline));
335
		else val=0;
336
337
		// skip space
338
		while(1){
339
			while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
340
			if(line<to && *line=='['){
341
				msl_value dval;
342
				DoCode(++line, to, dval, ']');
343
344
				// next []
345
				if(do_opt_active) val=val->SGet(dval.val);
346
				line++;
347
			}
348
			else return val;
349
		}
350
351
		return 0;
352
	}
353
354
	void DoCodeFunction(unsigned char*&line, unsigned char *to){
355
		VString name; unsigned char *pline=line; msl_fl_fargs args;
356
		unsigned char *code, *ecode;
357
358
		while(line<to){
359
			// normal name
360
			if(*line>='a' && *line<='z' || *line>='A' && *line<='Z' || *line=='_'){}
361
			else{
362
				name.setu(pline, line-pline);
363
				while(line<to){
364
					if(*line=='('){
365
						line++;
366
						code=line;
367
						
368
						while(!do_opt_stopit){
369
							msl_value val;
370
							DoCode(line, to, val, ',', ')');
371
							//if(!DoCodeFunctionArgs(line, to, args)) return ;
372
							args.Add(val);
373
							if(line>=to){ SetError("not found ')'. EOF"); return ; }
374
							if(*line!=',') break;
375
							line++;
376
						}
377
						ecode=line;
378
						line++;
379
						// Exec function
380
						if(!DoCodeFunctionExec(name, args)) return ;
381
						//line++;
382
383
						// if, while, for functions
384
						if(do_opt_ifw){
385
							if(name=="if")
386
								DoCodeFunctionIf(line, to);
387
							else if(name=="while")
388
								DoCodeFunctionWhile(line, to, code, ecode);
389
							//else if(name=="for")
390
								//DoCodeFunctionFor(line, to);
391
						}
392
393
						return ;
394
					}
395
					else if(!(*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')){
396
						SetError(HLString()+"function '"+name+"' open '(' not found.");
397
						return ;
398
					}
399
400
					line++;
401
				}
402
			}
403
			line++;
404
		}
405
406
		// line='functionname'EOF
407
		SetError(HLString()+"end of function name: '"+VString(pline, line-pline)+"'");
408
		return ;
409
	}
410
411
	void DoCodeFunctionIf(unsigned char*&line, unsigned char *to){
412
		msl_value val; unsigned char endcode;
413
		// save values
414
		int old_ifw=do_opt_ifw, old_active=do_opt_active; do_opt_ifw=0;
415
416
		// skip space
417
		while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
418
		// single or {multi}
419
		if(line>=to){ SetError("if(...) EOF"); return ; }
420
		
421
		// set active
422
		do_opt_active=old_active && old_ifw==2;
423
		// do if(){ code }
424
		if(*(line)=='{'){ endcode='}'; line++; } else endcode=';';
425
		DoCodeMulti(line, to, val, endcode); line++;
426
427
		// skip space
428
		while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
429
		// test on 'else'
430
		if(line+4<to && *line=='e' && *(line+1)=='l' && *(line+2)=='s' && *(line+3)=='e'){
431
			// skip 'else'
432
			line+=4;
433
			// skip space
434
			while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
435
			// set active
436
			do_opt_active=old_active && old_ifw==1;
437
			// do else{ code }
438
			if(*(line)=='{'){ endcode='}'; line++; } else endcode=';';
439
			DoCodeMulti(line, to, val, endcode); line++;
440
		}
441
442
		// load old value
443
		do_opt_active=old_active; do_opt_ifw=0;
444
		return ;
445
	}
446
447
	void DoCodeFunctionWhile(unsigned char *&line, unsigned char *to, unsigned char *code, unsigned char *ecode){
448
		msl_value val; unsigned char *lline, *elline, *tline; unsigned char endcode;
449
		
450
		// save values
451
		int old_ifw=do_opt_ifw, old_active=do_opt_active; do_opt_ifw=0;
452
		// skip space
453
		while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
454
		if(line>=to){ SetError("if(...) EOF"); return ; }
455
456
		// set active
457
		do_opt_active=old_active && old_ifw==2; lline=line;
458
		// do while(){ code }
459
		if(*(line)=='{'){ endcode='}'; line++; } else endcode=';';
460
		DoCodeMulti(line, to, val, endcode); line++;
461
		elline=line;
462
463
		// while
464
		while(old_active && old_ifw==2){
465
			msl_value val;
466
			// do while( it code )
467
			tline=code;
468
			DoCode(tline, ecode+1, val, ')');
469
			// result
470
			if(!val.val || val.val=="0") break;
471
472
			// do while(1){ it code }
473
			tline=lline;
474
			if(*(tline)=='{'){ endcode='}'; tline++; } else endcode=';';
475
			DoCodeMulti(tline, elline, val, endcode);
476
		}
477
478
		// load old value
479
		do_opt_active=old_active; do_opt_ifw=0;
480
		return ;
481
	}
482
483
484
	int DoCodeFunctionExec(VString name, msl_fl_fargs &args){
485
		// all sections
486
487
		if((name=="if" || name=="while") && args.Sz()==1){
488
			do_opt_ifw=args[0].val.val && args[0].val.val!="0"; do_opt_ifw++;
489
			return 1;
490
		}
491
492
		// if active
493
		if(!do_opt_active) return 1;
494
495
		// exec
496
		if(name=="print" || name=="echo"){
497
			for(int i=0; i<args.Sz(); i++){
498
				print(args[i].val.val);
499
			}
500
			return 1;
501
		}
502
503
		//
504
		SetError(HLString()+"Function: '"+name+"' not found");
505
		return 0;
506
	}
507
508
	// global value
509
	void SetValue(VString key, VString val){
510
	
511
512
	}
513
514
	// get output
515
	MString GetOutput(){
516
		// return result;
517
		return MString(output.oneline(), output.size());
518
	}
519
520
protected:
521
	// set output
522
	void SetOutput(VString line){
523
		// add line to result
524
		output+line;
525
		return ;
526
	}
527
528
	void SetWarning(VString line){
529
		// add error line to result
530
		output+"MSL-FL Warning: "+line+"\r\n";
531
		return ;
532
	}
533
534
	void SetError(VString line){
535
		// add error line to result
536
		output+"MSL-FL Error: "+line+"\r\n";
537
		// stop
538
		do_opt_stopit=1;
539
		return ;
540
	}
541
542
	void SetEpic(VString line){
543
		// add error line to result
544
		output+"MSL-FL Epic Fail: "+line+"\r\n";
545
		// stop
546
		do_opt_stopit=1;
547
		return ;
548
	}
549
550
};
551
552
int TestMSL(){
553
	msl_fl msl;
554
555
	msl.Do("<? print('Hello World!!!'); $i=55; while($i){ $i--; print('1'); } ?>");
556
	MString res=msl.GetOutput();
557
	print(res);
558
559
	return 0;
560
}
561
562
// Result to console: Hello World!!!1111111111111111111111111111111111111111111111111111111