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