XService.CalcRPN 2026.4.3.1906

dotnet add package XService.CalcRPN --version 2026.4.3.1906
                    
NuGet\Install-Package XService.CalcRPN -Version 2026.4.3.1906
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="XService.CalcRPN" Version="2026.4.3.1906" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="XService.CalcRPN" Version="2026.4.3.1906" />
                    
Directory.Packages.props
<PackageReference Include="XService.CalcRPN" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add XService.CalcRPN --version 2026.4.3.1906
                    
#r "nuget: XService.CalcRPN, 2026.4.3.1906"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package XService.CalcRPN@2026.4.3.1906
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=XService.CalcRPN&version=2026.4.3.1906
                    
Install as a Cake Addin
#tool nuget:?package=XService.CalcRPN&version=2026.4.3.1906
                    
Install as a Cake Tool

Introduction

CalcRPN is a Reverse Polish Notation Calculator. The lightweight calculation & programming engine which could be easily built into any .NET application. I developed this component in 2004 and we were used it as a simple programming language for automation tasks. First version was developed on Borland Delphi 5 that is why some constructions are based on Borland concepts (such as lists).

Example of CalcRPN expression:

1 2 * 3 4 + /

Telling with a human language that sounds like this:

  • 1 and 2 - multiply
  • 3 and 4 - add
  • divide 1st result by 2nd

Or, written in a classical way that will be like this:

(1 * 2) / (3 + 4)

Also you can use varialbles. Like this:

var1 var2 * var3 var4 + /

To access variables there are appropriate delegate methods in StackCalculator class interface:

  • OnGetVariableProc OnGetVariable
  • OnSetVariableProc OnSetVariable

For example:

this.PrgEngine = new StackCalculator();
this.PrgEngine.LoggerProc += this._onLogger;
this.PrgEngine.OnGetVariable += this._onGetVariable;
this.PrgEngine.OnSetVariable += this._onSetVariable;
this.PrgEngine.OnSetReturnCode += this._onSetReturnCode;
this.PrgEngine.OnDbgPoint += this._onDbgPoint;

private void _onLogger(StackCalculator.ELogLevel ALevel, string AMsg) { ... }
private object _onGetVariable(string AVariableName) { ... }
private bool _onSetVariable(string AVariableName, object AValue) { ... }
private bool _onSetReturnCode(string AResultCode) { return true; }
private int _onDbgPoint(string AParam) { return -1; }

Note: {return code} is a special term in a host-app - just any string descrining resulting state. Usually we use return codes like: 'envNotFound', 'evtReset', 'evtSuccess' and so on. See the $event calculator command.

So, it supports:

  • mathematic operations
  • string operations
  • lists operations
  • logical operations
  • execution control ($goto, $ifyes, $ifno, ...)
  • memory registers

Syntax Elements

The free context grammar of CalcRPN expression is here:

EXPR := spaces ITEM spaces [ITEM ...] ACTION [ACTION ...] spaces ...
  ACTION := $ActionIdentifier[:counter] | + | ++ | - | -- | * | / | \ | % 
             | < | > | >= | <= | = | == | != | <> | << | >> 
             | ! | ~ | | | || | & | && | ^ | ^^
  ITEM := variable | constant
    variable := identifier
    constant := " string constant " | ( E | + | - ) number
  spaces := space | comment | label
    comment := { comment { another comment } also comment }
    label := [ identifier ]
  space := space char | tab char | CR+LF

Calculator Commands

There are about 272 calculator commands (in .NET version). In original win32 version there were 284 commands.

In expression commands recognized by '$' prefix. Ex:

"Hello, " "world" $concat

In expression above "Hello, " and "world" are string constants. And $concat is a calculator command which concatenate 2 strings.

Each of calculator command may have alias names. For example: $CountStr and $CountSubStr are 2 alias names for the same calculator command which counts number of occurencies of pattern in a string.

Also for mathematical and logical commands you can use its normal symbols as alias name. For example: you can use $mul command to multiple numbers or use "*" symbol.

Note: in case if you need to repeat a command multiple time you can specify ":{counter}". For example:

"Hello " Salutation Name ", how are you?" $concat:3

So, in this example we repeat $concat 3 times:

  • concat value of variable Name and ", how are you?" string
  • concat value of variable Salutation and result of previous concatenation
  • concat "Hello " string and result of previous concatenation

In result we got something like this:

"Hello Mr.Dmitry, how are you?"

Also it supports a kind of memory registrers where you can store values and then quickly access them without dealing with variables. For example:

"Mr." "Salutation" $cut

This will save "Mr." string in "Salutation" memory registrer and later you can access it with @Salutation. So, the @ + {nameOfRegister} is a shorthand command for

"Salutation" $paste

To work with memory registrers you can use commands: $cut, $copy, $paste. Example:

0 "I" $cut
list $count "itemsCount" $copy
"i" $paste "itemsCount" $paste >= 

Instead of "i" $paste "itemsCount" $paste you can write:

@i @itemsCount

To descrivbe all supported commands perhaps that would be easier just to simply copy-paste here constants which describing all calculator command with alias names, its groups and short help text:

