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 |