Advertisement
Guest User

MikelSV / MSL-FL

a guest
Dec 1st, 2013
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 36.03 KB | None | 0 0
  1. // My Server Language - Fast Line
  2. Versions msl_fl_version[]={
  3.     "0.0.1.0", "30.11.2013 15:12",
  4.     "0.0.0.8", "19.10.2013 21:29",
  5.     "0.0.0.7", "18.10.2013 21:48",
  6.     "0.0.0.6", "17.10.2013 23:13",
  7.     "0.0.0.5", "16.10.2013 05:06",
  8.     "0.0.0.4", "15.10.2013 17:24",
  9.     "0.0.0.3", "14.10.2013 16:22",
  10.     "0.0.0.2", "14.10.2013 01:08",
  11.     "0.0.0.1", "13.10.2013 21:05"  
  12. };
  13.  
  14. // Values
  15. class msl_value : public OMatrixT<msl_value>{
  16. public:
  17.     // prev, next, up first, up end
  18.     msl_value *_p, *_n;//, *_a, *_e;
  19.     MString key, val;
  20.  
  21.     msl_value(){ _p=0; _n=0; }
  22.  
  23.     msl_value* New(){
  24.         msl_value *p=new msl_value;
  25.         if(!p) return 0;
  26.  
  27.         OMAdd(p);
  28.         return p;
  29.     }
  30.  
  31.     msl_value* Find(VString key){
  32.         if(!this) return 0;
  33.        
  34.         for(msl_value*p=_a; p; p=p->_n){
  35.             if(p->key==key) return p;
  36.         }
  37.  
  38.         return 0;
  39.     }
  40.  
  41.     msl_value* FindByKey(VString key, VString val){
  42.         if(!this) return 0;
  43.        
  44.         for(msl_value*p=_a; p; p=p->_n){
  45.             if(p->Get(key)==val) return p;
  46.         }
  47.  
  48.         return 0;
  49.     }
  50.  
  51.     msl_value* Find(msl_value *key){
  52.         if(!this) return 0;
  53.        
  54.         for(msl_value*p=_a; p; p=p->_n){
  55.             if(p==key) return p;
  56.         }
  57.  
  58.         return 0;
  59.     }
  60.  
  61.     int Size(){
  62.         if(!this) return 0;
  63.         int sz=0;
  64.        
  65.         for(msl_value*p=_a; p; p=p->_n){
  66.             sz++;
  67.         }
  68.  
  69.         return sz;
  70.     }
  71.  
  72.     VString Get(VString key){
  73.         msl_value *p=Find(key);
  74.         if(p)
  75.             return p->val;
  76.         else
  77.             return VString();
  78.     }
  79.  
  80.     msl_value* GetV(VString key){
  81.         msl_value *p=Find(key);
  82.         if(p)
  83.             return p;
  84.         else
  85.             return 0;
  86.     }
  87.  
  88.     msl_value* GetV(msl_value *key){
  89.         msl_value *p=Find(key);
  90.         if(p)
  91.             return p;
  92.         else
  93.             return 0;
  94.     }
  95.  
  96.     msl_value* GetVByPos(int pos){
  97.         msl_value *p=_a;
  98.         while(p){
  99.             if(!pos--) return p;
  100.             p=p->_n;
  101.         }
  102.         return 0;
  103.     }
  104.  
  105.     msl_value* SGet(VString key){
  106.         int isnew;
  107.         return SGet(key, isnew);
  108.     }
  109.  
  110.     msl_value* SGet(VString key, int &isnew){
  111.         msl_value *p=Find(key);
  112.         if(!p){
  113.             p=New(); isnew=1;
  114.             if(p){
  115.                 p->key=key; p->val.sz=0xffffffff;
  116.             }
  117.         } else isnew=0;
  118.         return p;
  119.     }
  120.  
  121.     msl_value* Set(VString key, VString val){
  122.         msl_value *p=Find(key);
  123.         if(p){
  124.             p->val=val;
  125.         } else{
  126.             p=New();
  127.             if(p){
  128.                 p->key=key; p->val=val;
  129.             }
  130.         }
  131.         return p;
  132.     }
  133.  
  134.     // Add
  135.     void Add(VString key, msl_value *val){
  136.         msl_value *p=New();
  137.         p->key=key;
  138.         p->Copy(val);
  139.         //p->val=val; p->key=key;
  140.         return ;
  141.     }
  142.  
  143.     msl_value * Add(VString key, VString val){
  144.         msl_value *p=New();
  145.         p->val=val; p->key=key;
  146.         return p;
  147.     }
  148.  
  149.     int Del(VString key){
  150.         msl_value *p=Find(key);
  151.         if(p){
  152.             OMDel(p);
  153.             delete p;
  154.             return 1;
  155.         }
  156.         return 0;
  157.     }
  158.  
  159.     void Del(msl_value *p){
  160.         if(!p) return ;
  161.  
  162.         // test in this line
  163.         OMDel(p); delete p;
  164.  
  165.         return ;
  166.     }
  167.  
  168. //protected:
  169. /*
  170.     void operator=(msl_value &val){
  171.         return ;
  172.     }
  173.     void operator=(msl_value *val){
  174.         return ;
  175.     }
  176. */
  177. public:
  178.  
  179.     void Copy(msl_value *val){
  180.         if(val) Copy(*val);
  181.     }
  182.  
  183.     void Move(msl_value *val){
  184.         if(val) Move(*val);
  185.     }
  186.  
  187.     void Copy(msl_value &val){
  188.         Clear();
  189.         this->val=val.val;
  190.        
  191.         for(msl_value*p=val._a; p; p=p->_n){
  192.             Set(p->key, p->val)->Copy(p);
  193.         }
  194.         return ;
  195.     }
  196.  
  197.     void Move(msl_value &val){
  198.         Clear();
  199.         _a=val._a; _e=val._e; val._a=0; val._e=0;
  200.         this->val-=val.val;    
  201.         return ;
  202.     }
  203.  
  204.     msl_value* n(){ return this ? _n : 0; }
  205.     msl_value* a(){ return this ? _a : 0; }
  206.  
  207.     void Clear(){
  208.         msl_value *p=_a, *d=p;
  209.         while(p){
  210.             d=p; p=p->_n; OMDel(d); delete d;
  211.         }
  212.          _a=0; _e=0;
  213.     }
  214.  
  215.     ~msl_value(){
  216.         Clear();
  217.     }
  218. };
  219.  
  220. // Function Arguments
  221. class msl_fl_farg{
  222. public:
  223.     // in
  224.     msl_value val, *ppval, *pval;
  225.     // ($key=val)
  226.     VString fkey, fval;
  227. };
  228.  
  229. class msl_fl_fargs{
  230.     MString _args; // memory buffer
  231.     msl_fl_farg *args; //
  232.     int asz, usz; // all sz & use sz
  233.  
  234.     int UpSize(){
  235.         // reserv memory
  236.         _args.Reserv(sizeof(msl_fl_farg)*(asz+16));
  237.         // if error
  238.         if(!_args){
  239.             asz=0; usz=0;
  240.             return 0;
  241.         }
  242.         // update
  243.         asz+=16;
  244.         args=(msl_fl_farg*)_args.data;
  245.  
  246.         return 1;
  247.     }
  248.  
  249. public:
  250.     // constructor & destructor
  251.     msl_fl_fargs(){ args=0; asz=0; usz=0; }
  252.     ~msl_fl_fargs(){ Clear(); }
  253.  
  254.     // vals[id];
  255.     msl_fl_farg &operator[](const int i){
  256.         if(i>usz){ globalerror("msl_fl_fargs epic fail"); }
  257.         return args[i];
  258.     }
  259.  
  260.     // add value
  261.     msl_fl_farg* Add(msl_value &val, msl_value *pval, msl_value *ppval){
  262.         if(usz>=asz){ if(!UpSize()) return 0; }
  263.         // add
  264.         args[usz].val.Move(val);
  265.         args[usz].pval=pval;
  266.         args[usz].ppval=ppval;
  267.         return &args[usz++];
  268.     }
  269.  
  270.     // add value
  271.     msl_fl_farg* AddF(VString k, VString v){
  272.         if(usz>=asz){ if(!UpSize()) return 0; }
  273.         // add
  274.         args[usz].fkey=k;
  275.         args[usz].fval=v;
  276.         args[usz].pval=0;
  277.         return &args[usz++];
  278.     }
  279.  
  280.     int Sz(){ return usz; }
  281.     int MSz(){
  282.         for(int i=0; i<usz; i++){
  283.             if(args[i].fval.data) return i;
  284.         }
  285.         return usz;
  286.     }
  287.  
  288.     void Clear(){
  289.         for(int i=0; i<usz; i++){
  290.             args[i].val.Clear();
  291.         }
  292.     }
  293.    
  294. };
  295.  
  296. class msl_function_d{
  297. public:
  298.     msl_function_d(){ use=0; }
  299.  
  300.     msl_function_d *_p, *_n;
  301.     VString name;
  302.     msl_fl_fargs args;
  303.     VString code;
  304.     int use;
  305.  
  306.     void UseIt(int v=1){ use=v; }
  307. };
  308.  
  309. class msl_function : public OMatrixT<msl_function_d>{
  310.  
  311. public:
  312.     msl_function(){}
  313.     ~msl_function(){ Clear(); }
  314.  
  315.     msl_function_d* New(){
  316.         msl_function_d*p=new msl_function_d;
  317.         OMAdd(p);
  318.         return p;
  319.     }
  320.  
  321.     msl_function_d *Find(VString name, int args){
  322.         for(msl_function_d *p=_a; p; p=p->_n){
  323.             if(p->use && p->name==name && args>=p->args.MSz() && args<=p->args.Sz()) return p;
  324.         }
  325.         return 0;
  326.     }
  327.  
  328.     void Del(msl_function_d *p){
  329.         OMRealDel(p);
  330.     }
  331.  
  332.     void Clear(){ OMClear(); }
  333. };
  334.  
  335. //#include "omatrix-msl_value.h"
  336.  
  337. // Hints:
  338. // msl_value. Механизм балансировки возвращаемых значений.  Чтобы не копировать лишний раз структуру с данными.
  339.  
  340.  
  341. //
  342. class msl_fl_extfunc{
  343. public:
  344.     virtual int DoCodeFunctionExec(VString name, msl_fl_fargs &args, msl_value &val){
  345.         // exec
  346.         if(name=="print" || name=="echo"){
  347.             //for(int i=0; i<args.Sz(); i++){
  348.                 //SetOutput(args[i].val.val);
  349.                 //print(args[i].val.val);
  350.             //}
  351.             //return 1;
  352.         }
  353.  
  354.         if(name=="testextfunc"){
  355.             val.val="ok";
  356.             return 1;
  357.         }
  358.  
  359.         return 0;
  360.     }
  361.  
  362. };
  363.  
  364. class msl_cursor_d{
  365. public:
  366.     msl_value *val, *cur;
  367. };
  368.  
  369. int msl_cursor_find(msl_cursor_d &d, msl_value *&val){
  370.     return d.val==val;
  371. }
  372.  
  373. class msl_cursor : public MList<msl_cursor_d>{
  374.  
  375. public:
  376.  
  377.     void reset(msl_value *val){
  378.         if(!val) return ;
  379.         UGLOCK(this);
  380.         msl_cursor_d *d=Find(msl_cursor_find, val);
  381.         if(d) d->cur=0;
  382.         return ;
  383.     }
  384.  
  385.     msl_cursor_d* Get(msl_value* val){
  386.         msl_cursor_d *d=Find(msl_cursor_find, val);
  387.         if(!d){ d=New(); d->val=val; d->cur=0; }
  388.         if(d && !d->cur) d->cur=d->val->_a;
  389.         return d;
  390.     }
  391.  
  392.     msl_value* current(msl_value *val){
  393.         if(!val) return 0;
  394.         UGLOCK(this);
  395.         msl_cursor_d *d=Get(val);
  396.         if(d){
  397.             if(val->GetV(d->cur)){
  398.                 return d->cur;
  399.             }
  400.         }
  401.         return 0;
  402.     }
  403.  
  404.     msl_value* prev(msl_value *val){
  405.         if(!val) return 0;
  406.         UGLOCK(this);
  407.         msl_cursor_d *d=Get( val);
  408.         if(d){
  409.             if(val->GetV(d->cur)){
  410.                 if(!d->cur->_p) return 0;
  411.                 d->cur=d->cur->_p;
  412.                 return d->cur;
  413.             }
  414.         }
  415.         return 0;
  416.     }
  417.  
  418.     msl_value* next(msl_value *val){
  419.         if(!val) return 0;
  420.         UGLOCK(this);
  421.         msl_cursor_d *d=Get(val);
  422.         if(d){
  423.             if(val->GetV(d->cur)){
  424.                 if(!d->cur->_n) return 0;
  425.                 d->cur=d->cur->_n;
  426.                 return d->cur;
  427.             }
  428.         }
  429.         return 0;
  430.     }
  431.  
  432.     msl_value* end(msl_value *val){
  433.         if(!val) return 0;
  434.         UGLOCK(this);
  435.         msl_cursor_d *d=Get(val);
  436.         if(d){ d->cur=val->_e; return d->cur;  }
  437.         return 0;
  438.     }
  439. };
  440.  
  441.  
  442. // spaces
  443. // Do() - all process operations
  444. // Set () - set
  445. // Get () - get
  446.  
  447. //#define MSL_DOOPT_ERROR 0
  448. //#define MSL_DOOPT_STOPIT (MSL_DOOPT_ERROR)
  449. #define MSLCBR_NULL 0
  450. #define MSLCBR_CONT 1
  451. #define MSLCBR_BREAK 2
  452. #define MSLCBR_RET  3
  453.  
  454. class msl_fl{
  455.     // result
  456.     HLString output;
  457.  
  458.     // options
  459.     int do_opt, do_opt_stopit, do_opt_ifw, do_opt_cbr, do_opt_active;
  460.  
  461.     // positions line count, char *line, char this pos in line
  462.     int do_line_count; unsigned char *do_line, *do_line_t;
  463.  
  464.     // values
  465.     msl_value global_value;
  466.     msl_value *local_value;
  467.     msl_value null_value;
  468.     // functions
  469.     msl_function functions;
  470.  
  471.     msl_fl_extfunc* extfunc;
  472.  
  473.  
  474.     // cursor reset(), prev(), current(), next(), end();
  475.     msl_cursor cursor;
  476.     msl_value *cursor_value, *cursor_value_p;
  477.  
  478.     public:
  479.  
  480.     // init
  481.     msl_fl(){ do_opt=0; do_opt_stopit=0; do_opt_cbr=0; local_value=&global_value; extfunc=0; }
  482.     ~msl_fl(){  }
  483.    
  484.     // process
  485.     void Do(VString code){
  486.         unsigned char *line=code, *pline=line, *to=code.endu();
  487.         // stop it & active
  488.         do_opt_stopit=0; do_opt_active=1; do_opt_ifw=0; do_opt_cbr=0; do_line_count=0; do_line=line; do_line_t=line;
  489.         // value;
  490.         msl_value outval;
  491.  
  492.         while(line<to && !do_opt_stopit){
  493.             if(*line=='<' && line+1<to && *(line+1)=='?'){
  494.                 // set result
  495.                 SetOutput(VString(pline, line-pline));
  496.                 // *line='<?...' skip this 2 sumbols
  497.                 line+=2;
  498.  
  499.                 //while(!do_opt_stopit){
  500.                     // do msl
  501.                 //  DoCode(line, to, outval, ';');
  502.                 //  if(line>=to || *line!=';') break;
  503.                 //  line++;
  504.                 //}
  505.                 DoCodeMulti(line, to, outval);
  506.  
  507.                 // if(line='?>')
  508.                 if(line+1>=to || *line!='?' || *(line+1)!='>'){
  509.                     // oh no
  510.                     SetError("No find '?>'");
  511.                     // exit
  512.                     return ;
  513.                 } else{
  514.                     // *line='?>...' skip this 2 sumbols
  515.                     line+=2; pline=line+1;
  516.                 }
  517.             }else if(*line=='\n'){ do_line_count++; do_line=line+1; }
  518.             line++;
  519.         }
  520.  
  521.         if(!DoTestCBR()) return ;
  522.  
  523.  
  524.         // set result
  525.         SetOutput(VString(pline, line-pline));
  526.         return ;
  527.     }
  528.  
  529.     // test continue, break, return
  530.     int DoTestCBR(){
  531.         if(do_opt_cbr){
  532.             if(do_opt_cbr==MSLCBR_CONT){ SetError("for/while for continue; not found"); return 0; }
  533.             if(do_opt_cbr==MSLCBR_BREAK){ SetError("for/while for break; not found"); return 0; }
  534.             if(do_opt_cbr==MSLCBR_RET) do_opt_cbr=MSLCBR_NULL;
  535.         }
  536.         return 1;
  537.     }
  538.  
  539.     // do code; code; code
  540.     void DoCodeMulti(unsigned char*&line, unsigned char *to, msl_value &outval, unsigned char ecode=1){
  541.         while(!do_opt_stopit){
  542.             // do msl
  543.             DoCode(line, to, outval, ';', ecode);
  544.             if(line>=to || *line!=';' || ecode==';') break;
  545.             line++;
  546.         }
  547.         return ;
  548.     }
  549.  
  550.     void DoCode(unsigned char*&line, unsigned char *to, msl_value &outval, unsigned char ecode=1, unsigned char ecodet=1){
  551.         msl_value *value=0, *pdvalue=0, *dvalue=0, *pvalue; msl_value valueline;
  552.         unsigned char *pline=0; int msl_do_inc=0; // 1 - ++, 2 - --
  553.  
  554.         while(line<to && !do_opt_stopit){
  555.  
  556.             // skip space
  557.             _skipspace(line, to);
  558.             //while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
  559.  
  560.             // $value
  561.             if(*line=='$'){
  562.                 if(dvalue){ pdvalue->Del(dvalue); dvalue=0; }
  563.                 if(value){ SetError("double $value"); return ; }
  564.                 value=DoCodeValue(++line, to, pdvalue, dvalue, pvalue);
  565.                 if(!value) return ;
  566.                
  567.                 if(msl_do_inc){
  568.                     value->val=itos(value->val.toi()+ (msl_do_inc==1 ? 1 : -1));   
  569.                     msl_do_inc=0;
  570.                 }
  571.  
  572.                 valueline.Add("t", value);
  573.  
  574.                 cursor_value=value;
  575.                 cursor_value_p=pvalue;
  576.  
  577.                 //outval.val=value->val;
  578.                 continue;
  579.             }else
  580.             // function
  581.             if(*line>='a' && *line<='z' || *line>='A' && *line<='Z' || *line=='_'){
  582.                 msl_value val; int df=0;
  583.                 DoCodeFunction(line, to, val, df);
  584.                 if(!df){
  585.                     msl_value *v=valueline.New();
  586.                     v->Move(val); v->key="t";
  587.                 }
  588.                 continue;
  589.             }
  590.             // ecode
  591.             else if(*line==ecode || *line==ecodet){
  592.                 if(msl_do_inc){
  593.                     SetError("Increment found!");
  594.                     return ;
  595.                 }
  596.  
  597.                 if(dvalue){ pdvalue->Del(dvalue); dvalue=0; }
  598.                 DoCodeOneValue(valueline, outval);
  599.                 //if(value) outval.val=value->val;
  600.                 return ;
  601.             }
  602.             // string
  603.             else if(*line=='"' || *line=='\''){
  604.                 pline=++line;
  605.                 if(*(line-1)=='"')
  606.                     while(line<to){
  607.                         if(*line=='"'){
  608.                             if(pline<line && *(line-1)=='\\'){
  609.                                 valueline.Add("t", VString(pline, line-pline-1));
  610.                                 valueline.Add("o", ".");
  611.                                 pline=line+1; line++; continue;
  612.                             }
  613.                             break;
  614.                         }
  615.  
  616.                         if(*line=='{' && line+1<to && *(line+1)=='$'){
  617.                             msl_value val;
  618.                             valueline.Add("t", VString(pline, line-pline));
  619.                             valueline.Add("o", ".");
  620.  
  621.                             line++;
  622.                             DoCode(line, to, val, '}');                        
  623.                             valueline.Add("t", val.val);
  624.  
  625.                             valueline.Add("o", ".");
  626.                             pline=line+1;
  627.                         }
  628.                         line++;
  629.                     }
  630.                 else
  631.                     while(line<to && *line!='\'') line++;
  632.                 if(line>=to){ SetError("closed \" or ' not found"); return ; }
  633.                 //outval.val=VString(pline, line-pline);
  634.                 valueline.Add("t", VString(pline, line-pline));
  635.                 line++;
  636.                 continue;
  637.             }
  638.             // numbers
  639.             else if(*line>='0' && *line<='9'){
  640.                 pline=line;
  641.                 while(line<to && *line>='0' && *line<='9') line++;
  642.                 //outval.val=VString(pline, line-pline);
  643.                 valueline.Add("t", VString(pline, line-pline));
  644.                 continue;
  645.             }
  646.             // comments
  647.             else if(*line=='/' && line+1<to && ( *(line+1)=='/' || *(line+1)=='*')){
  648.                 line+=2;
  649.                 if(*(line-1)=='/'){
  650.                     while(line<to && ( *line!='\r' && *line!='\n')) line++;
  651.                 } else{
  652.                     while(line<to && ( *line!='/' || *(line-1)!='*')){
  653.                         if(*line=='\n') ++do_line_count;
  654.                         line++;
  655.                     }
  656.                     line++;
  657.                 }
  658.  
  659.                 continue;
  660.             }
  661.             // operators
  662.             else if(*line=='+' || *line=='-' || *line=='*' || *line=='/' || *line=='.' || *line=='!' || *line=='<' || *line=='>' || *line=='=' || *line=='|' || *line=='&' || *line=='%'){
  663.                 pline=line++;
  664.                 while(*line=='+' || *line=='-' || *line=='*' || *line=='/' || *line=='.' || *line=='!' || *line=='<' || *line=='>' || *line=='=' || *line=='|' || *line=='&' || *line=='%') line++;
  665.                 if(line>=to){ SetError("EOF"); return ; }
  666.                
  667.                 VString name(pline, line-pline);
  668.                 if(line-pline>1 && *(pline+1)=='-' && *pline=='='){ name.sz=1; line-=line-pline-1; }
  669.  
  670.                 // =
  671.                 if(*(line-1)=='=' && !((*(pline)=='=' || *(pline)=='>' || *(pline)=='<' || *(pline)=='!' ) && line-pline==2)){
  672.                     msl_value val;
  673.                     DoCode(line, to, val, ecode, ecodet);
  674.                    
  675.                     if(!value || valueline._e->key!="t"){
  676.                         SetError("lvalue for = not set");
  677.                         return ;
  678.                     }
  679.                    
  680.                     if(name=="="){
  681.                         value->Move(val);
  682.                     }else if(name=="+="){
  683.                         value->val = itos(value->val.toi() + val.val.toi());
  684.                     }else if(name=="-="){
  685.                         value->val = itos(value->val.toi() - val.val.toi());
  686.                     }else if(name=="*="){
  687.                         value->val = itos(value->val.toi() * val.val.toi());
  688.                     }else if(name=="/="){
  689.                         if(!val.val.toi()){
  690.                             SetWarning("Divide by zero");
  691.                             value->val="0";
  692.                         } else
  693.                             value->val = itos(value->val.toi() / val.val.toi());
  694.                     }else if(name==".="){
  695.                         value->val.Add(value->val, val.val);
  696.                     }
  697.  
  698.                     if(dvalue){ dvalue=0; }
  699.  
  700.                     valueline._e->Copy(value);
  701.                     value=0;
  702.                     continue;
  703.                 }
  704.  
  705.                 if(name=="++" || name=="--"){
  706.                     if(msl_do_inc){
  707.                         SetError("Increment found!");
  708.                         return ;
  709.                     }
  710.  
  711.                     if(value){
  712.                         value->val=itos(value->val.toi()+ (name=="++" ? 1 : -1));
  713.                         valueline._e->val=value->val;
  714.  
  715.                         value=0; dvalue=0;
  716.                         continue;
  717.                     }
  718.  
  719.                     msl_do_inc = name=="++" ? 1 : 2;
  720.                     value=0;
  721.                     continue;
  722.                 }
  723.  
  724.                 valueline.Add("o", name);
  725.                 value=0;
  726.                
  727.                 //DoCodeOperation(VString(pline, line-pline), value,
  728.                 continue;
  729.             }
  730.             // ()
  731.             else if(*line=='('){
  732.                 msl_value val;
  733.                 DoCode(++line, to, val, ')');
  734.                 if(line>=to || *line!=')'){
  735.                     SetError("Close ')' not found");
  736.                     return ;
  737.                 } line++;
  738.                 valueline.Add("t", val.val);
  739.                 continue;
  740.             }
  741.             // '?>' end do code
  742.             else if(*line=='?' && line+1<to && *(line+1)=='>'){
  743.                 return ;
  744.             }
  745.             // what the sumbol?
  746.             else{
  747.                 SetError(HLString()+"Unknown sumbol: '"+VString(line, 1)+"'.");
  748.                 return ;
  749.             }
  750.  
  751.             // skip space
  752.             _skipspace(line, to);
  753.             //while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
  754.             line++;
  755.         }
  756.  
  757.         SetError("EOF");
  758.         return ;
  759.     }
  760.  
  761.     void DoCodeInclude(VString data){
  762.         // save
  763.         int _do_line_count=do_line_count;
  764.  
  765.         // do
  766.         Do(data);
  767.  
  768.         // load
  769.         do_line_count=_do_line_count;
  770.         return ;
  771.     }
  772.  
  773.     void DoCodeOneValue(msl_value &line, msl_value &outval){
  774.         int sz=line.Size();
  775.  
  776.         for(int i=0; i<8; i++){
  777.             msl_value *val=line._a;
  778.             for(val; val && sz!=1; val=val->_n){
  779.                
  780.                 switch(i){
  781.                 case 0:
  782.                     if(val->key=="o" && val->val=="!"){
  783.                         if(!val->_n || val->_n->key!="t"){
  784.                             SetError("Operator ! no have value");
  785.                             return ;
  786.                         }
  787.                         val->key="t"; val->val= (val->_n->val && val->_n->val!="0")==0 ? "1" : "0";
  788.                         line.Del(val->_n); sz--;
  789.                     }
  790.                     if(val->key=="o" && val->val=="-" && (!val->_p || val->_p->key!="t")){
  791.                         if(!val->_n || val->_n->key!="t"){
  792.                             SetError("Operator - no have value");
  793.                             return ;
  794.                         }
  795.                         val->key="t"; val->val.Add("-", val->_n->val);
  796.                         line.Del(val->_n); sz--;
  797.                     }
  798.                     break;
  799.                 case 1: case 2: case 3: case 4: case 5: case 6: case 7:
  800.                     if(val->key=="o"){
  801.                         if(!val->_p || val->_p->key!="t" || !val->_n || val->_n->key!="t"){
  802.                             SetError(HLString()+"Operator'"+val->val+"'no have value");
  803.                             return ;
  804.                         }
  805.  
  806.                         // */%
  807.                         if(i==1 && (val->val=="*" || val->val=="/" || val->val=="%")){
  808.                             if(val->val=="/" && !val->_n->val.toi()){
  809.                                 SetWarning("Divide by zero");
  810.                                 val->val="0";
  811.                             }else{
  812.                                 if(val->val=="*") val->val= itos(val->_p->val.toi()*val->_n->val.toi());
  813.                                 else if(val->val=="/") val->val= itos(val->_p->val.toi()/val->_n->val.toi());
  814.                                 else if(val->val=="%") val->val= itos(val->_p->val.toi()%val->_n->val.toi());
  815.                             }
  816.                         } else
  817.                         // +-
  818.                         if(i==2 && (val->val=="+" || val->val=="-" || val->val==".")){
  819.                             if(val->val=="+") val->val= itos(val->_p->val.toi()+val->_n->val.toi());
  820.                             else if(val->val=="-") val->val= itos(val->_p->val.toi()-val->_n->val.toi());
  821.                             else if(val->val==".") val->val.Add(val->_p->val, val->_n->val);
  822.  
  823.                             //val->val=itos("+" ? val->_p->val.toi()+val->_n->val.toi() : val->_p->val.toi()-val->_n->val.toi() );
  824.                         }else
  825.                         // >> <<
  826.                         if(i==3 && (val->val==">>" || val->val=="<<")){
  827.                             val->val=itos(">>" ? val->_p->val.toi()>>val->_n->val.toi() : val->_p->val.toi()<<val->_n->val.toi() );
  828.                         }else
  829.                         //< <= > >=
  830.                         if(i==4 && (val->val==">" || val->val=="<" || val->val==">=" || val->val=="<=")){
  831.                             if(val->val==">") val->val= itos(val->_p->val.toi()>val->_n->val.toi());
  832.                             else if(val->val=="<")val->val= itos(val->_p->val.toi()<val->_n->val.toi());
  833.                             else if(val->val==">=") val->val= itos(val->_p->val.toi()>=val->_n->val.toi());
  834.                             else if(val->val=="<=") val->val= itos(val->_p->val.toi()<=val->_n->val.toi());
  835.                         } else
  836.                         // == !=
  837.                         if(i==5 && (val->val=="==" || val->val=="!=")){
  838.                             val->val= (val->val=="==" ? val->_p->val==val->_n->val : val->_p->val!=val->_n->val) ? "1" : "0";
  839.                         }else
  840.                         // & ^ |
  841.                         if(i==6 && (val->val=="&" || val->val=="^" || val->val=="|")){
  842.                             if(val->val=="&") val->val= itos(val->_p->val.toi()&val->_n->val.toi());
  843.                             else if(val->val=="^") val->val= itos(val->_p->val.toi()^val->_n->val.toi());
  844.                             else if(val->val=="|") val->val= itos(val->_p->val.toi()|val->_n->val.toi());
  845.                         } else
  846.                         // && ||
  847.                         if(i==7 && (val->val=="&&" || val->val=="||")){
  848.                             int l=val->_p->val && val->_p->val!="0";
  849.                             int r=val->_n->val && val->_n->val!="0";
  850.                             val->val= (val->val=="&&" ? l && r : l || r) ? "1" : "0";
  851.                         }else{
  852.                             continue;
  853.                         }
  854.  
  855.                         val->key="t"; //val->val= val->val==itos("+" ? val->_p->val.toi()+val->_n->val.toi() : val->_p->val.toi()-val->_n->val.toi() );
  856.                         line.Del(val->_n); line.Del(val->_p); val=line._a; sz-=2;
  857.                     }
  858.                 break;
  859.                 }
  860.  
  861.             }
  862.         }
  863.        
  864.         if(sz>1 || sz && line._a->key!="t"){
  865.             SetError("One value. Bad code");
  866.             return ;
  867.         }
  868.  
  869.         if(sz && line._a){
  870.             outval.Move(*line._a);
  871.             //outval.val=line._a->val;
  872.         }
  873.  
  874.         return ;
  875.     }
  876.  
  877.     msl_value* DoCodeValue(unsigned char*&line, unsigned char *to, msl_value *&pnval, msl_value *&nval, msl_value *&pval){
  878.         unsigned char *pline=line; int isnew=0; nval=0;
  879.  
  880.         while(line<to && *line>='a' && *line<='z' || *line>='A' && *line<='Z' || *line>='0' && *line<='9' || *line=='_') line++;
  881.         if(line>=to){
  882.             SetError(HLString()+"EOF.");
  883.             return 0;
  884.         }
  885.        
  886.         // Get existing or create new
  887.         msl_value *val, *lval=0;
  888.        
  889.         if(do_opt_active){
  890.             val=local_value->SGet(VString(pline, line-pline), isnew); pval=local_value;
  891.             if(isnew){ pnval=local_value; nval=val; }
  892.         }
  893.         else val=&null_value;
  894.  
  895.         lval=val;
  896.  
  897.         while(1){
  898.             // skip space
  899.             _skipspace(line, to);
  900.             //while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
  901.  
  902.             if(line<to && *line=='['){
  903.                 msl_value dval;
  904.                 DoCode(++line, to, dval, ']');
  905.  
  906.                 // next []
  907.                 if(do_opt_active){
  908.                     pval=val; val=val->SGet(dval.val, isnew);
  909.                     if(isnew && !nval){ pnval=lval; nval=val; }
  910.                     lval=val;
  911.                 }else val=&null_value;
  912.                 line++;
  913.             }
  914.             else return val;
  915.         }
  916.  
  917.         return 0;
  918.     }
  919.  
  920.     void DoCodeFunction(unsigned char*&line, unsigned char *to, msl_value &val, int &df){
  921.         VString name; unsigned char *pline=line; msl_fl_fargs args;
  922.         unsigned char *code, *ecode;
  923.  
  924.         while(line<to){
  925.             // normal name
  926.             if(*line>='a' && *line<='z' || *line>='A' && *line<='Z' || *line=='_'){}
  927.             else{
  928.                 name.setu(pline, line-pline);
  929.  
  930.                 if(name=="function"){
  931.                      DoCodeFunctionFunction(line, to); df=1; return ;
  932.                 }
  933.  
  934.                 while(line<to){
  935.                     if(*line=='('){
  936.                         line++;
  937.                         code=line;
  938.  
  939.                         if(name=="for"){
  940.                              DoCodeFunctionFor(line, to); df=1; return ;
  941.                         }
  942.  
  943.                         if(!DoCodeFunctionArgs(line, to, args)) return ;
  944.                         ecode=line; line++;
  945.                         // Exec function
  946.                         if(!DoCodeFunctionExec(name, args, val)) return ;
  947.                         //line++;
  948.  
  949.                         // if, while, for functions
  950.                         if(do_opt_ifw){
  951.                             if(name=="if")
  952.                                 DoCodeFunctionIf(line, to);
  953.                             else if(name=="while")
  954.                                 DoCodeFunctionWhile(line, to, code, ecode);
  955.                             //else if(name=="for")
  956.                                 //DoCodeFunctionFor(line, to);
  957.                             df=1;
  958.                         }
  959.  
  960.                         return ;
  961.                     }
  962.                     else if(!(*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')){
  963.                         if(*line==';'){
  964.                             if(name=="continue"){ if(do_opt_active) do_opt_cbr=MSLCBR_CONT; do_opt_active=0; return ; }
  965.                             if(name=="break"){ if(do_opt_active) do_opt_cbr=MSLCBR_BREAK; do_opt_active=0; return ; }
  966.                             if(name=="return"){ if(do_opt_active) do_opt_cbr=MSLCBR_RET; do_opt_active=0; return ; }
  967.                         }
  968.  
  969.                         SetError(HLString()+"function '"+name+"' open '(' not found.");
  970.                         return ;
  971.                     }
  972.  
  973.                     line++;
  974.                 }
  975.             }
  976.             line++;
  977.         }
  978.  
  979.         // line='functionname'EOF
  980.         SetError(HLString()+"end of function name: '"+VString(pline, line-pline)+"'");
  981.         return ;
  982.     }
  983.  
  984.     int DoCodeFunctionArgs(unsigned char *&line, unsigned char *to, msl_fl_fargs &args){
  985.         while(!do_opt_stopit){
  986.  
  987.             // skip space
  988.             _skipspace(line, to);
  989.             // no data
  990.             if(line<to && *line==')') break;
  991.  
  992.             msl_value val;
  993.             DoCode(line, to, val, ',', ')');
  994.             //if(!DoCodeFunctionArgs(line, to, args)) return ;
  995.             args.Add(val, cursor_value, cursor_value_p);
  996.             if(line>=to){ SetError("not found ')'. EOF"); return 0; }
  997.             if(*line!=',') break;
  998.             line++;
  999.         }
  1000.         return 1;
  1001.     }
  1002.  
  1003.     void DoCodeFunctionIf(unsigned char*&line, unsigned char *to){
  1004.         msl_value val; unsigned char endcode; unsigned char *pline;
  1005.         // save values
  1006.         int old_ifw=do_opt_ifw, old_active=do_opt_active; do_opt_ifw=0;
  1007.  
  1008.         // skip space
  1009.         _skipspace(line, to);
  1010.         //while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
  1011.  
  1012.         // single or {multi}
  1013.         if(line>=to){ SetError("if(...) EOF"); return ; }
  1014.        
  1015.         // set active
  1016.         do_opt_active=old_active && old_ifw==2;
  1017.         // do if(){ code }
  1018.         if(*(line)=='{'){ endcode='}'; line++; } else endcode=';';
  1019.         DoCodeMulti(line, to, val, endcode); pline=line++; // if(line<to && *line!=';') line++;
  1020.  
  1021.         // skip space
  1022.         _skipspace(line, to);
  1023.         //while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
  1024.  
  1025.         // test on 'else'
  1026.         if(line+4<to && *line=='e' && *(line+1)=='l' && *(line+2)=='s' && *(line+3)=='e'){
  1027.             // skip 'else'
  1028.             line+=4;
  1029.             // skip space
  1030.             _skipspace(line, to);
  1031.             //while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
  1032.             // set active
  1033.             do_opt_active=old_active && old_ifw==1;
  1034.             // do else{ code }
  1035.             if(*(line)=='{'){ endcode='}'; line++; } else endcode=';';
  1036.             DoCodeMulti(line, to, val, endcode); if(endcode!=';') line++;
  1037.         }
  1038.         else if(endcode==';') line=pline;
  1039.  
  1040.         // load old value
  1041.         do_opt_active=old_active; do_opt_ifw=0;
  1042.  
  1043.         // if cbr
  1044.         if(do_opt_cbr){
  1045.             do_opt_active=0;
  1046.         }
  1047.  
  1048.         return ;
  1049.     }
  1050.  
  1051.     void DoCodeFunctionWhile(unsigned char *&line, unsigned char *to, unsigned char *code, unsigned char *ecode){
  1052.         msl_value val; unsigned char *lline, *elline, *tline; unsigned char endcode;
  1053.        
  1054.         // save values
  1055.         int old_ifw=do_opt_ifw, old_active=do_opt_active; do_opt_ifw=0;
  1056.         // skip space
  1057.         _skipspace(line, to);
  1058.         //while(line<to && (*line==' ' || *line=='\t' || *line=='\r' || *line=='\n')) line++;
  1059.  
  1060.         if(line>=to){ SetError("if(...) EOF"); return ; }
  1061.  
  1062.         // set active
  1063.         do_opt_active=old_active && old_ifw==2; lline=line;
  1064.         // do while(){ code }
  1065.         if(*(line)=='{'){ endcode='}'; line++; } else endcode=';';
  1066.         DoCodeMulti(line, to, val, endcode); line++;
  1067.         elline=line;
  1068.  
  1069.         // while
  1070.         while(!do_opt_stopit && old_active && old_ifw==2){
  1071.             msl_value val;
  1072.             // do while( it code )
  1073.             tline=code;
  1074.             DoCode(tline, ecode+1, val, ')');
  1075.            
  1076.             // cbr
  1077.             if(do_opt_cbr){
  1078.                 if(do_opt_cbr==MSLCBR_CONT){ do_opt_cbr=MSLCBR_NULL; }
  1079.                 if(do_opt_cbr==MSLCBR_BREAK){ do_opt_cbr=MSLCBR_NULL; break; }
  1080.                 if(do_opt_cbr==MSLCBR_RET){ break; }
  1081.             }
  1082.            
  1083.             // result
  1084.             if(!val.val || val.val=="0") break;
  1085.  
  1086.             // do while(1){ it code }
  1087.             tline=lline;
  1088.             if(*(tline)=='{'){ endcode='}'; tline++; } else endcode=';';
  1089.             DoCodeMulti(tline, elline, val, endcode);
  1090.  
  1091.             // set active
  1092.             do_opt_active=old_active && old_ifw==2;
  1093.         }
  1094.  
  1095.         // load old value
  1096.         do_opt_active=old_active; do_opt_ifw=0;
  1097.         return ;
  1098.     }
  1099.  
  1100.     int DoCodeFunctionFor(unsigned char *&line, unsigned char *to){
  1101.         // save values
  1102.         int old_active=do_opt_active; do_opt_active=0;
  1103.         // for args
  1104.         VString a[4]; int as=0;
  1105.  
  1106.         while(!do_opt_stopit && as<4){
  1107.             msl_value val;
  1108.             a[as].data=line;
  1109.             DoCode(line, to, val, ';', ')');
  1110.             a[as].sz=line-a[as].data; as++;
  1111.  
  1112.             if(line>=to){ SetError("not found ')'. EOF"); return 0; }
  1113.             if(*line==')') break;
  1114.             line++;
  1115.         }
  1116.         line++;
  1117.  
  1118.         if(as!=3){
  1119.             SetError("for(args!=3)."); return 0;
  1120.         }
  1121.  
  1122.         // Do {}
  1123.         msl_value val; unsigned char *lline, *elline, *tline, *eline; unsigned char endcode;
  1124.  
  1125.         lline=line;
  1126.         if(*(line)=='{'){ endcode='}'; line++; } else endcode=';';
  1127.         DoCodeMulti(line, to, val, endcode); line++;
  1128.         elline=line;
  1129.  
  1130.         // load old value
  1131.         do_opt_active=old_active;
  1132.  
  1133.         // Go or Nooo...
  1134.         if(old_active){
  1135.             // do for(1)
  1136.             tline=a[0].data; eline=a[0].endu()+1;
  1137.             DoCode(tline, eline, val, ';');
  1138.  
  1139.             while(!do_opt_stopit){
  1140.                 // do for(2), test
  1141.                 tline=a[1].data; eline=a[1].endu()+1;
  1142.                 DoCode(tline, eline, val, ';');
  1143.                 if(!val.val || val.val=="0") break;
  1144.            
  1145.                 // do {}
  1146.                 tline=lline; eline=elline;
  1147.                 if(*(tline)=='{'){ endcode='}'; tline++; } else endcode=';';               
  1148.                 DoCodeMulti(tline, eline, val, endcode);
  1149.  
  1150.                 // cbr
  1151.                 if(do_opt_cbr){
  1152.                     if(do_opt_cbr==MSLCBR_CONT){ do_opt_cbr=MSLCBR_NULL; }
  1153.                     if(do_opt_cbr==MSLCBR_BREAK){ do_opt_cbr=MSLCBR_NULL; break; }
  1154.                     if(do_opt_cbr==MSLCBR_RET){ break; }
  1155.                 }
  1156.  
  1157.                 // set value
  1158.                 do_opt_active=old_active;
  1159.  
  1160.                 // do for(3)
  1161.                 tline=a[2].data; eline=a[2].endu()+1;
  1162.                 DoCode(tline, eline, val, ')');            
  1163.             }
  1164.         }
  1165.  
  1166.         // load old value
  1167.         do_opt_active=old_active; do_opt_ifw=0;
  1168.         return 1;
  1169.     }
  1170.  
  1171.     int DoCodeFunctionFunction(unsigned char *&line, unsigned char *to){
  1172.         unsigned char *lline; VString name, key, val; msl_value value;
  1173.         int def_value=0;
  1174.  
  1175.         // skip space
  1176.         _skipspace(line, to);
  1177.  
  1178.         // find name
  1179.         lline=line;
  1180.         while(line<to && (*line>='a' && *line<='z' || *line>='A' && *line<='Z' || *line=='_')) line++;
  1181.  
  1182.         // add functions
  1183.         msl_function_d *func=functions.New();
  1184.         func->name.setu(lline, line-lline);
  1185.  
  1186.         // '('
  1187.         if(line>=to || *line!='('){
  1188.             SetError("function '(' not found"); return 0;
  1189.         } line++;
  1190.  
  1191.         while(1){
  1192.             _skipspace(line, to);
  1193.             if(line<to && *line=='$'){
  1194.                 lline=++line;
  1195.                 while(line<to && (*line>='a' && *line<='z' || *line>='A' && *line<='Z' || *line=='_')) line++;
  1196.                 if(lline==line){ SetError("$(no_name)"); return 0; }
  1197.                 key.setu(lline, line-lline);
  1198.  
  1199.                 _skipspace(line, to);
  1200.                 if(line<to && *line=='='){
  1201.                     def_value=1; line++; val.Clean();
  1202.  
  1203.                     if(_skipnum(line, to, val)){ }
  1204.                     else if(_skipquote(line, to, val)){ line++; }
  1205.                     else{ SetError("$key= unknow"); return 0; }
  1206.                 }else
  1207.                     if(def_value){
  1208.                         SetError("$key=default value, $key= no default value"); return 0;
  1209.                 }
  1210.                
  1211.  
  1212.                 func->args.AddF(key, val);
  1213.  
  1214.                 // ,
  1215.                 _skipspace(line, to);
  1216.                 if(line<to){
  1217.                     if(*line==','){ line++; continue; }
  1218.                     if(*line==')') break;
  1219.                 }
  1220.                 SetError("bad value"); return 0;
  1221.  
  1222.             }else if(line<to && *line==')'){ break; }
  1223.             else { SetError("bad parameter"); return 0; }
  1224.         }
  1225.  
  1226.         if(line>=to || *line!=')'){ SetError("Fubction ')' not found"); return 0; }
  1227.         line++;
  1228.  
  1229.         _skipspace(line, to);
  1230.         if(line>=to || *line!='{'){ SetError("Fubction '{' not found"); return 0; }
  1231.  
  1232.         // save values
  1233.         int old_active=do_opt_active; do_opt_active=0;
  1234.  
  1235.         // Get Function Code
  1236.         lline=++line;
  1237.         DoCodeMulti(line, to, value, '}');
  1238.  
  1239.         if(line>=to || *line!='}'){
  1240.             SetError("function '}' not found"); return 0;
  1241.         }
  1242.         line++;
  1243.  
  1244.         func->code.setu(lline, line-lline);
  1245.  
  1246.         // activate function
  1247.         func->UseIt();
  1248.  
  1249.         // load old value
  1250.         do_opt_active=old_active; do_opt_ifw=0;
  1251.         return 1;
  1252.     }
  1253.  
  1254.     void _skipspace(unsigned char *&line, unsigned char *to){
  1255.         //while(line<to && (*line==' ' || *line=='\t' || *line=='\r' && (line+1>=to || *(line+1)=='\n' || line++ && ++do_line_count && (do_line=line+1))
  1256.         //  || (*line=='\n' && ++do_line_count && (do_line=line+1) ))) line++;
  1257.         while(line<to){
  1258.             if(*line==' ' || *line=='\t') line++;
  1259.             else if(*line=='\r'){
  1260.                 if(line+1<to || *(line+1)=='\n'){ ++do_line_count; do_line=line+2; }
  1261.                 line++;
  1262.             }
  1263.             else if(*line=='\n'){
  1264.                 line++; ++do_line_count; do_line=line;
  1265.             }
  1266.             else break;
  1267.         }
  1268.         return ;
  1269.     }
  1270.  
  1271.     int _skipnum(unsigned char *&line, unsigned char *to, VString &val){
  1272.         if(line<to && *line>'0' && *line<'9'){
  1273.             val.data=line;
  1274.             while(line<to && *line>'0' && *line<'9') line++;
  1275.             val.sz=line-val.data;
  1276.             return 1;
  1277.         }
  1278.         return 0;
  1279.     }
  1280.  
  1281.     int _skipquote(unsigned char *&line, unsigned char *to, VString &val){
  1282.         if(line>=to) return 0;
  1283.  
  1284.         if(*line=='\'' || *line=='"'){
  1285.             unsigned char q=*line;
  1286.             val.data=++line;
  1287.             while(line<to && *line!=q) line++;
  1288.             val.sz=line-val.data;
  1289.             return 1;
  1290.         }
  1291.         return 0;
  1292.     }
  1293.  
  1294.  
  1295.     void msv_func_print_r(msl_value *v, HLString &ls){
  1296.         int f=1;
  1297.         ls+"{";
  1298.         while(v){
  1299.             if(!f) ls+", "; else f=0;
  1300.             ls+"'"+v->key+"' => '"+v->val+"'";
  1301.             if(v->_a)
  1302.                 msv_func_print_r(v->_a, ls);
  1303.             v=v->_n;
  1304.         }
  1305.         ls+"}";
  1306.         return ;
  1307.     }
  1308.  
  1309.     int DoCodeFunctionExec(VString name, msl_fl_fargs &args, msl_value &val){
  1310.         // all sections
  1311.  
  1312.         if((name=="if" || name=="while") && args.Sz()==1){
  1313.             do_opt_ifw=args[0].val.val && args[0].val.val!="0"; do_opt_ifw++;
  1314.             return 1;
  1315.         }
  1316.  
  1317.         // if active
  1318.         if(!do_opt_active) return 1;
  1319.  
  1320.         if(extfunc){
  1321.             int r=extfunc->DoCodeFunctionExec(name, args, val);
  1322.             if(r) return 1;
  1323.         }
  1324.  
  1325.         // exec
  1326.         if(name=="print" || name=="echo"){
  1327.             for(int i=0; i<args.Sz(); i++){
  1328.                 SetOutput(args[i].val.val);
  1329.                 //print(args[i].val.val);
  1330.             }
  1331.             return 1;
  1332.         }
  1333.  
  1334.         if(name=="print_r" && args.Sz()==1){
  1335.             SetOutput(args[0].val.val);
  1336.             msl_value *v=args[0].val._a;
  1337.             HLString ls;
  1338.  
  1339.             msv_func_print_r(v, ls);
  1340.             SetOutput(ls);
  1341.             return 1;
  1342.         }
  1343.  
  1344.         if(name=="array"){
  1345.             int n=0;
  1346.             for(int i=0; i<args.Sz(); i++){
  1347.                 val.Set(args[i].val.key ? args[i].val.key : itos(n++), args[i].val.val);
  1348.             }
  1349.             return 1;
  1350.         }
  1351.  
  1352.         if(name=="include" && args.Sz()==1){
  1353.             if(!IsFile(args[0].val.val)) SetError(HLString()+"include('"+args[0].val.val+"'), file not found");
  1354.             DoCodeInclude(LoadFile(args[0].val.val));
  1355.             return 1;
  1356.         }
  1357.  
  1358.         // text
  1359.         if(name=="substr" && args.Sz()==2){
  1360.             val.val=args[0].val.val.str(args[1].val.val.toi());
  1361.             return 1;
  1362.         }
  1363.        
  1364.         if(name=="substr" && args.Sz()==3){
  1365.             val.val=args[0].val.val.str(args[1].val.val.toi(), args[2].val.val.toi());
  1366.             return 1;
  1367.         }
  1368.  
  1369.         // time & data
  1370.         if(name=="clock" && args.Sz()==0){
  1371.             val.val=itos(clock());     
  1372.             return 1;
  1373.         }
  1374.  
  1375.         if(name=="time" && args.Sz()==0){
  1376.             val.val=itos(time());
  1377.             return 1;
  1378.         }
  1379.  
  1380.         if(name=="date" && args.Sz()==1){
  1381.             MTime64 mt; val.val=mt.date(args[0].val.val);
  1382.             return 1;
  1383.         }
  1384.  
  1385.         if(name=="date" && args.Sz()==2){
  1386.             MTime64 mt; val.val=mt.date(args[0].val.val, args[1].val.val.toi());
  1387.             return 1;
  1388.         }
  1389.  
  1390.         // size
  1391.         if(name=="sizeof" && args.Sz()==1){
  1392.             if(args[0].pval){ val.val=itos(args[0].pval->Size()); }else SetWarning("sizeof(need $value);"); return 1;
  1393.         }
  1394.  
  1395.  
  1396.         // cursor
  1397.         if(name=="reset" && args.Sz()==1){
  1398.             if(args[0].pval){ cursor.reset(args[0].pval); }else SetWarning("reset(need $value);"); return 1;
  1399.         }
  1400.  
  1401.         if(name=="prev" && args.Sz()==1){
  1402.             if(args[0].pval){ msl_value *v=cursor.prev(args[0].pval); if(v) val.val=v->key; } else SetWarning("prev(need $value);"); return 1;
  1403.         }
  1404.  
  1405.         if(name=="current" && args.Sz()==1){
  1406.             if(args[0].pval){ msl_value *v=cursor.current(args[0].pval); if(v) val.val=v->key; } else SetWarning("current(need $value);"); return 1;
  1407.         }
  1408.  
  1409.         if(name=="next" && args.Sz()==1){
  1410.             if(args[0].pval){ msl_value *v=cursor.next(args[0].pval); if(v) val.val=v->key; } else SetWarning("next(need $value);"); return 1;
  1411.         }
  1412.  
  1413.         if(name=="end" && args.Sz()==1){
  1414.             if(args[0].pval){ msl_value *v=cursor.end(args[0].pval); if(v) val.val=v->key; } else SetWarning("end(need $value);"); return 1;
  1415.         }
  1416.  
  1417.  
  1418.         // unset
  1419.         if(name=="unset" && args.Sz()==1){
  1420.             if(args[0].pval){ args[0].ppval->Del(args[0].pval); } else SetWarning("unset(need $value);"); return 1;
  1421.         }
  1422.  
  1423.         //
  1424.         msl_function_d *func=functions.Find(name, args.Sz());
  1425.         if(func){
  1426.             // save and new
  1427.             msl_value *_local_value=local_value, func_value; local_value=&func_value;
  1428.             // save values
  1429.             int old_active=do_opt_active;
  1430.  
  1431.             for(int i=0; i<func->args.Sz(); i++){
  1432.                 local_value->Set(func->args[i].fkey, (args.Sz()>=i+1) ? args[i].val.val : func->args[i].fval);
  1433.             }
  1434.  
  1435.             unsigned char *fline=func->code, *eline=func->code.endu(); msl_value outval;
  1436.             DoCodeMulti(fline, eline, outval, '}');
  1437.            
  1438.             // test continue, break, return
  1439.             DoTestCBR();
  1440.  
  1441.             // load old value
  1442.             do_opt_active=old_active; do_opt_ifw=0;
  1443.             // load
  1444.             local_value=_local_value;
  1445.  
  1446.             return 1;
  1447.         }
  1448.  
  1449.  
  1450.  
  1451.         //
  1452.         SetError(HLString()+"Function: '"+name+"' not found");
  1453.         return 0;
  1454.     }
  1455.  
  1456.     void SetExtFunc(msl_fl_extfunc *f){
  1457.         extfunc=f;
  1458.     }
  1459.  
  1460.     // global value
  1461.     msl_value* SetValue(VString key, VString val){
  1462.         return local_value->Set(key, val);     
  1463.     }
  1464.  
  1465.     VString GetValue(VString key){
  1466.         return local_value->Get(key);      
  1467.     }
  1468.    
  1469.     msl_value* GetVValue(VString key){
  1470.         return local_value->GetV(key);     
  1471.     }
  1472.  
  1473.  
  1474.     // get output
  1475.     MString GetOutput(){
  1476.         // return result;
  1477.         return MString(output.oneline(), output.size());
  1478.     }
  1479.  
  1480.     int _getlinecount(){ return do_line_count; }
  1481.     int _getlinesz(){ if(do_line>do_line_t) return 0; return do_line_t-do_line; }
  1482.  
  1483. protected:
  1484.  
  1485.     // set output
  1486.     void SetOutput(VString line){
  1487.         // add line to result
  1488.         output+line;
  1489.         return ;
  1490.     }
  1491.  
  1492.     void SetWarning(VString line){
  1493.         // add error line to result
  1494.         output+"MSL-FL Warning: '"+line+"' on "+itos(_getlinecount())+" line "+itos(_getlinesz())+" row\r\n";
  1495.         return ;
  1496.     }
  1497.  
  1498.     void SetError(VString line){
  1499.         // add error line to result
  1500.         output+"MSL-FL Error: '"+line+"' on "+itos(_getlinecount())+" line "+itos(_getlinesz())+" row\r\n";
  1501.         // stop
  1502.         do_opt_stopit=1;
  1503.         return ;
  1504.     }
  1505.  
  1506.     void SetEpic(VString line){
  1507.         // add error line to result
  1508.         output+"MSL-FL Epic Fail: '"+line+"' on "+itos(_getlinecount())+" line "+itos(_getlinesz())+" row\r\n";
  1509.         // stop
  1510.         do_opt_stopit=1;
  1511.         return ;
  1512.     }
  1513.  
  1514. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement