# CCalc documentation and reference

Homepage | Download | Reference

Contents

- Expressions syntax
- Library reference
  - StrMap
  - MathParser

## CCalc expressions syntax

You may use mathematically-correct expressions, including brackets, functions etc.

#### CCalc expressions syntax admits:

- Numbers
  Decimal numbers
    123.456e+78
  Integer hex numbers
    0x123
  Integer oct numbers
    0677
- Mathematical constants E and Pi
- Large number of arithmetical and bitwise operations
  + - * /
    It is obvious
  %
    Remainder
  **
    Power
  & | ^ ~
    Bitwise and / or / xor / not
- Logical operations and relations
  <> = > <
    not equal / equal / greater / less relations
  && ||
    Logical and / or
- Functions

      ARCTAN, ARCSIN, ARCCOS, COS, SIN, TAN,
      ABS, EXP, LN, LOG, SQRT, SQR, SGN, SIGN,
      FRAC, TRUNC, FLOOR, CEIL, ROUND( x[, precision] )

- Conditional operator

      <condition> ? <true expr.> : <false expr.>

  where
  <condition>
    - logical condition. 0 - false, nonzero - true. Logical relations and operations may be used.
  <true expr.>
    - expression for true expression
  <false expr.>
    - expression for false expression

#### Correct expressions examples:

(sin(Pi/2) + 1) / 4
  = 0.5
2 > 3
  = 0 (false)
(2*2=4) ? 1 : 0
  = 1
round( 1.2345, 2 )
  = 1.23
round( 27.45, -1 )
  = 30

#### CCalc script

CCalc script begins with "#!". The syntax is clear from the example:

    #!
    a := 2;
    b := 3;
    return a * b + 1;

## CCalc Library

The library consists of three components with their own API:

StrMap (strmap.h)
  Small "sublibrary" for working with "string lists". You must communicate with StrMap if you want to add your own user-defined functions (UDFs) and user-defined variables (UDVs)
Lexer (lexer.h)
  Universal lexical analyser used as backend layer for parsing expressions. In general developers have no need to communicate directly with Lexer. But they can use it separately for their own needs.
MathParser (mparser.h)
  Core component which calculates expressions. It is very easy to use but may be hard to initialize to match your needs.

### StrMap reference

    hqStrMap* Strmap_Create( int extrabytes, int dup );
    hqStrMap* Strmap_CreateFromChain( int extrabytes, char *strchain, void *data );
    void StrMap_Destroy( hqStrMap* strmap );

    void StrMap_AddString( hqStrMap* strmap, char *str, void *data );
    void StrMap_AddStrLen( hqStrMap* strmap, char *str, int len, void *data );
    void StrMap_ShrinkMem( hqStrMap* strmap );
    void StrMap_Trim( hqStrMap* strmap, int NewCount );
    void StrMap_TrimClear( hqStrMap* strmap, int NewCount );
    void StrMap_SetCapacity( hqStrMap* strmap, int NewCapacity );
    int StrMap_IndexOf( hqStrMap* strmap, char *str, void **data );
    int StrMap_LenIndexOf( hqStrMap* strmap, char *str, int len, void **data );
    char* StrMap_GetString( hqStrMap* strmap, int index, int *len, void **data );
    void Strmap_FillFromChain( hqStrMap* strmap, char *strchain, void *data );

I have no time to describe each function, just some examples of most common usage:

#### Creating list of variables from "char chain"

Variables will be associated with `double` values;

    char varnames[] = "X\000" "Y\000" "Z\000\000";
    double varvalues[] = { 5.3, 6.1, -7.45 };

    hqStrMap* varmap = Strmap_CreateFromChain( sizeof(double), varnames, varvalues );

    ...

    StrMap_Destroy( varmap );

Note that `varnames` is a special data structure ("char chain"):
a string containing zero-separated "substrings" terminated by double zero.

#### Creating list of variables step-by-step

    double varvalues[] = { 5.3, 6.1 };

    hqStrMap* varmap = Strmap_Create( sizeof(double), 0 /* do not copy strings */ );

    StrMap_AddString( varmap, "X", varvalues );
    StrMap_AddString( varmap, "Y", varvalues+1 );

    ...

    StrMap_Destroy( varmap );

### MathParser reference

    typedef int (*PrmSrchFunc) ( const char *str, int len, double *value,
    			     void *param );

    typedef struct {
        /* public */
        hqStrMap   *Parameters;	// List of numeric veriables
        hqStrMap   *ExtFunctions;   // List of multi-argument external functions
        PrmSrchFunc MoreParams;	// Function for calculating unhandled parameters
        void       *ParamFuncParam; // Parameter given to this function
        /* private */
        ...
    } hqMathParser;

    hqMathParser* MathParser_Create( char *MoreLetters );
    void MathParser_Destroy( hqMathParser* parser );
    char* MathParser_Parse( hqMathParser* parser, char *Formula, double *result );

Some examples of usage:

#### Initializing MathParser for using with list of UDVs

    /* ... creating list of variables. See StrMap reference for example */

    hqMathParser* parser = MathParser_Create( NULL );

    parser->Parameters = varmap;

#### Initializing MathParser for using with list of UDFs

    /* multiarg test function  */
    char* dummy( int paramcnt, double *args, hqStrMap *strparams, double *result );

    char funcnames[] =
        "DUMMY\000";
    char* (*funcaddrs[])() = {
        &dummy };

    hqStrMap* strmap = Strmap_CreateFromChain( sizeof(void*), funcnames, funcaddrs );

    hqMathParser* parser = MathParser_Create( NULL );

    parser->ExtFunctions = strmap;

#### Calculating expression

    double result;
    char *ErrMsg = MathParser_Parse( parser, "sin(x * x) / 2", &result );
    if ( ErrMsg == NULL )
        printf( "%.15G\n", result );
    else {
        puts( ErrMsg );

#### Destroying MathParser

    MathParser_Destroy( parser );
    /* Don't forget to destroy lists of UDFs and UNVs if they are created before */
    StrMap_Destroy( strmap );

Of course this documentation is incomplete as I have no time now to write more. For more information see ccalc.c as an example of usage of the library;