Parse::RPN(3)         User Contributed Perl Documentation        Parse::RPN(3)



NNAAMMEE
        Parse::RPN (2.xx) - Is a minimalist RPN parser/processor (a little like FORTH)

SSYYNNOOPPSSIISS
        use Parse::RPN;
        $result=rpn(string ...);
        @results=rpn(string ...);

        $error=rpn_error();

        string... is a list of RPN operators and values separated by a coma
        in scalar mode RPN return the result of the calculation (If the stack contain more then one element,
        you receive a warning and the top value on the stack)
        in array mode, you receive the content of the stack after evaluation

DDEESSCCRRIIPPTTIIOONN
        rpn() receive in entry a scalar of one or more elements coma separated
        and evaluate as an RPN (Reverse Polish Notation) command.
        The function split all elements and put in the stack.
        The operator are case sensitive.
        The operator are detect as is, if they are alone in the element of the stack.
        Extra space before or after are allowed
        (e.g "3,4,MOD" here MOD is an operator but it is not the case in "3,4,MOD 1")
        If element is not part of the predefined operator (dictionary), the element is push as a litteral.
        If you would like to put a string which is part of the dictionary, put it between quote or double-quote
        (e.g "3,4,'MOD'" here MOD is a literal and the evaluation return MOD)
        If the string contain a coma, you need also to quote or double-quote the string.
        (be care to close your quoted or double-quoted string)

        The evaluation follow the rule of RPN or FORTH or POSTCRIPT or pockect calcutor HP.
        Look on web for documentation about the use of RPN notation.

        I use this module in a application where the final user need to create and maintain
        a configuration file with the possibility to do calculation on variables returned from application.

        The idea of this module is comming from Math::RPN of Owen DeLong, [email protected] that I used for more then a year
        before some of my customer would like more...

        rpn_error() return the last error from the evaluation (illegal division by 0, error from the PERL function execution...)
        each time that rpn() is call the rpn_error() is reinitianised.

MMAATTHHEEMMAATTIICC ooppeerraattoorrss
  aa bb ++
            return the result of 'a' + 'b'

  aa bb --
            return the result of 'a' - 'b'

  aa bb **
            return the result of 'a' * 'b'

  aa bb //
            return the result of 'a' / 'b'
            if b =0 return '' (to prevent exception raise)

  aa bb ****
            return the result of 'a' ** 'b'  (exponant)

  aa 11++
            return the result of 'a' +1

  aa 11--
            return the result of 'a' -1

  aa 22--
            return the result of 'a' -2

  aa 22++
            return the result of 'a' +2

  aa bb MMOODD
            return the result of 'a' % 'b'

  aa AABBSS
            return the result of  abs 'a'

  aa IINNTT
            return the result of INT 'a'

  aa ++--
            return the result negate value of 'a' (- 'a' )

  aa RREEMMAAIINN
            return the result of 'a' - int 'a' (fractional part of 'a' )

  aa SSIINN
            return the result of sin 'a'  ('a' in RADIAN)

  aa CCOOSS
            return the result of cos 'a'  ('a' in RADIAN)

  aa TTAANN
            return the result of tan 'a'  ('a' in RADIAN)

  aa CCTTAANN
            return the result of cotan 'a'  ('a' in RADIAN)

  aa LLNN
            return the result of ln 'a'
            if = 0 return '' (to prevent exception raise)

  aa EEXXPP
            return the result of 'e' ** 'a'

  PPII
            return the value of PI (3.14159265358979)

  aa bb MMIINN
            return the smallest value of the 2 arguments

  aa bb MMAAXX
            return the greatest value of the 2 arguments

  aa MMIINNXX
            return the smallest value from the a elements from the stack

  aa bb MMAAXXXX
            return the greatest value from the a elements from the stack

  aa SSUUMM
              sum the a elements from the top of the stack
              remove these a elements
              and return the result value on the stack

  aa SSTTAATTSS
              STATS the a element on top of the stack
              remove these a element
              the new variable _SUM_, _MULT_, _ARITH_MEAN_, _GEOM_MEAN_, _QUAD_MEAN_ (= _RMS_), _HARM_MEAN_, _STD_DEV_, _SAMPLE_STD_DEV_, _VARIANCE_,

RREELLAATTIIOONNAALL ooppeerraattoorrss
  aa bb <<
            return the result of 'a' < 'b'  ( BOOLEAN value )

  aa bb <<==
            return the result of 'a' <= 'b'  ( BOOLEAN value )

  aa bb >>
            return the result of 'a' > 'b'  ( BOOLEAN value )

  aa bb >>==
            return the result of 'a' >= 'b'  ( BOOLEAN value )

  aa bb ====
            return the result of 'a' == 'b'  ( BOOLEAN value ) 1 if a == b else 0

  aa bb <<==>>
            return the result of 'a' <=> 'b'  ( BOOLEAN value  ) -1 if a < b ,0 if a == b, 1 if a > b

  aa bb !!==
            return the result of 'a' != 'b'  ( BOOLEAN value ) 0 if a == b else 1

  aa bb vv >><<
            return the 1 ( BOOLEAN value ) if v greater than a but lower than b. Otherwise return 0
            ( aka between boundaries excluded )

  aa bb vv >>==<<
            return 1 ( BOOLEAN value ) if v greater or equal to a but lower or equal to b. Otherwise return 0
            ( aka between boundaries included )

  aa bb NN<<
            return the result of 'a' N< 'b'  ( BOOLEAN value ) if a is ISNUM

  aa bb NN>>==
            return the result of 'a' N<= 'b'  ( BOOLEAN value ) if a is ISNUM

  aa bb NN>>
            return the result of 'a' N> 'b'  ( BOOLEAN value ) if a is ISNUM

  aa bb NN>>==
            return the result of 'a' N>= 'b'  ( BOOLEAN value ) if a is ISNUM

  aa bb NN====
            return the result of 'a' N== 'b'  ( BOOLEAN value ) 1 if a == b and a ISNUM else 0

  aa bb NN!!==
           return the result of 'a' != 'b'  ( BOOLEAN value ) 0 if a == b and a ISNUM else 1

LLOOGGIICCAALL ooppeerraattoorrss
  aa bb OORR
            return the 1 one of the 2 argument are not equal to 0

  aa bb AANNDD
            return the 0 one of the 2 argument are equal to 0

  aa bb XXOORR
            return the 0 if the  2 argument are equal

  aa bb NNXXOORR
            return the 0 if the  2 argument are equal. Any non numeric elements is seen as a 0.

  aa NNOOTT
            return the 0 if the argument is not eqauk to 0
            return the 1 if the argument is  eqauk to 0

  aa TTRRUUEE
            return the 1 if the top of stack is !=0 and if stack not empty

  aa FFAALLSSEE
            return the 0 if the top of stack is !=0

  aa bb >>>>
            bitwise shift to the right
            shift the bits in a to the left of b level

  aa bb <<<<
            bitwise shift to the left
            shift the bits in a to the left of b level

