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! |