!
X , ,   
  -  



    !^eval()[] ,   ::
        ! #
                   
                 
        !  :
            !|  xor
            !||  xor
            ~  
            \   10\3=3
        !def   defined,
               defined
               defined
             hash  defined
        ^if(method $hash.delete){yes}
        !eq ne lt gt le ge   , 
        !in "/dir/"  
            ["  ,     , 
               ].
        !is 'type'     , 
            ,  , " hash   ?"
        !-f      ,
        !-d      ,
        !  | - ,  |   
             whitespace
        !   0xABC
        !:
           /* logical */
           %left "!||"
           %left "||"
           %left "&&"
           %left '<' '>' "<=" ">="   "lt" "gt" "le" "ge"
           %left "==" "!="  "eq" "ne"
           %left "is" "def" "in" "-f" "-d"
           %left '!'
            ? : 

           /* bitwise */
           %left '!|'
           %left '|'
           %left '&' 
           %left '~'

           /* numerical */
           %left '-' '+'
           %left '*' '/' '%' '\\'
           %left NEG     /* negation: unary - */
        !
           true
           false

           
    !^if(){ }{ }
    !^if(1){}[(2){}[(2){}[...]]]{} --  .    (  elseif  :)
    !^switch[]{^case[1[;2...]]{}^case[DEFAULT]{  }}
    !^while(){}[[]|{        }]
    !^for[i](0;4){}[[]|{        }]
    !^use[]
    !^try{
        ...
        !^throw[sql.connect[;[;]]] //  ^error[]
        !^throw[
        	$.type[sql.connect]
        	$.source[]
        	$.comment[]
        ]
        ...
    }{
        ^if($exception.type eq "sql"){
            $exception.handled(1|true)  ^rem{,  exception }
            ....
        }
        
        ^switch[$exception.type]{
            ^case[sql;mail]{
                $exception.handled(1)
                ,  sql 
                $exception.type = sql.connect
                $exception.file $exception.lineno $exception.colno [    ]
                $exception.source = 
                $exception.comment = 
            }
            ^case[DEFAULT]{
                ,   
                ^throw[$exception] << re-throw // DON'T! It's default behaviour!
            }
        }
    }
    !^break[] + -  
    !^continue[] + -   
    !^untaint[[as-is|file-spec|uri|http-header|mail-header|sql|js|json|parser-code|regex|xml|html|optimized-[as-is|xml|html]]]{}
        default as-is
    !^taint[[lang]][]
        default "just tainted, language unknown"
    !^process[[$caller.CLASS|$object|$:CLASS]]{,   process-ed,  }[
        $.main[   @main]
        $.file[   , ,  ]
        $.lineno(   ,   .  ) 
    ]
    !^process..[][   @main]
       ,    $self [  , $self=$MAIN:CLASS]
    !^connect[protocol:// ]]{  ^sql[...]-}
        !mysql://user:pass@{host[:port]|[/unix/socket]}/database?
            ClientCharset=parser-charset << charset in which parser thinks client works
            charset=UTF-8&
            timeout=3&
            compress=0&
            named_pipe=1&
            multi_statements=1&	allow execute more then one query in one parser :sql{} request
            autocommit=1
            autocommit    0,   commit/rollback

        !pgsql://user:pass@{host[:port]|[local]}/database?
            client_encoding=win,[to-find-out]
            &datestyle=ISO,SQL,Postgres,European,NonEuropean=US,German,DEFAULT=ISO
            &ClientCharset=parser-charset << charset in which parser thinks client works
        
        !oracle://user:pass@service?
            NLS_LANG=RUSSIAN_AMERICA.CL8MSWIN1251&
            NLS_LANGUAGE  language-dependent conventions
            NLS_TERRITORY  territory-dependent conventions
            NLS_DATE_FORMAT=YYYY-MM-DD HH24:MI:SS
            NLS_DATE_LANGUAGE  language for day and month names
            NLS_NUMERIC_CHARACTERS  decimal character and group separator
            NLS_CURRENCY  local currency symbol
            NLS_ISO_CURRENCY  ISO currency symbol
            NLS_SORT  sort sequence
            ORA_ENCRYPT_LOGIN=TRUE
            ClientCharset=parser-charset << charset in which parser thinks client works

        !odbc://DSN=dsn^;UID=user^;PWD=password^;ClientCharset=parser-charset
            ClientCharset << charset in which parser thinks client works
            
        !sqlite://DBfile?
            ClientCharset=parser-charset& << charset in which parser thinks client works
            autocommit=1

          connect ,  (    auto.p)
          
#sql drivers
$SQL[
    $.drivers[^table::create{protocol	driver	client
mysql	/www/parser3/libparser3mysql.so	libmysqlclient.so
pgsql	/www/parser3/libparser3pgsql.so	libpq.so
oracle	/www/parser3/libparser3oracle.so	/u01/app/oracle/product/8.1.5/lib/libclntsh.so?ORACLE_HOME=/u01/app/oracle/product/8.1.5&ORA_NLS33=/u01/app/oracle/product/8.1.5/ocommon/nls/admin/data
sqlite	/www/parser3/libparser3sqlite.so	sqlite3.so
odbc	c:\drives\y\parser3project\odbc\debug\parser3odbc.dll
}]
]
        !   oracle    
          environment  (     ),
         ,   NLS_ ORA_  ORACLE_,    +
         win32 
             PATH+=^;C:\Oracle\Ora81\bin
         : 
          ORA_NLS33       ( NLS_LANG)
                -,    .drivers,
                  NLS 
             (  ,      NLS_LANG)
          ORACLE_HOME       ,
             ,  ,     ,
             NLS_LANG,  .

        :        oracle&pgsql[  ],
             , ,   
        /**_**/'literal'
    !^rem{}
    !^cache[](){}[{catch }]
        !  
        ! ,       '' 
        ! 0,   ,    
        ! catch  $exception.handled[cache]  ^rem{,  exception }
    !^cache[][expires date]{}[{catch }]
        !  
    !^cache[]   [ ,   ]
    !^cache()
    !^cache[expires date]
        !  ^cache "  - ''/'expires'"
        ! : ^cache(0)  
    !^cache[]   expires date

    !      $result,     ,
    ! __   ,    
    !      $caller,     stack frame,
    !  

    !use(^use  @USE)  ...
    !1. ...    /,  ,       
    !  / $MAIN:CLASS_PATH  /    .
        ! /     .
    !2. ...   table $MAIN:CLASS_PATH,  
           auto.p  

    !  $CHARSETS[$.[ ]]
    !    (whitespace, letter, etc),    unicode
    !: tab delimited ,  :
    !    char    white-space    digit    hex-digit    letter    word    lowercase    unicode1    unicode2    
    !    A            x    x    x    a    0x0041    0xFF21
    !  char  lowercase   ,     0x
    !     unicode ,   , 
    !    unicode
    !   UTF-8, 
    !   -  request  response
    !:   case sensitive


    !$[ ]
    !$(   )
    !${  }
    !$ whitespace  ${}   
    !^   
    !$.CLASS  
    !$.CLASS_NAME  
    !$[$.key[] () {}]    - $.key
    !^method[$.key[] () {}]   - $parameter.key
    $CLASS.     

      :  tab linefeed ; ] } ) " < >  + * / % & | = ! ' , ? {}
    .. 
    $,aaaa
         ,  -, 
    ${}-
      +  -    
    !     : $name.subname
    ! subname :
    !    
    !    $
    !    $
    !    [,  ]
    : $[$.(88)] $[$.[]] ^.[$.].format{%05d}