// array with calculator commands(actions) definications, 
// Note: #0 is delimiter for aliase names of the same command
actions: array[TExprAction] of string = (
    // names delimited by #0              | #0#0
    ''                                     +#0#0 , // ac_Unknown   ???
    'NOP'                                  +#0#0 , // ac_NOP       nop()
    'VER'#0'VERSION'                       +#0#0 , // ac_VER       ver()
    'INFO'                                 +#0#0 , // ac_INFO      info()
    'CHECKVER'#0'CHKVER'#0'CHECKVERSION'   +#0#0 , // ac_CHECKVER  CheckVer(E)
    'EXIT'#0'QUIT'#0'ABORT'#0'STOP'        +#0#0 , // ac_EXIT      exit()
    'EVENT'                                +#0#0 , // ac_EVENT     event()
    'THROW'#0'RAISE'                       +#0#0 , // ac_THROW     throw(E)
    'DUMP'                                 +#0#0 , // ac_DUMP      dump()
    'GETPRM'#0'GETPARAM'#0'GETPARAMETER'   +#0#0 , // ac_GETPARAM  GetParam(E)
    'SETPRM'#0'SETPARAM'#0'SETPARAMETER'   +#0#0 , // ac_SETPARAM  SetParam(E, D)
    'TOLOG'                                +#0#0 , // ac_TOLOG     ToLog(E, D)
    'GETENV'#0'GETENVVAR'                  +#0#0 , // ac_GETENV    GetEnv(E)
    'SETENV'#0'SETENVVAR'                  +#0#0 , // ac_SETENV    SetEnv(E, D)
    'GETENVIRONMENT'#0'ENVIRONMENT'        +#0#0 , // ac_GETENVIRONMENT  Environment()
    'SLEEP'#0'WAIT'                        +#0#0 , // ac_SLEEP     Sleep(E)
    ''                                     +#0#0 , // ac_PUSH      push -- internal command !
    'POP'                                  +#0#0 , // ac_POP       pop
    'POPN'                                 +#0#0 , // ac_POPN      N $PopN  
    'POPALL'#0'CLEANSTACK'#0'CLEANUPSTACK' +#0#0 , // ac_POPALL    PopAll
    'DUP'                                  +#0#0 , // ac_DUP       dup
    'DUPN'                                 +#0#0 , // ac_DUPN      N $dupn
    'SWAP'#0'SWP'                          +#0#0 , // ac_SWAP      swap
    'VARTYPE'                              +#0#0 , // ac_VARTYPE   VarType(E)
    'VARTYPEMASK'#0'TYPEMASK'              +#0#0 , // ac_VARTYPEMASK  push VarTypeMask
    'VARTYPENAME'#0'TYPENAME'              +#0#0 , // ac_VARTYPENAME  VarTypeName(E)
    'CUT'                                  +#0#0 , // ac_CUT       cut(E)
    'COPY'                                 +#0#0 , // ac_COPY      copy(E)
    'PASTE'                                +#0#0 , // ac_PASTE     paste(E)
    'WINCUT'                               +#0#0 , // ac_WINCUT    WinCut(E)
    'WINCOPY'                              +#0#0 , // ac_WINCOPY   WinCopy(E)
    'WINPASTE'                             +#0#0 , // ac_WINPASTE  WinPaste(E)
    'LOADVAR'#0'GETVAR'                    +#0#0 , // ac_GETVAR    UpdateVar(E)
    'UPDATEVAR'#0'SETVAR'#0'ASSIGN'        +#0#0 , // ac_UPDATEVAR  UpdateVar()
    'FILESIZE'#0'SIZEOFFILE'               +#0#0 , // ac_FILESIZE   FileSize(E)
    'FILEEXIST'#0'ISFILEEXIST'             +#0#0 , // ac_FILEEXIST  IsFileExist(E)
    'RESETFILE'                            +#0#0 , // ac_RESETFILE  ResetFile(E)
    'LOADFILE'                             +#0#0 , // ac_LOADFILE   LoadFile(E)
    'READFILE'                             +#0#0 , // ac_READFILE   ReadFile(C, D, E)
    'WRITEFILE'                            +#0#0 , // ac_WRITEFILE  WriteFile(C, D, E)
    'RENAMEFILE'                           +#0#0 , // ac_RENAMEFILE  RenameFile(D, E)
    'DELETEFILE'#0'DELFILE'                +#0#0 , // ac_DELETEFILE  DeleteFile(E)
    'GETDIR'#0'CURDIR'#0'CURRENTDIR'       +#0#0 , // ac_GETDIR     push (GetDir)
    'DIREXIST'                             +#0#0 , // ac_DIREXIST   DirExist(E)
    'CHDIR'                                +#0#0 , // ac_CHDIR      ChDir(E)
    'MKDIR'                                +#0#0 , // ac_MKDIR      MkDir(E)
    'FORCEDIRS'#0'FORCEDIRECTORIES'        +#0#0 , // ac_FORCEDIRS  ForceDirs(E)
    'EXPANDFILENAME'                       +#0#0 , // ac_EXPANDFILENAME   ExpandFileName(E)
    'EXPANDUNCFILENAME'                    +#0#0 , // ac_EXPANDUNCFILENAME  ExpandUncFilename(E)
    'EXTRACTFILEDRIVE'                     +#0#0 , // ac_EXTRACTFILEDRIVE  ExtractFileDrive(E)
    'EXTRACTFILEPATH'                      +#0#0 , // ac_EXTRACTFILEPATH  ExtractFilePath(E)
    'EXTRACTSHORTFILEPATH'                 +#0#0 , // ac_EXTRACTSHORTFILEPATH ExtractShortFilePath(E)
    'EXTRACTFILENAME'                      +#0#0 , // ac_EXTRACTFILENAME  ExtractFileName(E)
    'EXTRACTFILEEXT'                       +#0#0 , // ac_EXTRACTFILEEXT  ExtractFileEXT(E)
    'EXTRACTRELPATH'                       +#0#0 , // ac_EXTRACTRELPATH  ExtractRelativePath(D, E)
    'CHANGEFILEEXT'                        +#0#0 , // ac_CHANGEFILEEXT  ChangeFileExt(D, E)
    'MATCHWILDCARD'                        +#0#0 , // ac_MATCHWILDCARD   MatchWildCard(D, E)
    'DISKFREE'                             +#0#0 , // ac_DISKFREE   push (DiskFree)
    'DISKSIZE'                             +#0#0 , // ac_DISKSIZE   push (DiskSize)
    'SEARCHFILES'                          +#0#0 , // ac_SEARCHFILES  SearchFiles(?)
    'FINDFILE'#0'SEARCHFILE'               +#0#0 , // ac_FINDFILE
    'PLUS'#0'+'#0'ADD'                     +#0#0 , // ac_PLUS      +
    'MINUS'#0'-'#0'SUB'                    +#0#0 , // ac_MINUS     -
    'MUL'#0'*'                             +#0#0 , // ac_MUL       *
    'DIV'#0'/'                             +#0#0 , // ac_DIV       /
    'MOD'#0'%'                             +#0#0 , // ac_MOD       %
    'INTDIV'#0'\'                          +#0#0 , // ac_INTDIV    \
    'INC'#0'++'                            +#0#0 , // ac_INC       ++
    'DEC'#0'--'                            +#0#0 , // ac_DEC       --
    'NOT'#0'~'                             +#0#0 , // ac_B_NOT     ~
    'OR'#0'|'                              +#0#0 , // ac_B_OR      |
    'AND'#0'&'                             +#0#0 , // ac_B_AND     &
    'XOR'#0'^'                             +#0#0 , // ac_B_XOR     ^
    'L_NOT'#0'!'                           +#0#0 , // ac_L_NOT     !
    'L_XOR'#0'^^'                          +#0#0 , // ac_L_XOR     ^^
    'L_OR'#0'||'                           +#0#0 , // ac_L_OR      ||
    'L_AND'#0'&&'                          +#0#0 , // ac_L_AND     &&
    'SHL'#0'<<'                            +#0#0 , // ac_SHL       <<
    'SHR'#0'>>'                            +#0#0 , // ac_SHR       >>
    'EQ'#0'=='#0'='                        +#0#0 , // ac_EQ        ==
    'NEQ'#0'!='#0'<>'                      +#0#0 , // ac_NEQ       !=
    'LT'#0'<'                              +#0#0 , // ac_LT        <
    'GT'#0'>'                              +#0#0 , // ac_GT        >
    'LTEQ'#0'<='#0'EQLT'                   +#0#0 , // ac_EQLT      <=
    'GTEQ'#0'>='#0'EQGT'                   +#0#0 , // ac_EQGT      >=
    'CHECKBIT'#0'CHKBIT'                   +#0#0 , // ac_CHECKBIT  CheckBit(D, E)
    'SETBIT'                               +#0#0 , // ac_SETBIT    SetBit(D, E)
    'CLEARBIT'#0'RESETBIT'                 +#0#0 , // ac_CLEARBIT  ClearBit(D, E)
    'CRC32'                                +#0#0 , // ac_CRC32     CRC32(E)
    'ISEMPTY'                              +#0#0 , // ac_ISEMPTY   IsEmpty(E)
    'ISERROR'                              +#0#0 , // ac_ISERROR   IsError(E)
    'ISNULL'                               +#0#0 , // ac_ISNULL    IsNull(E)
    'IFYES'#0'IFTRUE'#0'IF'                +#0#0 , // ac_IFYES     if_yes(D, E)
    'IFNO'#0'IFNOT'#0'IFFALSE'             +#0#0 , // ac_IFNO      if_no(D, E)
    'IIF'                                  +#0#0 , // ac_IIF       Iif(C, D ,E)
    'GOTO'#0'GO'#0'JUMP'#0'JMP'            +#0#0 , // ac_JMP       goto(E)
    'SIGN'                                 +#0#0 , // ac_SIGN      sign (-1,0,1)
    'INT8'                                 +#0#0 , // ac_CINT8     AsInt8()
    'INT16'#0'SHORT'                       +#0#0 , // ac_CINT16    AsInt16()
    'INT32'#0'LONG'                        +#0#0 , // ac_CINT32    AsInt32()
    'INT64'                                +#0#0 , // ac_CINT64    AsInt64()
    'UINT8'#0'BYTE'                        +#0#0 , // ac_CUINT8    AsUInt8()
    'UINT16'#0'WORD'                       +#0#0 , // ac_CUINT16   AsUInt16()
    'UINT32'#0'DWORD'                      +#0#0 , // ac_CUINT32   AsUInt32()
    'UINT64'                               +#0#0 , // ac_CUINT64   AsUInt64()
    'CRAWDATA'#0'TORAWDATA'#0'ASRAWDATA'   +#0#0 , // ac_CRAWDATA  CRawData
    'INT'                                  +#0#0 , // ac_CINT      AsInt()
    'FLOAT'                                +#0#0 , // ac_CFLOAT    AsFloat()
    'BOOL'                                 +#0#0 , // ac_CBOOL     AsBool()
    'STRING'                               +#0#0 , // ac_CSTRING   AsString()
    'ISNUM'#0'ISINT'#0'ISINTEGER'          +#0#0 , // ac_ISNUMBER  IsNumber(E)
    'ISFLOAT'#0'ISDOUBLE'                  +#0#0 , // ac_ISFLOAT   IsFloat(E)
    'ISBOOL'#0'ISBOOLEAN'                  +#0#0 , // ac_ISBOOL    IsBool(E)
    'NOW'#0'CURRENT'#0                     +#0#0 , // ac_NOW       Push(Now())
    'DATE'#0'CURRENTDATE'                  +#0#0 , // ac_DATE      => Push(Date())
    'TIME'#0'CURRENTTIME'                  +#0#0 , // ac_TIME      => Push(Time())
    'FORMATDATETIME'#0'FORMATDT'           +#0#0 , // ac_FORMATDATETIME  FormatDateTime(D, E)
    'ASDATETIME'#0'ASTIME'                 +#0#0 , // ac_ASDATETIME  AsDateTime(E)
    'DAYOFWEEK'#0'DOW'                     +#0#0 , // ac_DAYOFWEEK   DayOfWeek(E)
    'DAYOFYEAR'#0'DOY'                     +#0#0 , // ac_DAYOFYEAR   DayOfYear(E)
    'WEEKOFYEAR'#0'WOY'                    +#0#0 , // ac_WEEKOFYEAR  WeekOfYear(E)
    'ISLEAPYEAR'                           +#0#0 , // ac_ISLEAPYEAR  IsLeapYear(E)
    'DECODEDATE'                           +#0#0 , // ac_DECODEDATE  DecodeDate(E) will push E, F, G
    'DECODETIME'                           +#0#0 , // ac_DECODETIME  DecodeTime(E) will push E, F, G, H
    'ENCODEDATE'                           +#0#0 , // ac_ENCODEDATE  EncodeDate(C, D, E)
    'ENCODETIME'                           +#0#0 , // ac_ENCODETIME  EncodeTime(B, C, D, E)
    'DAYTIMEASMS'#0'TIMEASMS'              +#0#0 , // ac_DAYTIMEASMS  TimeAsMs => push int value
    'TIMESTAMPASMS'#0'TSASMS'              +#0#0 , // ac_TIMESTAMPASMS  TimestampAsMs => push int value
    'RND'                                  +#0#0 , // ac_RND       rnd()
    'ABS'                                  +#0#0 , // ac_ABS       abc()
    'NEG'                                  +#0#0 , // ac_NEG       neg(E)
    'MIN'                                  +#0#0 , // ac_MIN       min(D, E)
    'MAX'                                  +#0#0 , // ac_MAX       max(D, E)
    'MAXBYTE'                              +#0#0 , // ac_MAXBYTE    push MaxByte value
    'MAXWORD'                              +#0#0 , // ac_MAXWORD    push MaxWord value
    'MININT'                               +#0#0 , // ac_MININT     push MinInt value
    'MAXINT'                               +#0#0 , // ac_MAXINT     push MaxInt value
    'MINSINGLE'                            +#0#0 , // ac_MINSINGLE  push MinSingle value
    'MAXSINGLE'                            +#0#0 , // ac_MAXSINGLE  push MaxSingle value
    'MINDOUBLE'                            +#0#0 , // ac_MINDOUBLE  push MinDouble value
    'MAXDOUBLE'                            +#0#0 , // ac_MAXDOUBLE  push MaxDouble value
    'POW'#0'POWER'                         +#0#0 , // ac_POWER     power(D, E)
    'SQRT'                                 +#0#0 , // ac_SQRT      sqrt(D, E)
    'TRUNC'                                +#0#0 , // ac_TRUNC     trunc(E)
    'ROUND'                                +#0#0 , // ac_ROUND     round(E)
    'CEIL'                                 +#0#0 , // ac_CEIL      ceil(E)
    'FLOOR'                                +#0#0 , // ac_FLOOR     floor(E)
    'FREXP'                                +#0#0 , // ac_FREXP     frexp(E) -> E, F
    'FRAC'#0'FRACTION'                     +#0#0 , // ac_FRAC      frac(E)
    'FINT'                                 +#0#0 , // ac_FINT      fint(E)
    'LOG10'                                +#0#0 , // ac_LOG10     log10(E)
    'LOGX'#0'LOG'                          +#0#0 , // ac_LOGX      logN(E, D)
    'LN'                                   +#0#0 , // ac_LN        ln(E)
    'EXP'#0'EXPONENT'                      +#0#0 , // ac_EXP       exp(E)
    'TRUE'                                 +#0#0 , // ac_TRUE      True()
    'FALSE'                                +#0#0 , // ac_FALSE     False()
    'EMPTY'                                +#0#0 , // ac_EMPTY     Empty()
    'NULL'                                 +#0#0 , // ac_NULL      Null()
    'PI'                                   +#0#0 , // ac_PI        PI()
    'E'                                    +#0#0 , // ac_E         E()
    'DEG2RAD'#0'DEGTORAD'                  +#0#0 , // ac_DEG2RAD   deg2rad()
    'RAD2DEG'#0'RADTODEG'                  +#0#0 , // ac_RAD2DEG   rad2deg()
    'COS'                                  +#0#0 , // ac_COS       cos(E)
    'SIN'                                  +#0#0 , // ac_SIN       sin(E)
    'TAN'                                  +#0#0 , // ac_TAN       tan(E)
    'ACOS'#0'ARCCOS'                       +#0#0 , // ac_ACOS      acos(E)
    'ASIN'#0'ARCSIN'                       +#0#0 , // ac_ASIN      asin(E)
    'ATAN'#0'ARCTAN'                       +#0#0 , // ac_ATAN      atan(E)
    'COSH'                                 +#0#0 , // ac_COSH      cosh(E)
    'SINH'                                 +#0#0 , // ac_SINH      sinh(E)
    'TANH'                                 +#0#0 , // ac_TANH      tanh(E)
    'ACOSH'#0'ARCCOSH'                     +#0#0 , // ac_ACOSH     acos(E)
    'ASINH'#0'ARCSINH'                     +#0#0 , // ac_ASINH     asin()
    'ATANH'#0'ARCTANH'                     +#0#0 , // ac_ATANH     atan()
    'ASC'#0'ASCII'                         +#0#0 , // ac_ASC       asc()
    'CHR'                                  +#0#0 , // ac_CHR       chr()
    'LEN'                                  +#0#0 , // ac_LEN       length()
    'BIN'                                  +#0#0 , // ac_BIN       bin(E)
    'OCT'                                  +#0#0 , // ac_OCT       oct(E)
    'HEX'                                  +#0#0 , // ac_HEX       hex()
    'NUMBERASBASE'#0'NUMASBASE'#0'NUMTOSTR'#0'NUM2STR' +#0#0, // ac_NUMASBASE NumAsBase(D, E)
    'STRTONUMBASE'#0'STRTONUM'#0'STR2NUM'  +#0#0 , // ac_STRTONUMBASE StrToNumBase(D, E)
    'MAP'#0'MAPK2V'                        +#0#0 , // ac_MAPK2V    MapK2V value(E) by map(D)
    'MAPREPLACE'                           +#0#0 , // ac_MAPREPLACE  MapReplace(D, E)
    'MAPSIZE'                              +#0#0 , // ac_MAPSIZE  $MapSize(E)
    'MAPREMOVE'#0'MAPREMOVEITEM'           +#0#0 , // ac_MAPREMOVE  MapRemove(D, E)
    'MAPREMOVEAT'                          +#0#0 , // ac_MAPREMOVEAT  MapRemoveAt(D, E)
    'MAPSET'#0'MAPSETITEM'                 +#0#0 , // ac_MAPSET   MapSet(C, D, E)
    'MAPKEYS'                              +#0#0 , // ac_MAPKEYS   MapKeys(E)
    'MAPVALUES'                            +#0#0 , // ac_MAPVALUES  MapValues(E)
    'SORT'#0'SORTLIST'                     +#0#0 , // ac_SORTLIST  SortList(E)
    'CONCAT'                               +#0#0 , // ac_CONCAT    concat()
    'LEFT'                                 +#0#0 , // ac_LEFT      left()
    'RIGHT'                                +#0#0 , // ac_RIGHTT    right()
    'STARTSWITH'#0'STARTWITH'              +#0#0 , // ac_STARTSWITH  StartsWith(D, E)
    'CONTAINS'#0'CONTAIN'                  +#0#0 , // ac_CONTAINS  Contains(D, E)
    'ENDSWITH'#0'ENDWITH'                  +#0#0 , // ac_ENDSWITH  EndsWith(D, E)
    'MID'                                  +#0#0 , // ac_MID       mid(C, D, E)
    'SUBSTR'                               +#0#0 , // ac_SUBSTR    substr(C, D, E)
    'COUNTSUBSTR'#0'COUNTSTR'              +#0#0 , // ac_COUNTSUBSTR    CountSubStr(D, E)
    'DELETE'#0'DEL'                        +#0#0 , // ac_DELETE    delete(C, D, E)
    'INSERT'#0'INS'                        +#0#0 , // ac_INSERT    insert(C, D, E)
    'REPLACE'#0'REPL'                      +#0#0 , // ac_REPLACE   replace(C, D, E)
    'PAD'                                  +#0#0 , // ac_PAD       pad(D, E)
    'STRNG'                                +#0#0 , // ac_STRNG     Strng(D, E)
    'GETTOSTR'                             +#0#0 , // ac_GETTOSTR     GetToStr(D, E)
    'GETAFTERSTR'                          +#0#0 , // ac_GETAFTERSTR  GetAfterStr(D, E)
    'REVERS'#0'REVERSSTR'#0'REVERSE'#0'REVERSESTR' +#0#0 , // ac_REVERSSTR  ReversStr(E)
    'UPPERCASE'#0'UCASE'                   +#0#0 , // ac_UPPERCASE UpperCase(E)
    'LOWERCASE'#0'LCASE'                   +#0#0 , // ac_LOWERCASE LowerCase(E)
    'TRIM'                                 +#0#0 , // ac_TRIM      trim(E)
    'TRIMLEFT'                             +#0#0 , // ac_TRIMLEFT  trimleft(E)
    'TRIMRIGHT'                            +#0#0 , // ac_TRIMRIGHT trimright(E)
    'FIND'                                 +#0#0 , // ac_FIND      find(D, E)
    'FINDFROM'                             +#0#0 , // ac_FINDFROM  FindFrom(C, D, E)
    'FINDONEOF'#0'ONEOF'                   +#0#0 , // ac_FINDONEOF  FindOneOf(C, D, E)
    'FINDFIRSTOF'#0'FIRSTOF'               +#0#0 , // ac_FINDFIRSTOF  FindFirstOf(D, E)
    'FINDLASTOF'#0'LASTOF'                 +#0#0 , // ac_FINDLASTOF   FindLastOf(D, E)
    'RE_MATCH'#0'REMATCH'#0'REGEXPMATCH'   +#0#0 , // ac_RE_MATCH  ReMatch(D, E)
    'RE_PARSE'#0'REPARSE'#0'REGEXPPARSE'   +#0#0 , // ac_RE_PARSE  ReParse(D, E)
    'COMPILE'                              +#0#0 , // ac_COMPILE   compile()
    'DECOMPILE'                            +#0#0 , // ac_DECOMPILE  decompile()
    'FLAG'                                 +#0#0 , // ac_FLAG      flag(E)
    'SETFLAG'                              +#0#0 , // ac_SETFLAG    SetFlag(E)
    'CLEARFLAG'#0'RESETFLAG'                +#0#0 , // ac_ClearFLAG  ClearFlag(E)
    'PUSHFLAGS'#0'PUSHF'                   +#0#0 , // ac_PUSHFLAGS          , // PushFlags
    'POPFLAGS'#0'POPF'                     +#0#0 , // ac_POPFLAGS           , // PopFlags
    'ALL'                                  +#0#0 , // ac_ALL       all()
    'ONE'                                  +#0#0 , // ac_ONE       one()
    'IC'#0'IGNORECASE'                     +#0#0 , // ac_IGNORECASE  IgnoreCase()
    'CS'#0'CASESENSITIVE'                  +#0#0 , // ac_CASESENSITIVE CaseSensitive()
    'TXT'#0'TEXT'                          +#0#0 , // ac_TEXT      TextMode()
    'CSV'#0'COMMA'                         +#0#0 , // ac_COMMA     CommaMode()
    'COUNT'#0'ITEMSCOUNT'                  +#0#0 , // ac_ITEMSCOUNT  ItemsCount()
    'COUNTITEM'#0'COUNTITEMS'              +#0#0 , // ac_COUNTITEM   CountItem(D, E)
    'REMOVEDUP'#0'REMOVEDUPLICATES'        +#0#0 , // ac_REMOVEDUP   RemoveDup(E)
    'REVERSLIST'#0'REVERSITEMS'#0'REVERSELIST' +#0#0 , // ac_REVERSLIST  ReversList(E)
    'ITEM'                                 +#0#0 , // ac_ITEM        ItemAt(D, E)
    'SETITEM'                              +#0#0 , // ac_SETITEM     SetItemAt(C, D, E)
    'INSERTITEM'#0'INSITEM'                +#0#0 , // ac_INSERTITEM  InsertItemAt(C, D, E)
    'DELITEM'                              +#0#0 , // ac_DELITEM     DelItemAt()
    'ADDITEM'                              +#0#0 , // ac_ADDITEM     AddItem(D, E)
    'PACKITEMS'                            +#0#0 , // ac_PACKITEMS   PackItems(E)
    'SETCOUNT'                             +#0#0 , // ac_SETCOUNT    SetCount(A, B)   
    'ADJUSTLINEBREAKS'#0'FIXLINEBREAKS'     +#0#0 , // ac_ADJUSTLINEBREAKS  AdjustLineBreaks(E)
    'COMMA2TEXT'#0'COMMATOTEXT'            +#0#0 , // ac_COMMA2TEXT  Comma2Text(E)
    'TEXT2COMMA'#0'TEXTTOCOMMA'            +#0#0 , // ac_TEXT2COMMA  Text2Comma(E)
    'FINDITEM'                             +#0#0 , // ac_FINDITEM    FindItem()
    'FINDITEMFROM'                         +#0#0 , // ac_FINDITEMFROM FindItemFrom()
    'MSGBOX'#0'MESSAGEBOX'                 +#0#0 , // ac_MSGBOX      MessageBox(C, D, E)
    'INPUTBOX'                             +#0#0 , // ac_INPUTBOX    InputBox(C, D, E)
    'INPUTQUERY'                           +#0#0 , // ac_INPUTQUERY  InputQuery(C, D, E)
    'ENTERCRSECT'#0'EnterCriticalSection'  +#0#0 , // ac_ENTERCRSECT
    'LEAVECRSECT'#0'LeaveCriticalSection'  +#0#0 , // ac_LEAVECRSECT
    'SETSYNCEVENT'                         +#0#0 , // ac_SETSYNCEVENT    SetSyncEvent(E)
    'RESETSYNCEVENT'                       +#0#0 , // ac_RESETSYNCEVENT  ResetSyncEvent(E)
    'PULSESYNCEVENT'                       +#0#0 , // ac_PULSESYNCEVENT  PulseSyncEvent(E)
    'GETSYNCEVENT'                         +#0#0 , // ac_GETSYNCEVENT   GeySyncEvent(E)
    'WAITFORSYNCEVENTS'                    +#0#0 , // ac_WAITFORSYNCEVENTS  WaitForSyncEvents(C, D, E)
    'WAITFORSYNCOBJECT'                    +#0#0 , // ac_WAITFORSYNCOBJECT  WaitForSyncObject(D, E)
    'CREATESEMAPHORE'                      +#0#0 , // ac_CREATESEMAPHORE  CreateSemap
    'RELEASESEMAPHORE'                     +#0#0 , // ac_RELEASESEMAPHORE  ReleaseSemaphore(D, E)
    'ISGBVAREXIST'#0'ISGBVAREXISTS'        +#0#0 , // ac_ISGBVAREXIST      IsGbVarExists(E)
    'GETGBVARSLIST'#0'GBVARSLIST'          +#0#0 , // ac_GETGBVARSLIST     GetGbVarsList
    'INITGBVARS'                           +#0#0 , // ac_INITGBVARS        InitGbVars(E)
    'GETGBVAR'                             +#0#0 , // ac_GETGBVAR          GetGbVar(E)
    'SETGBVAR'                             +#0#0 , // ac_SETGBVAR          SetGbVar(D, E)
    'REMOVEGBVAR'                          +#0#0 , // ac_REMOVEGBVAR       RemoveGbVar(E)
    'SETGBVARSTATE'                        +#0#0 , // ac_SETGBVARSTATE      SetGbVarMode(D, E)    
    'READREGVALUE'                         +#0#0 , // ac_READREGVALUE      ReadRegValue(Key, Name)
    'WRITEREGVALUE'                        +#0#0 , // ac_WRITEREGVALUE     WriteRegValue(Key, Name, Value)
    'DEPTH'#0'STACKDEPTH'                  +#0#0 , // ac_DEPTH             $Depth ==> push Stack.Length
    'PICK'                                 +#0#0 , // ac_PICk              $Pick(E)
    'ROTATE'#0'STACKROTATE'                +#0#0 , // ac_ROTATE            $Rotate(E)
    'ROT'#0'STACKROT'                       +#0#0 , // ac_ROT               $Rot
    'STACKREVERSE'#0'REVERSESTACK'         +#0#0 , // ac_REVERSE           N $Reverse
    'STACKPUT'                             +#0#0 , // ac_STACKPUT          Value N $StackPut
    'STACKTOLIST'#0'STACK2LIST'            +#0#0 , // ac_STACKTOLIST       N $StackToList
    'LISTTOSTACK'#0'LIST2STACK'            +#0#0 , // ac_LISTTOSTACK       $ListToStack
    'ADDITEMS'#0'JOINLIST'                  +#0#0 , // ac_ADDITEMS          List1 List2 $AddItems
    'EXTRACTLINE'#0'READLINE'              +#0#0 , // ac_EXTRACTLINE       ExtractLine
    'BATCHSORT'                            +#0#0 , // ac_BATCHSORT         BatchSort
    'BUILDBATCH'                           +#0#0 , // ac_BUILDBATCH        BuildBatch
    'DBGPOINT'#0'DBGPNT'#0'DEBUGPOINT'     +#0#0 , // ac_DBGPOINT          DbgPoint
    'SIMULATE'                             +#0#0 , // ac_SIMULATE          Simulate
    ''                                            // ac_Unknown2  ???
);

