## DwScript language

**DwScript** is a domain-specific programming language embedded into DataStore/DataWindow functionality. The program code (expression) is parsed and evaluated dynamically at run time within some context scope. This context is always a row object that resides inside the DataStore/DataWindow's data array. Thus, any `column`/`compute` name of the DataStore`s row model is a valid identifier for the **DwScript**. The result of the evaluation process, if successful, is returned to the calling procedure. If a syntax error is detected during the parsing stage, a runtime error is generated.

> **DwScript** language doesn't understand the assignment operator (`=`) for now, so you CANNOT change a value of any identifiers, either internals or externals.

**DwScript** is a `JavaScript` based language. It understands almost all set of the JavaScript language operators out of the box, but the names of the built-in functions, unlike the latter, do not depend on the case of characters, so for **DwScript** `getRow`, `GetRow`, `GETROW` are identifiers of the same function object. Use the syntax that suits you best.

### Supported operators

| Type          | Values|
|---------------| --- |
| _Arithmetic_  | +, -, *, /, **, % |
| _Relational_  | ==, ===, !=, !==, >, >=, <, <=, &&, \|\|, in, ?? |
| _Bitwise_     | &, \|, ^, >>>, >>, <<  |
| _Unary_       | !, -, +, ~, typeof, void |
| _Conditional_ | (...) ? _ : _ |
| _Identifiers_ | Model properties, functions |
| _Literals_    | string, numeric, // (RegExp), _true_, _false_, _null_, _undefined_ |
| _Structures_  | Arrays, Objects |

### Pre-defined functions

The following table contains the names and descriptions of DataStore/DataWindow pre-defined expression functions, that is divided by categories. The default value of the function parameter (if any) is designated as: `parameter_name=...`

#### _General functions_
|Function | Returns |Description   |
| ---     | ---     | ---          |
|Between(v, b, e)| boolean | Tests whether a value `v` is between `b` and `e`|
|Fork(v, m, d=null)   | any     | Returns a key value of the map object `m` if it contains a key `v`, otherwise `d`|
|IfNull(v, d)    | any     | Returns `d` value if `v` is _null_, else `v` |
|IIF(b, t, f)    | any     | Returns `t` if the `b` is truthy, else `f` |
|InList(v, ...a[]) | boolean | Returns _true_ if the `v` is in the list `a`, else _false_ | 
|IsNull(v)       | boolean | Returns _true_ if the `v` is _null_, else _false_ |
|IsNumber(v)     | boolean | Returns _true_ if the `v` is a number, else _false_ |
|NullIf(v, c)    | any     | Returns _null_ if the `v` equals to `c`, else `v` |
|String(v)       | string  | Converts `v` to string. |