:=   
:=
    !( )     , 
|    ![]     , 
|    !{}  0     , 
    !  ;  -      


!void
    !  ,     string,     
    !^void:sql{  }{$.bind[. table::sql]}


!int,double
    !^.int[]    
    !^.double[]+  double  
    !^.bool[] + .bool(true|false)  bool 
    !^.inc(  +)
    !^.dec(  -)
    !^.mul(  *)
    !^.div(  /)
    !^.mod(  %)
    !^.format[]
    !^int/double:sql{query}[[$.limit(2) $.offset(4) $.default{0} $.bind[. table::sql]]]
        ,      / 

!string
    !  
        !def   " ?"
        !/      double,
                 0    

        :
        ^if(def $form:name)  ?
        ^if($user.isAlive) ? [  ,  ?]
    !^string:sql{query}[[$.limit(1) $.offset(4) $.default{n/a} $.bind[. table::sql]]]
             / 
    !^.int[] .int(default)   . 
          ,  default
    !^.double[]+ .double(default)  double  
    !^.bool[] + .bool(default)  bool  
          ,  default
    !^.format[] %d  %.2f %02d...
    !^.match[-|-regex][[ ]]  $prematch $match $postmatch $1 $2...
         =
        i CASELESS
        x whitespace in regex ignored
        s singleline = $    
        m multiline = $   [\n],    
        g   ,   
        '   prematch, match, postmatch
        n      ,     
        U    '?'
    !^.match[-|-regex][ ]{}
         +=
        g   ,   
    !^.split[][[lrhv]][[    ]]
        l   [default]
        r  
        h nameless    0, 1, 2, ...
        v   1  'piece'    [default]
    !^.{l|r}split[]    $piece
          
    !^.upper|lower[] 
    !^.length[]
    !^.mid(P[;N])
         N - "  "
    !^.left(N), -1   
    !^.right(N)
    !^.pos[]
    !^.pos[](,   )
        <0 =  
    !^.replace[$____]
    !^.replace[$;$-]
    !^.save[[append;]]
    !^.save[[;$.charset[   ] $.append(true)]]
    !^.normalize[]   ,       
            match ,   ,   
            
    !^.trim[start|both|end|left|right[;chars]]  chars  //   
        default 'chars' -- whitespace chars
    !^.trim[chars]  chars    
    !^.base64[] encode
    !^string:base64[encoded[;$.strict(true)]] decode
    !^.idna[] IDNA ,   
    !^string:idna[encoded] IDNA ,   
    !^.js-escape[]     JS (%uXXXX)
    !^string:js-unescape[escaped]    js
    !^string:unescape[js|uri;escaped; $.charset[] ]    js  uri