MMIISSCC ooppeerraattoorrss
  aa VVAALL,,RREETT,, ""ooppeerraattoorr"" LLOOOOKKUUPP
            test with the "operator" the [a] value on each elements of VAL and if test succeed return the value from array RET with the same index
            the "operator" must be quoted to prevent evaluation

  aa VVAALL,,RREETT,, ""ooppeerraattoorr"" LLOOOOKKUUPPPP
            Test with the perl "operator" the [a] value on each elements of VAL
            and if test succeed return the value from array RET with the same index
            The "operator" must be quoted to prevent evaluation

  aa VVAALL,,RREETT,,OOPPEE LLOOOOKKUUPPOOPP
            Loop on each item of array VAL and test the value [ a ]  with the operator from ope ARRAY
            against the corresponding value in array VAL and return the value from array RET with the same index

  aa VVAALL,,RREETT,,OOPPEE LLOOOOKKUUPPOOPPPP
            Loop on each item of array VAL and test the value [ a ]  with the perl operator from ope ARRAY
            against the corresponding value in array VAL and return the value from array RET with the same index

  TTIICCKK
            return the current time in ticks

  aa LLTTIIMMEE
            return the localtime coresponding to the ticks value 'a'
            the format is 'sec' 'min' 'hour' 'day_in_the_month' 'month' 'year' 'day_in_week' 'day_year' 'dayloight_saving'
            'year' is the elapsed year since 1900
            'month' start to 0
            The format is the same as localtime() in perl

  aa GGTTIIMMEE
            return the gmtime coresponding to the ticks value 'a'
            the format is 'sec' 'min' 'hour' 'day_in_the_month' 'month' 'year' 'day_in_week' 'day_year' 'dayloight_saving'
            'year' is the elapsed year since 1900
            'month' start to 0
            The format is the same as gmtime() in perl

  aa HHLLTTIIMMEE
            return the localtime coresponding to the ticks value 'a' in a human readable format

  aa HHGGTTIIMMEE
            return the gmtime coresponding to the ticks value 'a' in a human readable format

  aa HHTTTTPPTTIIMMEE
            return the ticks coresponding to the time value in a format accepted by HTTP::Date

  RRAANNDD
            return a random value in the range [0,1[

  aa LLRRAANNDD
            return a random value in the range [0,'a'[

  aa SSPPAACCEE
            return the number 'a' formated with space each 3 digits

  aa DDOOTT
            return the number 'a' formated with . (dot) each 3 digits

  aa NNOORRMM
            return the number 'a' normalize by slice of 1000 with extra power value "K", "M", "G", "T", "P" (or nothing if lower than 1000)

  aa NNOORRMM22
            return the number 'a' normalize by slice of 1024 with extra power value "K", "M", "G", "T", "P" (or nothing if lower than 1024)

  aa UUNNOORRMM
            reverse function of NORM
            return the number from a 'a' with a sufix "K", "M", "G", "T", "P" (or nothing if lower than 1000)
            and calculate the real value base 1000 ( e.g  7k = 7000)

  aa UUNNOORRMM22
            reverse function of NORM2
            return the number from a 'a' with a sufix "K", "M", "G", "T", "P" (or nothing if lower than 1024)
            and calculate the real value base 1024 ( e.g  7k = 7168)

  aa OOCCTT
            return the decimal value for the HEX, BINARY or OCTAL value 'a'
            OCTAL is like  '0nn' where n is in the range of 0-7
            BINARY is like '0bnnn...'   where n is in the range of 0-1
            HEX is like '0xnnn' where n is in the range of 0-9A-F
            if no specific format convert as an hexadecimal by default

  aa OOCCTTSSTTRR22HHEEXX
            return a HEX string from a OCTETSTRING.
            useful when receiving an SNMP ASN.1 OCTETSTRING like mac address

  aa HHEEXX22OOCCTTSSTTRR
            return a OCTETSTRING string from a HEX
            useful when you need to check if an SNMP ASN.1 OCTETSTRING if matching the hex value provided

  aa DDDDEECC22SSTTRR
            return a string from a dotted DEC string
            useful when you need to manipulate an SNMP extension with 'exec'

  aa SSTTRR22DDDDEECC
            return a dotted DEC string to a string
            useful when you need to manipulate an SNMP extension with 'exec'

SSttrruuccttuurraatteedd ssttrriinngg ((SSLLxxxxxx)) ooppeerraattoorrss
  ssttrriinngg aa bb SSLLSSLLIICCEE
            return the STRUCTURATED list slice  from 'a' to 'b' extracted from STRUCTURATED list.
            string are the STRUCTURATED list
            the STRUCTURATED LIST use this format:
            each entries are separated by ' # ' and inside each entry , the KEY and the VAL are separated by ' | '
            'keys1 | val1 # key2 | val2 # Keys3 | val3 # Keys4 | val4 #'
            example:
            'keys1 | val1 # key2 | val2 # Keys3 | val3 # Keys4 | val4 #,1,2,SLSLICE'
            return:
            # key2 | val2 # Keys3 | val3 #

  ssttrriinngg aa SSLLIITTEEMM
            return the STRUCTURATED item at position 'a' from a STRUCTURATED list.
            string are the STRUCTURATED list
            the STRUCTURATED LIST use this format:
            each entries are separated by ' # ' and inside each entry , the KEY and the VAL are separated by ' | '
            'keys1 | val1 # key2 | val2 # Keys3 | val3 #'
            example:
            'keys1 | val1 # key2 | val2 # Keys3 | val3 #,1,SLITEM'
            return:
            # key2 | val2 #

  ssttrriinngg aa SSLLGGRREEPP
            return a STRUCTURATED list from a STRUCTURATED list where the STRUCTURATED LIST match the REGEX a.
            string are the STRUCTURATED list
            the STRUCTURATED LIST use this format:
            each entries are separated by ' # ' and inside each entry , the KEY and the VAL are separated by ' | '
            'keys1 | val1 # key2 | val2 # Keys3 | val3 #'
            example:
            'keys1 | val1 # key2 | val2 # Keys3 | val3 #,Keys,SLGREP'
            return:
            #  Keys3 | val3 #

  ssttrriinngg aa SSLLGGRREEPPII
            return a STRUCTURATED list from a STRUCTURATED list where the STRUCTURATED LIST match the REGEX a (case insensitive).
            string are the STRUCTURATED list
            the STRUCTURATED LIST use this format:
            each entries are separated by ' # ' and inside each entry , the KEY and the VAL are separated by ' | '
            'keys1 | val1 # key2 | val2 # Keys3 | val3 #'
            example:
            'keys1 | val1 # key2 | val2 # Keys3 | val3 #,Keys,SLGREPI'
            return:
            #  keys1 | val1 # Keys3 | val3 #

  ssttrriinngg aa SSLLSSEEAARRCCHHAALLLL
            return all KEYS from a STRUCTURATED LIST where the STRUCTURATED LIST val match the REGEX a.
            string are the STRUCTURATED list
            the STRUCTURATED LIST use this format:
            each entries are separated by ' # ' and inside each entry , the KEY and the VAL are separated by ' | '

            example:
            '# 1.3.6.1.2.1.25.3.3.1.2.779 | 5 # 1.3.6.1.2.1.25.3.3.1.2.780 | 25 # 1.3.6.1.2.1.25.3.3.1.2.781 | 6 # 1.3.6.1.2.1.25.3.3.1.2.782 | 2 #,2,SLSEARCHALL'
            return:
            1.3.6.1.2.1.25.3.3.1.2.780  1.3.6.1.2.1.25.3.3.1.2.782

  ssttrriinngg aa SSLLSSEEAARRCCHHAALLLLII
            return all KEYS from a STRUCTURATED LIST where the STRUCTURATED LIST val match the REGEX a (case insensitive).
            string are the STRUCTURATED list
            the STRUCTURATED LIST use this format:
            each entries are separated by ' # ' and inside each entry , the KEY and the VAL are separated by ' | '
            '# key1 | val1 # key2 | val2 # key12 | VAL12 #,val1,SLSEARCHALLI'
            example:
            '# key1 | val1 # key2 | val2 # key12 | VAL12 #,val1,SLSEARCHALLI'
            return:
            key1  key12

  ssttrriinngg aa SSLLSSEEAARRCCHHAALLLLKKEEYYSS
            return all VALUES from a STRUCTURATED LIST where the STRUCTURATED LIST keys match the REGEX a
            string are the STRUCTURATED list
            the STRUCTURATED LIST use this format:
            each entries are separated by ' # ' and inside each entry , the KEY and the VAL are separated by ' | '
            '# 1.3.6.1.2.1.25.3.3.1.2.779 | 1 # 1.3.6.1.2.1.25.3.3.1.2.780 | 5 # 1.3.6.1.2.1.25.3.3.1.2.781 | 6 # 1.3.6.1.2.1.25.3.3.1.2.782 | 2 #'
            example:
            '# 1.3.6.1.2.1.25.3.3.1.2.779 | 1 # 1.3.6.1.2.1.25.3.3.1.2.780 | 5 # 1.3.6.1.2.1.25.3.3.1.2.781 | 6 # 1.3.6.1.2.1.25.3.3.1.2.782 | 2 #,1.3.6.1.2.1.25.3.3.1.2.,SLSEARCHALLKEYS'
            return:
            1 5 6 2

  ssttrriinngg aa SSLLSSEEAARRCCHHAALLLLKKEEYYSSII
            return all VALUES from a STRUCTURATED LIST where the STRUCTURATED LIST key match the REGEX a.
            string are the STRUCTURATED list.
            the STRUCTURATED LIST use this format:
            each entries are separated by ' # ' and inside each entry , the KEY and the VAL are separated by ' | '
            '# tata is not happy | and what? # tata is happy | and??  # toto is not happy | oops # toto is happy | yeah #'
            example:
            '# tata is not happy | and what? # tata is happy | and??  # toto is not happy | oops # toto is happy | yeah #,toto,SLSEARCHALLKEYSI'
            return:
            oops yeah

  ssttrriinngg aa OOIIDDSSEEAARRCCHHAALLLLVVAALL
            return all OID leaf from a snmpwalk macthing the REGEX a
            string are the OID walk list
            the OID walk result use this format:
            each snmpwalk entries are separated by ' # ' and inside each entry , the OID and the VAL are separated by ' | '
            '# .1.3.6.1.2.1.25.4.2.1.2.4704 | "TASKMGR.EXE" # .1.3.6.1.2.1.25.4.2.1.2.2692 | "winvnc4.exe" # .1.3.6.1.2.1.25.4.2.1.2.3128 | "CSRSS.EXE" #
            example:
            '# .1.3.6.1.2.1.25.4.2.1.2.488 | "termsrv.exe" # .1.3.6.1.2.1.25.4.2.1.2.688 | "Apache.exe" # .1.3.6.1.2.1.25.4.2.1.2.5384 | "aimsserver.exe" # .1.3.6.1.2.1.25.4.2.1.2.2392 | "Apache.exe" # .1.3.6.1.2.1.25.4.2.1.2.2600 | "cpqnimgt.exe" #,Apache\.exe,OIDSEARCHALLVAL'
            return:
            688 2392

  ssttrriinngg aa OOIIDDSSEEAARRCCHHAALLLLVVAALLII
            return all OID leaf from a snmpwalk macthing the REGEX a ( case insensitive )
            string are the OID walk list
            the OID walk result use this format:
            each snmpwalk entries are separated by ' # ' and inside each entry , the OID and the VAL are separated by ' | '
            '# .1.3.6.1.2.1.25.4.2.1.2.4704 | "TASKMGR.EXE" # .1.3.6.1.2.1.25.4.2.1.2.2692 | "winvnc4.exe" # .1.3.6.1.2.1.25.4.2.1.2.3128 | "CSRSS.EXE" #
            example:
            '# .1.3.6.1.2.1.25.4.2.1.2.488 | "termsrv.exe" # .1.3.6.1.2.1.25.4.2.1.2.688 | "Apache.exe" # .1.3.6.1.2.1.25.4.2.1.2.5384 | "aimsserver.exe" # .1.3.6.1.2.1.25.4.2.1.2.2392 | "Apache.exe" # .1.3.6.1.2.1.25.4.2.1.2.2600 | "cpqnimgt.exe" #,Apache\.exe,OIDSEARCHALLVALI'
            return:
            688 2392

  ssttrriinngg xx xx xx aa OOIIDDSSEEAARRCCHHLLEEAAFF
            return all VAL leaf from a snmpwalk when the OID leaf match each REGEX
            a is the number of leaf to pick from the stack
            x are all the leaf
            string are the OID walk list
            the OID walk result use this format:
            each snmpwalk entries are separated by ' # ' and inside each entry , the OID and the VAL are separated by ' | '
            '# .1.3.6.1.2.1.25.4.2.1.2.4704 | "TASKMGR.EXE" # .1.3.6.1.2.1.25.4.2.1.2.2692 | "winvnc4.exe" # .1.3.6.1.2.1.25.4.2.1.2.3128 | "CSRSS.EXE" #
            example:
            '# .1.3.6.1.2.1.25.4.2.1.7.384 | running # .1.3.6.1.2.1.25.4.2.1.7.688 | running # .1.3.6.1.2.1.25.4.2.1.7.2384 | invalid #,688,2384,2,OIDSEARCHLEAF'
            return:
            running invalid

  ssttrriinngg xx xx xx aa OOIIDDSSEEAARRCCHHLLEEAAFFII
            return all VAL leaf from a snmpwalk when the OID leaf match each REGEX
            a ( case insensitive ) is the number of leaf to pick from the stack
            x are all the leaf
            string are the OID walk list
            the OID walk result use this format:
            each snmpwalk entries are separated by ' # ' and inside each entriy , the OID and the VAL are separated by ' | '
            '# .1.3.6.1.2.1.25.4.2.1.2.4704 | "TASKMGR.EXE" # .1.3.6.1.2.1.25.4.2.1.2.2692 | "winvnc4.exe" # .1.3.6.1.2.1.25.4.2.1.2.3128 | "CSRSS.EXE" #'
            example:
            '# .1.3.6.1.2.1.25.4.2.1.7.384 | running # .1.3.6.1.2.1.25.4.2.1.7.688 | running # .1.3.6.1.2.1.25.4.2.1.7.2384 | invalid #,688,2384,2,OIDSEARCHLEAFI'
            return:
            running invalid

SSTTRRIINNGG ooppeerraattoorrss
  aa bb EEQQ
            return the result of 'a' EQ 'b'  ( BOOLEAN value )

  aa bb NNEE
            return the result of 'a' NE 'b'  ( BOOLEAN value )

  aa bb LLTT
            return the result of 'a' LT 'b'  ( BOOLEAN value )

  aa bb GGTT
            return the result of 'a' GT 'b'  ( BOOLEAN value )

  aa bb LLEE
            return the result of 'a' LE 'b'  ( BOOLEAN value )

  aa bb GGEE
            return the result of 'a' GE 'b'  ( BOOLEAN value )

  aa bb CCMMPP WWOORRDDSS,,LLEENN
      == 11558844'' ##   aatt tt//0099DDIICCTT..tt lliinnee 5588.. ## LLooookkss lliikkee yyoouu ffaaiilleedd 11 tteesstt ooff
      3311..
            return the result of 'a' CMP 'b'  ( BOOLEAN value )

  aa LLEENN
            return the length of 'a'

  aa CCHHOOMMPP
            remove any terminaison line charecter ( CR CR/LF) from 'a'

  aa bb CCAATT
            return the concatenation 'a' and 'b'

  aa bb ...... nn  xx CCAATTNN
            return the concatenation of the 'x' element from the stack

  aa bb CCAATTAALLLL
            return the concatenation all element on the stack

  aa bb xx JJOOIINN
            return the concatenation 'a', 'x' and 'b'

  aa bb ...... nn  xx yy JJOOIINNNN
            return the concatenation of the 'y' element from the stack with 'x' as separator

  aa bb xx JJOOIINNAALLLL
            return the concatenation all element on the stack with 'x' as separator

  aa bb RREEPP
            return the result of 'a' x 'b'  duplicate 'a' by the number of 'x'

  aa RREEVV
            return the reverse of 'a'

  aa bb cc SSUUBBSSTTRR
            return the substring of 'c' starting at 'b' with the length of 'a'

  aa UUCC
            return 'a' in uppercase

  aa LLCC
            return 'a' in lowercase

  aa UUCCFFIIRRSSTT
            return 'a' with the first letter in uppercase

  aa LLCCFFIIRRSSTT
            return 'a' with the first letter in lowercase

  aa RR11 RR22 KK VV SSPPLLIITT22
            split a with the REGEX R1
            each result are splitted with the REGEX R2
            the result are stored in the variable k and v

            # .1.3.6.1.2.1.25.3.3.1.2.768 | 48 # .1.3.6.1.2.1.25.3.3.1.2.769 | 38 # .1.3.6.1.2.1.25.3.3.1.2.771 | 42 # .1.3.6.1.2.1.25.3.3.1.2.770 | 58 #,\s?#\s?,\s\|\s,a,b,SPLIT2
            return a with .1.3.6.1.2.1.25.3.3.1.2.768,.1.3.6.1.2.1.25.3.3.1.2.769,.1.3.6.1.2.1.25.3.3.1.2.771,.1.3.6.1.2.1.25.3.3.1.2.770
            and b with 48,38,42,58

            !!! becare, if you need to use : as a regex, you need to backslash to prevent overlap with new dictionary entry
            SPLIT return the matched value WITHOUT the empty string of the beginning

  aa bb SSPPLLIITT
            return all splitted item of 'a' by the separator 'b'
            'b' is a REGEX
            !!! becare, if you need to use : as a regex, you need to backslash to prevent overlap with new dictionary entry
            !!! if the split match on the beginning of string,
            SPLIT return the matched value WITHOUT the empty string of the beginning

  aa bb SSPPLLIITTII
            return all splitted item of 'a' by the separator 'b'
            'b' is a REGEX case insensitive
            !!! becare, if you need to use : as a regex, you need to backslash to prevent overlap with new dictionary entry
            !!! if the split match on the beginning of string,
            SPLIT return the matched value WITHOUT the empty string of the beginning

  aa bb PPAATT
            return one or more occurance of 'b' in 'a'
            'b' is a REGEX
            !!! becare, if you need to use : as a regex, you need to backslash to prevent overlap with new dictionary entry

  aa bb PPAATTII
            return one or more occurance of 'b' in 'a'
            'b' is a REGEX case insensitive
            !!! becare, if you need to use : as a regex, you need to backslash to prevent overlap with new dictionary entry

  aa bb TTPPAATT
            test if the pattern 'b' is in 'a'
            'b' is a REGEX
            !!! becare, if you need to use : as a regex, you need to backslash to prevent overlap with new dictionary entry

  aa bb TTPPAATTII
            test if the pattern 'b' is in 'a'
            'b' is a REGEX
            !!! becare, if you need to use : as a regex, you need to backslash to prevent overlap with new dictionary entry

  aa bb cc SSPPAATT
            substitute the pattern 'b' by the pattern 'a'  in 'c'
            'b' and 'c' are a REGEX
            !!! becare, if you need to use : as a regex, you need to backslash to prevent overlap with new dictionary entry

  aa bb cc SSPPAATTGG
            substitute the pattern 'b' by the pattern 'a'  in 'c' as many time as possible (g flag in REGEX)
            'b' and 'c' are a REGEX
            !!! becare, if you need to use : as a regex, you need to backslash to prevent overlap with new dictionary entry

  aa bb cc SSPPAATTII
            substitute the pattern 'b' by the pattern 'a'  in 'c'case insensitive (i flag in REGEX)
            'b' and 'c' are a REGEX
            !!! becare, if you need to use : as a regex, you need to backslash to prevent overlap with new dictionary entry

  aa bb cc SSPPAATTGGII
            substitute the pattern 'b' by the pattern 'a'  in 'c' as many time as possible (g flag in REGEX)
            and case insensitive (1 flag in REGEX)
            'b' and 'c' are a REGEX
            !!! becare, if you need to use : as a regex, you need to backslash to prevent overlap with new dictionary entry

  aa ...... zz PPRRIINNTTFF
           use the format 'z' to print the value(s) on the stack
           7,3,/,10,3,/,%d %f,PRINTF -> 2 3.333333
           see printf in perl

  aa bb PPAACCKK
            pack the value 'a' with the format 'b'

            2004,06,08,a4 a2 a2,PACK
            result: 20040608

            see pack in perl

  aa bb UUNNPPAACCKK
            unpack the value 'a' with the format 'b'

            20040608,a4 a2 a2,UNPACK
            result: 2004,06,08

            see unpack in perl

  aa bb IISSNNUUMM
            test if top of the stack is a number
            return 1 if if it is a NUMBER otherwise return 0

  aa bb IISSNNUUMMDD
            test if top of the stack is a number
            delete the top element on the statck and return 1 if it is a NUMBER otherwise return 0

  aa bb IISSIINNTT
            test if top of the stack is a integer (natural number)
            return 1 if if it is a INTEGER otherwise return 0

  aa bb IISSIINNTTDD
            test if top of the stack is a integer (natural number)
            delete the top element on the statck and return 1 if it is a INTEGER otherwise return 0

  aa bb IISSHHEEXX
            test if top of the stack is a hexadecimal value (starting with 0x or 0X or # )
            return 1 if if it is a HEXADECIMAL otherwise return 0

  aa bb IISSHHEEXXDD
            test if top of the stack is a hexadecimal value (starting with 0x or 0X or # )
            delete the top element on the statck and return 1 if it is a HEXADECIMAL otherwise return 0

SSTTAACCKK ooppeerraattoorrss
  aa bb SSWWAAPP
              return 'b' 'a'

  aa bb OOVVEERR
              return 'a' 'b' 'a'

  aa DDUUPP
              return 'a' 'a'

  aa bb DDDDUUPP
              return 'a' 'b' 'a' 'b'

  aa bb cc RROOTT
              return 'b' 'c' 'a'

  aa bb cc RRRROOTT
              return 'c' 'a' 'b'

  DDEEPPTTHH
              return the number of elements on the stack

  aa bb PPOOPP
              remove the last element on the stack

  aa ...... zz PPOOPPNN
              remove the 'z' last element(s) from the stack

  aa bb cc dd ee nn RROOLLLL
              rotate the stack on 'n' element
              a,b,c,d,e,f,4,ROLL -> a b d e f c
              if n = 3 <=> ROT
              if  -2 < n < 2 nothing is done
              if n < -1 ROLL in reverse order
              a,b,c,d,e,f,-4,ROLL -> a b f e d c
              To reveerse a stack content use this:
              a,b,c,d,e,f,DEPTH,+-,ROLL => f e d c b a

  aa PPIICCKK
              copy element from depth 'a' to the stack

  aa GGEETT
              get (remove) element from depth 'a'
              and put on top of stack

  aa bb PPUUTT
              put element 'a' at the level 'b' of the stack
              if 'b' greater than the stack put at first place
              if 'b' < 0 start to the reverse order of the stack

  aa bb DDEELL
              delete 'b' element on the stack from level 'a'
              'a' and 'b' is get in absolute value

  aa FFIINNDD
              get the level of stack containing the exact value 'a'
              if no match, return 0

  aa FFIINNDDKK
              keep the level of stack containing the exact value 'a'
              f no match, return an empty stack
              ( shortcut for a,FIND,KEEP )

  aa SSEEAARRCCHH
              get the first level of stack containing the REGEX 'a'

  aa SSEEAARRCCHHII
              get the first level of stack containing the REGEX 'a' (cas insensitive)

  aa SSEEAARRCCHHIIAA
              get all level of stack containing the REGEX 'a' (cas insensitive)
              empty the stack and return all the index of item matching

  aa SSEEAARRCCHHAA
              get all level of stack containing the REGEX 'a' (cas sensitive)
              empty the stack and return all the index of item matching

              toto,toti,titi,tata,tota,tito,tutot,truc,tot,SEARCHA
              result: 8 7 4 2

  aa SSEEAARRCCHHKK
              keep all level of stack containing the REGEX 'a' (cas sensitive)

              toto,toti,titi,tata,tota,tito,tutot,truc,tot,SEARCHK
              result: toto toti tota tutot

  aa SSEEAARRCCHHIIKK
              keep all level of stack containing the REGEX 'a' (cas insensitive)

  aa KKEEEEPP
              delete all element on the stack except the level 'a'
              if 'a' is deeper then stack, keep the stack untouched

  aa KKEEEEPPVV
              delete all element on the stack except the levels with indice in the var A

              1,5,2,3,A,!!,a,b,c,d,e,f,g,i,A,KEEPV
              result: i d g

  aa KKEEEEPPVVVV
              keep element from array B with indice from ARRAY A

              1,5,2,3,A,!!,a,b,c,d,e,f,g,i,8,B,!!,B,A,KEEPVV
              result: i d g

  bb aa KKEEEEPPNN
              keep 'b' element on the stack from level 'a'
              and delete all other element
              'a' and 'b' is get in absolute value

              a,b,c,d,e,f,g,h,4,3,KEEPN
              result: c d e f

  bb aa KKEEEEPPRR
              delete all elements on the stack except the level 'a' and keep all element deeper than 'b'
              if 'a' is deeper then stack, keep the stack untouched

              a,b,c,d,e,f,g,h,6,3,KEEPR
              result: a b f

  cc bb aa KKEEEEPPRRNN
              keep 'b' element on the stack from level 'a' and keep all element deeper than 'c'
              if 'a' is deeper then stack, keep the stack untouched

              a,b,c,d,e,f,g,h,i,j,7,3,2,KEEPRN
              result: a b c g h i

  aa bb PPRREESSEERRVVEE
              keep  element on the stack from level 'a'
              to level 'b'
              and delete all other element
              'a' and 'b' is get in absolute value
              if 'a' > 'b'  keep the reverse of selection (boustrophedon)

  aa bb CCOOPPYY
              copy  element on the stack from level 'a'
              to level 'b'
              'a' and 'b' is get in absolute value
              if 'a' > 'b'  keep the reverse of selection (boustrophedon)

DDIICCTTIIOONNAARRYY aanndd VVAARRSS ooppeerraattoorrss
  WWOORRDDSS
              return as one stack element the list of WORD in DICT separated by a |

  VVAARRSS
              return as one stack element the list of VARS  separated by a |

  vv SSIIZZEE
              return the size of the variable on the stack

  vv PPOOPPVV
              remove return the first item of the variable on the stack

  vv SSHHIIFFTTVV
              remove return the latest item of the variable on the stack

  vv aa IINNDD
             return the element of the variable at the indice a  ( ARRAY emulation )

  vv IINNCC
              incremente (+ 1) the value of the variable on the statck

  vv DDEECC
              decremente (- 1) the value of the variable on the statck

  VVAARRIIAABBLLEE xxxxxx
             declare the variable 'xxx' (reserve memory)

  vv UUNNSSEETT
             delete the variable v

  xxxx vvaarr !!
              set and delete from the stack the value xx to the variable 'var'

  xxxx vvaarr !!AA
              append to the variable and delete from the stack the value xx to the variable 'var'

  xx11 xx22 xx33 ...... nn vvaarr !!!!
              put and delete from the stack 'n' element(s) from the stack in the variable 'var'
              'n' is in absolute value

  xx11 xx22 xx33 ...... nn vvaarr !!!!AA
              append and delete 'n' element(s) from the stack in the variable 'var'
              'n' is in absolute value

  xx11 xx22 xx33 ...... nn vvaarr !!!!CC
              copy 'n' element(s) from the stack in the variable 'var'
              'n' is in absolute value

  xx11 xx22 xx33 ...... nn vvaarr !!!!CCAA
              append  'n' element(s) from the stack in the variable 'var'
              'n' is in absolute value

  xx11 xx22 xx33 ...... bb aa vvaarr !!!!!!
              put and delete ' element(s) from the stack in the variable 'var'
              starting at element  'a' to element 'b'
              'a' and 'b' in absolute value
              if 'a' > 'b'  keep the reverse of selection (boustrophedon)

  xx11 xx22 xx33 ...... bb aa vvaarr !!!!!!AA
              append and delete ' element(s) from the stack in the variable 'var'
              starting at element  'a' to element 'b'
              'a' and 'b' in absolute value
              if 'a' > 'b'  keep the reverse of selection (boustrophedon)

  xx11 xx22 xx33 ...... bb aa vvaarr !!!!!!CC
              copy element(s) on the stack in the variable 'var'
              starting at element  'a' to element 'b'
              'a' and 'b' in absolute value
              if 'a' > 'b'  keep the reverse of selection (boustrophedon)

  xx11 xx22 xx33 ...... bb aa vvaarr !!!!!!CCAA
              append element(s) on the stack in the variable 'var'
              starting at element  'a' to element 'b'
              'a' and 'b' in absolute value
              if 'a' > 'b'  keep the reverse of selection (boustrophedon)

  vvaarr @@
              return the value of the variable 'var'

  :: xxxxxx  nnaammee11 ;;
              create a new entry in the dictionary whith name name1 and store the progam xxx

  nnaammee11 FFOORRGGOOTT
              delete/erase a create word (name1 )

  :: xxxxxx yyyyyy nnaammee11 PPEERRLL
              execute the PERL code
              with parameter(s) xxx yyy
              !!! be care if the perl code need to use a coma (,)
              you need to enclose the line inside double quote
              if you need double quote in code use qq{ ... }

  :: xxxxxx nnaammee11 PPEERRLLFFUUNNCC
              execute the PERL function name1 with the parameter xxx
              the default name space is "main::"
              It is possible tu use a specific name space
              the parameter are "stringified"
              e.g. ':,5,filename,save,PERLFUNC'
              call the function save("filename", 5);

  nnaammee11 PPEERRLLFFUUNNCC00
              execute the PERL function name1 with no parameters
              the default name space is "main::"
              It is possible tu use a specific name space
              the parameter are "stringified"
              !!! because this function don't know the namescape of the caller
              !!! the parameter for the function must be scalar
              !!! and not a perl variable or a ref to a perl compenent
              !!! see PERLVAR
              e.g. 'Test2,PERLFUNC0'
              call the function Test2();

  xxxxxx nnbbrr nnaammee11 PPEERRLLFFUUNNCCXX
              execute the PERL function name1 with nbr parameters from the stack xxx
              the default name space is "main::"
              It is possible tu use a specific name space
              the parameter are "stringified"
              !!! because this function don't know the namescape of the caller
              !!! the parameter for the function must be scalar
              !!! and not a perl variable or a ref to a perl compenent
              !!! see PERLVAR
              e.g. 'file,name,2,substit,PERLFUNCX'
              call the function substit("name", "file");

  xxxxxx nnaammee11 PPEERRLLFFUUNNCC11
              execute the PERL function name1 with the only one parameter xxx
              the default name space is "main::"
              It is possible tu use a specific name space
              the parameter are "stringified"
              e.g. 'file,name,CAT,substit,PERLFUNC1'
              call the function substit("filename");

  xxxxxx nnbbrr nnaammee11 PPEERRLLVVAARR
              Return the perl variable.
              If the var returned is an array, return each element of the array on the stack
              If the var returned is a hash , return a STRUCTURATED LIST
              the default name space is "main::"
              It is possible tu use a specific name space
              the parameter are "stringified"
              e.g.1 '{$data},PERLVAR'
              call the value of $data;
              e.g.2 '{%S}->{extra},PERLVAR'
              call the value of $S->{extra};

  aa >>RR
              put 'a' on the return stack

  RR>>
             remove first element from the return stack and copy on the normal stack

  RRLL
             return the depth of the return stack

  RR@@
             copy return stack on normal stack

FFIILLEE ooppeerraattoorrss (( bbaassiicc IIOO ))
  ffiillee,, mmooddee ,, FFHH,, OOPPEENN
             OPEN a file and keep the filehandle in the variable X
             mode could be all combination of :
             'r' ( read  ),
             'w' ( write ),
             'c' ( create ),
             't' ( truncate ),
             'a'( append = seek to end )

  ffiillee,, UUNNLLIINNKK
             UNLINK ( delete ) a file

  FFHH,, SSTTAATT
             STAT the file using the handle stored in the var FH ( FH could also be a file path )
             return the same content as perl stat. Keep in mind that the indice 0 from the perl array is the 1 fisrt stack level.
             To get the size of a file:
             /tmp/rpn,STAT,13,8,KEEPR

  OOFFFFSSEETT,, WWHHEENNCCEE,, FFHH,, SSEEEEKK
             SEEK of OFFSET in the file using the handle stored in the var FH
             if WHENCE = 0 seek from the beginning of the file
             if WHENCE = 1 seek from the current position
             if WHENCE = 2 seek from the end of the file ( offset must be < 0 )
             ( see perldoc -f seek )

  FFHH,, TTEELLLL
             TELL return the position in the file using the handle stored in the var FH

  FFHH,, CCLLOOSSEE
             CLOSE the file handle stored in the var FH

  NN,, FFHH,, GGEETTCC
             read and put on top of the stack N character from the filedscriptor stored in the variable FH
             to do a file slurp:
             /tmp/rpn,r,fh,OPEN,sh,STAT,13,6,KEEPR,fh,GETC,fh,CLOSE

  NN,, FFHH,, GGEETTCCSS
             read and put on the stack N character from the filedscriptor stored in the variable FH
             each character is pushed on the stack ( and then the stack is evalueted )

  NN,, FFHH,, WWRRIITTEE
              put and delete N element from the stack to the filedscriptor stored in the variable FH

  NN,, FFHH,, WWRRIITTEELLIINNEE
              put and delete N element from the stack as a new line for each element to the filedscriptor stored in the variable FH
              to flush buffer, use 0,0,FH,SEEK

  FFHH,, RREEAADDLLIINNEE
             read and put on the stack a line from the filedscriptor stored in the variable FH

LLOOOOPP aanndd DDEECCIISSIIOONN ooppeerraattoorrss
  aa IIFF xxxxxx TTHHEENN
              test the element on top of stack
                      if == 1 execute 'xxx' block

              The loop is executed always one time

  aa IIFF zzzzzz EELLSSEE xxxxxx TTHHEENN
              test the element on top of stack
                      if == 1 execute 'xxx' block
                      if != 1 execute 'zzz' block

              The loop is executed always one time

  BBEEGGIINN xxxxxx WWHHIILLEE zzzzzz RREEPPEEAATT
              execute 'xxx' block
              test the element on top of stack
                      if == 0 execute 'zzz' block and branch again at 'BEGIN'
                      if != 0 end the loop

              The loop is executed always one time

  eenndd ssttaarrtt DDOO,,bblloocckk,,LLOOOOPP
              process 'block' with iterator from value 'start' until 'end' value,with increment of 1;
              The iterator variable is the second value on the stack (start argument)

  eenndd ssttaarrtt iinnccrreemmeenntt DDOO,,bblloocckk,,++LLOOOOPP
              process 'block' with iterator from value 'start' untill 'end' value,with increment of 'increment'
              This allow rational or negative value
              The iterator variable is the second value on the stack (start argument)

UUsseeffuull ffuunnccttiioonnss ffoorr tthhee mmoodduullee ((nnoott rreellaatteedd ttoo tthhee RRPPNN llaanngguuaaggee))
  _r_p_n___e_r_r_o_r_(_)
              function which return the debug info from the calculation (like a division by 0)

  rrppnn__sseeppaarraattoorr__oouutt(( ''sseepp'' ))
              function to set a specific separator for the returned stack (default = space)
              This is useful when the result of rpn() is use inside another rpn() call

  rrppnn__sseeppaarraattoorr__iinn(( ''sseepp'' ))
              function to set a specific separator for the input data (default = ')

OOPPEERRAATTOORRSS
           The operators get value from the stack and push the result on top
           In the following explanation, the stack is represented as a pair of brackets ()
           and each elements by a pair of square barcket []
           The left part is the state before evalutation
           and the right part is the state of the stack after evaluation

              Arithmetic operators
              ---------------------
                  +                   ([a][b])                ([a+b])
                  -                   ([a][b])                ([a-b])
                  *                   ([a][b])                ([a*b])
                  /                   ([a][b])                ([a/b])         Becare if division by null return a blank value
                  **                  ([a][b])                ([a**b])
                  1+                  ([a])                   ([a+1])
                  1-                  ([a])                   ([a-1])
                  2+                  ([a])                   ([a+2])
                  2-                  ([a])                   ([a-2])
                  MOD                 ([a][b])                ([a%b])
                  ABS                 ([a])                   ([ABS a])
                  INT                 ([a])                   ([INT a])
                  +-                  ([a])                   ([-a])
                  REMAIN              ([a])                   ([a- INT a])

              Rationnal operators
              -------------------
                  SIN                 ([a])                   ([SIN a])       Unit in radian
                  COS                 ([a])                   ([COS a])       Unit in radian
                  TAN                 ([a])                   ([TAN a])       Unit in radian
                  CTAN                ([a])                   ([CTAN a])      Unit in radian
                  LN                  ([a])                   ([LOG a])
                  EXP                 ([a])                   ([EXP a])
                  PI                                          ([3.14159265358979])

              Relational operator
              ----------------
                  <                   ([a][b])                ([1]) if [a]<[b] else ([0])
                  <=                  ([a][b])                ([1]) if [a]<=[b] else ([0])
                  >                   ([a][b])                ([1]) if [a]>[b] else ([0])
                  >=                  ([a][b])                ([1]) if [a]>=[b] else ([0])
                  ==                  ([a][b])                ([1]) if [a]==[b] else ([0])
                  <=>                 ([a][b])                ([-1]) if [a]>[b],([1]) if [a]<[b], ([0])if [a]==[b]
                  !=                  ([a][b])                ([0]) if [a]==[b] else ([1])
                  TRUE                ([a])                   Return 1 if [a]>0 and exist
                  FALSE               ([a])                   Return 0 if [a]>0

              Logical operator
              ----------------

                  OR                  ([a][b])                ([1]) if [a] or [b] >0
                  AND                 ([a][b])                ([1]) if [a] and [b] >0
                  XOR                 ([a][b])                ([1]) if [a] and [b] are >0 or ==0
                  NOT                 ([a])                   Return 0 if [a]>0, Return 1 if[a]==0,

              Other operator
              ----------------

                  >>                  ([a][b])                shift to the right the bits from [a] of [b] rank
                  <<                  ([a][b])                shift to the left the bits from [a] of [b] rank
                  MIN                 ([a][b])                ([a]) if  [a]<[b] else ([b])
                  MAX                 ([a][b])                ([a]) if  [a]>[b] else ([b])
                  LOOKUP              ([a] V R [ope] )        test [ a ] on all value of array V with the operator [ope]
                                                              if succeed, return the value from array R at the succesfull indice
                  LOOKUPP             ([a] V R [ope] )        test [ a ] on all value of array V with the perl operator [ope]
                                                              if succeed, return the value from array R at the succesfull indice
                  LOOKUPOP            ([a] V R O] )           test [ a ] on all value of array V with the operator from the array OPE with the same indice
                  LOOKUPOPP           ([a] V R O] )           test [ a ] on all value of array V with the perl operator from the array OPE with the same indice
                                                              if succeed, return the value from array R at the succesfull indice
                  TICK                ()                      ([time]) time in ticks
                  LTIME               ([a])                   ([min][hour][day_in_the_month][month][year][day_in_week][day_year][daylight_saving]
                                                              localtime of [a] like PERL
                  GTIME               ([a])                   ([min][hour][day_in_the_month][month][year][day_in_week][day_year][daylight_saving]
                                                              ([a]) gmtime of [a] like PERL
                  HLTIME              ([a])                   ([a]) localtime human readeable
                  HGTIME              ([a])                   gmtime human readeable
                  RAND                ()                      ([rand]) a random numder between 0 and 1
                  LRAND               ([a])                   ([rand]) a random numder between 0 and [a]
                  SPACE               ([a])                   Return [a] with space between each 3 digits
                  DOT                 ([a])                   Return [a] with dot (.) between each 3 digits
                  NORM                ([a])                   Return [a] normalized by 1000 (K,M,G = 1000 * unit)
                  NORM2               ([a])                   Return [a] normalized by 1000 (K,M,G = 1024 * unit)
                  OCT                 (|a|)                   Return the DECIMAL value from HEX,OCTAL or BINARY value |a| (see oct from perl)
                  OCTSTR2HEX          (|a|)                   Return a HEX string from a OCTETSTRING
                  HEX2OCTSTR          (|a|)                   Return a OCTETSTRING string from a HEX
                  DDEC2STR            (|a|)                   Return a string from a dotted DEC string
                  STR2DDEC            (|a|)                   Return a dotted DEC string to a string

              String operators
              ----------------
                  EQ                  ([a][b])                ([1]) if [a] eq [b] else ([0])
                  NE                  ([a][b])                ([1]) if [a] ne [b] else ([0])
                  LT                  ([a][b])                ([1]) if [a] lt [b] else ([0])
                  GT                  ([a][b])                ([1]) if [a] gt [b] else ([0])
                  LE                  ([a][b])                ([1]) if [a] le [b] else ([0])
                  GE                  ([a][b])                ([1]) if [a] ge [b] else ([0])
                  CMP                 ([a][b])                ([-1]) if [a] gt [b],([1]) if [a] lt [b], ([0])if [a] eq [b]
                  LEN                 ([a])                   ([LENGTH a])
                  CAT                 ([a][b])                ([ab])  String concatenation
                  CATALL              ([a][b]...[z])          ([ab...z]) String concatenation of all elements on the stack
                  REP                 ([a][b])                ([a x b]) repeat [b] time the motif [a]
                  REV                 ([a])                   ([REVERSE a])
                  SUBSTR              ([a][b][c])             ([SUBSTR [a], [b], [c]) get substring of [a] starting from [b] untill [c]
                  UC                  ([a])                   ([UC a])
                  LC                  ([a])                   ([LC a])
                  UCFIRST             ([a])                   ([UCFIRST a])
                  LCFIRST             ([a])                   ([LCFIRST a])
                  PAT                 ([a][b])                ([r1]...) use the pattern [b] on the string [a] and return result
                                                              if more then one result like $1, $2 ... return all the results
                  PATI                ([a][b])                ([r1]...) use the pattern CASE INSENSITIVE [b] on the string [a] and return result
                                                              if more then one result like $1, $2 ... return all the results
                  TPAT                ([a][b])                ([r]) use the pattern [b] on the string [a] and return 1 if pattern macth
                                                              otherwise return 0
                  TPATI               ([a][b])                ([r]) use the pattern CASE INSENSITIVE [b] on the string [a] and return 1 if pattern macth
                                                              otherwise return 0
                  SPLIT               ([a][b])                split ([a]) using the pattern ([b]) and return all elements on stack
                  SPLITI                                      split ([a]) using the pattern CASE INSENSITIVE  ([b])) and return all elements on stack
                  SPLIT2              ([a][R1][R2][K][V])     split ([a]) using the pattern ([R1]), each result are splitted using the pattern ([R2])
                                                              the result are stored in the variables [K] and [V]
                  SPAT                ([a][b][c])             Do a pattern subsititution following this rule I<[c] =~s/[a]/[b]/>
                  SPATG               ([a][b][c])             Do a pattern subsititution following this rule I<[c] =~s/[a]/[b]/g>
                  SPATI               ([a][b][c])             Do a pattern subsititution following this rule I<[c] =~s/[a]/[b]/i>
                                                              (case insensitive)
                  SPATGI              ([a][b][c])             Do a pattern subsititution following this rule I<[c] =~s/[a]/[b]/gi>
                                                              (case insensitive)
                  PRINTF              ([a][b]...[x])          use the format present in [a] to print the value [b] to [x]
                                                              the format is the same as (s)printf
                  PACK                ([a][b]...[x])          Do an unpack on variable [b] to [x] using format [b]
                  UNPACK              ([a][b])                Do an unpack on variable [b] using format [a]

                  ISNUM               ([a])                   Test if a is a NUMBER return 1 if success ( [a] [1|0] )
                                                              Keep the value on the stack
                  ISNUMD              ([a])                   Test if a is a NUMBER return 1 if success ( [1|0] )
                                                              Remove the value from the stack
                  ISINT               ([a])                   Test if a is a INTEGER (natural number )
                                                              Return 1 if success ( [a] [1|0] )
                                                              Keep the value on the stack
                  ISINTD              ([a])                   Test if a is a INTEGER (natural number )
                                                              Return 1 if success ( [1|0] )
                                                              Remove the value from the stack
                  ISHEX               ([a])                   Test if a is a HEXADECIMAL (hex starting with 0x or 0X or # )
                                                              Return 1 if success ( [a] [1|0] )
                                                              Keep the value on the stack
                  ISHEXD              ([a])                   Test if a is a HEXADECIMAL (hex starting with 0x or 0X or # )
                                                              Return 1 if success ( [1|0] )
                                                              Remove the value from the stack


               Stack operators
               ---------------

                  SWAP                ([a][b])                ([b][a])
                  OVER                ([a][b])                ([a][b][a])
                  DUP                 ([a])                   ([a][a])
                  DDUP                ([a][b])                ([a][b][a][b])
                  ROT                 ([a][b][c])             ([b][c][a])
                  RROT                ([a][b][c])             ([c][a][b])
                  DEPTH               ([r1]...)               ([re1]...[nbr]) Return the number of elements in the statck
                  POP                 ([a][b])                ([a])
                  POPN                ([a][b][c]...[x])       ([l]...[x]) remove [b] element from the stack (starting at [c])
                  SWAP2               ([a][b][c])             ([a][c][b])
                  ROLL                ([a][b][c][d][e][n])    ([a][c][d][e][b]) rotate the [n] element of the stack (here [n]=4)
                                                              if  [n] =3 it is equivalent to ROT
                  PICK                ([a][b][c][d][e][n])    ([a][b][c][d][e][b]) copy element from depth [n] on top
                  GET                 ([a][b][c][d][e][n])    ([a][b][c][d][e][b]) get element from depth [n] and put on top
                  PUT                 ([a][b][c][d][v][n])    ([a][v][b][c][d]) put element [v] at level [n] (here [n]=3)
                  DEL                 ([a][b])                delete [b] element on the stack from level [a]
                                                              [a] and [b] is get in absolute value
                  KEEPN               ([a][b])                keep [b] element(s) on the stack from level [a]
                                                              (and delete all other elements)
                                                              [a] and [b] is get in absolute value
                  KEEPR
                  KEEPRN
                  PRESERVE            ([a][b])                keep element(s) on the stack from level [a] to level [b]
                                                              (and delete all other elements)
                                                              [a] and [b] is get in absolute value
                  COPY                ([a][b])                copy element(s) on the stack from level [a] to level [b]
                                                              [a] and [b] is get in absolute value
                  FIND                ([a])                   get the level of stack containing [a]
                  SEARCH              ([a])                   get the level of stack containing the REGEX [a]
                  SEARCHI             ([a])                   get the level of stack containing the REGEX [a] ( case insensitive )
                  SEARCHK             ([a])                   keep only level of stack matching the REGEX [a]
                  SEARCHIK            ([a])                   keep only level of stack matching the REGEX [a] ( case insensitive )
                  KEEP                ([a][b][c][d][e][n])    remove all elements of the stack except the element at deepth |n|

               Dictionary operators
               --------------------

                  WORDS               ()                              ([a])return as one stack element the list of WORD in DICT separated by a |
                  VARS                ()                              ([a])return as one stack element the list of VARIABLE in VAR separated by a |
                  INC                 ([a])                           () increment (+1) the value of variable [a]
                  DEC                 ([a])                           () decrement (-1) the value of variable [a]
                  VARIABLE            ([a])                           () create a entry in VAR for the variable [a]
                  !                   ([a][b])                        store the value [a] in the variable [b]
                  !A
                  !!                  ([a][b][c]...[n] [var])         put and delete 'n' element(s) from the stack in the variable 'var'
                                                                      'n' is in absolute value
                  !!A
                  !!C                 ([a][b][c]...[n] [var])         copy 'n' element(s) from the stack in the variable 'var'
                                                                      'n' is in absolute value
                  !!CA
                  !!!                 ([a][b][c]...[n1] [n2] [var])   put and delete element(s) from the stack in the variable 'var'
                                                                      starting at element  'a' to element 'b'
                                                                      'a' and 'b' in absolute value
                                                                      if 'a' > 'b'  keep the reverse of selection (boustrophedon)
                  !!!A
                  !!!C                        ([a][b][c]...[n] [var]) copy 'element(s) from the stack in the variable 'var'
                                                                      starting at element  'a' to element 'b'
                                                                      'a' and 'b' in absolute value
                                                                      if 'a' > 'b'  keep the reverse of selection (boustrophedon)
                  !!!CA
                  @                   ([a])                           ([a]) return the value of the variable [a]
                  : xxx yyy ;                                         create a new word (sub) into the dictionary with the xxx "code" and name yyy
                  : xxx yyy PERLFUNC                                  execute the PERL function yyy with parameter(s) yyy
                                                                      the default name space is "main::"
                                                                      It is possible tu use a specific name space
                  : xxx yyy PERL                                      execute the PERL code xxx ; yyy

               File oprator
               -------------

                 OPEN
                 STAT
                 SEEK
                 TELL
                 CLOSE
                 GETC
                 GETCS
                 READLINE
                 WRITE
                 WRITELINE

               Return Stack operators
               ----------------------

                 >R                   ([a])                   put ^a$ on the return stack
                 R>                   ()                      remove first element from the return stack and copy on the normal
                 RL                   ()                      return the depth of the return stack
                 R@                   ()                      copy return stack ion normal stack

              LOOP and DECISION operators
              ---------------------------

               [a] IF [..xxx] THEN                            Test the element on top of stack
                                                                if ==0, execute 'xxx' block
                                                              The loop is executed always one time

               [a] IF [...zzz...] ELSE [..xxx...] THEN        Test the element on top of stack
                                                                if ==0, execute 'xxx' block
                                                                if != 0 execute 'zzz' block
                                                              The loop is executed always one time

               BEGIN xxx WHILE zzz REPEAT                     Execute 'xxx' block
                                                              Test the element on top of stack
                                                                if ==0 execute 'zzz' block and branch again to BEGIN
                                                                if != 0 end the loop
                                                              The loop is executed always one time

              [a] [b] DO [...xxx...] LOOP     ([a][b])        process block [...xxx...] with iterator from value [b] untill [a] value,
                                                              with increment of 1;
                                                              The iterator variable is '_I_' (read only and scoop only the DO ... LOOP block)

              [a] [b] DO [...xxx...] [c] +LOOP        ([a][b])        process block [...xxx...] with iterator from value [b] untill [a] value,
                                                              with increment of [c];
                                                              The iterator variable is '_I_' (read only and scoop only the DO ... LOOP block)

EEXXAAMMPPLLEESS
              use Parse::RPN;

              $test ="3,5,+";
              $ret = rpn($test);  # $ret = 8

              $test = "Hello World,len,3,+";
              $ret = rpn($test);  # $ret = 14

              $test = "'Hello,World',len,3,+";
              $ret = rpn($test);  # $ret = 14

              $test = "'Hello,World,len,3,+";
              ---------^-----------^-
              $ret = rpn($test);  # $ret = 8 with a warning because the stack is not empty ([Hello] [8])
                                  # be care to close your quoted string

              $test = "'Hello world','or',PAT,'or',EQ,IF,'string contain or',ELSE,'No or in string',THEN"
              $ret = rpn($test);  # $ret = "Contain a coma"

              $test = "'Hello world','or',TPAT,IF,'string contain or',ELSE,'No or in string',THEN";
              $ret = rpn($test);  # $ret = "string contain or"


              $test = "3,10,/,5,+,82,*,%b,PRINTF";
              $ret = rpn($test);  # $ret = "110110010"

              $test = "3,10,/,5,+,82,*,%016b,PRINTF";
              $ret = rpn($test);  # $ret = "0000000110110010"

              $test = "55,N,pack,B32,unpack,^0+(?=\d), ,spat,'+',ds";
              $ret = rpn($test);  # $ret = 110111

              $test = "7,3,/,10,3,/,%d %f,PRINTF";
              @ret = rpn($test); # @ret = 2 3.333333

              $test = "VARIABLE,a,0,a,!,##,b,BEGIN,bbbb,a,INC,a,@,4,>,WHILE,####,a,@,****,REPEAT";
              @ret =rpn($test); # @ret = ## b bbbb #### 1 **** bbbb #### 2 **** bbbb #### 3 **** bbbb
              or
              $test = "0,a,!,##,b,BEGIN,bbbb,a,INC,a,@,4,>,WHILE,####,a,@,****,REPEAT"; # the VARIABLE declaration is optionel
              @ret =rpn($test); # @ret = ## b bbbb #### 1 **** bbbb #### 2 **** bbbb #### 3 **** bbbb #### 4 **** bbbb

              $test = "VARIABLE,a,0,a,!,z,0,5,-1,DO,a,INC,6,1,2,DO,A,_I_,+LOOP,#,+LOOP,##,a,@";
              @ret =rpn($test); # @ret = z A 3 A 5 A 7 # A 3 A 5 A 7 # A 3 A 5 A 7 # A 3 A 5 A 7 # A 3 A 5 A 7 # A 3 A 5 A 7 # ## 6

              $test = 'a,b,c,d,e,f,g,h,i,5,2,V1,!!!,uuu,V1,SIZE'
              $ret  =rpn($test); # $ret = a b c d i uuu 4

              $test = "1,2,3,4,5,6,7,8,9,3,KEEP";
              $ret =rpn($test); # $ret = 7

              $test = "1,2,3,4,5,6,7,8,9,30,KEEP";
              $ret =rpn($test); # $ret = 1,2,3,4,5,6,7,8,9

              $test = "h,g,f,e,d,c,b,a,4,3,DEL";
              $ret =rpn($test); # $ret = h,c,b,a

              $test = 'test for a split,\s,SPLIT,DEPTH';
              $ret =rpn($test); # $ret = test,for,a,split,4

              $test = '# .1.3.6.1.2.1.25.3.3.1.2.768 | 48 # .1.3.6.1.2.1.25.3.3.1.2.769 | 38 # .1.3.6.1.2.1.25.3.3.1.2.771 | 42 # .1.3.6.1.2.1.25.3.3.1.2.770 | 58 #,\s?#\s?,\s\|\s,a,b,SPLIT2
              $ret = rpn($test)
              $ret = rpn(a,@); # $ret = .1.3.6.1.2.1.25.3.3.1.2.768,.1.3.6.1.2.1.25.3.3.1.2.769,.1.3.6.1.2.1.25.3.3.1.2.771,.1.3.6.1.2.1.25.3.3.1.2.770
              $ret = rpn(b,@); # $ret = 48,38,42,58

              $test = "h,g,f,e,d,c,b,a,4,3,KEEPN"";
              ret =rpn($test); # @ret = g,f,e,d

              sub Test {
                 my $a  = shift;
                 my $b = shift;
                 my $c = $a/$b;
                 print "a=$a\tb=$b\ttotal=$c\n";
                 return $c;
              }
              $test = ":,5,6,Test,PERLFUNC";
              @ret =rpn($test); # call the function "Test" from the main package (the caller) with parameter 5,6 and return result (in @ret)

              $test = ":,05,11,01,0,0,0,Time::Local::timelocal,PERLFUNC";
              @ret =rpn($test); # @ret = 1133391600

              $test = "1,2,3,+,:, my $b=7, "open LOG , qq{ >/tmp/log }",print LOG time,PERL";
              @ret =rpn($test); # @ret = 1,5
              and the file /tmp/log contain a line with the tick time.

              $test = "11,55,*,5,2,401,+,:,my $b=,SWAP,CAT, "open LOG , qq{ >/tmp/log }",print LOG $b.qq{ \n },PERL"
              @ret =rpn($test); # @ret =1 2 3 1 (the latest 1 is the succes result return)
              and the file /tmp/log contain a line with 403 + a cariage return

              $test = 'mb,tb,gb,mb,kb,4,V,!!,12,9,6,3,4,R,!!,V,R,"TPATI",LOOKUP'
              @ret =rpn($test); # @ret = 6

              $test = '5,1,2,3,4,5,5,V,!!," "," ",ok," ",nok,5,R,!!,V,R,"<=",LOOKUPP'
              @ret =rpn($test); # @ret = nok

              $test = '3,1,2,3,4,5,5,V,!!,a,b,ok,d,nok,5,R,!!,"<","<","<","<","<",5,O,!!,V,R,O,LOOKUPOPP'
              @ret =rpn($test); # @ret = d

              $test =   1,2,3,4,2,5,2,10,7,DEPTH,1,DO,MAX,LOOP'
              @ret =rpn($test); # @ret = 10        ( = search the MAX in the stack )

              $test =     'toto,tata,tota,tato,titi,tito,toti,tot,SEARCHA,DEPTH,r,!!,res1,res2,res3,res4,res5,res6,res7,res8,r,SIZE,DUP,s,!,1,DO,r,POPV,PICK,st,!A,LOOP,DEPTH,POPN,st,@'
              @ret =rpn($test); # @ret = res2 res4 res8

              The small tool 'RPN.pl' provide an easy interface to test quickly an RPN.
              This include two test functions named 'save' and 'restore'
              Try RPN.pl to get a minimal help.
              Take a look to the minimalistic code, and put RPN.pl in your path.

              Sample of use:
              RPN.pl -r '1,2,3,:,123,100,+,7,*,test,save,PERLFUNC'
              save in file '/tmp/test' the value '1561' (whithout CR/LF) and return 1 2 3 1

AAUUTTHHOORR
              Fabrice Dulaunoy <[email protected]>
              It is a full rewrite from the version 1.xx to allow DICTIONNARY use
              and STRUCTURE control
              Thanks to the module Math::RPN from  Owen DeLong, <[email protected]>
              for the idea of using RPN in a config file

SSEEEE AALLSSOO
              Math-RPN from  Owen DeLong, <[email protected]>

TTOODDOO
              Error processing, stack underflow...

CCRREEDDIITTSS
              Thank's to Stefan Moser <[email protected]> for the idea
              to call a perl function from the rpn() and also for pin-pointing an error in stack return.

LLIICCEENNSSEE
              Under the GNU GPL2

              This program is free software; you can redistribute it and/or modify it
              under the terms of the GNU General Public
              License as published by the Free Software Foundation; either version 2
              of the License, or (at your option) any later version.

              This program is distributed in the hope that it will be useful,
              but WITHOUT ANY WARRANTY;  without even the implied warranty of
              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
              See the GNU General Public License for more details.

              You should have received a copy of the GNU General Public License
              along with this program; if not, write to the
              Free Software Foundation, Inc., 59 Temple Place,
              Suite 330, Boston, MA 02111-1307 USA

              Parse::RPN   Copyright (C) 2004 2005 2006 2007 2008 2009 2010 DULAUNOY Fabrice
              Parse::RPN comes with ABSOLUTELY NO WARRANTY;
              for details See: L<http://www.gnu.org/licenses/gpl.html>
              This is free software, and you are welcome to redistribute
              it under certain conditions;



perl v5.18.2                      2014-02-25                     Parse::RPN(3)