#### _String functions_
|Function | Returns | Description                                                                                                              |
| ---     | ---     |--------------------------------------------------------------------------------------------------------------------------|
|Asc(s)  | number | Converts the first character of a string `s` to its `Unicode` code point                                                 |
|Char(n) | char | Converts an integer to a Unicode character                                                                               |
|CharAt(s, n)| char | Returns character of the string `s` at position `n`                                                                      |
|Dec(s)  | Decimal | Converts the value of a string to a decimal                                                                              |
|Decode(s, f=Base64) | string | Returns the result of decoding a string `s` in the format `f`                                                            |
|Encode(s, f=Base64) | string | Returns the result of encoding a string `s` in the format `f`                                                            |
|EndsWith(s, e) | boolean | Checks if a string `s` is ended on `e`                                                                                   |
|Fill(s, n) | string | Builds a string of the specified length `n` by repeating the specified characters until the result string is long enough |
|Format(s, ...a[]) | string | Replaces the format item in a specified template `s` with the text equivalent of the value in arguments array `a`        |
|Hex(n)| string | Converts number `n` to hexadecimal string                                                                                |
|Integer(s) | number | Converts string `s` to integer                                                                                           |
|IsDate(s)  | boolean| Tests whether a string value is a valid date                                                                             |
|IsNumber(s)| boolean| Reports whether the value of a string is a number                                                                        |
|LastToken(s, d)| string | Gets the last token of string `s` delimited by `d`                                                                       |
|Len(s) | number | Returns length of the string `s`                                                                                         |
|Like(s, p) | boolean | Tests the string `s` against the pattern `p`, similar to the SQL LIKE function does                                      |
|Left(s, n)| string | Obtains a specified number of characters from the beginning of a string                                                  |
|LeftTrim(s, c=spaces)| string | Removes spaces from the beginning of a string                                                                            |
|Long(s) | Long | Converts the value of a string `s` to a Long data type                                                                   |
|Lower(s)| string | Converts all the characters in a string to lowercase                                                                     |
|Match(s, p)| boolean | Determines whether a string's value contains a particular _RegExp_ pattern of characters                                 |
|Mid(s, f, n=all) | string | Obtains a specified number `n` of characters from a specified position `f` in a string                                   |
|Number(s)| number | Converts a string `s` to a number                                                                                        |
|PadLeft(s, n, p=space)| string | Pads the left side of the string `s` by character `p` up the length `n`                                                  |
|PadRight(s, n, p=space)| string | Pads the right side of the string `s` by character `p` up the length `n`                                                 |
|Pos(s1, s2, n=0)| number | Finds one string within another string                                                                                   |
|PosR(s1, s2, n=last)| number | Finds one string within another string starting from the end                                                             |
|Real(s) | Real | Converts a string value to a Real datatype                                                                               |
|Repeat(s, n)| string | Repeats the string `n` times                                                                                             |
|Replace(s, t, r)| string | Replaces a portion of one string with another                                                                            |
|Right(s, n)| string | Obtains a specified number of characters from the end of a string                                                        |
|RightTrim(s, c=spaces)| string | Removes spaces from the end of a string                                                                                  |
|Space(n=1) | string | Builds a string of the specified length whose value consists of spaces                                                   |
|StartsWith(s, w)| boolean | Checks if a string `s` is started with `w` string                                                                        |
|Substr(s, f, e)| string | Gets the substring of `s` starting from `f` position and ending on `e` excluding                                         |
|Token(s, d) | string | Gets the first part of the string `s` delimited by `d`                                                                   |
|Trim(s) | string | Removes leading and trailing spaces from a string                                                                        |
|TrimEnd(s) | string | Removes spaces from the end of a string                                                                                  |
|TrimStart(s) | string | Removes spaces from the beginning of a string                                                                            |
|Upper(s) | string | Converts all characters in a string to uppercase letters                                                                 |
|WordCap(s) | string | Sets the first letter of each word in a string to a capital letter and all other letters to lowercase                    |

#### _Date/Time functions_
| Function   | Returns | Description |
| ---        | ---     | ---         |
|Date(v=now)     | Date    | Converts `v` to _Date_ data type |
|DateTime(v=now) | DateTime| Converts `v` to _DateTime_ data type|
|Day(d=now)      | number  | Obtains the day of the month in a date value|
|DayName(d=now)  | string  | Gets the day of the week in a date value and returns the weekday's name |
|DayNumber(d=now)| number  | Gets the day of the week of a date value and returns the number of the weekday| 
|DaysAfter(d1,d2)| number |Gets the number of days one date occurs after another|
|Hour(d=now)     | number   |Obtains the hour in a time value. The hour is based on a 24-hour clock.|
|Hours(d=now)    | number   |Obtains the hour in a time value. The hour is based on a 24-hour clock. (The same as `Hour`)|
|MilliSeconds(d=now) | number |Obtains the number of milliseconds in the date value|
|Minutes(d=now)  | number| Obtains the number of minutes in the date value|
|Month(d=now)    | number | Gets the month of a date value |
|Now()       | Date   | Obtains the current time based on the system time of the client machine |
|RelativeDate(d, n) | Date | Obtains the date that occurs a specified number of days `n` after or before another date |
|RelativeTime(d, s) | Date | Obtains a time that occurs a specified number of seconds `s` after or before another time within a 24-hour period |
|Seconds(d=now)| number | Gets the seconds of a Date object `d`, using local time |
|SecondsAfter(d1,d2)| number | Gets the number of seconds one time occurs after another |
|Time(s)     | Time   | Converts a string to a _Time_ datatype |
|Today()     | Date   | Obtains the system date and time |
|TzOffset()  | number | Gets the difference in minutes between the time on the local computer and Universal Coordinated Time (UTC) |
|WeekDay(d=now)| number | Gets the day of the week, using local time |
|YMD(y,m=0,d=1)| Date   | Gets the Date object from numbers of `y`ear, `m`onth and `d`ay|
|Year(d=now) | number | Gets the year of a date value |