!table
      
           " ?"
           count[]
    !^table::create[[nameless]]{}[[$.separator[^#09]]]   "set"
    !^table::create[table][[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]]
             
        reverse <<    (    locate,  table::create  )
    !^table::load[[nameless;][;]]
        !  nameless,      
        ! ,       '#',         
        !$.separator[^#09]
        !$.encloser["] -, .
    !^table::sql{query}[[$.limit(2) $.offset(4) $.bind[hash] todo:$.default{ ^table::create[...] }]]
        bind       
            oracle
            ":"
          bind  hash,   (  ) 
    !^.save[[nameless|append;][;, . load]]
    !$.
    !$.[ ]
    !$.fields   named      Hash
    !^.menu{}[[]]
    !^.offset[]  offset
    !^.offset[[whence]](5) 
        !whence=cur|set
        ! whence -  cur
    !^.count[], ^.count[rows] -    
    !^.count[columns] -   
    !^.count[cells] -      
    !^.line[] 1-based offset
    !^.sort{{ }|( )}[{desc|asc}] default=asc
    !^.append{}
    !^.append[ $. [ ] ]
    !^.insert{}     
    !^.insert[ $. [ ] ]
    !^.delete[] -     
    !^.join[][$.limit(1) $.offset(5) $.offset[cur]] -    .
            .
    !^.flip[]  ,  - ,  
    !^.locate[;][[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]] 
          ,  .  bool
    !^.locate( )[[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]]
          ,  .  bool
    !^.hash{[]|{}|()}[[ |table  ]][[$.distinct(1) $.distinct[tables]]]
         $hash.  hash      
             ,     ,  
         distinct  true,       
         distinct  tables,    hash  ,    
    !^.columns[[ ]]+     'column'   
    !$[^.select()] =       ,    
        $adults[^man.select($man.age>=18)]
    ^.color[1;2]


!hash
    !  
        !   " ?"
        !   _count[]
    !$.
        !_default -  ,  , 
            ,   ,  _default  
    !$.fields  $hash.   hash       table
    !^hash::create[[!copy_from_hash|copy_from_hashfile]]
          hash,  
    !^.add[]
         
    !^.sub[]
    !^.union[b] = 
         
    !^.intersection[b] = 
         
    !^.intersects[b] = bool
    !^hash::sql{}[[$.distinct(1) $.limit(2) $.offset(4) todo:$.default{$.field[]...}]]
         hash(=   )
        of hash(=   )
    !^.keys[[   ]]+     key   
    !^.count[]
    !^.foreach[key;value]{}[[]|{        }]
    !^.delete[]   
    !^.contain[] -      (bool)
    !^.at[first|last][[key|value|hash]]
    !^.at([-]N)[[key|value|hash]]
             
    !^.sort[key;value]{{ }|( )}[[desc|asc]] default=asc

!hashfile
    !^hashfile::open[filename]
    !^.clear[]   
    !$.[]   
    !$.[$.value[] $.expires[]}
         expires
        expires   date,   (0= )
    !$.  
    !^.delete[]   
    !^.delete[]   ,  
    !^.hash[]
           hash
           
    !^.foreach[key;value]{}[[]|{        }]
    !^.release[]
            .
              .
    !^.cleanup[]        .

    :
    $sessions[^hashfile::open[/db/sessions]]
   
    $sid[^math:uuid[]]
    $sessions.$sid[$.value[$uid] $.expires(1)]
    $uid[$sessions.$sid]


!form
    [      GET,    POST]
    !$form: = string/file 
    !$form:nameless =       "?value&...", "...&value&...", "...&value"
    !$form:qtail =       "?xxxxx",     ',' [imap]
    !$form:fields = hash    
    !$form:tables. = table    "field"   ""
    !$form:files. = hash     ,  - 0, 1, ...,  - 
    !$form:imap =    'x'  'y'
          ?1,2    server-site image map


!env
    !$env:
    !$env:fields    
    !$env:PARSER_VERSION  


!cookie
    !$cookie:    
    !$cookie:[]  90 
    !$cookie:[$.value[]  $.expires[] $.secure(true)]
    !  expires   'session', date,   (0=session)
    !  ,      "Sun, 25-Aug-2002 12:03:45 GMT"
    !   bool ,  $.secure(true), $.httponly(true)
    !$cookie:fields = hash   cookies


!request
    !$request:query
    !$request:uri
    !$request:document-root
        ,      parser, - = $env:DOCUMENT_ROOT
         ,   hosting -  
    !$request:argv = hash    .  0, 1, ... [0 --   ].
    !$request:charset
           
        !  upper/lower  match[][i]
        :  form       auto  MAIN
           $request/response:charset    .  .
    !$request:method   (GET|POST|PUT)
    !$request:body  POST-   
    !$request:body-file  POST-   
    !$request:body-charset  POST-
    !$request:headers     (  HTTP_)


!response
    !$response:[]      -- $response:
        !   string    hash:
        ! $value[abc] field: {abc}<<
        ! $attribute[zzz] field: abc; {attribute=zzz}<<
        !      string  date
        !  ,      "Sun, 25-Aug-2002 12:03:45 GMT"
    !$response:headers  
    !$response:body[DATA]    
    !$response:download[DATA]    , 
         ,  browser  download
    !$response:status
    !^response:clear[]    response 
    !$response:charset
          .. , 
        1)     $form:    browser'
        2)         browser
        3)       uri
           content-type ,  ,    
        :  form       auto  MAIN
           $request/response:charset    .  .


!regex
    !  
        !    true
        !      .
    !^regex::create[-][[ ]]
    !^.size[]    
            --     pcre , ,  .
    !^.study_size[]  study-. ==0 --     ""


!reflection
    !^reflection:create[;[;;[[;]]]]      (  100 )
    !^reflection:classes[]                    .  --  ,   methoded (  )  void
    !^reflection:class[]               
    !^reflection:class_name[]           
    !^reflection:base[]                 
    !^reflection:base_name[]             
    !^reflection:class_by_name[ ]    
    !^reflection:def[class; ]        
    !^reflection:methods[]                 ,  --  'native'  'parser'
    !^reflection:method[  ; ]  junction-method   
    !^reflection:fields[  ]             
    !^reflection:field[  ; ]        . getter- .
    !^reflection:uid[  ]         
    !^reflection:method_info[;]       
         $.inherited[]                 ,     (       )
         $.overridden[]                ,     (       )
          native   :
             .min_params(   )
             .max_params(   )
             .call_type[dynamic|static|any]
          parser   :
              --   (0, 1, ...),  -  
    !^reflection:dynamical[[object or class, caller if absent]]     true,       
                                                                       true,    ,
                                                                   false  
    !^reflection:delete[  ; ]                    
    !^reflection:is[ ; ][[]]             is,  ,    .


!mail
    !$mail.received=MESSAGE:
        .from
        .reply-to
        .subject
        .date  date
        .message-id
        .raw[
            ._--
        ]
        $.{text|html|file#}[ <<     mail:send (text, text2, ...) (file, file2, ...)
            $.content-type[
                $.value[{text|...|x-unknown}/{plain|html|...|x-unknown}]
                [$.charset[windows-1251]] <<   ,   
                $.--
            ]
            $.description
            $.content-id
            $.content-md5
            $.content-location
            .raw[
                ._--
            ]
            $.value[|FILE]
        ]
        $.message#[MESSAGE] (message, message2, ...)

    !^mail:send[
        $.options[-odd]
            unix: ,       sendmail
                -odd  "      email"
            win32: 
        $.charset[    ] 
        $.any-header-field 
        $.text[string]
        $.text[
           $.any-header-field 
           $.value[string]
        ]
        $.html{string}
        $.html[
            $.any-header-field 
            $.value{string}
        ]
        $.file#[FILE]
        $.file#[
            $.any-header-field 
            $value[FILE]
        ]
    ]
    ! charset ,     charset
    !content-type.charset    
    !     # 
        ^mail:send[
#           -,   source encoding.
#             body
            $.charset[windows-1251] 
#            
            $.content-type[$.value[text/plain] $.charset[windows-1251]]
            $.from["" <vasya@design.ru>]
            $.to["" <petya@design.ru>]
            $.subject[ ]
            $.body[
                
            ]
        ]
    !:send[$.header-field[] $.charset[ ] $.body[ body  , 
         hash,  multipart ]]
    ! charset ,     charset
    !content-type.charset    
    !      ,     .
    ! body  ,    ,  .
    ! body  hash,   ,    ,  
    !  ,    
    !      text,    .
    !      file,   ,  ::
        !$file[$.format[!uue|!base64] $.value[DATA] $.name[user-file-name]]
    !:  multipart   content-type
        ^mail:send[
#           -,   source encoding.
#             body
            $.charset[windows-1251] 
#            
            $.content-type[$.value[text/plain] $.charset[windows-1251]]
            $.from["" <vasya@design.ru>]
            $.to["" <petya@design.ru>]
            $.subject[ ]
            $.body[
                
            ]
        ]
        ^mail:send[
            $.from["" <vasya@design.ru>]
            $.to["" <petya@design.ru>]
            $.subject[ ]
            $.body[
                $.text[
#                     body
                    $.charset[windows-1251]
#                    
                    $.content-type[$.value[text/plain] $.charset[windows-1251]]
                    $.body[]
                ]
#       ,     multipart
                $.file[
                   $.value[^file::load[my beloved.doc]]
                   $.name[ .doc]
                   $.format[base64]
                ]
                $.file2[
                   $.value[^file::load[my beloved.doc]]
                   $.name[ .doc]
               ]
            ]
        ]
    !  
     unix    ,  
        $MAIL.sendmail[]
           , ,   
        /usr/sbin/sendmail 
        /usr/lib/sendmail
        ,  ,     "-t".    
     win32  SMTP ,   
        $MAIL.SMTP[smtp.domain.ru]

!image
    !$[^image::measure[DATA]]
          .ext case insensitive, 
            .gif  .jpg .jpeg
    !$.exif << hash  measure jpeg  exif  
        !$image.exif.DateTime & co 
            [  . http://www.ba.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html]
        !  int/double,
        !  date
        !   hash   0..count-1
    !$.src .width .height
    !$.line-width  = 
       !$.line-style =  '*** * '='*** * *** * *** * '
    !^.html[[hash]] = <img ...>
    !^image::load[.gif]
         gif 
    !^image::create( X; Y[;  default ]])
    !^.line(x0;y0;x1;y1;0xffFFff)
    !^.fill(x;y;0xffFFff)
    !^.rectangle(x0;y0;x1;y1;0xffFFff)
    !^.bar(x0;y0;x1;y1;0xffFFff)
    !^.replace(hex-1;hex-2)[table x:y _]
    !^.polyline+()[table x:y ]
    !^.polygon()[table x:y _]
    !^.polybar()[table x;y _]
    !^.font[_;__.gif][(_[;_])]
          =  /   
          _,  monospaced,  0,  _ =  gif
    !^.font[_;__.gif;
           $.space(_)             //   =  gif
           $.width(_)             // . ,   proportional
           $.spacing(  ) //   = 1
     ]
    !^.text(x;y)[_] AS_IS
    !^.length[_] AS_IS
    !^.gif[,  ] --   FILE  content-type=image/gif
             $response:download
    !^.arc(center x;center y;width;height;start in degrees;end in degrees;color)
    !^.sector(center x;center y;width;height;start in degrees;end in degrees;color)
    !^.circle(center x;center y;r;color)
    !^.copy[source](src x;src y;src w;src h;dst x;dst y[;dest w[;dest h[;tolerance]]])
          dest_w/dest_h    
               resample
                []   /pie,
             thumbnais  .
           dest_h  aspect ratio
        tolerance -  [   RGB    ], 
              [default=150]
             -   ,    
             -   ,    
    !^.pixel(x;y)[(color)]
            


!file
    !$__post.name 
    !$__post.size 
    !$t_post.text
    !^.save[text|binary; [;$.charset[   ]]]
    !^file:delete[ ]
    !^file:find[ ][{  }]
    !^file:list[[;-|-regex]] = table   name dir
    !^file:list[;$.filter[-|-regex] $.stat(true)] = table   name dir size [mca]date
    !^file::load[text|binary;!big.zip[;!domain_press_release_2001_03_01.zip][;]]
    !^file::create[text|binary;;data]
    !^file::create[text|binary;;data[;$.charset[    ] $.content-type[...]]]
    !^file::create[string-or-file-content[;$.name[] $.mode[text|binary] $.content-type[...] $.charset[...]]]
    !$___loaded.size
    !$___loaded__created.mode = text/binary
    !^file::stat[ ]
    !$___stated__loaded.size !.adate !.mdate !.cdate
    !^file::cgi[[text|binary;] [;env hash +options[;1cmd[;2line[;3ar[;4g[;5s]]]]]]]
            $
        $status
        $stderr
    !^file::exec[[text|binary;] [;env hash[;1cmd[;2line[;3ar[;4g[;5s;...under unix max 50 args]]]]]]]
        options:
            $.stdin[]    ,     HTTP-POST 
    !^file:move[  ;  ] 
            [win32:     ]
          dest    775
           ,   move   
    !^file:copy[ ;  ] 
           
    !^file:lock[ ]{}
           
        
         
        
    Xchmod[...]    ,     executable  ,   ftp  chmod.
    !^file:dirname[/a/some.tar.gz]=/a (   *nix)
    !^file:dirname[/a/b/]=/a (   *nix)
    !^file:basename[/a/some.tar.gz]=some.tar.gz (   *nix)
    !^file:basename[/a/b/]=b (   *nix)
    !^file:justname[/a/some.tar.gz]=some.tar
    !^file:justext[/a/some.tar.gz]=gz
    !/some/page.html: ^file:fullpath[a.gif] => /some/a.gif
    !^.sql-string[]  ^connect   escaped ,     
    !^file::sql{query}[[
        $.name[___download]
        $.content-type[ content-type]
    ]]
            " ".
        :
          - 
           -   
           -  content-type
    !^.base64[] encode
    !^file:base64[ ]
        encode
    !^file::base64[encoded string]
    !^file::base64[mode; ;encoded string[;$.content-type[...]]]
        decode
    !^file:crc32[ ]
         crc32    
    !^.crc32[]
         crc32 
    !^.md5[]
    !^file:md5[ ]
         digest ,  16    , 
          digest   hex , ,   


!math
    !$math:PI
    !^math:round floor ceiling 
    !^math:trunc frac
    !^math:abs sign 
    !^math:exp log 
    !^math:sin asin cos acos tan atan 
    !^math:degrees radians
    !^math:pow sqrt
    !^math:random( )
    !^math:uuid[]
        22C0983C-E26E-4169-BD07-77ECE9405BA5
        win32:  cryptapi
        unix:  /dev/urandom, 
             , /dev/random, 
             , rand 
            [ solaris /dev/random  ]
    !^math:uid64[]
       BA39BAB6340BE370
    !^math:md5[string]
         digest ,  16    , 
          digest   hex , ,   
    !^math:crypt[password;salt]
       salt prefix $apr1$   MD5 , 
            salt,   
       $1$  MD5   OS 'crypt',   [   solaris].
        salt     OS 'crypt'.
    !^math:crc32[string]
        crc32 
    !^math:sha1[string]
    !^math:convert[number](base-from;base-to)          
    !^math:digest[[md5|sha1|sha256|sha512];  ][[ $.format[hex|base64] $.hmac[] ]]
                .
       $.hmac[]     


!inet
    !^inet:ntoa(long)
    !^inet:aton[IP]
    !^inet:name2ip[name][[ $.ipv[4|6|any] $.table(true) ]]     IP 
    !^inet:ip2name[ip][ $.ipv[4|6|any] ]]    IP   