// groups of calculator commands ({short group name} + '=' + '{group description})
command_groups: string =
  'ALL=All Functions'#13#10 +
  'COM=Comminucation '#13#10 +
  'CMP=Comparicons and Logic'#13#10 +
  'DTM=Date and Time'#13#10 +
  'DBG=Debug'#13#10 +
  'FIL=File and Filenames'#13#10 +
  'CTR=Flow Control'#13#10 +
  'GEN=General'#13#10 +
  'INT=Internal Flags and Parameters'#13#10 +
  'LST=List Operations'#13#10 +
  'MAP=Mapping'#13#10 +
  'MAT=Mathematic'#13#10 +
  'MEM=Memory'#13#10 +
  'STK=Stack Functions'#13#10 +
  'STR=Strings'#13#10 +
  'SYS=System'#13#10 +
  'SYN=Synchronization and Communication'#13#10 +
  'CNV=Type Conversions'#13#10;

// help text for each of calculator command
// {Group} | {Command} \n { help text }
commands_help: array[TExprAction] of string = (
  '',
  'GEN|$Nop '#10'{ do nothing }                         ',
  'GEN|$CalcEngineVersion '#10'{ calc version number }  ',
  'GEN|$CalcEngineInfo '#10'{ calc author info }             ',
  'GEN|VersionNumber $CheckVersion '#10'{ throws an exeption if current version lower than specified }',
  'GEN|$exit '#10'{ stop calculating expression }   ',
  'COM|EventToReturn $Event '#10'{ set event-to-return }  ',
  'GEN|Message $Throw '#10'{ throws an exception }  ',
  'DBG|Dump '#10'{ dump calc internal state info to $Calc.dmp } ',
  'INT|PrmName $GetParam '#10'{ value of specified internal parameter }',
  'INT|PrmName Value $SetParam '#10'{ set value of specified internal parameter }',
  'FIL|Value FileName $ToLog '#10'{ write (append) specified value to specified log file }',
  'SYS|EnvVarName $GetEnv '#10'{ value of specified enviroment variable }',
  'SYS|EnvVarName Value $SetEnv '#10'{ set value of specified enviroment variable }',
  'SYS|$Environment '#10'{ all environment strings splitted by CR+LF }',
  'SYS|TimeMs $SLEEP '#10'{ wait specified number of milliseconds }',
  '                                               ',
  'STK|$Pop '#10'{ remove top value from stack }',
  'STK|N $PopN '#10'{ remove top N values from stack }',
  'STK|$PopAll '#10'{ remove all values from stack }',
  'STK|Value $DUP '#10'{ duplicate top value in stack }',
  'STK|N $DUPN '#10'{ duplicate top N values in stack }',
  'STK|Value1 Value2 $Swap '#10'{ swap two top values in stack }',
  'GEN|Value $VarType '#10'{ replace top value with value type index }',
  'GEN|$VarTypeMask '#10'{ VARIANT type mask }',
  'GEN|Value $VarTypeName '#10'{ VARIANT value type name }',
  'MEM|/Value/ MemoryCellID $Cut '#10'{ save /value/ in specified memory cell and removes it from stack }',
  'MEM|/Value/ MemoryCellID $Copy '#10'{ save /value/ in specified memory cell (left value in stack) }',
  'MEM|MemoryCellID $Paste '#10'{ value from specified memory cell, short form of this command - @MemoryCellID }',
  'SYS|$WinCut '#10'{ cut top value to Windows clipboard }',
  'SYS|$WinCopy '#10'{ copy top value to Windows clipboard }',
  'SYS|$WinPaste '#10'{ push value from Windows clipboard (as text) }',
  'COM|VarName $GetVar '#10'{ value of specified variable }',
  'COM|Value VarName $UpdateVar '#10'{ update value of specified variable }',
  'FIL|FileName  $FileSize '#10'{ size of specified file }',
  'FIL|FileName  $FileExist '#10'{ True or False depends on specified file exists }',
  'FIL|FileName  $ResetFile '#10'{ destroys content of specified file (truncate to zero size) }',
  'FIL|FileName  $LoadFile '#10'{ content of specified file as string }',
  'FIL|FileName  PosFrom  Count  $ReadFile '#10'{ specified part of content of specified file as string }',
  'FIL|FileName  Value  PosFrom  $WriteFile '#10'{ write specified value to specified location in specified file }',
  'FIL|OldName  NewName  $RenameFile '#10'{ rename file }',
  'FIL|FileName  $DeleteFile '#10'{ delete file }',
  'FIL|$GetDir '#10'{ current directory on current drive }',
  'FIL|DirName  $DirExist '#10'{ depends of specified directory exists }',
  'FIL|DirName  $ChDir '#10'{ change current directory }',
  'FIL|DirName  $MkDir '#10'{ create directory }',
  'FIL|Dir  $ForceDirs '#10'{ force create directories in specified path }',
  'FIL|FileName  $ExpandFileName '#10'{ expand filename with fullpath to that file }',
  'FIL|FileName  $ExpandUncFileName '#10'{ expand UNC filename with fullpath to that file }',
  'FIL|FileName  $ExtractFileDrive '#10'{ extract drive name component from file name }',
  'FIL|FileName  $ExtractFilePath '#10'{ extract path component from file name }',
  'FIL|FileName  $ExtractShortFilePath '#10'{ extract short path component from file name }',
  'FIL|FileName  $ExtractFileName '#10'{ extract file name component from file name }',
  'FIL|Filename  $ExtractFileEXT '#10'{ extract file extension component from file name }',
  'FIL|BaseName  DestName  $ExtractRelativePath '#10'{ extract relative path to file }',
  'FIL|FileName  NewExt  $ChangeFileExt '#10'{ change extension in specified file name }',
  'FIL|FileName  Mask  $MatchWildCard '#10'{ True of False depends on speicified file name match specified wildcard }',
  'FIL|$DiskFree '#10'{ number of free kilobytes on current drive }',
  'FIL|$DiskSize '#10'{ total number of kilobytes on current drive }',
  'FIL|Path  FileSpec  Recursive  $SearchFiles '#10'{ search files by filespec at [Path] }',
  'FIL|FileName  Pathes  $FindFile '#10'{ search specified filename in specified [pathes] list }',
  'MAT|Number1 Number2 $PLUS '#10'{ add number2 to number1 }',
  'MAT|Number1 Number2 $MINUS '#10'{ substract number2 from number1 }',
  'MAT|Number1 Number2 $MUL '#10'{ multiple number2 with number1 }',
  'MAT|Number1 Number2 $DIV '#10'{ divide number2 on number1 }',
  'MAT|Number1 Number2 $MOD '#10'{ remainder of division number2 on number1 }',
  'MAT|Number1 Number2 $INTDIV '#10'{ integer division number2 on number1 }',
  'MAT|Number $INC '#10'{ increment number }',
  'MAT|Number $DEC '#10'{ decrement number }',
  'MAT|Value $B_NOT '#10'{ bitwise NOT operation }',
  'MAT|Value1 Value2 $B_OR '#10'{ bitwise OR operation }',
  'MAT|Value1 Value2 $B_AND '#10'{ bitwise AND operation }',
  'MAT|Value1 Value2 $B_XOR '#10'{ bitwise XOR operation }',
  'CMP|Value $L_NOT '#10'{ logical NOT operation }',
  'CMP|Value1 Value2 $L_XOR '#10'{ logical XOR operation }',
  'CMP|Value1 Value2 $L_OR '#10'{ logical OR operation }',
  'CMP|Value1 Value2 $L_AND '#10'{ logical AND operation }',
  'MAT|Number Offset $SHL '#10'{ bitwise left shift operation }',
  'MAT|Number Offset $SHR '#10'{ bitwise right shift operation }',
  'CMP|Value1 Value2 $Eq '#10'{ comparison: Value1 equals to Value2 }',
  'CMP|Value1 Value2 $NEq '#10'{ comparison: Value1 not equals to Value2 }',
  'CMP|Value1 Value2 $Lt '#10'{ comparison: Value1 less than Value2 }',
  'CMP|Value1 Value2 $Gt '#10'{ comparison: Value1 greather than Value2 }',
  'CMP|Value1 Value2 $EqLt '#10'{ comparison: Value1 less or equals to Value2 }',
  'CMP|Value1 Value2 $EqGt '#10'{ comparison: Value1 greather or equals to Value2 }',
  'CMP|Value BitIndex $CheckBit '#10'{ check that bit [BitIndex] is turned on in [Value] }',
  'CMP|Value BitIndex $SetBit '#10'{ turn on bit [BitIndex] in [Value] }',
  'CMP|Value BitIndex $ClearBit '#10'{ turn off bit [BitIndex] in [Value] }',
  'MAT|Value CrcValue $CRC32 '#10'{ CRC32 of string [Value], [CrcValue] should be 0 or other CRC32 to continue CRC32 calculation }',
  'CMP|Value $ISEMPTY '#10'{ test if Value is (EMPTY) (special Variant) datatype }',
  'CMP|Value $ISERROR '#10'{ test if Value is (ERROR) (special Variant) datatype }',
  'CMP|Value $ISNULL '#10'{ test if Value is (NULL) (special Variant) datatype }',
  'CTR|Value "LabelID" $IFYES '#10'{ jump to (continue expression calculation from specificied place) label if Value is true }',
  'CTR|Value "LabelID" $IFNO '#10'{ jump to (continue expression calculation from specificied place) label if Value is false }',
  'CTR|BoolValue ValueIfTrue ValueIfFalse $IIF '#10'{ if [BoolValue] is true the [ValueIfTrue] will left on stack, otherwise [ValueIfFalse] will left on stack }',
  'CTR|"LabelID" $GOTO '#10'{ jump to (continue expression calculation from specificied place) label }',
  'MAT|Value $SIGN '#10'{ left on stack -1 if Value<0, 0 if Value=0, 1 if Value>0 }',
  'CNV|Value $CINT8 '#10'{ datatype casting: cast to 8-bit integer }',
  'CNV|Value $CINT16 '#10'{ datatype casting: cast to 16-bit integer }',
  'CNV|Value $CINT32 '#10'{ datatype casting: cast to 32-bit integer }',
  '                                               ',
  'CNV|Value $CUINT8 '#10'{ datatype casting: cast to unsigned 8-bit integer }',
  'CNV|Value $CUINT16 '#10'{ datatype casting: cast to unsigned 16-bit integer }',
  'CNV|Value $CUINT32 '#10'{ datatype casting: cast to unsigned 32-bit integer }',
  '                                               ',
  'CNV|Value $CRawData '#10'{  }',
  'CNV|Value $CINT '#10'{ datatype casting: cast to integer (32-bit, signed) }',
  'CNV|Value $CFLOAT '#10'{ datatype casting: cast to float }',
  'CNV|Value $CBOOL '#10'{ datatype casting: cast to boolean }',
  'CNV|Value $CSTRING '#10'{ datatype casting: cast to string }',
  'CMP|Value $ISNUM '#10'{ True or False depends on top value in stack could be represented as a number }',
  'CMP|Value $ISFLOAT '#10'{ True or False depends on top value in stack could be represented as a floating-point number }',
  'CMP|Value $ISBOOL '#10'{ True or False depends on top value in stack could be represented as a boolean value }',
  'DTM|$NOW '#10'{ current datetime }',
  'DTM|$DATE '#10'{ current date }',
  'DTM|$TIME '#10'{ current time }',
  'DTM|TimeValue TemplateStr $FORMATDATETIME '#10'{ format datetime value }',
  'DTM|Value $ASDATETIME '#10'{ convert top value in stack to datetime value }',
  'DTM|DateTimeValue $DAYOFWEEK '#10'{ the day-of-week number of specified datetime value }',
  'DTM|DateTimeValue $DAYOFYEAR '#10'{ the day-of-year number of specified datetime value }',
  'DTM|DateTimeValue 1stDayIsMon $WEEKOFYEAR '#10'{ the week-of-year number of specified datetime value }',
  'DTM|Year $ISLEAPYEAR '#10'{ True or False depends on specified year is leap }',
  'DTM|Value $DECODEDATE '#10'{ decode top value in stack to three values - year, month, day }',
  'DTM|Value $DECODETIME '#10'{ decode top value in stack to three values - hours, miniutes, seconds, milliseconds }',
  'DTM|y m d $encodedate '#10'{ encode three top values in stack to one datetime value }',
  'DTM|h n s f $encodetime '#10'{ encode four top values in stack to one datetime value }',
  'DTM|$DayTimeAsMs'#10'{ push to stask int32 value reprenenting number of milliseconds passed after midnight this day }',
  'DTM|$TimestampAsMs'#10'{ push to stask int32 value reprenenting number of milliseconds passed after 1970-01-01:00:00:00 }',
  'MAT|$RND '#10'{ random number (within the range 0 <= Number < 1) }',
  'MAT|Value $ABS '#10'{ absolute value of [Value] }',
  'MAT|Value $NEG '#10'{ negative value of [Value] }',
  'MAT|Value1 Value2 $MIN '#10'{ minimal of two values - [Value1] and [Value2] }',
  'MAT|Value1 Value2 $MAX '#10'{ maximal of two values - [Value1] and [Value2] }',
  'MAT|$MaxByte '#10'{ maximal value of BYTE datatype }',
  'MAT|$MaxWord '#10'{ maximal value of WORD datatype }',
  'MAT|$MinInt '#10'{ minimal value of INTEGER datatype }',
  'MAT|$MaxInt '#10'{ maximal value of INTEGER datatype }',
  'MAT|$MinSingle '#10'{ minimal value of SINGLE datatype  }',
  'MAT|$MaxSingle '#10'{ maximal value of SINGLE datatype  }',
  'MAT|$MinDouble '#10'{ minimal value of DOUBLE datatype }',
  'MAT|$MaxDouble '#10'{ maximal value of DOUBLE datatype  }',
  'MAT|Value Power $POWER '#10'{ [Value] in power [Power] }',
  'MAT|Value $SQRT '#10'{ square root of [Value] }',
  'MAT|Value $Trunc '#10'{ truncate fraction part of floating-point number }',
  'MAT|Value $Round '#10'{ round floating-point number to nearest integer }',
  'MAT|Value $Ceil '#10'{ round floating-point number to highest integer }',
  'MAT|Value $Floor '#10'{ round floating-point number to lowest integer }',
  'MAT|Value $FrExp '#10'{ --- }',
  'MAT|Value $Frac '#10'{ fraction part of floating-point number }',
  'MAT|Value $Fint '#10'{ integer part of floating-point number }',
  'MAT|Value $Log10 '#10'{ 10-based logarithm of [Value] }',
  'MAT|Value Base $LogX '#10'{ [Base]-based logarithm of [Value] }',
  'MAT|Value $Ln '#10'{ E-based logarithm of [Value] }',
  'MAT|Value $Exp '#10'{ exponent of [Value] }',
  'GEN|$True '#10'{ boolean value - TRUE }',
  'GEN|$False '#10'{ boolean value - FALSE }',
  'GEN|$Empty '#10'{ special value - EMPTY }',
  'GEN|$Null '#10'{ special value - NULL }',
  'MAT|$PI '#10'{ value of number PI }',
  'MAT|$E '#10'{ value of number E }',
  'MAT|Value $DegToRad '#10'{ convert derees to redians }',
  'MAT|Value $RadToDeg '#10'{ convert redians to derees }',
  'MAT|Value $Cos '#10'{ cosine of [Value] }',
  'MAT|Value $Sin '#10'{ sine of [Value] }',
  'MAT|Value $Tan '#10'{ tangent of [Value] }',
  'MAT|Value $ACos '#10'{ arccosine of [Value] }',
  'MAT|Value $ASin '#10'{ arcsine of [Value] }',
  'MAT|Value $ATan '#10'{ arctangent of [Value] }',
  'MAT|Value $CosH '#10'{ hyperbolic cosine of [Value] }',
  'MAT|Value $SinH '#10'{ hyperbolic sine of [Value] }',
  'MAT|Value $TanH '#10'{ hyperbolic tangent of [Value] }',
  'MAT|Value $ACosH '#10'{ hyperbolic arccosine of [Value] }',
  'MAT|Value $ASinH '#10'{ hyperbolic arcsine of [Value] }',
  'MAT|Value $ATanH '#10'{ hyperbolic arctangent of [Value] }',
  'STR|Char $ASC '#10'{ code of character [Char]}',
  'STR|Number $CHR '#10'{ character with code [Number] }',
  'STR|Value $LEN '#10'{ length of string }',
  'STR|Value $BIN '#10'{ string that is binary (2-based) representation of [Value] }',
  'STR|Value $OCT '#10'{ string that is oct (8-based) representation of [Value] }',
  'STR|Value $HEX '#10'{ string that is hexadecimal (16-based) representation of [Value] }',
  'STR|Number Base $NumAsBase '#10'{ string that is [Base]-based representation of [Value] }',
  'STR|StrNum Base $StrToNumBase '#10'{ number that is interpretation of string [Value] as [Base]-based number }',
  'MAP|MapDef Key $MAP '#10'{ search [KeyValue] in [MapDef] defintions, left on stack appropriate value or (EMPTY) is [KeyValue] was not found in [MapDef] }',
  'MAP|MapDef Text $MapReplace '#10'{ replace all keys found in Text with appropriate values defined for that keys in MapDef }',
  'MAP|MapDef $MapSize '#10'{ put to stack number of items in MapDef }',
  'MAP|MapDef Key $MapRemove '#10'{ remove item identified by [key] from [MapDef] }',
  'MAP|MapDef Index $MapRemoveAt '#10'{ remove item identified by [index] from [MapDef] }',
  'MAP|MapDef Key Value $MapSet '#10'{ set value of item identified by [key] in [MapDef], if no such item it will be added }',
  'MAP|MapDef $MapKeys '#10'{ put to stack list of keys of MapDef }',
  'MAP|MapDef $MapValues '#10'{ put to stack list of values of MapDef }',
  'LST|List $SORT '#10'{ sort items in list }',
  'STR|Value1 Value2 $CONCAT '#10'{ string that is concatenation of [Value1] and [Value2] strings }',
  'STR|Value Count $LEFT '#10'{ [Count] characters from left of string [Value] }',
  'STR|Value Count $RIGHT '#10'{ [Count] characters from right of string [Value] }',
  'STR|Value Pattern $StartsWith '#10'{ true if string [Value] starts with [Pattern] }',
  'STR|Value Pattern $Contains '#10'{ true if string [Value] contains [Pattern] }',
  'STR|Value Pattern $EndsWith '#10'{ true if string [Value] ends with [Pattern] }',
  'STR|Value StartPos Count $MID '#10'{ substring of [Value] - [Count] chars from position [StartPos] }',
  'STR|Value StartPos EndPos $SUBSTR '#10'{ substring of [Value] - from position [StartPos] till position [EndPos] }',
  'STR|String SubStr $CountSubStr '#10'{ number of [SubStr] found in [String] }',
  'STR|Value Index Count $DELETE '#10'{ delete substring - [Count] chars from position [Index] from string [Value] }',
  'STR|Value SubStr Index $INSERT '#10'{ insert substring - [SubStr] at position [Index] from string [Value] }',
  'STR|Value OldSubStr NewSubStr $REPLACE '#10'{ replace [OldSubStr] with [NewSubStr] in string [Value] }',
  'STR|Value Width $PAD '#10'{ pad string [Value] with spaces to width [Width], or truncate if length was greather than [Width] }',
  'STR|Pattern Count $STRNG '#10'{ string of [Count] concatenations of [Pattern] }',
  'STR|String  SubStr  $GetToStr '#10'{ part of string before [SubStr] of full [string] if [SubStr] not found in [string] }',
  'STR|String  SubStr  $GetAfterStr '#10'{ part of string after [SubStr] of empty string if [SubStr] not found in [string] }',
  'STR|Value  $Revers '#10'{ reversed string ("ABC" -> "CBA") }',
  'STR|Value $UPPERCASE '#10'{ uppercased [Value] }',
  'STR|Value $LOWERCASE '#10'{ lowercased [Value] }',
  'STR|Value CharsToTrim $TRIM '#10'{ trim characters [CharsToTrim] in string [Value] }',
  'STR|Value CharsToTrim $TRIMLEFT '#10'{ trim at left characters [CharsToTrim] in string [Value] }',
  'STR|Value CharsToTrim $TRIMRIGHT '#10'{ trim at right characters [CharsToTrim] in string [Value] }',
  'STR|Value SubStr $Find '#10'{ position of found [SubStr] in string [Value] or -1 if not found }',
  'STR|Value SubStr StartPos $FindFrom '#10'{ position of found [SubStr] in string [Value] or -1 if not found }',
  'STR|Value CharsToFind StartPos $FindOneOf '#10'{ position of found any of [CharsToFind] in string [Value] or -1 if not found }',
  'STR|Value CharsToFind $FindFirstOf '#10'{ position of first found any of [CharsToFind] in string [Value] or -1 if not found }',
  'STR|Value CharsToFind $FindLastOf '#10'{ position of last found any of [CharsToFind] in string [Value] or -1 if not found }',
  'STR|Value RegExpStr $ReMatch '#10'{ TRUE if string [Value] match regular expression [RegExpStr] }',
  'STR|Value RegExpStr $ReParse '#10'{ number of values that is result of matching string [Value] with regular expression [RegExpStr] }',
  'STR|Value $Compile '#10'{ compile escape sequences (like - \r, \n, \x20, etc) in string [Value] }',
  'STR|Value $Decompile '#10'{ convert some of real characters in string [Value] to escape sequences (like - \r, \n, \x20, etc) }',
  'INT|ID $FLAG '#10'{ value of specified flag }',
  'INT|ID $SETFLAG '#10'{ set specified flag to TRUE (ON) }',
  'INT|ID $CLEARFLAG '#10'{ set specified flag to FALSE (OFF) }',
  'INT|$PUSHF '#10'{ value of calculator flags }',
  'INT|Value $POPF '#10'{ restore calculator flags from [Value] }',
  'GEN|$ALL '#10'{ switch to Affect-All-Items mode (oposite to $One) }',
  'GEN|$ONE '#10'{ switch to Affect-One-Item mode (oposite to $All) }',
  'GEN|$IgnoreCase '#10'{ switch to Ignore-Case mode (oposite to $CaseSensitive) }',
  'GEN|$CaseSensitive '#10'{ switch to Case-Sensitive mode (oposite to $IgnoreCase) }',
  'GEN|$Text '#10'{ switch to Text mode (to work with CR+LF-separated lists) }',
  'GEN|$Comma '#10'{ switch to Comma mode (to work with comma-separated lists) }',
  'LST|List $ITEMSCOUNT '#10'{ number of items in list }',
  'LST|List ItemValue $CountItem '#10'{ number of [ItemValue] items in list }',
  'LST|List $RemoveDup '#10'{ remove duplicate items from [List] }',
  'LST|List $ReversList '#10'{ reverse items in [List] }',
  'LST|List Index $ITEM '#10'{ return [Index] item from [List] }',
  'LST|List Value Index $SETITEM '#10'{ set [Index] item in [List] }',
  'LST|List Value Index $INSERTITEM '#10'{ insert item to [List] at pos [Index] }',
  'LST|List ItemIndex $DELITEM '#10'{ delete [Index] item from [List] }',
  'LST|List ItemValue $ADDITEM '#10'{ add new item to [List] }',
  'LST|List $PACKITEMS '#10'{ remove empty items from [List] }',
  'LST|List Count $SETCOUNT '#10'{ set number of items in [List], remove if more than [Count], add empty strings if less than [Count] }',
  'STR|Text $ADJUSTLINEBREAKS '#10'{ adjust line breaks in [Text] }',
  'LST|List $COMMA2TEXT '#10'{ convert comma-separated [List] to CR+LF-separated }',
  'LST|List $TEXT2COMMA '#10'{ convert CR+LF-separated [List] to comma-separated }',
  'LST|List Item $FindItem '#10'{ search [Item] in [List] }',
  'LST|List ItemValue StartPos $FindItemFrom '#10'{ position of found [ItemValue] in list [List] or -1 if not found }',
  'SYS|Text Caption Flags $MessageBox '#10'{ display MessageBox dialog window }',
  'SYS|Caption Prompt Ddefault $InputBox '#10'{ display InputBox dialog window }',
  'SYS|Caption Prompt Value $InputQuery '#10'{ display InputQuery dialog window }',
  'SYN|SectionID Flags $EnterCrSect '#10'{ enter named critical section (such named critical section objects shared between all threads in application) }',
  'SYN|SectionID $LeaveCrSect '#10'{ leave named critical section (such named critical section objects shared between all threads in application) }',
  'SYN|EventID $SetSyncEvent '#10'{ set named synchronization event }',
  'SYN|EventID $ResetSyncEvent '#10'{ reset named synchronization event  }',
  'SYN|EventID $PulseSyncEvent '#10'{ pulse named synchronization event  }',
  'SYN|EventID $GetSyncEvent '#10'{ current value of named synchronization event (TRUE or FALSE) }',
  'SYN|EventsList Timeout Flags $WaitForSyncEvents '#10'{ freeze execution until one or all (depends on calculator flags) of specified in [EventsList] became set }',
  'SYN|ObjectName|Handle Timeout $WaitForSyncObject '#10'{  }',
  'SYN|SemName InitCount MaxCount $CreateSemaphore'#10'{  }',
  'SYN|SemName Count $ReleaseSemaphore'#10'{  }',
  'SYN|VarName $IsGbVarExist '#10'{ TRUE if [VarName] internal global variable exists (such variables shared between all threads in application) }',
  'SYN|$GetGbVarsList '#10'{ put to stack list of global variables known at the moment }',
  'SYN|VarDefs $InitGbVars '#10'{ initialize bunch of global vars }',
  'SYN|VarName $GetGbVar '#10'{ value of internal global variable (such variables shared between all threads in application) }',
  'SYN|Value VarName $SetGbVar '#10'{ set internal global variable (such variables shared between all threads in application) }',
  'SYN|VarName $RemoveGbVar '#10'{ remove internal global variable (such variables shared between all threads in application) }',
  'SYN|VarName Mode $SetGbVarState '#10'{ set state of specified global variables ("sessioned" or "global") }',
  'SYS|Key Name $ReadRegValue '#10'{ system registry access: read value [Name] from key [Key] }',
  'SYS|Key Name Value $WriteRegValue '#10'{ system registry access: assign value [Value] to value [Name] in key [Key] }',
  'STK|$Depth '#10'{ push to stack the length of stack before this command }',
  'STK|N $Pick '#10'{ push to stack a copy of stack item # N counting from top of stack }',
  'STK|N $Rotate '#10'{ rotate top N items in stack, negative N means backward rotation }',
  'STK|$Rot '#10'{ rotate top 3 items in stack }',
  'STK|N $StackReverse '#10'{ reverse top N items in stack }',
  'STK|Value N $StackPut '#10'{ replace item in stack on depth N with Value }',
  'STK|N $StackToList '#10'{ convert top N items in stack to list }',
  'STK|List $ListToStack '#10'{ push all list items to stack }',
  'LST|List1 List2 $AddItems '#10'{ add items from List2 to List1 }',
  'SYS|Text StartPos $ExtractLine { }',
  'SYS|VarsList SortSpecs $BatchSort { }',
  'SYS|VarsList FormatSpecs $BuildBatch { }',
  'SYS|Prm $DbgPnt { call debug procedure with specified parameter }',
  'SYS|[ Prm1 ... PrmN ] CaseID $Simulate { simulate }',
  ''
  );