#### _Numeric functions_
| Function | Returns | Description |
| ---      | ---     | ---         |
|Abs(n)| number | Calculates the absolute value of a number |
|Atan(n)| number | Calculates the arc tangent of an angle |
|Ceil(n)| number | Retrieves the smallest whole number that is greater than or equal to a specified limit |
|Cos(n)| number | Calculates the cosine of an angle |
|Exp(n)| number | Raises e to the specified power|
|Floor(n)| number | Returns the greatest integer less than or equal to its numeric argument.|
|Greater(...n[])| number | Returns the larger of a set of supplied numeric expressions|
|Int(n)| number | Gets the largest whole number less than or equal to a number |
|Lesser(...n[])| number | Returns the smaller of a set of supplied numeric expressions|
|Log(n)| number | Gets the natural logarithm of a number|
|PI(n=1)| number | This is the ratio of the circumference of a circle to its diameter|
|Rand(n=1)| number| Returns a pseudorandom number between 0 and 1|
|Round(n, d=0)| number | Rounds a number to the specified number of decimal places|
|Sign(n)| number | Reports whether the number is negative, zero, or positive by checking its sign|
|Sin(n)| number |Calculates the sine of an angle|
|Sqrt(n)| number | Calculates the square root of a number|
|Tan(n)| number | Calculates the tangent of an angle|
|Truncate(n, d=0)| number | Truncates a number to the specified number of decimal places|

#### _DataWindow specific functions_
| Function | Returns | Description |
| ---      | ---     | ---         |
|Avg(x, r={range:"all"}) | number | Calculates the average of the values of the column or expression `x` in the specified range `r` of data |
|Count(x, r={range:"all"}) | number | Calculates the total number of rows in the specified column or expression `x` in the specified range `r` of data|
|CumulativePercent(x, r={range:"all"}) | number | Calculates the total value of the rows up to and including the current row in the specified column as a percentage of the total value of the column/expression `x` (a running percentage) in the specified range `r` of data|
|CumulativeSum(x, r={range:"all"}) | number | Calculates the total value of the rows up to and including the current row in the specified column/expression `x` (a running total) in the specified range `r` of data|
|CurrentRow()| number | Reports the number of the current row (the row with focus)|
|Describe(...s[])| string[] | Reports the values of properties of a DataWindow object and controls within the object|
|First(x, r={range:"all"}) | any | Reports the value in the first row in the specified column/expression `x` in the specified range `r` of data|
|GetRow()| number | Reports the number of a row associated with a band in a DataWindow object|
|IsRowModified()| boolean | Reports whether the row has been modified|
|IsRowNew()| boolean| Reports whether the row has been newly inserted|
|IsSelected()| boolean | Determines whether the row is selected|
|Last(x, r={range:"all"}) | any | Gets the value in the last row in the specified column/expression `x` in the specified range `r` of data|
|LookupDisplay(c,v)| string| Obtains the display value in the code table associated with the data value in the specified column|
|Max(x, r={range:"all"}) | number | Gets the maximum value in the specified column/expression `x` in the specified range `r` of data |
|Min(x, r={range:"all"}) | number | Gets the minimum value in the specified column/expression `x` in the specified range `r` of data |
|Percent(x, r={range:"all"}) | number | Gets the percentage that the current value represents of the total of the values in the column/expression `x` in the specified range `r` of data|
|RowCount()| number | Obtains the number of rows that are currently available in the primary buffer |
|StDev(x, r={range:"all"})| number | Calculates an estimate of the standard deviation for the specified column/expression `x` in the specified range `r` of data |
|StDevP(x, r={range:"all"})| number | Calculates the standard deviation for the specified column/expression `x` in the specified range `r` of data |
|Sum(x, r={range:"all"}) | number | Calculates the sum of the values in the specified column/expression `x` in the specified range `r` of data|
|VarE(x, r={range:"all"})| number | Calculates an estimate of the variance for the specified column/expression `x` in the specified range `r` of data |
|VarP(x, r={range:"all"})| number | Calculates the variance for the specified column/expression `x` in the specified range `r` of data |


> All aggregate functions of the DataStore/DataWindow ignore _null_ values while processing the result of an expression