!json
    !^json:parse[-json--[;
        $.depth( , default == 19)
        $.double(false)                     (  )
                                              
        $.int(false)                      (  )
                                              
        $.distinct[first|last|all]          
                                     first --     
                                     last  --     
                                     all   --    .   ,   2
                                                 (key_2 )
                                           exception
        $.object[method-junction]     [;],      
                                        ,    
        $.array[method-junction]      ,    
    ]]
         json-  
    !^json:string[system or user object[;
        $.skip-unknown(false)     exception   'null'     
                                   void, bool, string, int, double, date, table, hash  file
        $.indent(true)                 
        $.date[sql-string|gmt-string|iso-string|unix-timestamp]      ,   -- sql-string
        $.table[object|array|compact]      ,   -- object
                                 object: [{"c1":"v11","c2":"v12",...},{"c1":"v21","c2":"v22",...},...]
                                 array:  [["c1","c2",...] || null (for nameless),["v11","v12",...],...]
                                 compact:  ["v11" || ["v11","v12",...],...]
        $.file[text|base64|stat]       (    
                                    output)
        $.xdoc[hash]               xdoc   (  ^xdoc.string[])
        $.[method-junction]          ,  
                                   3 : ,      
                                  ^json:string[]
        $._default[ ]     ,       
                                 
        $.void[null|string]            null ( )
                                   
    ]]
              json-