Lists

CalcRPN can work with lists of 2 types:

  • CR+LF separated (use $text command to switch into this mode)
  • command separated (use $comma command to switch into this mode)

Practically list is a string with delimiters - that is how TStringList class works in Borland Delphi 5+. For example:

$text "item 1\r\nitem 2\r\nitem 3\r\n" 
$count

This will return 3 - 3 items in list (because in $text mode the list delimiter is not a start-of-item but end-of-item).

But in $comma mode the comma (",") is delimiter between items. However, from Borland Delphi we derive a behaviour when items with space inside enclosed with double quotes. For example:

$text "item 1\r\nitem 2\r\nitem 3\r\n" 
$textToComma

This will rerturn ""item 1","item 2","item 3"" string.

Expression Examples

Load Text File and Convert it Into Pascal String

$text
  "MatView2.config" $loadfile "data" $cut

  0 "I" $cut
  "" "Txt" $cut
  @data $count "CNT" $cut

[LOOP]
  @I @CNT < "END" $ifnot
  @Txt
    "  '" @data @I $item "'#13#10 + " $concat:2
    $additem
  "Txt" $cut
  @I $inc "I" $cut
  "LOOP" $go

[END]
  @Txt "$txt.pas" $ToLog

Parse Data Resultset for UI

$text $all
  "" 
    "Output" $copy 
    "PartsList" $copy
  resultSet "Data" $copy $count "Count" $cut
  0 "I" $cut
[LoopRow]
  @I @Count < "LoopRowEnd" $ifnot

    @Data @I $item "," "\r\n" $replace "Item" $cut

    @Output
    @Item 0 $item { this is Item# } 4 $pad
    @Item 1 $item { this is Part# } "PN" $copy 24 $pad
    @Item 2 $item { this is Qty }   4 $pad 
    @Item 3 $item { this is Descr } 40 $pad
    "\r\n"
    $concat:5 "Output" $cut

    @PartsList @PN $additem "PartsList" $cut

  @I $inc "I" $cut "LoopRow" $goto
[LoopRowEnd]
  @Output "DataGridText" $assign $pop
  @PartsList "PartsList" $assign $pop
  DataGridText
    

Note: also I have versions of CalcRPN for Borland Delphi 5 and 7 and for C++.

/Dmitry Bond. (dmitry_bond@hotmail.com)/

Product Compatible and additional computed target framework versions.
.NET Framework net20 is compatible.  net35 was computed.  net40 was computed.  net403 was computed.  net45 was computed.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2026.4.3.1906 105 4/3/2026
2026.4.3.1823 102 4/3/2026
2025.2.22.1801 266 2/22/2025

Just a 1st official release