!date
    !  time    ,  
           epoch [1  1970 (UTC)], 
    !    ,   UTC
    !     OS  
    !^date::now[]
    !^date::now(  )  +
    !^date::today[]   00:00:00  
    !^date::create(  epoch)
    !^date::create(year;month[;day[;hour[;minute[;second]]]])
    !^date::create[   %Y-%m-%d %H:%M:%S]
              
        1: %Y[-%m[-%d[ %H[:%M[:%S]]]]]
        2: %H:%M[:%S]
    !^date::create[   %Y-%m-%dT%H:%M[:%S]TZ]
              ISO 8601
         TZ: Z(UTC)  +-hour[:minute] (  UTC)
    !^date::unix-timestamp()
    !^.unix-timestamp[]
    !$.year month day  hour minute second  weekday yearday(0...) daylightsaving TZ weekyear
        read-only
        TZ="" <<  
    !^.roll[year|month|day](+-)  
    !^.roll[TZ; ] ,    -  :   .hour & Co
    !^date:roll[TZ; ] ,       -  
    !^.sql-string[[datetime|date|time]]
        datetime    -- %Y-%m-%d %H:%M:%S
        date                       -- %Y-%m-%d
        time                       -- %H:%M:%S
        where published='^.sql-string[]'
    !^date:calendar[rus|eng](;)    
        : 0..6, week, year
    !^date:calendar[rus|eng](;;)   
        : year, month, day, weekday
    !^date:last-day(;)    
    !^.last-day[]     $
    !^.gmt-string[]  Fri, 23 Mar 2001 09:32:23 GMT
    !^.iso-string[]  2001-03-23T12:32:23+3


xdoc(xnode)
    !$xdoc.search-namespaces hash, where keys=prefixes, values=urls
    
    DOM1 attributes:
    !readonly attribute DocumentType doctype
    Xreadonly attribute DOMImplementation implementation
    !readonly attribute Element documentElement

    DOM1 methods:
    !Element createElement(in DOMString tagName)
    !DocumentFragment createDocumentFragment()
    !Text createTextNode(in DOMString data)
    !Comment createComment(in DOMString data)
    !CDATASection createCDATASection(in DOMString data)
    !ProcessingInstruction createProcessingInstruction(in DOMString target,in DOMString data)
    !Attr createAttribute(in DOMString name)
    !EntityReference createEntityReference(in DOMString name)
    !NodeList getElementsByTagName(in DOMString tagname)

    DOM2 some methods:
    !^.getElementById[elementId] = xnode
        The DOM implementation must have information that says which attributes are of type ID. 
        Attributes with the name "ID" are not of type ID unless so defined. 
        Implementations that do not know whether attributes are of type ID or not 
        are expected to return null.

    !     $.encoding 
    !    ,
        $response:charset
    ::sql{...}
    !::create[[URI]]{<?xml?><string/>}   'set'
    !::create[[URI]][qualifiedName]
      URI default = disk path to requested document
         / 
    !::create[file] can be usable:
    	$f[^file::load[binary;http://;some HTTP options here...]]
    	$x[^xdoc::create[$f]]
    !::load[file.xml[;]]
    !.transform[rules.xsl|xdoc][[params hash]]  dom
         ,       ,
            " .stamp"[  stamp ]
        <xsl:output
        !method = "xml" | "html" | "text"
            X| qname-but-not-ncname 
        !version = nmtoken 
        !encoding = string 
        !omit-xml-declaration = "yes" | "no"
        !standalone = "yes" | "no"
        X[,  xsltSaveResultTo   ]doctype-public = string 
            X   "-//W3C//DTD XHTML"    XHTML
        X[,  xsltSaveResultTo   ]doctype-system = string 
        !cdata-section-elements = qnames 
        !indent = "yes" | "no"
        !media-type = string /> 
        !   ,  xpath 

    !.string[[output options]]
    !.save[file.xml[;output options]]  
    !.file[[output options]] = file
        output options   xsl:output 
            [:  cdata-section-elements,  , ]
         media-type   $response:body[]


	!    :
	    parser://method/param/to/that/method
	         ^MAIN:method[/param/to/that/method]
	    [:      /, ,     ]

!xnode
    DOM1 attributes:
    !$node.nodeName
    !$node.nodeValue
    	!read
    	!write
    !$node.nodeType = int
      ELEMENT_NODE                   = 1 
      ATTRIBUTE_NODE                 = 2 
      TEXT_NODE                      = 3 
      CDATA_SECTION_NODE             = 4 
      ENTITY_REFERENCE_NODE          = 5 
      ENTITY_NODE                    = 6 
      PROCESSING_INSTRUCTION_NODE    = 7 
      COMMENT_NODE                   = 8 
      DOCUMENT_NODE                  = 9 
      DOCUMENT_TYPE_NODE             = 10 
      DOCUMENT_FRAGMENT_NODE         = 11 
      NOTATION_NODE                  = 12 
            $vasyaNode.type==$xnode:ELEMENT_NODE
    !$node.parentNode
    !$node.childNodes = array of nodes
    !$node.firstChild
    !$node.lastChild
    !$node.previousSibling
    !$node.nextSibling
    !$node.ownerDocument = xdoc
    !$node.prefix
    !$node.namespaceURI
    !$element_node.attributes = hash of xnodes
    !$element_node.tagName
    !$attribute_node.specified = boolean
        true if the attribute received its value explicitly in the XML document, 
        or if a value was assigned programatically with the setValue function.
        false if the attribute value came from the default value declared in the document's DTD. 
    !$attribute_node.name
    !$attribute_node.value
    $text_node/cdata_node/comment_node.substringData
    !$pi_node.target = target of this processing instruction
        XML defines this as being the first token following the markup 
        that begins the processing instruction.
    !$pi_node.data = The content of this processing instruction
        This is from the first non white space character after the target 
        to the character immediately preceding the ?>. 
    document_node.
        readonly attribute DocumentType doctype
        readonly attribute DOMImplementation implementation    
        readonly attribute Element documentElement
    document_type_node.
        !readonly attribute DOMString name
        readonly attribute NamedNodeMap entities
        readonly attribute NamedNodeMap notations
    !notation_node.
        !readonly attribute DOMString publicId
        !readonly attribute DOMString systemId

    !DOM1 node methods:
    !Node insertBefore(in Node newChild,in Node refChild)
    !Node replaceChild(in Node newChild,in Node oldChild)
    !Node removeChild(in Node oldChild)
    !Node appendChild(in Node newChild)
    !boolean hasChildNodes()
    !Node cloneNode(in boolean deep)

    !DOM1 element methods:
    !DOMString getAttribute(in DOMString name)
    !void setAttribute(in DOMString name, in DOMString value) raises(DOMException)
    !void removeAttribute(in DOMString name) raises(DOMException)
    !Attr getAttributeNode(in DOMString name)
    !Attr setAttributeNode(in Attr newAttr) raises(DOMException)
    !Attr removeAttributeNode(in Attr oldAttr) raises(DOMException)
    !NodeList getElementsByTagName(in DOMString name)
    !void normalize()


    !Introduced in DOM Level 2:
    !Node importNode(in Node importedNode, in boolean deep) raises(DOMException)
    !NodeList getElementsByTagNameNS(in DOMString namespaceURI, in DOMString localName)
    !boolean hasAttributes()

    !XPath:
    !^node.select[xpath/query/expression] = array of nodes, 
        empty array if nothing found
    !^node.selectSingle[xpath/query/expression] = first node if any
    !^node.selectBool[xpath/query/expression] = bool if any or die
    !^node.selectNumber[xpath/query/expression] = double if any or die
    !^node.selectString[xpath/query/expression] = string if any or die

    !error codes(       ):
        INDEX_SIZE_ERR
        If index or size is negative, or greater
        than the allowed value
        DOMSTRING_SIZE_ERR
        If the specified range of text does not
        fit into a DOMString
        HIERARCHY_REQUEST_ERR
        If any node is inserted somewhere it
        doesn't belong
        WRONG_DOCUMENT_ERR
        If a node is used in a different
        document than the one that created it
        (that doesn't support it)
        INVALID_CHARACTER_ERR
        If an invalid character is specified,
        such as in a name.
        NO_DATA_ALLOWED_ERR
        If data is specified for a node which
        does not support data
        NO_MODIFICATION_ALLOWED_ERR
        If an attempt is made to modify an
            object where modifications are not
        allowed
        NOT_FOUND_ERR
        If an attempt was made to reference a
        node in a context where it does not
        exist
        NOT_SUPPORTED_ERR
        If the implementation does not support
        the type of object requested
        INUSE_ATTRIBUTE_ERR
        If an attempt is made to add an
        attribute that is already inuse
        elsewhere

!memory
    !^memory:compact[]  ,     
    (:     )
       XSL transform.

!status
    !   ,  apache   
    <Location /parser-status.html>
    ParserStatusAllowed
    </Location>
    ! cgi  
    ! isapi   

    !$status:sql hash
        !cache table
            url    time    
            url    time    
            url    time    
    !$status:stylesheet
        !cache table
            file    time
            file    time
            file    time

    !$status:rusage hash
        !utime user time used
        !stime system time used
        !maxrss max resident set size
        !ixrss integral shared text memory size
        !idrss integral unshared data size
        !isrss integral unshared stack size
        !tv_sec
        !tv_usec
           $s[$status:rusage]
           ^s.tv_sec.format[%.0f].^s.tv_usec.format[%06.0f]

    !$status:memory hash
        !used
            Includes some pages that were allocated but never written.

        !free

        !ever_allocated_since_compact
            Return the number of bytes allocated since the last collection.	

        !ever_allocated_since_start
            Return the total number of bytes [EVER(c)PAF] allocated in this process.
            Never decreases.

    !$status:pid process id
    !$status:tid thread id

console
    $console:timeout
    !$console:line
        read/write 

DATA::=string | file | hash

!hash 
[
	$.file[   ]
	$.name[   ]
	$.mdate[date]
]

!MAIN
     ,      auto.p, 
     auto.p   :
        ! auto.p 
            cgi: 
                1.       CGI_PARSER_SITE_CONFIG
                       parser' 
            isapi: windows directory
            apache module: 
                1) ParserConfig [can be in .htaccess]
        !auto.p   DOCUMENT_ROOT/        
         ,    
       MAIN,    
    
    !  MAIN    @main[]
    !     @postprocess[data] if($data is string) ...
    !   

!    try  ,     , 
    !
    !@unhandled_exception[exception;stack]
    !$exception.type   " "
    !$exception.file $exception.lineno $exception.colno ,   ,    [    ]
    !$exception.source , -   
    !$exception.comment  english
    !stack    file line name,
             [name]   [file line] 
        /,   .

!   (file::load, table::load, xdoc::load)     :
    !http://domain/document[?params<<deprecated, use $.form[...]]
    ! , ,  :
        !$.method[GET|POST|HEAD]
        !$.timeout(3)  <<  , - =2
        !$.cookies[
        	$.[]
        ]
        !$.headers[
        !    $.[] <<   ,  $response:
        !]
        $.enctype[multipart/form-data]
        $.form[
            !$.field1[string]
            !$.field2[^table::create{one_column_only^#0Avalue1^#0Avalue2}]
            $.field3[file]
        ]
        !$.body[string]
        	|file
        !-, user-agent=parser3
        !-,  http status != 200 >>  http.status ,
        !  , 
        !$.any-status(1)
        !$.charset[   -],    content-type:charset - _
        !$.response-charset[  ],   content-type:charset
        !$.user[]
        !$.password[]
    !file::load    
        !: (    )
        !tables <<   ->table    "value". 
                  . ,  set-cookies
            todo:  cookies

!  :
    !parser.compile       ^test[}                 ( , ...)
    !parser.runtime       ^if(0).                 (/,  ,   , ...)
    !number.zerodivision  ^eval(1/0) ^eval(1%0)
    !number.format        ^eval(abc*5)
    !file.lock                                                        shared/exclusive lock error
    !file.missing         ^file:delete[delme]                         not found
    !file.access          ^table::load[.]                             no rights
    !file.read            ^file::load[...]                            error while reading file
    !file.seek                                                        seek failed
    !file.execute         ^file::cgi[...]                             incorrect cgi header/can't execute
    !image.format         ^image::measure[index.html]                 not gif/jpg
    !sql.connect          ^connect[mysql://baduser:pass@host/db]{}    not found/timeout
    !sql.execute          ^void:sql{select bad}                       syntax error
    sql.duplicate
    sql.access
    sql.missing
    sql.xxx [serge asked]
    !xml                  ^xdoc::create{<forgot?>}                    any error in xml/xslt libs
    !smtp.connect                                                     not found/timeout
    !smtp.execute                                                     communication error
    !email.format         hren tam@null.ru                            wrong email format(bad chars/empty)
    !email.send           $MAIL.sendmail[/shit]                       sendmail not executable
    !http.host            ^file::load[http://notfound/there]          host not found
    !http.connect         ^file::load[http://not_accepting/there]     host found, but do not accept connections
    !http.timeout         ^file::load[http://host/doc]                whole load operation failed to complete in # seconds
    !http.response        ^file::load[http://ok/there]                host found, connection accepted, bad answer
    !http.status          ^file::load[http://ok/there]                host found, connection accepted, status!=200
    !date.range           ^date::create(1950;1;1)                     date out of valid range

!  MAIN  $SIGPIPE(1)   ,     , 
	     parser3.log (   )

!      result   
    (   )
             -,
         
              

