# Gentee script programming language

Gentee programming language documentation

Gentee is a strongly typed procedural language. First of all, it is designed to write scripts to automate repetitive actions and processes on the computer. The Gentee language has a simple syntax and it is easy to learn and maintain.

**GitHub repository:** [**https://github.com/gentee/gentee**](https://github.com/gentee/gentee)\
**Download for Linux, macOS, Windows:** [**https://github.com/gentee/gentee/releases**](https://github.com/gentee/gentee/releases)\
Documentation GitHub repository: <https://github.com/gentee/docs-gentee>\
Development language: Go

```go
run : ||"Hello, world!\r\n"
```

```go
run : $ echo "Hello, world!"
```

```go
run {
    str name = ReadString(`Enter your name: `)
    Println(`Hello, %{ ?(*name>0, name, `world`) }!` )
}
```

Want to see a sample application that successfully uses the Gentee programming language? Take a look at [**Eonza**](https://www.eonza.org/), a free cross-platform program for easy creation and management of scripts.

## Documentation

* [Gentee Programming language (English)](https://docs.gentee.org)
* [Язык программирования Gentee (Russian)](https://ru.gentee.org)


# Language Reference


# Lexical elements

Source code is UTF-8 encoded. The syntax is specified using Extended Backus-Naur Form.

```go
newline        = 0x0A
unicode_char = /* Unicode code point */
unicode_linechar  = /* Unicode code point except newline */
unicode_letter = /* a Unicode code point classified as "Letter" */
letter        = unicode_letter | "_"
decimal_digit = "0" … "9" 
octal_digit   = "0" … "7" 
hex_digit     = "0" … "9" | "A" … "F" | "a" … "f" 
decimals  = decimal_digit { decimal_digit }
exponent  = ( "e" | "E" ) [ "+" | "-" ] decimals
```

## Comments and character substitution

There are the following types of comments and automatically substitution characters.

`// Single-line comment is here`\
This single-line comment starts with the character sequence `//` and stops at the end of the line.

`/* General comment is here */`\
General comments can appear anywhere. Such comment begins with a forward slash/asterisk combination / *and is terminated by “end comment” delimiter* /.

`# header`\
At the beginning of the script, you can specify the parameters for use in other programs. Such comments should must be listed one after the other in each line from the beginning of the script. If you do not want to specify '#' at the beginning of each line, then insert **###** before and after the text.

```go
#!/usr/local/bin/gentee
# the first line can be used to run the script on Linux.
###
  desc = Description of the script
  result = ok
  var = value
###
```

**;**\
The new line character is the separating character between expressions and statements. A semicolon is replaced with a new line character. So, you can use semicolons if you want to put several statements on one line.

**:**\
A colon is replaced with an opening curly brace and a closing curly brace is added at the end of the current line.

```go
// These examples are equivalent
if a == 10 : a = b + c; c = d + e 

if a == 10 
{
   a = b + c
   c = d + e
}
```

## Identifiers

Identifiers are names that are used to refer to variables, types, functions, constants etc. An identifier is a sequence of letters and digits. The first character of the identifier must be a letter.

```go
identifier = letter { letter | unicode_digit }
IdentifierList = identifier { identifier }
```

There are some predeclared identifiers and keywords. The following words are reserved and may not be used as identifiers.

### Keywords

**catch const elif else false for func go if in local recover retry return run struct true try while**

## Literals

An integer literal is a sequence of digits representing an integer constant.

```go
decimal = ( "1" … "9" ) { decimal_digit } 
octal = "0" { octal_digit } .
hex = "0" ( "x" | "X" ) hex_digit { hex_digit } 
integer = decimal | octal | hex
float = decimals "." [ decimals ] [ exponent ] | decimals exponent
```

```go
0x34Fab
0722
19023862
0.123e+3
234.e-2
9.7732E-1
0.0177E+2
5e-2
```

A *char* literal represents an integer value identifying a Unicode code point. You can specify one character or a sequence of characters beginning with a backslash enclosed in single quotes. Multi-character sequences can be like these:

```go
'\r',  '\n',  '\t', '\"', '\'', '\\' 
\xa5 \x2B  (\x + two hex_digit)
\u03B1  (\u + four hex_digit)
\0371  (\0 + three octal_digit)
```

```go
byteVal  = octalStr | hexStr .
octalStr = `\` "0" octal_digit octal_digit octal_digit .
hexStr   = `\` "x" hex_digit hex_digit .
uShort   = `\` "u" hex_digit hex_digit hex_digit hex_digit .
uLong    = `\` "U" hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit .
escapedChar     = `\` ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | `\` | `"` ) 
charLit         = "'" ( unicode_char | uShort | uLong | escapedChar | byteVal | `\'`) "'" .
```

There are two types of string literals. 1. A string in backquotes can contain any characters. If you want to specify a backquote, then you need to double it. 2. A double-quoted string can also contain any characters (including a line break), but it has a backslash control character. You can specify the following characters after a backslash:

```go
\a   U+0007 alert or bell  
\b   U+0008 backspace  
\f   U+000C form feed  
\n   U+000A newline  
\r   U+000D carriage return  
\t   U+0009 horizontal tab  
\v   U+000b vertical tab  
\\   U+005c backslash  
\"   U+0022 double quote
```

```go
stringLit         = stringBackQuote | stringDoubleQuote
stringBackQuote   = "`" { unicode_char | "%{" Expression "}" | "${" identifier "}" } "`"
stringDoubleQuote = `"` { unicode_char | uShort | uLong | escapedChar | byteVal | "\{" Expression "}" } `"`
```

You can insert expressions into any type of string. In this case, the result type of expression can be any, if there is a corresponding function that can convert this value to a string. Expressions must be enclosed in curly brackets with the preceding **%** sign (for backquotes) or a backslash (for double quotes).

```go
`10+20 equals %{10 + 20}. User name is "%{USERNAME}"`
"This is the first line.\r\nThis is \{ `the` + `second`} line."
```


# Types

## Type declaration

A type determines a set of values that have the same operations and functions specific for those values. A type is denoted by a type name. A map is a group of elements of one type, indexed by a set of unique string keys. By default, *arr* and *map* arrays consist of strings, but you can specify any nested types by separating them with a dot. Note that variables of types **arr**, **map**, **buf**, **set**, **obj** and types that has been defined with **struct**, unlike other types, are passed by reference, not by value. This means that if you change the value of this parameter inside the function, you will change the original variable.

```go
TypeName  = identifier { "." identifier }
```

The Gentee language predeclares the following types.

**arr bool buf char error finfo float handle int map obj range set str time trace thread**

| Name       | Description         | Values                                      | Initial value                      |
| ---------- | ------------------- | ------------------------------------------- | ---------------------------------- |
| **int**    | 64-bit integer type | -9223372036854775808 .. 9223372036854775807 | 0                                  |
| **float**  | 64-bit double       | 2.22 E–308 ..    1.79 E+308                 | 0.0                                |
| **bool**   | boolean type        | *true* or *false*                           | false                              |
| **str**    | string              | a sequence of bytes                         | empty string                       |
| **char**   | Unicode character   | Unicode code point int32                    | space                              |
| **arr**    | array               | array of elements                           | empty array of strings             |
| **map**    | associative array   | associative array of elements               | empty associative array of strings |
| **buf**    | array of bytes      | array of uint8                              | empty array                        |
| **set**    | set of bool         | array of uint64 with 1 bit per value        | empty set                          |
| **obj**    | object              | int, bool, float, str, arr.obj, map.obj     | nil                                |
| **handle** | hidden type         | any Golang type                             | nil                                |

The **handle** type is used to pass values between built-in Golang functions. A variable of this type can contain a value of any Golang type. Go functions should keep track of the types of received values, which are described as *handle* in Gentee.

```go
arr.map.int a
map.arr.str b   // the same as map.arr b
map.bool c
arr.int  d
```

## Type casting

There is no automatic type casting in Gentee . For basic types, there are functions for converting from one type to another, their names are the same as the name of the resulting type.

|       | int       | bool       | str             | char     | float      |
| ----- | --------- | ---------- | --------------- | -------- | ---------- |
| int   |           | int(false) | int("-23")      | int('A') | int(3.24)  |
| bool  | bool(1)   |            | bool("0")       |          | bool(1.1)  |
| str   | str(20)   | str(false) |                 | str('z') | str(5.662) |
| char  |           |            |                 |          |            |
| float | float(10) |            | float("-2E-34") |          |            |

```go
int(false) // = 0           
int(true) // = 1    
bool(0) // = false  
bool(0.) // = false  
bool(integer except zero) // = true    
bool("")  bool("0") bool("false") //=false
bool("not empty, zero or false string")   //=true
```

## Type definition

You can define a structure type by using the **struct** keyword. Specify a type name after the keyword, and list the field types and names inside the curly braces. All fields in a variable of a structured type are automatically initialized. All variables of these types are passed by reference, rather than by value, when passed to functions. To assign or get a field value, specify its name after the dot.

```go
structDecl = "struct" identifier "{" FieldDecl { newline  FieldDecl } "}"
FieldDecl = TypeName identifier
FieldExpr = PrimaryExpr "." identifier
```

```go
struct my : int ID; str name
struct myStruct {
      int ID
      my myval
      arr st_arr
      map.int st_map
}
run int {
    myStruct ms
    ms.ID = 20
    return ms.ID * 2
}
```

## Function type

The Gentee language allows you to work with function identifiers. You can get the ID of the function, pass it as a parameter and call the corresponding function. To work with function identifiers, you must define a function type using the **fn** keyword and specify the types of parameters and return value. To get the function ID, specify **\&function\_name.fn\_type**. The function identifier can be passed in parameters or assigned to a variable of the corresponding *fn* type. To call a function by its identifier, it is sufficient to specify the variable name and parentheses with parameters, as when calling a function by name.

The function identifier does not apply to the following functions:

* Built-in functions.
* Functions with a variable number of parameters.
* Functions with optional variables.

```go
fnDecl = "fn" FnName [FnParameters] [ TypeName ]
FnName = identifier
FnParameters     = "(" [ FnParameterList ] ")"
FnParameterList  = TypeName { [","] TypeName }
FnIdent = "&" FuncName "." FnName
```

```go
fn bin( int int ) int
func add( int i, int j ) int : return i + j
func sub( int i, int j ) int : return i - j
func mybin(int i j, bin f ) int : return j + f(i, j)

run int {
  bin isub = &sub.bin
  return mybin(1, 2, &add.bin) + mybin(3, 7, isub)
}
```


# Declarations

### Constant declarations

The constant name can not contain lowercase letters. Constants can be assigned to any expressions. The value of the constant is computed when the constant is first accessed, but the type of the constant is automatically determined at the compilation stage by the type of the assigned expression. Therefore, despite the fact that the type is not specified when defining a constant, type checking is in effect when a constant is used.

```
ConstDecl      = "const" ( ConstIota | ConstExp )
ConstIota = Expression "{" { IdentifierList newline } "}"
ConstExp = "{" { identifier "=" Expression newline } "}"
```

Constants can be defined in two ways.

1. Specifying an initial value or an expression for each constant.

   ```
   const {
    MY_ID = 1
    MY_VAL = myFunc( MY_ID + 23)
    CHECK= MY_VAL < 32
   }
   ```
2. Using a common expression with **IOTA**.  Sometimes it is necessary to define a list of constants with values that are computed according to certain rules. In this case, after the **const** keyword, you need to specify one common expression that will be calculated for each constant in this definition. In this expression, you can use the special variable *IOTA*, which is equal to the ordinal index of the constant in the list, starting at zero. Constants should be separated by a space or a new line.

```
const 0x1 << IOTA {
      FIRST SECOND   // 0x1    0x2
      THIRD                   // 0x4
}
const (IOTA * 2) + 1 {
      MY1    // 1
      MY2   // 3
      MY3   // 5
}
```

### Function declarations

The function declaration consists of two parts - a description of the parameters with the return type and the function body. When you define a function, you must specify the keyword "func", the function name, the parameters to be passed, and the type of the return value. Only the function name is required.

```
FunctionDecl   = "func" FunctionName [Parameters] [ Result ] Block
FunctionName   = identifier 
Result         = TypeName 
Parameters     = "(" [ ParameterList ] ["..."] ")"
ParameterList  = VarList { "," VarList }
```

```
func VariadicExample(int i, int s...) int {
    int sum = i*2
    for v in s {
       sum += v
    }
    return sum
}
func MyFunc(int par1 par2) int { 
    int par3 = VariadicExample(3, par1, par2, 4, 5, par1+par2)
    return (par1+par2 +par3)/3 
}
```

The final incoming parameter in a function signature may have a *'...'* suffix. A function with such a parameter is called *variadic* function and may be invoked with zero or more arguments for that parameter. You get this parameter as an array of arguments. For example, *int pars...* means that *pars* is really *arr.int* and you can get the i-th argument with *pars\[i]*.

### Run declaration

The Gentee script must contain a special function without parameters, which is defined using the keyword "run". The script starts by calling this function. The script must have only one definition of "run".

```
RunDecl = "run" [FunctionName] [ Result ] Block
```

```
run int {
    int i ret
    while i < 10 {
       ret += myFunc(i++)
    }
    return ret
}
```


# Statements

A block is a sequence of declarations and statements within curly braces. Blocks can be nested into each other.

```
Block = "{" StatementList "}" .
StatementList = { Statement newline } .
Statement = ReturnStmt | IfStmt | Expression | WhileStmt | VarDeclaration | ForStmt | 
            LocalDecl | BreakStmt | ContinueStmt | SwitchStmt | GoStmt | TryStmt | 
            RecoverStmt | RetryStmt
```

### Variable declarations

Any function variable must be described before it can be used. A variable declaration creates one or more variables and assign to each an initial value. A variable can be defined in any block. The scope of the variable extends to the block in which it is defined and to all nested blocks. You cannot create variables with the name of existing functions and "visible" variables. Also, the variable name must contain at least one lowercase letter, because uppercase names are used for constants. A variable declaration begins by specifying its type. There are two types of initialization - you can define a single variable with a value assigned to it or several variables of the same type with default initialization.

```
VarDeclaration = VarAssign | VarList
VarList = TypeName ["?"] IdentifierList
VarAssign = TypeName ["?"] identifier "=" | "&=" VarInit
```

```
int x y myVal
int z = myFunc(x) + y + 10
arr a &= b
```

You can define the **optional parameters-variables** by specifying **?** after the variable type. If you initialize the optional parameter using the assignment operator **=** or **&=**, it will be the default value if the parameter is not defined when the function is called.\
In order to pass an optional parameter when calling the function, it is necessary to specify the variable name and its value separated by a colon. Optional parameters are specified after the obligatory parameters.

```
func mul(int i) int {
      int ? j = 10
      return i*j
}

run int {
      return mul(7) + mul(5, j: 5)  // 70+25
}
```

### If statement

The **"if"** statements begin with "if", they can have one or more "elif" blocks and end with "else". The statement sequentially evaluates the condition for each branch and if the condition is true, then the corresponding block executes. In this case, the remaining branches are skipped, the statement ends and the control is passed to the next command. If all branch conditions are false, then, if present, the "else" branch is executed.

```
IfStmt = "if" Expression Block [{ "elif" Expression Block }][ "else" Block ]
```

```
if a == 11 {
    b = 20
} else {
    c = a+b
}
if x > y && isOK { 
     x = 1 
} elif a > 1 {
   x++
} elif b < 10 {
    b = a
} else {x = 0}
```

### While statement

The **"while"** statement is a simple loop. It specifies the repeated execution of a block as long as a boolean condition evaluates to true. If the condition is false the first time through the loop, the statements inside the loop are never executed.

```
WhileStmt = "while" Expression Block
```

```
a = 0
while a < 5 {
   с += a
   a++
}
```

### For statement

The **"for"** statement is used to iterate through all the elements of the specified object. The object must be of a type that supports indexing such as **arr**, **map**, **str**, **buf**, **set**, **range of integers**. For each entry **for** assigns iteration values to corresponding iteration variables if present and then executes the block. You must specify the name of the variable for iteration values and, optionally, the name of the variable for the index value.\
If you want to iterate through a range of integer numbers, use the syntax **from..to** as the object, where *from* and *to* are values of the integer type. This will iterate through all the numbers between *from* and *to*, including the extreme values. The initial value can be greater than the final value, in this case, the iteration value will be decreased.

```
ForStmt = "for" identifier [, identifier] "in" Expression Block
```

```
str dest
for ch, i in `strΔ` {
   dest += "\{i}\{ch}"
}
int sum
for i in 0..100 : sum += i
```

### Switch statement

The **"switch"** statement allows you to perform different operations in case an expression has different values. The **switch** keyword is followed by the initial expression that is calculated and stored as the switch value. The switch value can be of type **int, float, char, str**. Then you enumerate **case** statement in curly braces with all possible values and the source code that should be executed. One case can have several possible values separated with a comma in case of which it will be executed. After executing the case block with the matching value, the program goes to the statement coming after switch. The rest of case blocks are not checked.

If you want to execute some operations in case none of the case blocks is executed, insert the **default** construction at the end of switch. The default statement can appear only once and should come after all case statements.

```
SwitchStmt = "switch" Expression newline CaseStmt { CaseStmt } [ "default" Block ]
CaseStmt = "case" Expression {, Expression } Block
```

```
int i = 67
int j
switch i+3 
case 20,10,5 {
  i +=10
}
case j,20+50,80 {
  i -=10
}
default: i *= 2
```

### Local functions

You can define the **local** functions within the **func** functions. Local functions can accept parameters and return values. Local functions do not support a variable number of arguments. To return from a local function, you must use the **return** statement. In local functions, you can access external variables and parameters that have been defined above.

```
LocalDecl   = "local" FunctionName [Parameters] [ Result ] Block
```

```
run int {
    int i
    local loc(int step) int {
          return (i += 2)+step
    }
    return loc(1) + loc(2)*loc(3)
} 
// result: 57
```

### Return statement

A "return" statement terminates the execution of the current function, and optionally provides a result value. If a function doesn't have a result type, a "return" statement must not specify any result value. You can use "return" statement in any nested block.

```
ReturnStmt = "return" [ Expression ]
```

```
func mul2(int i) int { return i*2}
```

### Break statement

The **"break"** statement terminates **switch/case** statement or the execution of the loop (**for** and **while**). **break** is likely to be located within nested blocks. If a program contains several nested loops, break will exit the current loop.

```
BreakStmt = "break"
```

```
while b > c {
   if !myfunc( b ) {
      break   
   }
   b++
}
```

### Continue statements

The "continue" statement may occur within loops (**for** and **while**) and attempts to transfer control to the loop expression, which is used to increment or decrement the counter (for *for* or to the conditional expression for *while*; moreover, the execution of the loop body is not completely executed. The instruction executes only the most tightly enclosing loop, if this loop is nested.

```
ContinueStmt = "continue"
```

```
for i in 0..100 {
   if i > 10 && i < 20 {
      continue 
   }
   a += i // The given expression is not evaluated if i>10 and i<20
}
```

##


# Error handling

### Try catch statement

By default, if an error was received at the time of the script execution, the script immediately finishes its work. If you want to avoid the termination of the script, you should use the **try** statement. If an error occurs during the execution of the code inside the *try* block, the control will pass to the **catch** block, which must be after **try**. After the *catch* keyword, it is necessary to specify the name of the variable of *error* type, which will contain information about the error. You can use \[special functions] (<https://gentee.github.io/stdlib/runtime#erriderror-err-int>) to get the identifier and error text. If you do not remove the error inside *catch* with **recover** or **retry**, it will be passed on and the script will finish its work.

```
TryStmt ="try" Block CatchStmt
CatchStmt = "catch" identifier Block
```

```
run  {
   try {
      myfunc()
      error(101, "Custom error")
   }
   catch err {
      if ErrID(err) != 101:  error( 102, "Error \{ErrText(err)} has occurred in myfunc()")
   } 
}
```

### Recover statement

The **recover** statement is used inside a **catch** block to remove the error. This command removes the error information, the script exits the current *catch* block and continues execution.

```
RecoverStmt = "recover"
```

```
run str {
   try : 10/0
   catch err :  recover
   return "ok"
} 
// ok
```

### Retry statement

The **retry** statement is used inside a **catch** block to restart **try**. This command removes the error information and the script re-executes the corresponding *try* block.

```
RetryStmt = "retry"
```

```
run {
   str fname
   try {
       fname = ReadString("Specify filename: ")
       Println("Beginning of the file: ", str(ReadFile(fname, 0, 50)))
    } catch err {
       Println("ERROR #\{ErrID(err)}: \{ErrText(err)}")
       retry
    }
}
```

##


# Expressions

The expression returns a value by applying operators and functions to operands. An operand may be a literal, an identifier denoting a constant, variable, or function, or a parenthesized expression. To call a function, specify its name and list the parameters in parentheses separated by comma. Parameters can also be expressions. In addition, you can set the first parameter before the function and separate it by a dot. This helps to more clearly indicate the sequence of function calls.

```go
(b*c).func3(d).func2(a).func1(10)
"my string".Upper().TrimRight("g")
// the same as
func1(func2(func3( b*c, d ), a), 10)
TrimRight(Upper("my string"), "g")
```

```
Operand     = Literal | OperandName | "(" Expression ")" | GoStmt
Literal     = BasicLiteral
constLit    = "true" | "false"
BasicLiteral    = float | integer | stringLit | constLit | charLit
OperandName = identifier | EnvVariable | FnIdent
PrimaryExpr = Operand | FuncName Arguments | Expression "." FuncName Arguments | IfOp | 
              IndexExp | FieldExpr
OptionalArgs = identifier ":" Expression { "," identifier ":" Expression }
Arguments    = "(" [ ExpressionList ] [ OptionalArgs ] ")" 
ExpressionList = Expression { "," Expression } 
Expression = UnaryExpr | Expression binaryOp Expression | OperandName assignOp Expression
UnaryExpr  = PrimaryExpr | unaryOp UnaryExpr | incOp OperandName | OperandName incOp | 
             UnaryExpr postunaryOp
binaryOp  = "||" | "&&" | relOp | mathOp | assignOp | rangeOp
relOp     = "==" | "!=" | "<" | "<=" | ">" | ">=" 
mathOp     = "+" | "-" | "|" | "^" | "*" | "/" | "%" | "<<" | ">>" | "&" | 
unaryOp   = "-" | "!" | "^" | "*" | "#" | "##"
postunaryOp = "?"
incOp = "++" | "--" 
rangeOp = ".."
assignOp = "=" | "+=" | "-=" | "|=" | "^=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | "&=" | "#="
IfOp = "?" "(" Expression "," Expression "," Expression ")"
```

When calculating the logical operators "&&" (AND) and "||" (OR), the right operand is evaluated optionally. For example, in the cases of `false && myFunc()` and `true || myFunc ()`, the myFunc function will not be called.

Assignment operators are binary operators that return an assigned value. Therefore, assignment operators can be used within expressions.

```go
int i j k
i = j = 5+(k=60/5)*2
return (k+j)*2 + i   // 111
```

## Operator precedence

As a rule, all statements are executed from left to right, but there is such a concept as statement priority. If the next statement has a higher priority, the statement with a higher priority is executed first. For example, multiplication has a higher priority and 4 + 5 *2 is 14, but if we use parentheses, ( 4 + 5 )* 2 is 18.

| Operator                                                | Type          | Associativity |
| ------------------------------------------------------- | ------------- | ------------- |
| The highest priority                                    |               |               |
| (   )  \[   ]                                           |               | Left to right |
| -   ^   #   ##   \*   ++   --                           | Unary prefix  | Right to left |
| ?                                                       | Unary postfix | Right to left |
| !                                                       | Unary prefix  | Right to left |
| ++   --                                                 | Unary postfix | Left to right |
| /   %   \*                                              | Binary        | Left to right |
| +   -                                                   | Binary        | Left to right |
| <<   >>                                                 | Binary        | Left to right |
| &                                                       | Binary        | Left to right |
| ^                                                       | Binary        | Left to right |
| \|                                                      | Binary        | Left to right |
| ==   !=   <   <=   >   >=                               | Binary        | Left to right |
| \|\|                                                    | Binary        | Left to right |
| &&                                                      | Binary        | Left to right |
| #=                                                      | Binary        | Left to right |
| =   +=   -=   \*=   /=   %=   <<=   >>=   &=   ^=   \|= | Binary        | Right to left |
| ..                                                      | Binary        | Left to right |
| The lowest priority                                     |               |               |

Parentheses () change the order in which expressions are evaluated. Increment operations ++ and -- can be occurred either in the prefix or in the postfix notation.

## Conditional operator "?"

Conditional operator "?" is similar in its work to the "if" statement, but can be used inside an expression. The conditional operator has three operand expressions. The operands are enclosed in parentheses and separated by commas, at the beginning the value of the first logical expression is evaluated. If the value is true, the second expression is evaluated and the resulting value is the result of the conditional operator. Otherwise, the third operand is evaluated and its value is returned.

```go
if a >= ?( x, 0xFFF, ?( y < 5 && y > 2, y, 2*b )) + 2345
{
     r = ?( a == 10, a, a + b ) 
}
```

## Arrays and structures initialization

When defining variables of the type *arr*, *set*, *buf* or *map*, you can immediately assign array elements. You can also specify the field values of structural type variables. Values are listed separated by commas or line breaks. You can specify expressions as a value. When initializing an associative array *map*, you must specify the key as a string and the value after a colon. If the elements of the array are other arrays, they are also initialized using braces. When initializing structure fields, you must specify the key as an identifier and a colon-separated value. A variable of **buf** type can be initialized by a combination of the values of the **int**, **str**, **char**, **buf** types.

```
DelimInit = "," | newline
ArrInit = "{" VarInit {DelimInit VarInit} "}"
BufInit = "{" Expression {DelimInit Expression} "}"
MapInit = "{" Expression ":" VarInit { DelimInit Expression ":" VarInit  }  "}"
SetInit = "{" Expression {DelimInit Expression} "}"
StructInit = "{" identifier ":" VarInit { DelimInit identifier ":" VarInit  }  "}"
VarInit = ArrInit | BufInit | MapInit | StructInit | SetInit | Expression
```

```go
mystruct my = {ID: 20, name: "some text"}
buf a = {250+5, '1', 'A', "test", 0}
map.arr.int ret = {"key1": {0, 1 }, `key2`:{ 2, 3 } }
arr.map ret = { {"test": "value 1"}
                {`next`:"value 2"} }
arr.bool mb = : true, false, true
map  my = {"key1": GetVal(1), "key2": GetVal(2)}
set s &= {1, 0, 45, myintval, MYCONST}
```

## Index Expression

Indexing allows you to get or set a specific element of a variable by its index. The index is a position of some element inside of the specified variable. Gentee has zero-based indexing (excepting **map**), meaning that the first element has the index zero, the second element has the index one, etc. The following types support indexing:

* **str**. The index must be of the **int** type and less than the length of the string. If the index is out of range, a run-time error occurs. The type of the result is **char**.
* **buf**. The index must be of the **int** type and less than the length of the array. If the index is out of range, a run-time error occurs. The type of the result is **int** but 0 <= result value <= 255.
* **arr**. The index must be of the **int** type and less than the length of the array. If the index is out of range, a run-time error occurs. The type of the result is the same as the type of array's elements.
* **map**. The index must be of the **string** type. If a value is obtained, the map must have the element with this key. If there is not the such index, a run-time error occurs. The type of the result is the same as the type of map's elements.
* **set**. The index must be of the **int** type and less than 64000000. If the index is out of range, a run-time error occurs. The type of the result is the boolean value.

If *array* or *map* consists of arrays, then you can sequentially apply the index expression.

```
IndexExp = PrimaryExpr "[" Expression "]" { "[" Expression "]" }
```

```go
str temp = `0123`
temp[1] = temp[3]  // result `0323`
arr ain
ain += `test`
temp = ain[0]
map mymap
mymap["mykey"] = "myvalue"
arr.map amap
amap += mymap
amap[0]["mykey"] = "new value"
```

## Assignment Expressions

There is an assignment operator **=** for all types in the Gentee language. When you use assignment for **buf, arr, map, set**, and all structure types, you will get copies of the data. Consider an example

```go
arr a1 = {`A`, `B`, `C`}
arr a2 = a1
a2 += `D`
a1[0] = `Z`
//  a1 = `Z`, `B`, `C`
//  a2 = `A`, `B`, `C`, `D`
```

When assigning *a2 = a1* we got a copy of the array *a1*. Actions on arrays will not affect each other in any way. Sometimes making copies of large objects can slow down program execution. For example, if a function returns some structure that you want to work with further, then there is no point in creating its copy. To resolve such situations, there is another assignment operator **&=** for types **buf, arr, map, set** and all structure types. This operator does not copy data into a variable, but creates a clone of this data. In this case, the data remains in a single copy.

```go
arr a1 = {`A`, `B`, `C`}
arr a2 &= a1
a2 += `D`
a1[0] = `Z`
//  a1 = `Z`, `B`, `C`, `D`
//  a2 = `Z`, `B`, `C`, `D`
```

```go
time t
t &= Now()  // it is better than t = Now()
```

## Context

There are no global variables in Gentee. Instead, there is an associative array *map.str*, which is readable and writable from any functions and streams. In addition to storing data as a key-value, the context can also recursively replace keys in strings of the form *"#key\_name# #another\_key\_name#"*. All [context functions](https://gentee.github.io/stdlib/context) are described in the standard library. Here we consider only operators.

* Unary operator **## str** recursively replaces keys with their values in the passed string and returns the result.&#x20;
* Unary operator **# key** works similarly to the **##** operator, but it needs to pass the name-identifier of the context key.
* The **key #= value** operator writes the *key* key with the specified value into the context. If the value is of type *int, bool, float* instead of type *str*, it will be converted to a string.

```go
func ooops() {
    AB #= `oops`
}
run str {
    AB #= `test`
    CD #= `#AB# - `    // don't replace #AB#.  CD = #AB# - 
    E #= #AB           // get #AB#. E = test
    ooops()            // change AB
    val #= 10
    return #CD + #E + ##` #val# == 10`
}
// Result:  oops - test 10 == 10
```


# Running programs

The language has a special command **$** to run applications and operating system commands with the specified parameters. The script takes the entire line up to the newline character and execute it. There must be a space between the **$** and the command line. If this command is used in an expression, it captures the standard output and returns it as a string. Otherwise, the standard output will be visible in the console. You can specify expressions with **%{Expression}** as in a backquoted string. If any parameter contains a space, enclose that parameter in any quotes - *"a b", 'c d', \`e f\`*. If the executable application or command terminates with an error code other than zero, the script will also stop working and return an error.

```
Command = "$ " { unicode_linechar | "%{" Expression "}" | "${" identifier "}" }
```

```
run str {
   $ dir
   str name = $ echo "John Smith"
   return $ echo My name is %{name}
}
```

### Environment Variables

The Gentee language allows you to easily get environment variables and assign values to them. To do this, specify the **$** character before the variable name. In addition, you can substitute the environment variables with the **${ENV\_NAME}** construct in the **$** launch commands and back-quoted strings. This entry is shorter than *%{ $ENV\_NAME }*. Environment variables are always of string type, but you can assign them values of **str**, **int**, and **bool** types.

```
EnvVariable = "$" identifier
```

```
run str {
    $MYVAR = `Go path: ${GOPATH}` + $GOROOT
    return $ echo ${MYVAR}
}
```


# Multithreading

The Gentee language allows you to create multi-threaded scripts. In this case, part of the script can be performed in parallel, which reduces the time of its work. To execute some code in a separate thread, you must specify it in the **go** statement. The script will continue to perform the following constructions without waiting for the end of the code inside *go*, but immediately after the new thread is launched. The **go** statement returns the identifier of the created thread, which can be assigned to a variable of the **thread** type and then used in the multithreading functions. If the script has finished its work earlier than the child threads, then it will wait for all threads to finish working. If an error occurs in any of the threads while executing a multi-threaded script, all the threads are closed and the script returns this error.

```
GoStmt = "go" [ "(" GoArgs ")" ] Block
GoArgs = identifier ":" Expression { "," identifier ":" Expression }
```

```
func myThread {
  for i in 0..50 {
    Print(`x` )
    if i % 3 == 0 : sleep(5)
  }
}

run {
  thread th = go {
    for i in 0..100 {
      Print(` `, i )
      if i % 7 == 0 : sleep(5)
    }
  }
  suspend( th )
  go : myThread()
  resume(th)
  Print( `OK`)
  wait(th)
  Print( `END`)
}
```

You can pass any parameters in the **go** command. To do this, you need to specify the name of the parameter and its value separated by a colon. The type of the parameter is automatically determined by the passed value. If you pass structures or arrays, the parameter will be assigned a copy of the value.

```
run str {
  str s = "ok"
  thread th1 = go (a: s + " test") : ctxPar #= a
  thread th2 = go (a: Max(1,23), b: Min(100,87)) {
     ctxSum #= a + b
  }
  wait(th2)
  wait(th1)
  return #ctxPar + #ctxSum
}
```

##


# Include and import

### Include and import declarations

The **include** declaration imports all types, functions and constants from the specified files and their included files.

The **import** declaration imports only public types, functions and constants from the specified files and their included files. Public objects are defined using the **pub** keyword.

```
stringConst         = "`" { unicode_char } "`" | stringDoubleConst
stringDoubleConst = `"` { unicode_char | uShort | uLong | escapedChar | byteVal } `"`
importDecl = "import" "{" {stringConst newline} "}"
includeDecl = "include" "{" {stringConst newline} "}"
```

Consider the visibility of objects as a table. Let there be two files.

```
// a.g can include or import b.g
func afunc(i int) : return i*2
pub func apubfunc(i int) : return i*3

// b.g 
func bfunc(i int) : return i*4
pub func bpubfunc(i int) : return i*5
```

Let the *c.g* file can import or include *a.g* file. You can see what functions are visible in *c.g* in different situations.

|          | <p>include a <br> a includes b</p> | <p>include a <br> a imports b</p> | <p>import a <br> a includes b</p> | <p>import a <br> a imports b</p> |
| -------- | ---------------------------------- | --------------------------------- | --------------------------------- | -------------------------------- |
| afunc    | visible                            | visible                           |                                   |                                  |
| apubfunc | visible                            | visible                           | visible                           | visible                          |
| bfunc    | visible                            |                                   |                                   |                                  |
| bpubfunc | visible                            |                                   | visible                           |                                  |

### Pub declaration

The **pub** declaration marks the next function, type or constants as public. They can be imported with **import** declaration.

```
pubDecl = "pub"
objects = [pubDecl] (structDecl | FnDecl | ConstDecl | FunctionDecl)
```

The **pub** keyword indicates that the next function, constants, or structure will be passed when the file is imported.

```
pub const IOTA {  // public constants. Visible when include or import
    MY1
    MY2
}

const IOTA*2 {  // private constants. Visible only when include
    MY3
    MY4
}
```


# Standard Library Reference


# Archiving

The functions for working with **zip** and **tar.gz** archives are described here.

* [ArchiveName( finfo fi, str root ) str](/stdlib/archive#archivename-finfo-fi-str-root-str)
* [CloseTarGz( handle h )](/stdlib/archive#closetargz-handle-h)
* [CloseZip( handle h )](/stdlib/archive#closezip-handle-h)
* [CreateTarGz( str name ) handle](/stdlib/archive#createtargz-str-name-handle)
* [CreateZip( str name ) handle](/stdlib/archive#createzip-str-name-handle)
* [CompressFile( handle h, str fname, str packname )](/stdlib/archive#compressfile-handle-h-str-fname-str-packname)
* [ReadTarGz( str name ) arr.finfo](/stdlib/archive#readtargz-str-name-arr-finfo)
* [ReadZip( str name ) arr.finfo](/stdlib/archive#readzip-str-name-arr-finfo)
* [TarGz( str name, str path )](/stdlib/archive#targz-str-name-str-path)
* [UnpackTarGz( str name, str path )](/stdlib/archive#unpacktargz-str-name-str-path)
* [UnpackTarGz( str name, str path, arr pattern, arr ignore )](/stdlib/archive#unpacktargz-str-name-str-path-arr-pattern-arr-ignore)
* [UnpackZip( str name, str path )](/stdlib/archive#unpackzip-str-name-str-path)
* [UnpackZip( str name, str path, arr pattern, arr ignore )](/stdlib/archive#unpackzip-str-name-str-path-arr-pattern-arr-ignore)
* [Zip( str name, str path )](/stdlib/archive#zip-str-name-str-path)

## Functions

### ArchiveName(finfo fi, str root) str

The *ArchiveName* function concatenates the *Name* and *Dir* fields in a variable of *finfo* type and returns the file path for the archive relative to the root path *root*.

### CloseTarGz(handle h)

The *CloseTarGz* function finishes creating the *.tar.gz* archive. The *h* parameter is the identifier that was returned by the **CreateTarGz** function.

### CloseZip(handle h)

The *CloseZip* function finishes creating the *.zip* archive. The *h* parameter is the identifier that was returned by the **CreateZip** function.

### CreateTarGz(str name) handle

The *CreateTarGz* function starts creating a **.tar.gz** archive with the specified name. You can add files to this archive with the **CompressFile** function. The function returns an identifier, which you will need to close with the *CloseTarGz* function.

### CreateZip(str name) handle

The *CreateZip* function starts creating a **.tar.gz** archive with the specified name. You can add files to this archive with the **CompressFile** function. The function returns an identifier, which you will need to close with the *CloseZip* function.

### CompressFile(handle h, str fname, str packname)

The *CompressFile* function adds the specified *fname* file to the created archive. The *packname* parameter contains the relative path and file name to be saved in the archive. Use **/** symbol as a separator. The archive must be previously created using the **CreateZip** or **CreateTarGz** functions.

```go
    handle zip = CreateZip(`my.zip`)
    CompressFile(zip, `../data/my.txt`, `my.txt`)
    CompressFile(zip, `/home/user/folder/copy.txt`, `folder/copy.txt`)
    CloseZip(zip)
```

### ReadTarGz(str name) arr.finfo

The *ReadTarGz* function returns the list of files in the specified **tar.gz** archive. The *Name* field contains the file name together with the relative path.

```go
   arr.finfo list = ReadTarGz(`my.tar.gz`)
   for fi in list : Println( "\{fi.Name} \{fi.Size}")
```

### ReadZip(str name) arr.finfo

The *ReadZip* function returns the list of files in the specified **.zip** archive. The *Name* field contains the file name together with the relative path.

### TarGz(str name, str path)

The *TarGz* function packs the file or the contents of the *path* directory into a **.tar.gz** archive named *name*.

```go
   TarGz("/home/user/out/my.tar.gz", `/home/user/docs`)
```

### UnpackTarGz(str name, str path)

The *UnpackTarGz* function unpacks a **.tar.gz** archive named *name* into the *path* directory.

```go
   UnpackTarGz("/home/user/out/my.tar.gz", `/home/user/olddocs`)
```

### UnpackTarGz(str name, str path, arr pattern, arr ignore)

The *UnpackTarGz* function selectively unpacks a **.tar.gz** archive named *name* into the *path* directory. The *pattern* array contains file patterns to be unpacked. The *ignore* array contains file patterns to skip. The *pattern* and *ignore* parameters can be empty arrays. If the pattern begins and ends with **/**, then it is treated as a regular expression.

```go
   arr empty
   arr doc = {`*.docx`, `/.txt$/`}
   UnpackTarGz("/home/user/out/my.tar.gz", `/home/user/tmp`, doc, empty )
```

### UnpackZip(str name, str path)

The *UnpackZip* function unpacks a **.zip** archive named *name* into the *path* directory.

```go
   UnpackZip("/home/user/out/my.zip", `/home/user/olddocs`)
```

### UnpackZip(str name, str path, arr pattern, arr ignore)

The *UnpackZip* function selectively unpacks a **.tar.gz** archive named *name* into the *path* directory. The *pattern* array contains file patterns to be unpacked. The *ignore* array contains file patterns to skip. The *pattern* and *ignore* parameters can be empty arrays. If the pattern begins and ends with **/**, then it is treated as a regular expression.

```go
   arr empty
   arr skip = {`/temp.pdf/`, `/.txt$/`}
   UnpackZip("/home/user/out/my.tar.gz", `/home/user/tmp`, empty, skip )
```

### Zip(str name, str path)

The *Zip* function packs the file or the contents of the *path* directory into a **.zip** archive named *name*.

```go
   Zip("/home/user/out/mydoc.zip", `/home/user/docs/important.docx`)
```


# Array

Operators and functions for working with arrays (**arr** type) are described here. **arr.typename** means that you can specify any type name but in the case of the binary operator this type must be the same in both arrays.

* [bool( arr.typename a ) bool](/stdlib/array#bool-arr-typename-a-bool)
* [Join( arr.str a, str sep ) str](/stdlib/array#join-arr-str-a-str-sep-str)
* [Reverse( arr.typename a ) arr.typename](/stdlib/array#reverse-arr-typename-a-arr-typename)
* [Slice( arr.typename a, int start, int end ) arr.typename](/stdlib/array#slice-arr-typename-a-int-start-int-end-arr-typename)
* [Sort( arr.str a ) arr.str](/stdlib/array#sort-arr-str-a-arr-str)

## Operators

| Operator                             | Result           | Description                                                                      |
| ------------------------------------ | ---------------- | -------------------------------------------------------------------------------- |
| **\*** arr.typename                  | int              | Returns the number of elements in the array.                                     |
| arr.typename **?**                   | bool             | Calls *bool(arr.typename)*.                                                      |
| arr.typename **=** arr.typename      | arr.typename     | Assignment operator.                                                             |
| arr.typename **&=** arr.typename     | arr.typename     | Creates a clone of the array. The new variable will work with the same data set. |
| arr.typename **+=** arr.typename     | arr.typename     | Adds items from one array to another.                                            |
| arr.str **+=** str                   | arr.str          | Adds a string to an array of strings.                                            |
| arr.int **+=** int                   | arr.int          | Adds an integer number to an array of integer numbers.                           |
| arr.bool **+=** bool                 | arr.bool         | Adds a Boolean value to an array of Boolean values.                              |
| arr.arr.typename **+=** arr.typename | arr.arr.typename | Adds an array to an array of arrays.                                             |
| arr.map.typename **+=** map.typename | arr.map.typename | Adds a map to an array of maps.                                                  |
| arr.typename **\[** int **]**        | typename         | Sets/gets an array value by index.                                               |

## Functions

### bool(arr.typename a) bool

The *bool* function returns *false* if the array is empty, otherwise, it returns *true*.

### Join(arr.str a, str sep) str

The *Join* function joins strings of the array. The separator string *sep* is placed between strings in the resulting string.

### Reverse( arr.typename a ) arr.typename

The *Reverse* function reverses the order of the elements in the array and returns this array.

### Slice( arr.typename a, int start, int end ) arr.typename

The *Slice* function copies some consecutive elements from within an array. *start* is inclusive, while *end* is exclusive. The function returns the created array.

### Sort(arr.str a) arr.str

The *Sort* function sorts an array of strings in increasing order and returns it.


# Boolean

Operators and functions for working with boolean (**bool** type) are described here.

* [int( bool b ) int](/stdlib/bool#int-bool-b-int)
* [str( bool b ) str](/stdlib/bool#str-bool-b-str)

## Operators

| Operator           | Result | Description                                                                          |
| ------------------ | ------ | ------------------------------------------------------------------------------------ |
| bool **&&** bool   | bool   | Logical AND operator. If both the operands are true then condition becomes true.     |
| bool **\|\|** bool | bool   | Logical OR Operator. If any of the two operands is true then condition becomes true. |
| **!** bool         | bool   | Logical NOT Operator.                                                                |
| bool **=** bool    | bool   | Assignment operator.                                                                 |

## Functions

### int(bool b) int

The *int* function returns 1 if the parameter is true and returns 0 otherwise.

### str(bool b) str

The *str* function returns the "true" if the parameter is *true* and returns the "false" otherwise.


# Buffer

Operators and functions for working with an array of bytes (**buf** type) are described here.

* [bool( buf b ) bool](/stdlib/buffer#bool-buf-b-bool)
* [buf( str s ) buf](/stdlib/buffer#buf-str-s-buf)
* [str( buf b ) str](/stdlib/buffer#str-buf-b-str)
* [Base64( buf b ) str](/stdlib/buffer#base-64-buf-b-str)
* [DecodeInt( buf b, int offset ) int](/stdlib/buffer#decodeint-buf-b-int-offset-int)
* [Del( buf b, int off, int length ) buf](/stdlib/buffer#del-buf-b-int-off-int-length-buf)
* [EncodeInt( buf b, int i ) buf](/stdlib/buffer#encodeint-buf-b-int-i-buf)
* [Hex( buf b ) str](/stdlib/buffer#hex-buf-b-str)
* [Insert( buf b, int off, buf src) buf](/stdlib/buffer#insert-buf-b-int-off-buf-src-buf)
* [SetLen( buf b, int size ) buf](/stdlib/buffer#setlen-buf-b-int-size-buf)
* [Subbuf( buf b, int off, int length ) buf](/stdlib/buffer#subbuf-buf-b-int-off-int-length-buf)
* [UnBase64( str s ) buf](/stdlib/buffer#unbase-64-str-s-buf)
* [UnHex( str s ) buf](/stdlib/buffer#unhex-str-s-buf)
* [Write( buf b, int off, buf src ) buf](/stdlib/buffer#write-buf-b-int-off-buf-src-buf)

## Operators

| Operator             | Result | Description                                                                      |
| -------------------- | ------ | -------------------------------------------------------------------------------- |
| **\*** buf           | int    | Returns the number of bytes in the array.                                        |
| buf **?**            | bool   | Calls *bool(buf)*.                                                               |
| buf **+** buf        | buf    | Merges two buffers.                                                              |
| buf **=** buf        | buf    | Assignment operator.                                                             |
| buf **&=** buf       | buf    | Create a clone of the buffer. The new variable will work with the same data set. |
| buf **+=** buf       | buf    | Appends a buffer to a buffer variable.                                           |
| buf **+=** int       | buf    | Appends one byte to the buffer. The number must be less than 256.                |
| buf **+=** str       | buf    | Appends a string to the buffer.                                                  |
| buf **+=** char      | buf    | Appends a character to the buffer.                                               |
| buf **\[** int **]** | int    | Sets/gets a byte by index.                                                       |

## Functions

### bool(buf b) bool

The *bool* function returns *false* if the buffer is empty, otherwise, it returns *true*.

### buf(str s) buf

The *buf* function converts a string to a *buf* value and returns it.

### str(buf b) str

The *str* function converts a *buf* value to a string and returns it.

### Base64(buf b) str

The *Base64* function converts a value of the *buf* type into a string in **base64** encoding and returns it.

### DecodeInt(buf b, int offset) int

The *DecodeInt* function gets an integer from a parameter of *buf* type. *offset* is the offset in the buffer at which to read the number. The function reads 8 bytes and returns them as an integer.

### Del(buf b, int off, int length) buf

The *Del* function removes part of the data from the byte array. *off* is the offset of the data to be deleted, *length* is the number of bytes to be deleted. If *length* is less than zero, then the data will be deleted to the left of the specified offset. The function returns the *b* variable in which the deletion occurred.

### EncodeInt(buf b, int i) buf

The *EncodeInt* function appends an integer number to a specified variable of *buf* type. Since the *int* value occupies 8 bytes, 8 bytes are appended to the buffer regardless of the *i* parameter value. The function returns the *b* parameter.

### Hex(buf b) str

The *Hex* function encodes a *buf* value to a hexadecimal string and returns it.

### Insert(buf b, int off, buf src) buf

The *Insert* function inserts an array of bytes *src* into the array *b*. *off* is the offset where the specified byte array will be inserted. The function returns the variable *b*.

### SetLen(buf b, int size) buf

The *SetLen* function sets the size of the buffer. If *size* is less than the size of the buffer, then it will be truncated. Otherwise, the buffer will be padded with zeros to the specified size.

### Subbuf(buf b, int off, int length) buf

The *Subbuf* function returns a new buffer that contains the chunk of the *b* buffer with the specified offset and length.

### UnBase64(str s) buf

The *UnBase64* function converts a string in **base64** encoding into a value of the *buf* type and returns it.

### UnHex(str s) buf

The *UnHex* function returns the *buf* value represented by the hexadecimal string *s*. The input string must contain only hexadecimal characters.

### Write(buf b, int off, buf src) buf

The *Write* function writes the byte array of the *src* variable into the *b* variable starting from the specified offset. The data is written over existing values. The function returns variable *b*.


# Characters

Operators and functions for working with characters (**char** type) are described here.

* [int( char c ) int](/stdlib/char#int-char-c-int)
* [str( char c ) str](/stdlib/char#str-char-c-str)

## Operators

| Operator         | Result | Description                                                                                          |
| ---------------- | ------ | ---------------------------------------------------------------------------------------------------- |
| char **+** char  | str    | Returns a string of two characters.                                                                  |
| char **+** str   | str    | Returns a string as the result of adding a string to a character.                                    |
| str **+** char   | str    | Returns a string as the result of adding a character to the string.                                  |
| char **=** char  | char   | Assignment operator.                                                                                 |
| str **+=** char  | str    | Appends a character to the string                                                                    |
| char **==** char | bool   | Returns *true* if the two characters are equal and *false*, otherwise.                               |
| char **>** char  | bool   | Returns *true* if the first character is greater than the second and *false*, otherwise.             |
| char **<** char  | bool   | Returns *true* if the first character is less than the second and *false*, otherwise.                |
| char **!=** char | bool   | Returns *true* if the two characters are not equal and *false*, otherwise.                           |
| char **>=** char | bool   | Returns *true* if the first character is greater than or equal to the second and *false*, otherwise. |
| char **<=** char | bool   | Returns *true* if the first character is less than or equal to the second and *false*, otherwise.    |

## Functions

### int( char c ) int

The *int* function returns the numeric value of a character.

### str(char c) str

The *str* function converts a character to a string and returns this string.


# Console

Functions for working with a console described here.

* [ClearCarriage( str input ) str](/stdlib/console#clearcarriage-str-input-str)
* [Print( anytype par... ) int](/stdlib/console#print-anytype-par-int)
* [Println( anytype par... ) int](/stdlib/console#println-anytype-par-int)
* [ReadString( str text ) str](/stdlib/console#readstring-str-text-str)

## Operators

| Operator     | Result | Description                                                                                                                                                      |
| ------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **\|\|** str | int    | This unary operator writes a string to standard output but it trims whitespace characters in the each line before printing. Returns the number of bytes written. |

```
run {
   ||`One
      Two
      Three
      `
}
/* It prints
One
Two
Three
*/
```

## Functions

### ClearCarriage(str input) str

The function *ClearCarriage* clears the string from all carriage return characters **\r** back to the previous line break character **\n**. It is recommended to use *ClearCarriage* if you get the console output when calling the **Run** function. The function is called automatically in case of *str s = $ command line* operator.

```go
buf dirout
Run("myapp", stdout: dirout)
// dirout == Start\nPercent: 0%\rPercent: 50%\rPercent: 100%\nFinish
ret = ClearCarriage(str(dirout))
// ret == Start\nPercent: 100%\nFinish
```

### Print(anytype par...) int

The *Print* function formats using the default formats for operands of any types and writes to standard output. Spaces are added between operands when neither is a string. *Print* returns the number of bytes written.

### Println(anytype par...) int

The *Println* function formats using the default formats for operands of any types and writes to standard output. Also, it writes a new line character to standard output at the end. Spaces are always added between operands. *Println* returns the number of bytes written.

### ReadString(str text) str

The *ReadString* function reads the standard input until the first occurrence of '\n' (Enter key). It returns a string containing the data up to. If the *text* parameter is not empty, the function prints this text before reading input.


# Constants

## Predefined constants

### CYCLE

Maximum number of iterations in a cycle. By default, it is 1600000000.

### DEPTH

Maximum nesting of executable blocks. Limits the recursion depth. By default, it is equal to 1000.

### IOTA

The *IOTA* constant is used to automatically calculate the sequence of constants.

```
const IOTA * 2 {"a6}
    ZERO // 0
    TWO // 2
    FOUR // 4
}
```

### SCRIPT

The *SCRIPT* constant returns the path of the current script. If it was not specified, the *run* name is returned.

```go
// compile from file: /home/ak/gentee/scripts/myscript.g
run {
    Println(SCRIPT) // /home/ak/gentee/scripts/myscript.g
}

// compile from memory
run my_best_script {
    Println(SCRIPT) // my_best_script
}
```

### VERSION

The *VERSION* constant returns the current version of the Gentee compiler.


# Context

There are no global variables in the Gentee language. One of the ways to exchange data is a special associative array of strings (*context*). Any function can safely add key-value pairs there or get a value by key. In addition, the context has the ability to substitute other existing values from the context. For example, if the pairs *"a": "String A"* and *"b": "String B"* has been defined, then *"#a# and #b#"* will return *"String A and String B"*. The functions and operators for working with the context are described below.

* [Ctx( str input ) str](/stdlib/context#ctx-str-input-str)
* [CtxGet( str key ) str](/stdlib/context#ctxget-str-key-str)
* [CtxIs( str key ) bool](/stdlib/context#ctxis-str-key-bool)
* [CtxSet( str key, str val ) str](/stdlib/context#ctxset-str-key-str-val-str)
* [CtxSet( str key, bool b ) str](/stdlib/context#ctxset-str-key-bool-b-str)
* [CtxSet( str key, float f ) str](/stdlib/context#ctxset-str-key-float-f-str)
* [CtxSet( str key, int i ) str](/stdlib/context#ctxset-str-key-int-i-str)
* [CtxValue( str key ) str](/stdlib/context#ctxvalue-str-key-str)

## Operators

| Operator           | Result | Description                                                               |
| ------------------ | ------ | ------------------------------------------------------------------------- |
| **#** ident        | str    | The same as *CtxGet(key)*, where *ident* is the context key.              |
| **##** str         | str    | The same as *Ctx(str)*. Specify any expression that returns a string.     |
| ident **#=** str   | str    | The same as *CtxSet(str key, str s)*, where *ident* is the context key.   |
| ident **#=** bool  | str    | The same as *CtxSet(str key, bool b)*, where *ident* is the context key.  |
| ident **#=** float | str    | The same as *CtxSet(str key, float f)*, where *ident* is the context key. |
| ident **#=** int   | str    | The same as *CtxSet(str key, int i)*, where *ident* is the context key.   |

```go
run str {
  str s = ` #AºB#`
  AºB #= `ººº`
  b #= 71
  CD #= `#AºB# #b# == ` 
  return #CD + #b + ##s
}
// ººº 71 == 71 ººº
```

## Functions

### Ctx(str input) str

The *Ctx* function replaces substrings **#keyname#** in *input* string with the value of the corresponding key, if it exists.

```
run str {
    CtxSetBool(`qq`, true)
    CtxSetFloat(`ff`, 3.1415)
    CtxSet(`out`, "it is #qq# that PI equals #ff#")
    return Ctx("#out#. #notexist#")
}
// it is true that PI equals 3.1415. #notexist#
```

### CtxGet(str key) str

The *CtxGet* function gets the value of the *key* key, replaces all occurrences of other keys in it, and returns the resulting string. If the specified key is missing, an empty string is returned.

```
func init {
   CtxSet(`a1`, `end`)
   CtxSet(`a2`, `=#a1#=`)
   CtxSet(`a3`, `+#a2#+#a1#`)
}

run str {
    init()
    return CtxGet(`a3`)
}
// +=end=+end
```

### CtxIs(str key) bool

The *CtxIs* function returns *true* if there is a value with the specified key in the context. Otherwise, it returns *false*.

### CtxSet(str key, str val) str

The *CtxSet* function adds a key and a value to the context. If the key already exists, it will be assigned a new value. The function returns the value of the key.

### CtxSet(str key, bool b) str

The *CtxSet* function adds a key and a logical value *b* to the context. A boolean value will be converted to the string *true* or *false*. The function returns the value of the key.

### CtxSet(str key, float f) str

The *CtxSet* function adds a key and a floating-point number *f* to the context. The number will be converted to a string. The function returns the value of the key.

### CtxSet(str key, int i) str

The *CtxSet* function adds a key and an integer *i* to the context. The number will be converted to a string. The function returns the value of the key.

### CtxValue(str key) str

The *CtxValue* function returns the value of the *key* key as is. Unlike the **CtxGet** function, it does not replace occurrences of other keys. If the specified key is missing, an empty string is returned.

```
run str {
    CtxSet(`test`, `?value`)
    CtxSet(`param`, `#test# ==`)
    return CtxValue(`param`) + CtxValue(`nop`) + CtxGet(`param`)
}
// #test# ==?value ==
```


# Cryptography

The cryptographic functions are described below.

* [AESDecrypt( str key, buf data ) buf](/stdlib/crypto#aesdecrypt-str-key-buf-data-buf)
* [AESEncrypt( str key, buf data ) buf](/stdlib/crypto#aesencrypt-str-key-buf-data-buf)
* [Md5( buf | str data ) buf](/stdlib/crypto#md-5-buf-or-str-data-buf)
* [RandomBuf( int size ) buf](/stdlib/crypto#randombuf-int-size-buf)
* [Sha256( buf | str data ) buf](/stdlib/crypto#sha-256-buf-or-str-data-buf)

## Functions

### AESDecrypt( str key, buf data ) buf

The *AESDecrypt* function decrypts the content of the *buf* variable using the *key* encryption key. The encrypted data must be obtained using the *AESEncrypt* function. The function returns a variable of the *buf* type with decrypted data.

```go
buf encrypted = AESDecrypt(`my password`, encrypted)
```

### AESEncrypt( str key, buf data ) buf

The *AESEncrypt* function encrypts the content of a *buf* variable using the AES-256 algorithm. The *key* parameter is an encryption key. The function returns a variable of *buf* type with encrypted data. Use the *AESDecrypt* function to decrypt the data.

```go
buf crypted = AESEncrypt(`my password`, buf(`Test message`))
```

### Md5(buf|str data) buf

The *Md5* function returns MD5 hash of the *buf* or *str* type variable.

### RandomBuf(int size) buf

The *RandomBuf* function returns a variable of the *buf* type that contains a sequence of random bytes of the specified size.

### Sha256(buf|str data) buf

The *Sha256* function returns SHA5 hash of the *buf* or *str* type variable.


# Encoding

The functions for converting data from one format to another are described here.

* [Json( obj o ) str](/stdlib/encoding#json-obj-o-str)
* [JsonToObj( str s ) obj](/stdlib/encoding#jsontoobj-str-s-obj)
* [StructDecode( b buf, struct s )](/stdlib/encoding#structdecode-buf-b-struct-s)
* [StructEncode( struct s ) buf](/stdlib/encoding#structencode-struct-s-buf)

## Functions

### Json( obj o ) str

The *Json* function converts a variable of *obj* type into **json** string.

### JsonToObj( str s ) obj

The *JsonToObj* function converts **json** string into a variable of the *obj* type.

```go
run str {
  return Json(JsonToObj(`{
         "int": 1234,
         "str": "value",
         "float": -45.67,
          "list":[{"on": true},
            "sub 2",
            "sub 3",
            {
                "q": "OK"
            }]
    }`))
}
// Result {"float":-45.67,"int":1234,"list":[{"on":true},"sub 2","sub 3",{"q":"OK"}],"str":"value"}
```

### StructDecode( buf b, struct s )

The *StructDecode* function converts the binary data of a *buf* variable to the field values of the specified structure variable. The binary data must be created with *StructEncode* function.

```go
  time t
  StructDecode(StructEncode(Now()), t)
```

### StructEncode( struct s ) buf

The *StructEncode* function converts a structure variable to binary and stores the result into a *buf* variable. The function saves only fields of the following types: **int, bool, char, float, buf, str**. Fields of other types are skipped.

```go
struct tmp {
    str head
    int i
}

run str {
  tmp t1 = {head: `HEADER`, i: -356}
  buf bout = StructEncode(t1)
  ...
}
```


# Files

Functions for working with files and directories are described here.

* [AppendFile( str filename, buf | str data )](/stdlib/file#appendfile-str-filename-buf-or-str-data)
* [ChDir( str dirname )](/stdlib/file#chdir-str-dirname)
* [ChMode( str name, int mode )](/stdlib/file#chmode-str-name-int-mode)
* [CloseFile( file f )](/stdlib/file#closefile-file-f)
* [CopyFile( str src, str dest ) int](/stdlib/file#copyfile-str-src-str-dest-int)
* [CreateDir( str dirname )](/stdlib/file#createdir-str-dirname)
* [CreateFile( str name, bool trunc )](/stdlib/file#createfile-str-name-bool-trunc)
* [ExistFile( str name ) bool](/stdlib/file#existfile-str-name-bool)
* [FileInfo( file f ) finfo](/stdlib/file#fileinfo-file-f-finfo)
* [FileInfo( str name ) finfo](/stdlib/file#fileinfo-str-name-finfo)
* [FileMode( str name ) int](/stdlib/file#filemode-str-name-int)
* [GetCurDir() str](/stdlib/file#getcurdir-str)
* [IsEmptyDir( str path ) bool](/stdlib/file#isemptydir-str-path-bool)
* [Md5File( str filename ) str](/stdlib/file#md-5-file-str-filename-str)
* [obj( finfo fi ) obj](/stdlib/file#obj-finfo-fi-obj)
* [OpenFile( str filename, int flags ) file](/stdlib/file#openfile-str-filename-int-flags-file)
* [Read( file f, int size ) buf](/stdlib/file#read-file-f-int-size-buf)
* [ReadDir( str dirname ) arr.finfo](/stdlib/file#readdir-str-dirname-arr-finfo)
* [ReadDir( str dirname, int flags, str pattern ) arr.finfo](/stdlib/file#readdir-str-dirname-int-flags-str-pattern-arr-finfo)
* [ReadDir( str dirname, int flags, arr.str patterns, arr.str ignore ) arr.finfo](/stdlib/file#readdir-str-dirname-int-flags-arr-str-patterns-arr-str-ignore-arr-finfo)
* [ReadFile( str filename ) str](/stdlib/file#readfile-str-filename-str)
* [ReadFile( str filename, buf out ) buf](/stdlib/file#readfile-str-filename-buf-out-buf)
* [ReadFile( str filename, int offset, int length ) buf](/stdlib/file#readfile-str-filename-int-offset-int-length-buf)
* [Remove( str name )](/stdlib/file#remove-str-name)
* [RemoveDir( str dirname )](/stdlib/file#removedir-str-dirname)
* [Rename( str oldpath, str newpath )](/stdlib/file#rename-str-oldpath-str-newpath)
* [SetFileTime( str name, time modtime )](/stdlib/file#setfiletime-str-name-time-modtime)
* [SetPos( file f, int off, int whence ) int](/stdlib/file#setpos-file-f-int-off-int-whence-int)
* [Sha256File( str filename ) str](/stdlib/file#sha-256-file-str-filename-str)
* [TempDir() str](/stdlib/file#tempdir-str)
* [TempDir( str path, str prefix ) str](/stdlib/file#tempdir-str-path-str-prefix-str)
* [Write( file f, buf b ) file](/stdlib/file#write-file-f-buf-b-file)
* [WriteFile( str filename, buf | str data )](/stdlib/file#writefile-str-filename-buf-or-str-data)

## Types

### finfo

The *finfo* is used for getting information about a file and has the following fields:

* **str Name** - base name of the file
* **int Size** - length in bytes for regular files
* **int Mode** - file's mode and permission bits
* **time Time** - last modification time
* **bool IsDir** - true if it is a directory
* **str Dir** - directory where the file is located. This field is only filled when calling the function [ReadDir(str, int, str)](/stdlib/file#readdir-str-dirname-int-flags-str-pattern-arr-finfo)

### file

The *file* type is used in functions that work with the open file descriptor.

## Functions

### AppendFile(str filename, buf|str data)

The *AppendFile* function appends data of *buf* variable or a string to a file named by *filename*. If the file does not exist, *AppendFile* creates it with 0644 permissions.

### ChDir(str dirname)

The *ChDir* function changes the current directory.

### ChMode(str name, int mode)

The *ChMode* function changes the attributes of the file.

### CloseFile(file f)

The *CloseFile* function closes the file descriptor that was opened with the **OpenFile** function.

### CopyFile(str src, str dest) int

The *CopyFile* function copies *src* file to *dest* file. If *dest* file exists it is overwritten. The file attributes are preserved when copying. The function returns the number of copied bytes.

### CreateDir(str dirname)

The *CreateDir* function creates a directory named *dirname*, along with any necessary parents. If *dirname* is already a directory, *CreateDir* does nothing.

### CreateFile(str name, bool trunc)

The *CreateFile* function creates a file with the specified name. If the *trunc* parameter is *true* and the file already exists, its size becomes 0.

### ExistFile(str name) bool

The *ExistFile* function returns *true* if the specified file or directory exists. Otherwise, it returns *false*.

### FileInfo(file f) finfo

The *FileInfo* function receives information about the specified file and returns the *finfo* structure. The file must be opened using the **OpenFile** function.

### FileInfo(str name) finfo

The *FileInfo* function gets information about the named file and returns *finfo* structure.

### FileMode(str name) int

The *FileMode* function returns the file attributes.

### GetCurDir() str

The *GetCurDir* function returns the current directory.

### IsEmptyDir(str path) bool

The *IsEmptyDir* function returns *true* if the specified directory is empty. Otherwise, it returns *false*.

### Md5File(str filename) str

The *Md5File* function returns the MD5 hash of the specified file as a hex string.

### obj(finfo fi) obj

The *obj* function converts a variable of finfo type into an object. The resulting object has fields: *name, size, mode, time, isdir, dir*.

### OpenFile(str filename, int flags) file

The *OpenFile* function opens the specified file and returns a variable of *file* type with an open file descriptor. After working with the file, the open file descriptor must be closed using the **CloseFile** function. The *flags* parameter may be zero or a combination of the following flags:

* *CREATE* - if the file does not exist, it will be created.
* *TRUNC* - file will be truncated to zero length after opening.
* *READONLY* - the file will be open for reading only.

```go
    file f = OpenFile(fname, CREATE)
    Write(f, buf("some test string"))
    SetPos(f, -15, 1)
    buf b &= Read(f, 5)
    CloseFile(f)
```

### Read(file f, int size) buf

The *Read* function reads the *size* number of bytes from the current position in the file that was opened using the **OpenFile** function. The function returns a variable of the *buf* type, which contains the read data.

### ReadDir(str dirname) arr.finfo

The *ReadDir* function reads the directory named by dirname and returns a list of directories and files entries.

### ReadDir(str dirname, int flags, str pattern) arr.finfo

The *ReadDir* function reads the *dirname* directory with the specified name and returns the list of its subdirectories and files according to the specified parameters. The *flags* parameter can be a combination of the following flags:

* **RECURSIVE** - In this case there will be a recursive search for all subdirectories.
* **ONLYFILES** - The returned array will contain only files.
* **ONLYDIRS** - The returned array will contain only directories.
* **REGEXP** - The *pattern* parameter contains a regular expression for matching file names.

If you specify the **ONLYFILES** and **ONLYDIRS** flags at the same time, the files and directories will be searched.

The *pattern* parameter can contain a wildcard for files or a regular expression. In this case, the files and directories that match the specified pattern will be returned. The wildcard can contain the following characters:

* '\*' - matches any sequence of non-separator characters
* '?' - matches any single non-separator character

```go
for item in ReadDir(ftemp, RECURSIVE, `*fold*`) {
    ret += item.Name
}
for item in ReadDir(ftemp, RECURSIVE | ONLYFILES | REGEXP, `.*\.pdf`) {
    ret += item.Name
}
```

### ReadDir(str dirname, int flags, arr.str patterns, arr.str ignore) arr.finfo

The *ReadDir* function reads the *dirname* directory with the specified name and returns the list of its subdirectories and files according to the specified parameters. The parameter *flags* is described above. The *patterns* parameter is an array of strings and may contain file masks or regular expressions. The *ignore* parameter also contains file wildcards or regular expressions, but such files or directories will be skipped. If you want to specify a regular expression in these arrays, enclose it between **'/'** characters.

```go
arr.str aignore = {`/txt/`, `*.pak`}
arr.str amatch = {`/\d+/`, `*.p?`, `/di/`}.
for item in ReadDir(ftemp, RECURSIVE, amatch, aignore) {
    ret += item.Name
}
```

### ReadFile(str filename) str

The *ReadFile* function reads the specified file and returns the contents as a string.

### ReadFile(str filename, buf out) buf

The *ReadFile* function reads the file named by *filename* to the *buf* variable *out* and returns it.

### ReadFile(str filename, int offset, int length) buf

The *ReadFile* function reads data from the *filename* file starting at offset *offset* and length *length*. If *offset* is less than zero, then the offset is counted from the end to the beginning of the file.

### Remove(str name)

The *Remove* function removes a file or an empty directory.

### RemoveDir(str dirname)

The *RemoveDir* function removes *dirname* directory and any children it contains.

### Rename(str oldpath, str newpath)

The *Rename* function renames (moves) *oldpath* to *newpath*. If *newpath* already exists and is not a directory, *Rename* replaces it.

### SetFileTime(str name, time modtime)

The *SetFileTime* function changes the modification time of the named file.

### SetPos(file f, int off, int whence) int

The *SetPos* function sets the current position in the file for read or write operations. The file must be opened with the **OpenFile** function. The function returns the offset of the new position. The *whence* parameter can take the following values:

* *0* - the *off* offset is specified from the beginning of file.
* *1* - the *off* offset is specified from the current position.
* *2* - the *off* offset is specified from the end of a file.

### Sha256File(str filename) str

The *Sha256File* function returns the SHA256 hash of the specified file as a hex string.

### TempDir() str

The *TempDir* function returns the default temporary directory.

### TempDir(str path, str prefix) str

The *TempDir* function creates a new temporary directory in the directory *path* with a name beginning with *prefix* and returns the path of the new directory. If *path* is the empty string, *TempDir* uses the default temporary directory.

### Write(file f, buf b) file

The *Write* function writes data from a variable of the *buf* type to a file that was opened using the **OpenFile** function. The function returns the *f* parameter.

### WriteFile(str filename, buf|str data)

The *WriteFile* function writes data of *buf* variable or a string to a file named by *filename*. If the file does not exist, *WriteFile* creates it with 0777 permissions, otherwise the file is truncated before writing.


# Float numbers

Operators and functions for working with decimal numbers of **float** type are described here.

* [bool( float f ) bool](/stdlib/float#bool-float-f-bool)
* [Ceil( float f ) int](/stdlib/float#ceil-float-f-int)
* [Floor( float f ) int](/stdlib/float#floor-float-f-int)
* [int( float f ) int](/stdlib/float#int-float-f-int)
* [Max( float fl, float fr ) float](/stdlib/float#max-float-fl-float-fr-float)
* [Min( float fl, float fr ) float](/stdlib/float#min-float-fl-float-fr-float)
* [Round( float f ) int](/stdlib/float#round-float-f-int)
* [Round( float f, int digit ) float](/stdlib/float#round-float-f-int-digit-float)
* [str( float f ) str](/stdlib/float#str-float-f-str)

## Operators

| Operator            | Result | Description                                                                                   |
| ------------------- | ------ | --------------------------------------------------------------------------------------------- |
| float **?**         | bool   | Calls *bool(float)*.                                                                          |
| float **+** float   | float  | Adds two numbers.                                                                             |
| float **+** int     | float  |                                                                                               |
| int **+** float     | float  |                                                                                               |
| float **-** float   | float  | Subtracts second number from the first.                                                       |
| float **-** int     | float  |                                                                                               |
| int **-** float     | float  |                                                                                               |
| float **\*** float  | float  | Multiplies both numbers.                                                                      |
| float **\*** int    | float  |                                                                                               |
| int **\*** float    | float  |                                                                                               |
| float **/** float   | float  | The division of two numbers. When dividing by zero, an error is returned.                     |
| float **/** int     | float  |                                                                                               |
| int **/** float     | float  |                                                                                               |
| float **==** float  | bool   | Returns true if two numbers are equal and false, otherwise.                                   |
| float **==** int    | bool   |                                                                                               |
| float **>** float   | bool   | Returns true if the first number is greater than the second and false, otherwise.             |
| float **>** int     | bool   |                                                                                               |
| float **<** float   | bool   | Returns true if the first number is less than the second and false, otherwise.                |
| float **<** int     | bool   |                                                                                               |
| float **!=** float  | bool   | Returns true if two numbers are not equal and false, otherwise.                               |
| float **!=** int    | bool   |                                                                                               |
| float **>=** float  | bool   | Returns true if the first number is greater than or equal to the second and false, otherwise. |
| float **>=** int    | bool   |                                                                                               |
| float **<=** float  | bool   | Returns true if the first number is less than or equal to the second and false, otherwise.    |
| float **<=** int    | bool   |                                                                                               |
| **-** float         | float  | Change the sign of a decimal number.                                                          |
| float **=** float   | float  | Simple assignment operator.                                                                   |
| float **+=** float  | float  | Add and assignment operator.                                                                  |
| float **-=** float  | float  | Subtract and assignment operator.                                                             |
| float **/=** float  | float  | Divide and assignment operator.                                                               |
| float **\*=** float | float  | Multiply and assignment operator.                                                             |

## Functions

### bool(float f) bool

The bool function returns false if the passed parameter is 0.0, otherwise it returns true.

### int(float f) int

The *int* function converts a decimal number to an integer number which is less than or equal to this number.

### str(float f) str

The *str* function converts a decimal number to a string.

### Ceil(float f) int

The *Ceil* function returns the least integer value greater than or equal to *f*.

### Floor(float f) int

The *Floor* function returns the greatest integer value less than or equal to *f*.

### Max(float fl, float fr) float

The *Max* function returns the maximum of two values.

### Min(float fl, float fr) float

The *Min* function returns the minimum of two values.

### Round(float f) int

The *Round* function returns the nearest integer, rounding half away from zero.

```
   Round(4.5) // 5
   Round(4.1) // 4
   Round(4.9) // 5
```

### Round(float f, int digit) float

The *Round* function rounds *f* to the specified number of decimal places.

```
   Round(4.567, 2) // 4.57
   Round(4.111, 1) // 4.1
```


# Integer

Operators and functions for working with integers of **int** type are described here.

* [Abs( int i ) int](/stdlib/integer#abs-int-i-int)
* [bool( int i ) bool](/stdlib/integer#bool-int-i-bool)
* [float( int i ) float](/stdlib/integer#float-int-i-float)
* [Max( int l, int r ) int](/stdlib/integer#max-int-l-int-r-int)
* [Min( int l, int r ) int](/stdlib/integer#min-int-l-int-r-int)
* [Random( int n ) int](/stdlib/integer#random-int-n-int)
* [str( int i ) str](/stdlib/integer#str-int-i-str)

## Operators

| Operator        | Result | Description                                                                                       |
| --------------- | ------ | ------------------------------------------------------------------------------------------------- |
| int **?**       | bool   | *true*, if the number doesn't equal zero.                                                         |
| int **+** int   | int    | The addition of two integers.                                                                     |
| int **-** int   | int    | Subtract two integers.                                                                            |
| int **\*** int  | int    | Multiplication of two integers.                                                                   |
| int **/** int   | int    | The division of two integers. When dividing by zero, an error is returned.                        |
| int **==** int  | bool   | Returns *true* if two numbers are equal and *false*, otherwise.                                   |
| int **>** int   | bool   | Returns *true* if the first number is greater than the second and *false*, otherwise.             |
| int **<** int   | bool   | Returns *true* if the first number is less than the second and *false*, otherwise.                |
| int **!=** int  | bool   | Returns *true* if two numbers are not equal and *false*, otherwise.                               |
| int **>=** int  | bool   | Returns *true* if the first number is greater than or equal to the second and *false*, otherwise. |
| int **<=** int  | bool   | Returns *true* if the first number is less than or equal to the second and *false*, otherwise.    |
| int **%** int   | int    | Returns the remainder after dividing two numbers (modulo operator).                               |
| int **\|** int  | int    | Bitwise OR.                                                                                       |
| int **^** int   | int    | Bitwise XOR.                                                                                      |
| int **&** int   | int    | Bitwise AND.                                                                                      |
| int **<<** int  | int    | Bitwise left shift.                                                                               |
| int **>>** int  | int    | Bitwise right shift.                                                                              |
| **-** int       | int    | Change the sign of an integer.                                                                    |
| **^** int       | int    | Bitwise NOT.                                                                                      |
| int **=** int   | int    | Simple assignment operator.                                                                       |
| int **=** char  | int    | Assigning a character to a variable.                                                              |
| int **+=** int  | int    | Add and assignment operator.                                                                      |
| int **-=** int  | int    | Subtract and assignment operator.                                                                 |
| int **/=** int  | int    | Divide and assignment operator.                                                                   |
| int **\*=** int | int    | Multiply and assignment operator.                                                                 |
| int **%=** int  | int    | Modulus and assignment operator.                                                                  |
| int **\|=** int | int    | Bitwise and assignment operator.                                                                  |
| int **^=** int  | int    | Bitwise exclusive OR and assignment operator.                                                     |
| int **&=** int  | int    | Bitwise inclusive OR and assignment operator.                                                     |
| int **<<=** int | int    | Left shift and assignment operator.                                                               |
| int **>>=** int | int    | Right shift AND assignment operator.                                                              |

## Functions

### Abs(int i) int

The *Abs* function returns the absolute value of the number.

### bool(int i) bool

The *bool* function returns *false* if the passed parameter is 0, otherwise it returns *true*.

### float(int i) float

The *float* function converts an integer to a *float* number.

### Max(int l, int r) int

The *Max* function returns the maximum of two values.

### Min(int l, int r) int

The *Min* function returns the minimum of two values.

### Random(int n) int

The *Random* function returns a non-negative pseudo-random number in \[0,n).

### str(int i) str

The *str* function converts an integer to a string.


# Map

Operators and functions for working with map arrays (**map** type) are described here. **map.typename** means that you can specify any type name but in the case of the binary operator this type must be the same in both maps.

* [bool( map.typename m ) bool](/stdlib/map#bool-map-typename-m-bool)
* [Del( map.typename m, str key ) map.typename](/stdlib/map#del-map-typename-m-str-key-map-typename)
* [IsKey( map.typename m, str key ) bool](/stdlib/map#iskey-map-typename-m-str-key-bool)
* [Key( map.typename m, int index ) str](/stdlib/map#key-map-typename-m-int-index-str)

## Operators

| Operator                         | Result       | Description                                                                    |
| -------------------------------- | ------------ | ------------------------------------------------------------------------------ |
| **\*** map.typename              | int          | Returns the number of elements in the map.                                     |
| map.typename **?**               | bool         | Calls *bool(map.typename)*.                                                    |
| map.typename **=** map.typename  | map.typename | Assignment operator.                                                           |
| map.typename **&=** map.typename | map.typename | Creates a clone of the map. The new variable will work with the same data set. |
| map.typename **\[** str **]**    | typename     | Sets/gets a map value by key.                                                  |

## Functions

### bool(map.typename m) bool

The *bool* function returns *false* if the map is empty, otherwise, it returns *true*.

### Del( map.typename m, str key ) map.typename

The *Del* function deletes the specified key and its value from the *map* array. The *m* parameter is returned.

### IsKey( map.typename m, str key ) bool

The *IsKey* function returns *true* if there is a value with the specified key in the *map* and *false*, otherwise.

### Key( map.typename m, int index ) str

The *Key* function returns the item key by its index. For example, this function can be used in the *for* loop to get the item key.

```go
for val,i in mymap {
    Println("\(Key(mymap, i)):\(val)")
}
```


# Multithreading

Operators and functions for working with threads (**thread** type) are described here.

* [Lock()](#lock)
* [resume( thread th )](#resume-thread-th)
* [SetThreadData(obj o)](#setthreaddata-obj-o)
* [sleep( int duration )](#sleep-int-duration)
* [suspend( thread th )](#suspend-thread-th)
* [terminate( thread th )](#terminate-thread-th)
* [ThreadData() obj](#threaddata-obj)
* [Unlock()](#unlock)
* [wait( thread th )](#wait-thread-th)
* [WaitAll()](#waitall)
* [WaitDone()](#waitdone)
* [WaitGroup( int count )](#waitgroup-int-count)

## Operators

| Operator            | Result | Description          |
| ------------------- | ------ | -------------------- |
| thread **=** thread |        | Assignment operator. |

## Functions

### Lock()

The *Lock* function blocks access to the global resource (mutex). If it is already occupied by another thread, then the current thread is waiting for it to be released. The mutex must be freed using the *Unlock* function.

### resume(thread th)

The *resume* function continues the work of the thread that was stopped by *suspend* function.

### SetThreadData(obj o)

The *SetThreadData* function assigns a variable of type *obj* to the current thread. The value of the variable can be retrieved with the *ThreadData* function.

### sleep(int duration)

The *sleep* function pauses the current thread for at least the *duration*, in milliseconds.

### suspend(thread th)

The *suspend* function suspends the *th* thread. Use the *resume* function to continue the thread.

### terminate(thread th)

The *terminate* function terminates the thread. If the thread has already completed, the function does nothing.

### ThreadData() obj

The *ThreadData* function returns the object that was assigned to the current thread. A variable of type *obj* is assigned to the thread by the function *SetThreadData*.

### Unlock()

The *Unlock* function releases access to a global resource (mutex).

### wait(thread th)

The *wait* function waits for the *th* thread to finish. If the thread has already finished, the function does nothing.

### WaitAll()

The *WaitAll* function waits when the *WaitGroup* counter becomes zero.

```go
run {
  int count = 3
  WaitGroup(count)
  for i in 1..count {
    go {
      // ...
      WaitDone()
    }
  }
  WaitAll()
}
```

### WaitDone()

The *WaitDone* function decreases the counter *WaitGroup* by one.

### WaitGroup(int count)

The *WaitGroup* function creates a *WaitGroup* counter for the threads that should end with a calling the *WaitDone* function. *count* - the initial value of the counter.


# Network

The functions for network/internet operations are described here.

* [Download( str url, str filename ) int](/stdlib/network#download-str-url-str-filename-int)
* [HeadInfo( str url ) hinfo](/stdlib/network#headinfo-str-url-hinfo)
* [HTTPGet( str url ) buf](/stdlib/network#httpget-str-url-buf)
* [HTTPPage( str url ) str](/stdlib/network#httppage-str-url-str)
* [HTTPRequest( str url, str method, map.str params, map.str headers ) str](/stdlib/network#httprequest-str-url-str-method-map-str-params-map-str-headers-str)

## Types

### hinfo

The *hinfo* type is used to get url address information and has the following fields:

* **int Status** - response status.
* **int Length** - content size. It may not be specified (equal to 0).
* **str Type** - content type. For example, *text/html; charset=UTF-8*.

## HTTP functions

### Download( str url, str filename ) int

The *Download* function downloads the file from the specified URL and saves it with the specified filename. The function returns the size of the downloaded file.

```go
    str ftemp = TempDir() + `/readme.html`
    int size = Download("https://github.com/gentee/gentee", ftemp)
```

### HeadInfo(str url) hinfo

The *HeadInfo* function sends a **HEAD** request to the specified *url* and returns the *hinfo* structure.

### HTTPGet( str url ) buf

The *HTTPGet* function sends a GET request to the specified URL and returns a response as a *buf* variable. The function can be used to download small files without saving them to disk.

### HTTPPage( str url ) str

The *HTTPPage* function sends a GET request to the specified URL and returns a string response.

### HTTPRequest( str url, str method, map.str params, map.str headers ) str

The *HTTPRequest* function sends an HTTP request to the specified URL and returns the response as a string. In the *method* parameter you need to specify the calling method - **GET, POST, UPDATE, PUT, DELETE**. The function also allows you to specify parameters and request headers. They are described as associative arrays where parameter name or header name is specified as a key. By default, the parameters are passed as form data when *POST* is called. If you want to send them in JSON format, then specify *"Content-Type": "application/json; charset=UTF-8"* in the *headers* parameter.

```go
    map empty
    Println(HTTPRequest(TESTURL, "GET", empty, empty))
    map params = { `name`: `Jong Doe`, `id`: `101` }
    Println(HTTPRequest(TESTURL, "GET", params, empty))
    Println(HTTPRequest(TESTURL, "POST", params, empty))
    map headjson = { `Content-Type`: `application/json; charset=UTF-8` }
    Println(HTTPRequest(TESTURL, "POST", params, headjson))
```


# Object

The **obj** type is used to store values of the following types - **int, bool, float, str, arr.obj, map.obj**. If no value is assigned to the object, then it is equal to **nil**. An object can be assigned values of a type that is different from the current one.\
The operators and functions for working with objects are described here.

* [arr( obj o ) arr.obj](/stdlib/obj#arr-obj-o-arr-obj)
* [arrstr( obj o ) arr.str](/stdlib/obj#arrstr-obj-o-arr-str)
* [bool( obj o ) bool](/stdlib/obj#bool-obj-o-bool)
* [bool( obj o, bool def ) bool](/stdlib/obj#bool-obj-o-bool-def-bool)
* [float( obj o ) float](/stdlib/obj#float-obj-o-float)
* [float( obj o, float def ) float](/stdlib/obj#float-obj-o-float-def-float)
* [int( obj o ) int](/stdlib/obj#int-obj-o-int)
* [int( obj o, int def ) int](/stdlib/obj#int-obj-o-int-def-int)
* [IsArray( obj o ) bool](/stdlib/obj#isarray-obj-o-bool)
* [IsMap( obj o ) bool](/stdlib/obj#ismap-obj-o-bool)
* [IsNil( obj o ) bool](/stdlib/obj#isnil-obj-o-bool)
* [item( obj o, int i ) obj](/stdlib/obj#item-obj-o-int-i-obj)
* [item( obj o, str s ) obj](/stdlib/obj#item-obj-o-str-s-obj)
* [map( obj o ) map.obj](/stdlib/obj#map-obj-o-map-obj)
* [obj( arr.typename a ) obj](/stdlib/obj#obj-arr-typename-a-obj)
* [obj( bool b ) obj](/stdlib/obj#obj-bool-b-obj)
* [obj( float f ) obj](/stdlib/obj#obj-float-f-obj)
* [obj( int i ) obj](/stdlib/obj#obj-int-i-obj)
* [obj( map.typename m ) obj](/stdlib/obj#obj-map-typename-m-obj)
* [obj( str s ) obj](/stdlib/obj#obj-str-s-obj)
* [Sort( arr.obj o, cmpobjfunc cmpfunc ) arr.obj](/stdlib/obj#sort-arr-obj-o-cmpobjfunc-cmpfunc-arr-obj)
* [str( obj o ) str](/stdlib/obj#str-obj-o-str)
* [str( obj o, str def ) str](/stdlib/obj#str-obj-o-str-def-str)
* [Type( obj o ) str](/stdlib/obj#type-obj-o-str)

## Types

### fn cmpobjfunc(obj, obj) int

The **cmpobjtype** function type is used to compare two objects. Functions of this type are used to sort objects in an array.

## Operators

| Operator                 | Result | Description                                                                                                     |
| ------------------------ | ------ | --------------------------------------------------------------------------------------------------------------- |
| \*obj                    | int    | If the object is *arr.obj* or *map.obj*, the number of items in the array is returned. Otherwise, it returns 0. |
| obj **?**                | bool   | Calls *bool(obj)*.                                                                                              |
| obj **=** arr.typename   | obj    | Assigning an array to an object.                                                                                |
| obj **=** bool           | obj    | Assigning a boolean value to an object.                                                                         |
| obj **=** float          | obj    | Assigning a decimal number to an object.                                                                        |
| obj **=** int            | obj    | Assigning a number to an object.                                                                                |
| obj **=** map.typename   | obj    | Assigning an associative array to an object.                                                                    |
| obj **=** obj            | obj    | Assignment operator.                                                                                            |
| obj **=** str            | obj    | Assigning a string to an object.                                                                                |
| obj **+=** obj           | obj    | Adding an object to an array of objects.                                                                        |
| obj **&=** obj           | obj    | Creates a clone of the object. The new variable will work with the same data set.                               |
| obj **\[** int/str **]** | obj    | Assign / get the value of an array by index. If the object is not *arr.obj* or *map.obj*, then an error occurs. |

## Functions

### arr(obj o) arr.obj

The *arr* function returns an array of objects. Object *o* must be an array, otherwise it returns an error. Calling the function does not create a new array, but returns the current array that contains the *o* object.

### arrstr(obj o) arr.str

The *arrstr* function converts an array of objects into an array of strings. The *o* object must be an array, otherwise an error is returned. The function returns the resulting array of strings.

### bool(obj o) bool

The *bool* function returns a logical value of the current type. For example, if an object contains a string, the result of calling *bool(str)* is returned. If the object is not defined, an error is returned.

### bool(obj o, bool def) bool

The *bool* function returns a logical value of the current type. If the object is not defined, the second parameter is returned.

### float(obj o) float

The *float* function converts an object to a decimal floating-point number. The object must contain a value of **str, int, float** type, otherwise, an error occurs.

### float(obj o, float def) float

The *float* function converts an object to a decimal floating-point number. If the object is not defined, the second parameter is returned.

### int(obj o) int

The *int* function converts an object to an integer. The object must contain a value of **str, int, float, bool** type, otherwise, an error occurs.

### int(obj o, int def) int

The *int* function converts an object to an integer. If the object is not defined, the second parameter is returned.

### IsArray(obj o) bool

The *IsArray* function returns *true* if the object is an array. Otherwise, the function returns *false*.

### IsMap(obj o) bool

The *IsMap* function returns *true* if the object is an associative array (map). Otherwise, the function returns *false*.

### IsNil(obj o) bool

The *IsNil* function returns *true* if the object is undefined (equal to **nil**). Otherwise, the function returns *false*.

### item(obj o, int i) obj

The *item* function returns the i-th element of the object. The object must be of **arr.obj** type. If the element is missing, then an empty object is returned.

### item(obj o, str s) obj

The *item* function returns the value of key **s**. The object must be of **map.obj** type. If there is no element, it returns an empty object.

### map(obj o) map.obj

The *map* function returns an associative array of objects. The *o* object must be an associative array (map), otherwise an error is returned. When the function is called, no new array is created, but the current *map* which contains object *o* is returned.

### obj(arr.typename a) obj

The *obj* function converts an array of the *arr* type into an object.

### obj(bool b) obj

The *obj* function creates an object with the specified logical value.

### obj(float f) obj

The *obj* function creates an object with the specified **float** value.

### obj(int i) obj

The *obj* function creates an object with the specified **int** value.

### obj(map.typename m) obj

The *obj* function converts an associative array of the *map* type into an object.

### obj(str s) obj

The *obj* function creates an object with the specified **str** value.

### Sort(arr.obj o, cmpobjfunc cmpfunc) arr.obj

The *Sort* function sorts an array of objects and returns it. Sorting is done using a function of **cmpobjfunc** type.

```go
func mySort(obj left, obj right) int {
  if str(left) < str(right) : return -1
  if str(left) > str(right) : return 1
  return 0
}

run str {
  arr a = {"qwr","7","10","ab","тест","абв", "ka"}
  obj o = a
  Sort( arr(o), &mySort.cmpobjfunc )
  ...
}
```

### str(obj o) str

The *str* function converts the object to a string and returns it.

### str(obj o, str def) str

The *str* function converts the object to a string and returns it. If the object is not defined, the second parameter is returned.

### Type(obj o) str

The *Type* function returns the value type of the specified object. The following types may be returned: **int, bool, float, str, arr.obj, map.obj**. If the object is undefined, then **nil** is returned.


# Path

The functions for manipulating filename paths are described here.

* [AbsPath( str path ) str](/stdlib/path#abspath-str-path-str)
* [BaseName( str path ) str](/stdlib/path#basename-str-path-str)
* [Dir( str path ) str](/stdlib/path#dir-str-path-str)
* [Ext( str path ) str](/stdlib/path#ext-str-path-str)
* [JoinPath( str path... ) str](/stdlib/path#joinpath-str-path-str)
* [MatchPath( str pattern, str path ) bool](/stdlib/path#matchpath-str-pattern-str-path-bool)
* [Path( finfo fi ) str](/stdlib/path#path-finfo-fi-str)

## Functions

### AbsPath(str path) str

The *AbsPath* function returns an absolute representation of path.

### BaseName(str path) str

The *BaseName* function returns the last element of path. Trailing path separators are removed before extracting the last element. If the path is empty, the function returns ".".

### Dir(str path) str

The *Dir* function returns all but the last element of path, typically the path's directory.

### Ext(str path) str

The *Ext* function returns the file name extension. The result extension is without a dot.

### JoinPath(str path...) str

The *JoinPath* function joins any number of path elements into a single path, adding a separator if necessary.

### MatchPath(str pattern, str path) bool

The *MatchPath* function checks if the given name matches the specified pattern. The function checks the pattern completely for the specified path, not for the substring. You can use a regular expression as a pattern. To do this, add a */* at the beginning and end.

* '\*' - matches any sequence of non-separator characters
* '?' - matches any single non-separator character

```
MatchPath(`*.txt`, `myfile.txt`)       // true
MatchPath(`?a?.pdf`, `1ab.pdf`)        // true
MatchPath(`/home/ak/my.pdf`, `*.pdf`)         // false
MatchPath(`/home/ak/my.pdf`, `/home/*/my.*`)  // true
MatchPath(`/home/ak/my.pdf`, `/home/*/my.*`) // true
MatchPath(`/user/`, `/home/user/myfile`) // true
```

### Path(finfo fi) str

The *Path* function concatenates the *Name* and *Dir* fields of the *finfo* variable and returns the resulting path.


# Process

Operators and functions for working with processes and applications are described here. The *Args* and *ArgCount* functions work with any command line format. For the correct operation of other *Arg...* functions, the command line must have the following format.

```go
CmdLine = [ CmdOptions ] ["-"] [ CmdParameters ]
CmdParameters = { CmdParameter }
CmdParameter = ParamWithoutSpace | "Param With Spaces" | 'Param With Spaces'
CmdOptions = {CmdOption}
CmdOption = "-" | "--" {letter} [ CmdOptionValue | CmdOptionValues ]
CmdOptionValue = "=" | ":" CmdParameter
CmdOptionValues = " " CmdParameters
```

```
-p="my value" --flag - one two three
-i:10 -n:Bob "one par" two three
--ext "*.txt" .js .html -o=/home/ak/dest /home/ak/in1 /home/ak/in2
```

* [Arg( str name ) str](/stdlib/process#arg-str-name-str)
* [Arg( str name, str def ) str](/stdlib/process#arg-str-name-str-def-str)
* [Arg( str name, int def ) int](/stdlib/process#arg-str-name-int-def-int)
* [ArgCount() int](/stdlib/process#argcount-int)
* [Args() arr.str](/stdlib/process#args-arr-str)
* [Args( str name ) arr.str](/stdlib/process#args-str-name-arr-str)
* [ArgsTail() arr.str](/stdlib/process#argstail-arr-str)
* [IsArg( str name ) bool](/stdlib/process#isarg-str-name-bool)
* [Open( str path )](/stdlib/process#open-str-path)
* [OpenWith( str app, str path )](/stdlib/process#openwith-str-app-str-path)
* [Run( str cmd, str params... )](/stdlib/process#run-str-cmd-str-params)
* [SplitCmdLine( str cmdline ) arr.str](/stdlib/process#splitcmdline-str-cmdline-arr-str)
* [Start( str cmd, str params... )](/stdlib/process#start-str-cmd-str-params)

## Operators

| Operator                 | Result | Description                                       |
| ------------------------ | ------ | ------------------------------------------------- |
| **$** command line       |        | Executes the command line.                        |
| str = **$** command line |        | Executes the command line and returns its output. |

## Functions

### Arg(str name) str

The *Arg* function returns the value of the parameter with the specified name. If the parameter was not specified at the start of the script, an empty string will be returned. You can omit the initial character **-** in the *name* parameter.

### Arg(str name, str def) str

The *Arg* function returns the value of the parameter with the specified **name**. If the parameter was not specified at the start of the script, **def** will be returned. You can omit the initial character **-** in the *name* parameter.

### Arg(str name, int def) int

The *Arg* function returns the numeric value of the parameter with the specified **name**. If the parameter was not specified at the start of the script, **def** will be returned. You can omit the initial character **-** in the *name* parameter.

### ArgCount() int

The *ArgCount* function returns the number of command line parameters with which the script was run.

### Args() arr.str

The *Args* function returns a list of all command-line parameters and options with which the script has been run.

### Args(str name) arr.str

The *Args* function returns a list of parameter values named **name**. You can omit the initial character **-** in the *name* parameter.

```
// --ext .txt .js .html -o=/home/ak/dest /home/ak/in1 /home/ak/in2
list = Args(`--ext`) 
// list == [.txt, .js, .html]
```

### ArgsTail() arr.str

The *ArgsTail* function returns the list of command line parameters after the options. You can explicitly specify the beginning of such parameters with **-**.

```
// --ext .txt .js .html -o=/home/ak/dest /home/ak/in1 /home/ak/in2
list = ArgsTail() // list == [/home/ak/in1, /home/ak/in2]

// -i=false - val0 -value1 "value 2" 
list = ArgsTail() // list == [val0, -value1, value 2]
```

### IsArg(str name) bool

The *IsArg* function returns *true* if the command line has an option with the specified name. Otherwise, it returns *false*. You can omit the initial character **-** in the *name* parameter.

### Open(str path)

The *Open* function opens a file, directory, or URI using the OS's default application for that object type. Don't wait for the open command to complete.

### OpenWith(str app, str path)

The *OpenWith* function opens a file, directory, or URI using the specified application. Don't wait for the open command to complete.

### Run(str cmd, str params...)

**Optional parameters**

* **buf stdin** - the buffer that will be passed to the application as standard input.
* **buf stdout** - the buffer into which the standard output of the application will be written.
* **buf stderr** - the buffer into which the standard error output of the application will be written.

The *Run* function starts the specified *cmd* program with parameters and waits for it to finish. Additionally, you can override the standard input and output.

```go
    buf dirout
    Run("dir", stdout: dirout)
    Run("bash", stdin: buf(
      |`echo "dirs"
        #comment    
        echo "%{str(dirout)}"`
    ))
```

### SplitCmdLine(str cmdline) arr.str

The *SplitCmdLine* function parses the input string with command line parameters and returns an array of parameters.

```go
run str {
    return SplitCmdLine(`param1 "second par" "qwert\"y" 100 'oo ps'
-lastparam`).Join(`=`)
}
// returns param1=second par=qwert"y=100=oo ps=-lastparam
```

### Start(str cmd, str params...)

**Optional parameters**

* **buf stdin** - the buffer that will be passed to the application as standard input.

The *Start* function starts the specified program *cmd* with parameters and runs the script further. Additionally, you can pass the buffer as standard input.

```go
    Start("echo", "hello, world!")
    Start("bash", stdin: buf(
      |`./myscript1.sh
        ./myscript2.sh`
    ))
```


# Regular expressions

Functions for working with regular expressions are described here.

* [FindFirstRegExp( str src, str re ) arr.str](/stdlib/regexp#findfirstregexp-str-src-str-re-arr-str)
* [FindRegExp( str src, str re ) arr.arr.str](/stdlib/regexp#findregexp-str-src-str-re-arr-arr-str)
* [Match( str s, str re ) bool](/stdlib/regexp#match-str-s-str-re-bool)
* [RegExp( str src, str re ) str](/stdlib/regexp#regexp-str-src-str-re-str)
* [ReplaceRegExp( str src, str re, str repl ) str](/stdlib/regexp#replaceregexp-str-src-str-re-str-repl-str)

## Functions

### FindFirstRegExp(str src, str re) arr.str

The *FindFirstRegExp* function finds the first occurrence of the regular expression *re* in the specified string *src*. The function returns an array of strings. The first element contains a substring that matches the regular expression, the remaining elements contain values of **(...)** groups, if they are defined in the regular expression.

```go
arr.str a &= FindFirstRegExp(`This45i33s a isi777s inis1i2sg`, `is(\d*)i(\d+)s`)
// a = {`is45i33s`, `45`, `33`}
```

### FindRegExp(str src, str re) arr.arr.str

The *FindRegExp* function finds all occurrences of the *re* regular expression in the specified string *src*. The function returns an array of arrays. The first element in each array contains a substring that matches the regular expression.

```go
arr.arr.str a &= FindRegExp(`My email is xyz@example.com`, `(\w+)@(\w+)\.(\w+)`)
// a = { { `xyz@example.com`, `xyz`, `example`, `com`} }
a &= FindRegExp(`This is a test string`, `i.`)
// a = { { `is` }, {`is`}, {`in`} }
```

### Match(str s, str re) bool

The *Match* function reports whether the string *s* contains any match of the regular expression pattern *re*.

```go
bool a = Match(`somethiabng striabnbg`, `a.b`)  // false
a = Match(`somethianbg string`, `a.b`) // true
```

### RegExp(str src, str re) str

The *RegExp* function returns the first occurrence of the regular expression *re* in the specified line *src*. If no match is found, an empty string is returned.

```go
  str input = "This is a string тестовое значение"
  ret = RegExp(input, `is (.{2})`) + RegExp(input, `е(.+?)е`)
  // isстово
```

### ReplaceRegExp(str src, str re, str repl) str

The *FindRegExp* function replaces matches of the *re* regular expression with the replacement string *repl. You can specify* $i *or* ${i} *in* repl\* for i-the submatch.

```go
str s = ReplaceRegExp("This is a string", `i(.{2})`, "xyz") 
// Thxyzxyza strxyz
s = ReplaceRegExp(" email is xyz@example.com", `(\w+)@(\w+)\.(\w+)`, "${3}.${2}@zzz")
// email is com.example@zzz
```


# Runtime

The functions for working with a virtual machine during script execution are described here.

* [error( int id, str text, anytype pars... )](/stdlib/runtime#error-int-id-str-text-anytype-pars)
* [ErrID( error err ) int](/stdlib/runtime#errid-error-err-int)
* [ErrText( error err ) str](/stdlib/runtime#errtext-error-err-str)
* [ErrTrace( error err ) arr.trace](/stdlib/runtime#errtrace-error-err-arr-trace)
* [exit( int code )](/stdlib/runtime#exit-int-code)
* [Progress( int id inc )](/stdlib/runtime#progress-int-id-inc)
* [ProgressEnd( int id )](/stdlib/runtime#progressend-int-id)
* [ProgressStart( int total ptype, str src dest ) int](/stdlib/runtime#progressstart-int-total-ptype-str-src-dest-int)
* [Trace() arr.trace](/stdlib/runtime#trace-arr-trace)

## Types

### trace

The *trace* type is used to store information about the called function and has the following fields:

* **str Path** - filename
* **str Entry** - current function
* **str Func** - called function
* **int Line** - the line in the source code
* **int Pos** - the position in the line where the function was called

## Functions

### error(int id, str text, anytype pars...)

The *error* function throws a custom runtime error.

* *id* - the identifier of the error,
* *text* - the text of the error,
* *pars* - optional parameters. If they are specified, then *text* must contain an appropriate template

  as in [Format](https://gentee.github.io/stdlib/string#formatstr-s-anytype-args-str) function.

```go
    error(10, `Error message %{ 10 }`)
    error(10, `Error message %d`, 10)
```

### ErrID(error err) int

The *ErrID* function returns the identifier of the *err* error. This function can be used inside **try-catch** statement for error handling.

```go
run {
  try {
    .....
    error(101, `oooops`)
  }
  catch err {
    if ErrID(err) == 101 {
      recover
    } elif ErrID(err) < 100 {
      retry
    }
  }
}
```

### ErrText(error err) str

The *ErrText* function returns the text of the *err* error. This function can be used inside **try-catch** statement for error handling.

### ErrTrace(error err) arr.trace

The *ErrTrace* function returns the stack of called functions at the moment when the *err* error occurs. This function can be used inside **try-catch** statement for error handling.

### exit(int code)

The *exit* function terminates the script. The function can be called in any thread. The script returns the value of *code*.

```go
func ok(int par) int {
  if par == 0 : exit(0)
  return 3 * par
}
run int {
  int sum
  for i in 10..-10 {
    sum += ok(i)
  }
  return sum
}
```

### Progress( int id inc )

The *Progress* function increases the process counter by the value of parameter *inc*. *id* is the progress bar identifier returned by the *ProgressStart* function. The *Progress* function calls Go function *ProgressFunc* which must be defined in the settings when the script starts.

```go
  int total = 200
  int prog = ProgressStart(total, 100, `counter`, ``)
  for i in 1...5 {
    Progress(prog, 40)
  }
  ProgressEnd(prog)
```

### ProgressEnd( int id )

The *ProgressEnd* function removes the process counter with the *id* identifier.

### ProgressStart( int total ptype, str src dest ) int

The *ProgressStart* function creates a process counter and returns its identifier. *total* is the maximum counter value. *ptype* - counter type, can be any number. *src* is the name of the source. *dest* is the name of the target. The functions for working with the progress bar do not display anything, they call the *ProgressFunc* function, which should be defined in [settings](/golang/reference) when running the script. In the *ProgressFunc* function you can display the state of the process in a way that is convenient for you. After you have finished working with this counter you must call *ProgressEnd* to delete it.

### Trace() arr.trace

The *Trace* function returns a stack of called functions.


# Sets

Operators and functions for working with an array of boolean values (**set** type) are described here.

* [arr( set s ) arr.int](/stdlib/sets#arr-set-s-arr-int)
* [set( arr.int a ) set](/stdlib/sets#set-arr-int-a-set)
* [set( str s ) set](/stdlib/sets#set-str-s-set)
* [str( set s ) str](/stdlib/sets#str-set-s-str)
* [Set( set s, int index ) set](/stdlib/sets#set-set-s-int-index-set)
* [Toggle( set s, int index ) bool](/stdlib/sets#toggle-set-s-int-index-bool)
* [UnSet( set s, int index ) set](/stdlib/sets#unset-set-s-int-index-set)

## Operators

| Operator             | Result | Description                                                                                |
| -------------------- | ------ | ------------------------------------------------------------------------------------------ |
| **\*** set           | int    | Returns the set size.                                                                      |
| **^** set            | set    | Returns a new set as logical NOT of the source set. *!s\[i]* for each item.                |
| set **=** set        | set    | Assignment operator.                                                                       |
| set **&=** set       | set    | Create a clone of the set. The new variable will work with the same data set.              |
| set **+=** set       | set    | Appends a set to a set variable.                                                           |
| set **&** set        | set    | Returns a set that is the intersection of two sets. *left\[i] && right\[i]* for each item. |
| set **\|** set       | set    | Returns a set that is the union of two sets. *left\[i] \|\| right\[i]* for each item.      |
| set **\[** int **]** | bool   | Sets/gets a set value.                                                                     |

## Functions

### arr(set s) arr.int

The *arr* function converts a *set* value to an array of integers that contains indexes of *set* items.

### set(str s) set

The *set* function converts a string to a *set* value and returns it. The string must only have 1 and 0 characters.

### set(arr.int a) set

The *set* function converts an array of integers to a *set* value and returns it. The result set will have items with corresponding indexes.

```
run arr.int {
  set s &= {780, 99, 128, 105, 136}
  arr.int as = arr(s)
  as += 330
  s &= set(as)
  return arr(s) // [99 105 128 136 330 780]
}
```

### str(set s) str

The *str* function converts a *set* value to a string and returns it. The result string contains only 1 and 0.

### Set(set s, int index) set

The *Set* function adds an index item to the set. It is the same as *s\[index] = true*. The function returns *s*.

### Toggle(set s, int index) bool

The *Toggle* function adds an index item to the set if the set doesn't have it and otherwise, the function removes the item. It is the same as *s\[index] = !s\[index]*. The function returns the previous state - *true* if the item existed and, otherwise, false.

### UnSet(set s, int index) set

The *UnSet* function removes an index item from the set. It is the same as *s\[index] = false*. The function returns *s*.


# Strings

Operators and functions for working with strings (**str** type) are described here.

* [bool( str s ) bool](/stdlib/string#bool-str-s-bool)
* [float( str s ) float](/stdlib/string#float-str-s-float)
* [int( str s ) int](/stdlib/string#int-str-s-int)
* [Find( str s, str substr ) int](/stdlib/string#find-str-s-str-substr-int)
* [Format( str s, anytype args... ) str](/stdlib/string#format-str-s-anytype-args-str)
* [HasPrefix( str s, str prefix ) bool](/stdlib/string#hasprefix-str-s-str-prefix-bool)
* [HasSuffix( str s, str suffix ) bool](/stdlib/string#hassuffix-str-s-str-suffix-bool)
* [Left( str s, int i ) string](/stdlib/string#left-str-s-int-i-str)
* [Lines( str s ) arr.str](/stdlib/string#lines-str-s-arrstr)
* [Lower( str s ) string](/stdlib/string#lower-str-s-str)
* [Repeat( str s, int count ) str](/stdlib/string#repeat-str-s-int-count-str)
* [Replace( str s, str old, str new ) str](/stdlib/string#replace-str-s-str-old-str-new-str)
* [Right( str s, int i ) string](/stdlib/string#right-str-s-int-i-str)
* [Size( int size, str format ) string](/stdlib/string#size-int-size-str-format-str)
* [Split( str s, str sep ) arr.str](/stdlib/string#split-str-s-str-sep-arrstr)
* [Substr( str s, int off, int length ) str](/stdlib/string#substr-str-s-int-off-int-length-str)
* [Trim( str s, str cutset ) str](/stdlib/string#trim-str-s-str-cutset-str)
* [TrimLeft( str s, str cutset ) str](/stdlib/string#trimleft-str-s-str-cutset-str)
* [TrimRight( str s, str cutset ) str](/stdlib/string#trimright-str-s-str-cutset-str)
* [TrimSpace( str s ) str](/stdlib/string#trimspace-str-s-str)
* [Upper( str s ) string](/stdlib/string#upper-str-s-str)

## Operators

| Operator             | Result | Description                                                                                       |
| -------------------- | ------ | ------------------------------------------------------------------------------------------------- |
| str **+** str        | str    | Merges two strings.                                                                               |
| **\*** str           | int    | Returns the length of the string.                                                                 |
| str **?**            | bool   | Calls *bool(str)*.                                                                                |
| **\|** str           | str    | This unary operator trims whitespace characters in the each line of the string.                   |
| str **==** str       | bool   | Returns *true* if the two strings are equal and *false*, otherwise.                               |
| str **>** str        | bool   | Returns *true* if the first string is greater than the second and *false*, otherwise.             |
| str **<** str        | bool   | Returns *true* if the first string is less than the second and *false*, otherwise.                |
| str **!=** str       | bool   | Returns *true* if the two strings are not equal and *false*, otherwise.                           |
| str **>=** str       | bool   | Returns *true* if the first string is greater than or equal to the second and *false*, otherwise. |
| str **<=** str       | bool   | Returns *true* if the first line is less than or equal to the second and *false*, otherwise.      |
| str **=** str        | str    | Assignment operator.                                                                              |
| str **=** int        | str    | Converts an integer to a string and assigns it to a variable.                                     |
| str **=** bool       | str    | Assigns "true" or "false".                                                                        |
| str **+=** str       | str    | Appends a string to a string variable.                                                            |
| str **\[** int **]** | int    | Sets/gets Unicode code by index.                                                                  |

## Functions

### bool(str s) bool

The *bool* function returns *false* if the string is empty, "0" or "false", otherwise, it returns *true*.

### float(str s) float

The *float* function converts a string to a number of *float* type. If the string has the wrong format, an error is returned.

### int(str s) int

The *int* function converts a string to an integer number. If the string has the wrong format, an error is returned.

### Find(str s, str substr) int

The *Find* function returns the index of the first instance of *substr* in *s*, or -1 if *substr* is not present in *s*.

### Format(str s, anytype args...) str

The *Format* function formats according to a *s* specifier and returns the resulting string. There are the following format verbs:

#### General

* **%v** - the value in a default format
* **%%** - a literal percent sign; consumes no value

#### bool

* **%t** -    the word true or false

#### int

* **%b** - base 2
* **%c** - the character represented by the corresponding Unicode code point
* **%d** - base 10. This is the default format for *int*.
* **%o** - base 8
* **%x** - base 16, with lower-case letters for a-f
* **%X** - base 16, with upper-case letters for A-F
* **%U** - Unicode format: U+1234

#### float

* **%e** - scientific notation, e.g. -1.234456e+78
* **%E** - scientific notation, e.g. -1.234456E+78
* **%f** - decimal point but no exponent, e.g. 123.456. You can specify the width and the precision like *%\[width].\[precision]f* - *%8.2f, %.3f, %7f*.
* **%g** - %e for large exponents, %f otherwise. Precision is discussed below. This is the default format for *float*.

#### str

* **%s** - the default format for strings
* **%x** - base 16, lower-case, two characters per byte
* **%X** - base 16, upper-case, two characters per byte

You can specify i-th argument in the format string like this - *Format("%d %\[1]d %\[1]d", 10)*

```
arr.int mya = {1,2,3}
time t
Format(`%s %v %v %g %6.2[4]f`, `ok`, mya, Now(t), 99.0 + 1.)
```

### HasPrefix(str s, str prefix) bool

The *HasPrefix* function returns *true* if the string *s* begins with *prefix*.

### HasSuffix(str s, str suffix) bool

The *HasSuffix* function returns *true* if the string *s* ends with *suffix*.

### Left(str s, int i) str

The *Left* function extracts a given number of characters from the left side of the string *s*.

### Lines(str s) arr.str

The *Lines* function slices *s* multi-line string into all substrings separated by new line. All substrings are returned as an array of strings.

### Lower(str s) str

The *Lower* function converts a copy of *s* string to lower case and returns it.

### Repeat(str s, int count) str

The *Repeat* function returns a new string consisting of *count* copies of the string *s*.

### Replace(str s, str old, str new) str

The *Replace* function returns a copy of the string *s* with all *old* strings replaced by *new* string.

### Right(str s, int i) str

The *Right* function returns a substring of the last *i* characters of the *s* string.

### Size(int size, str format) str

The *Size* function returns the rounded size as a string. In the *format* parameter specify an output pattern for a decimal floating-point number and a string. If *format* is an empty string, the format *%.2f%s* is used.

```go
Print( Size(956348901, `%.1f %s `) + Size(62, `%[2]s%.2[1]f `) + Size(123789, ``))
// 912.0 MB B62 120.89KB
```

### Split(str s, str sep) arr.str

The *Split* function slices *s* string into all substrings separated by *sep* string. All substrings are returned as an array of strings.

### Substr(str s, int off, int length) str

The *Substr* function returns a substring of the string *s* with the specified offset and length.

### Trim(str s, str cutset) str

The *Trim* function returns a substring of the string *s*, with all leading and trailing Unicode code points contained in *cutset* removed.

### TrimLeft(str s, str cutset) str

The *TrimLeft* function returns a substring of the string *s*, with all leading Unicode code points contained in *cutset* removed.

### TrimRight(str s, str cutset) str

The *TrimRight* function returns a substring of the string *s*, with all trailing Unicode code points contained in *cutset* removed.

### TrimSpace(str s) str

The *TrimSpace* function returns a substring of the string *s*, with all leading and trailing white space removed.

### Upper(str s) str

The *Upper* function converts a copy of *s* string to upper case and returns it.


# System

General system functions are described here.

* [GetEnv( str name ) str](/stdlib/system#getenv-str-name-str)
* [SetEnv( str name, bool|int|str val )](/stdlib/system#setenv-bool-or-int-or-str-name)
* [UnsetEnv( str name )](/stdlib/system#unsetenv-str-name)

## Functions

### GetEnv(str name) str

The *GetEnv* function returns the value of the environment variable.

```go
Print( GetEnv("PATH"))
// the same as
Print( $PATH )
```

### SetEnv(bool|int|str name)

The *SetEnv* function assigns the specified value to the environment variable.

```go
SetEnv("MYVARB", true)
SetEnv("MYVARI", 101)
SetEnv("MYVAR", "Test value")
// the same as
$MYVARB = true
$MYVARI = 101
$MYVARI = "Test value"
```

### UnsetEnv(str name)

The *UnsetEnv* function removes the environment variable.


# Time

Operators and functions for working with date and time (**time** type) are described here.

* [int( time t ) int](/stdlib/time#int-time-t-int)
* [time( int unixtime ) time](/stdlib/time#time-int-unixtime-time)
* [AddHours( time t, int hours ) time](/stdlib/time#addhours-time-t-int-hours-time)
* [Date( int year month day ) time](/stdlib/time#date-int-year-month-day-time)
* [DateTime( int year month day hour minute second ) time](/stdlib/time#datetime-int-year-month-day-hour-minute-second-time)
* [Days( time t ) int](/stdlib/time#days-time-t-int)
* [Format( str layout, time t ) str](/stdlib/time#format-str-layout-time-t-str)
* [Now( ) time](/stdlib/time#now-time)
* [ParseTime( str layout, str value ) time](/stdlib/time#parsetime-str-layout-str-value-time)
* [str( time t ) str](/stdlib/time#str-time-t-str)
* [UTC( time t ) time](/stdlib/time#utc-time-t-time)
* [Weekday( time t ) int](/stdlib/time#weekday-time-t-int)
* [YearDay( time t ) int](/stdlib/time#yearday-time-t-int)

## Types

### time

The *time* type has the following fields:

* **int Year** - year
* **int Month** - month
* **int Day** - day of month
* **int Hour** - hour
* **int Minute** - minute
* **int Second** - second
* **bool UTC** - if it is *true*, then it is UTC time, otherwise it is local time.

## Operators

| Operator         | Result | Description                                                                                     |
| ---------------- | ------ | ----------------------------------------------------------------------------------------------- |
| time **==** time | bool   | Returns *true* if the two time values are equal and *false*, otherwise.                         |
| time **>** time  | bool   | Returns *true* if the first time is greater than the second and *false*, otherwise.             |
| time **<** time  | bool   | Returns *true* if the first time is less than the second and *false*, otherwise.                |
| time **!=** time | bool   | Returns *true* if the two time values are not equal and *false*, otherwise.                     |
| time **>=** time | bool   | Returns *true* if the first time is greater than or equal to the second and *false*, otherwise. |
| time **<=** time | bool   | Returns *true* if the first time is less than or equal to the second and *false*, otherwise.    |
| time **=** time  | time   | Assignment operator.                                                                            |

## Functions

### int(time t) int

The *int* function converts *time* value to a Unix time, the number of seconds elapsed since January 1, 1970 UTC and returns it.

### time(int unixtime) time

The *time* function converts the given Unix time, sec seconds since January 1, 1970 UTC to *time* structure and returns it.

### AddHours(time t, int hours) time

The *AddHours* function returns the time corresponding to adding the given number of hours to *t*. The *hours* parameter can be negative.

### Date(int year month day) time

The *Date* function returns a structure of the *time* type with the specified date.

### DateTime(int year month day hour minute second) time

The *DateTime* function returns the *time* structure as local time. Also, you can initialize a time variable like this

```
time t = {Year: 2018, Month: 12, Day: 12}
```

### Days(time t) int

The *Days* function returns the number of days in the month in which the specified time is located.

### Format(str layout, time t) str

The *Format* function returns a textual representation of the time value formatted according to layout. It takes a string of tokens and replaces them with their corresponding values.

|                 | Token | Output            |
| --------------- | ----- | ----------------- |
| **Year**        | YYYY  | 2019              |
|                 | YY    | 19                |
| **Month**       | MMMM  | January           |
|                 | MMM   | Jan               |
|                 | MM    | 01..12            |
|                 | M     | 1..12             |
| **Day**         | DD    | 01..31            |
|                 | D     | 1..31             |
| **Day of Week** | dddd  | Monday            |
|                 | ddd   | Mon               |
| **AM/PM**       | PM    | AM PM             |
|                 | pm    | am pm             |
| **Hour**        | HH    | 00..23            |
|                 | hh    | 01..12            |
|                 | h     | 1..12             |
| **Minute**      | mm    | 00..59            |
|                 | m     | 1..59             |
| **Second**      | ss    | 00..59            |
|                 | s     | 1..59             |
| **Time Zone**   | tz    | MST               |
|                 | zz    | -0700 ... +0700   |
|                 | z     | -07:00 ... +07:00 |

### Now() time

The *Now* function returns the current local time.

### ParseTime(str layout, str value) time

The *ParseTime* function parses a formatted string and returns the time value it represents. The list of layout tokens is the same as in **Format** function.

```
run str {
  time t &= ParseTime(`MMM D, YYYY at h:mmpm (zz)`, `Jun 7, 2019 at 6:05am (+0300)`)
  time t1 &= ParseTime(`YY/MM/DD HH:mm:s`, `19/05/29 03:21:3`)
  return Format(`YY/MM/DD HH:mm:ss zz`, UTC(t)) + Format(` YY/MM/DD HH:mm:ss`, UTC(t1))
}
// 19/06/07 03:05:00 +0000 19/05/29 03:21:03
```

### str(time t) str

The *str* converts the specified time to a string in the format **YYYY-MM-DD HH:mm:ss**.

### UTC(time t) time

The *UTC* function converts local time to UTC and returns a new time structure. If the time *t* was already UTC, then a copy of it is returned.

### Weekday(time t) int

The *Weekday* function returns the day of the week specified by *t*. 0 - Sunday, 1 - Monday etc.

### YearDay(time t) int

The *YearDay* function returns the day of the year specified by *t*.


# Go Integration

Documentation on using the Gentee programming language in Golang projects.


# Reference

The functions and structures for using the **Gentee** programming language in **Golang** projects are described here.

* [type Custom](/golang/reference#type-custom)
* [type EmbedItem](/golang/reference#type-embed-item)
* [type Settings](/golang/reference#type-settings)
* [type Progress](/golang/reference#type-progress)
* [Customize(custom \*Custom) error](/golang/reference#customize-custom-custom-error)
* [New() \*Gentee](/golang/reference#new-gentee)
* [(g \*Gentee) Compile(input, path string) (\*Exec, int, error)](/golang/reference#g-gentee-compile-input-path-string-exec-int-error)
* [(g \*Gentee) CompileAndRun(filename string) (interface{}, error)](/golang/reference#g-gentee-compileandrun-filename-string-interface-error)
* [(g \*Gentee) CompileAndRun(filename string) (\*Exec, int, error)](/golang/reference#g-gentee-compilefile-filename-string-exec-int-error)
* [(exec \*Exec) Run(settings Settings) (interface{}, error)](/golang/reference#exec-exec-run-settings-settings-interface-error)
* [Gentee2GoType(val interface{}, vtype... string) interface{}](/golang/reference#gentee-2-gotype-val-interface-vtype-string-interface)
* [Go2GenteeType(val interface{}, vtype... string) (interface{}, error)](/golang/reference#go-2-genteetype-val-interface-vtype-string-interface-error)
* [Version() string](/golang/reference#version-string)

## Types

### type Custom

The *Custom* type is used for additional configuration of the compiler and virtual machine. It is passed when the **Customize** function is called.

* **Embedded** \[]EmbedItem - an array of additional functions for the standard library.

### type EmbedItem

The *EmbedItem* type describes the function to be embedded in the standard library. It is used in the **Custom** type.

* **Prototype** string - a description of the function in the Gentee language. For example, *myfunc(str,int) int*.
* **Object** interface{} - the corresponding golang function.

### type Settings

The *Settings* type is used to specify additional parameters when starting the bytecode in the **Run** method.

* **CmdLine** \[]string -  an array of command line parameters.
* **Stdin** \*os.File - custom standard input.
* **Stdout** \*os.File - custom standard output.
* **Stderr** \*os.File - custom error output.
* **Input** \[]byte - predefined standard input (stdin). Can be used, for example, in the function [ReadString](/stdlib/console#readstring-string-text-str).
* **Cycle** uint64 - maximum number of iterations in the loop. By default, it is 1600000000.
* **Depth** uint32 - maximum nesting of executable blocks. Limits the recursion depth. By default, it is equal to 1000.
* **SysChan** chan int - the channel for sending *SysSuspend* (1), *SysResume* (2), *SysTerminate* (3) commands. It allows you to control the script execution from the outside.
  * *SysSuspend* - suspend the script execution and all its threads.
  * *SysResume* - resume the script execution and all its threads.
  * *SysTerminate* - terminate the script and all its threads.
* **IsPlayground** bool - assign *true* if you want to run the script in safe [playground](/golang/playground) mode.
* **Playground** Playground - configure the playground mode.
  * *Path* string - path to the temporary directory for writing and reading files. If it is not specified, the subdirectory in the temporary directory will be created.
  * *AllSizeLimit* int64 - total size of files. By default, it is 10 MB.
  * *FilesLimit* int - maximum number of files. By default, 100.
  * *SizeLimit* int64 - maximum file size. By default, 5 MB.
* **ProgressFunc** gentee.ProgressFunc - a function for displaying the progress of copying, downloading, etc., for example, as a progress bar. The function must be of the following type: &#x20;

  *func MyProgress(progress \*gentee.Progress) bool* &#x20;

  and return *true*. The *Progress* type is described below. The *ProgressFunc* function is called when copying, downloading files or also when calling the [Progress](/stdlib/runtime#progress-int-id-inc) function.

```go
    settings.SysChan = make(chan int)
    go func() {
        _, err = exec.Run(settings)
    }()
    settings.SysChan <- gentee.SysTerminate
```

### type Progress

The *Progress* type is used to display the process of copying, downloading. A variable of this type is passed to the *ProgressFunc* function and has the following fields:

* **ID uint32** - unique identifier.
* **Type int32** - process type.
  * *ProgressCopy (0)* - copying.
  * *ProgressDownload (1)* - downloading.
  * *ProgressCompress (2)* - compression.
  * *ProgressDecompress (3)* - unpacking.
* **Status int32** - status.
  * *ProgStatusStart (0)* - the beginning of the process.
  * *ProgStatusActive (1)* - the process is in progress. &#x20;
  * *ProgStatusEnd (2)* - the process is over. &#x20;
* **Total int64** - total size.
* **Current int64** - current size.
* **Source string** - source file (object).
* **Dest string** - target file (object).
* **Ratio float64** - *Current/Total* ratio. To get percent you need to multiply by 100.
* **Custom interface{}** - serves to store any additional information.

## Functions and methods

### Customize(custom \*Custom) error

The *Customize* function is used for [additional settings of the compiler](/golang/customize) and virtual machine. It should be called before all the functions. The function returns the error value.

### New() \*Gentee

The *New* function creates a workspace for compiling source code.

### (g \*Gentee) Compile(input, path string) (\*Exec, int, error)

The *Compile* function compiles the script passed to *input*. You can specify the path to the script in the *path* parameter. The function returns a bytecode structure, module number and error value.

### (g \*Gentee) CompileAndRun(filename string) (interface{}, error)

The *CompileAndRun* function compiles the script from the *filename* file and executes it. The function returns the result of the script and the error value.

### (g \*Gentee) CompileFile(filename string) (\*Exec, int, error)

The *CompileFile* function compiles the script from the *filename* file. The function returns a bytecode structure, module number, and error value.

### (exec \*Exec) Run(settings Settings) (interface{}, error)

The *Run* function executes bytecode from the *exec* structure. You can specify additional settings in the *settings* parameter. The function returns the result of the script and the error value.

### Gentee2GoType(val interface{}, vtype... string) interface{}

The *Gentee2GoType* function converts the Gentee variable to standard Go types. In the second parameter, you can specify the Gentee type of a variable. For example, *arr.bool*. In this case you will get an array of variables of *bool* type instead of *int64*. You can use this function in your embedded functions.

Type correspondence

| Gentee type | Param type    | Result type (vtype)     |
| ----------- | ------------- | ----------------------- |
| int         | int64         | int64                   |
| bool        | int64         | bool ("bool")           |
| char        | int64         | rune ("rune")           |
| float       | float64       | float64                 |
| str         | string        | string                  |
| arr         | \*core.Array  | \[]interface{}          |
| buf         | \*core.Buffer | \[]byte                 |
| map         | \*core.Map    | map\[string]interface{} |
| set         | \*core.Set    | \[]byte                 |
| struct type | \*core.Struct | map\[string]interface{} |
| obj         | \*core.Obj    | interface{}             |

```go
func cnv1(in *core.Map) (*core.Map, error) {
  my := gentee.Gentee2GoType(in).(map[string]interface{})
  for key, a := range my {
    for i, v := range a.([]interface{}) {
      a.([]interface{})[i] = v.(int64) + 1
    }
    delete(my, key)
    my[key+`2`] = a
  }
  ret, err := gentee.Go2GenteeType(my)
  return ret.(*core.Map), err
}
```

### Go2GenteeType(val interface{}, vtype... string) (interface{}, error)

The *Go2GenteeType* function converts a value of the standard Go type to a value of Gentee type. In the second parameter you can specify the Gentee type of the variable. For example, *set* if you want to convert *\[]byte* to \*core.Set. You can use this function in your embedded functions.

Type correspondence

| Gentee type | Param type              | Result type (vtype) |
| ----------- | ----------------------- | ------------------- |
| int         | all int & uint          | int64               |
| bool        | bool                    | int64               |
| char        | rune                    | int64               |
| float       | float64                 | float64             |
| str         | string                  | string              |
| arr         | \[]interface{}          | \*core.Array        |
| buf         | \[]byte                 | \*core.Buffer       |
| set         | \[]byte                 | \*core.Set ("set")  |
| map         | map\[string]interface{} | \*core.Map          |
| obj         | interface{}             | \*core.Obj ("obj")  |

```go
func cnv5(in *core.Set) (*core.Set, error) {
  my := gentee.Gentee2GoType(in).([]byte)
  for i, b := range my {
    if i > 10 {
      break
    }
    if b == 0 {
      my[i] = 1
    } else {
      my[i] = b - 1
    }
  }
  ret, err := gentee.Go2GenteeType(my, `set`)
  return ret.(*core.Set), err
}
```

### Version() string

The *Version* function returns the current version number of the language.


# Compilation and execution

Let's see how to use the Gentee compiler and virtual machine in projects in the **Go** programming language.

## Compilation

To get started, you need to create the *Gentee* structure using the **New** function. This structure will store all information about compiled scripts. You just need to create one instance and compile any number of scripts.

To compile scripts, you need to use the methods **Compile**, **CompileFile**, **CompileAndRun**. The methods *Compile*, *CompileFile*, in case of successful compilation, return the structure *Exec*, which contains the bytecode. You can save or pass this structure for later execution using the **Run** method. The *CompileAndRun* method immediately after compilation executes the script and returns its result.

```go
package main
import (
    "fmt"
    "log"

    "github.com/gentee/gentee"
)

func main() {
    g := gentee.New()

    exec,_, err := g.Compile("run : Print(`Hello, world!`)", "")
    if err != nil {
        log.Fatal(err)
    }
    exec.Run(gentee.Settings{})
    exec,_, err = g.CompileFile("/home/ak/scripts/myscript.g")
    if err != nil {
        log.Fatal(err)
    }
    exec.Run(gentee.Settings{})

    var result interface{}
    result, err = g.CompileAndRun("../torun.g")
    fmt.Println(`Error:`, err, `Result:`, result)
}
```

## Bytecode Execution

The ready byte code of the script is stored in a structure of the **Exec** type. To execute it, call the **Run** method. The parameter of the type [**Settings**](/golang/reference#type-settings) allows you to pass command line parameters and specify additional settings for the virtual machine.

```go
package main
import (
    "fmt"
    "log"

    "github.com/gentee/gentee"
)

func main() {
    g := gentee.New()

    exec,_, err := g.CompileFile("myscript.g")
    if err != nil {
        log.Fatal(err)
    }
    var result interface{}
    result, err = exec.Run(gentee.Settings{
        CmdLine: []string{
            "-par1",
            "-o",
            "/home/ak/tmp",
        },
    })
    fmt.Println(`Error:`, err, `Result:`, result)
}
```


# Advanced features

## How to add your functions to the standard library

When using **Gentee** in other projects, it may be necessary to expand the standard library. The **Customize** function allows you to add any number of go-functions to the standard library and use them in scripts. It should be noted that in this case the scripts will not be compiled by the original compiler, since there will be no added functions there. The **Customize** function must be called before calling other functions from the gentee package.

To expand the standard library, you should specify an array of functions in the parameter of the [*Custom*](/golang/reference#type-custom) type. Each function is described by the structure [*EmbedItem*](/golang/reference#type-embed-item), in which a prototype in the Gentee language and the function itself are specified. The function may return a value of the *error* type and have a variable number of parameters.

### Type correspondence

Parameters and return value of go-functions must have types in accordance with this table. When using *core* types, you must import *github.com/gentee/gentee/core*.

| Gentee type | Golang type   |
| ----------- | ------------- |
| int         | int64         |
| bool        | int64         |
| char        | int64         |
| thread      | int64         |
| float       | float64       |
| str         | string        |
| arr         | \*core.Array  |
| buf         | \*core.Buffer |
| map         | \*core.Map    |
| set         | \*core.Set    |
| struct type | \*core.Struct |
| obj         | \*core.Obj    |

```go
func sum(x, y int64) int64 {
    return x + 2*y
}

func varInt(init int64, pars ...int64) int64 {
    for _, i := range pars {
        init += i
    }
    return init
}

func shortLen(s string) (int64, error) {
    if len(s) < 10 {
        return len(s), nil
    }
    return 0, fmt.Errorf("string %s is too long", s)
}

func main() {
    var customLib = []gentee.EmbedItem{
        {Prototype: `sum(int,int) int`, Object: sum},
        {Prototype: `InitSum(int) int`, Object: varInt},
        {Prototype: `ShortLen(str) int`, Object: shortLen},
    }
    err := gentee.Customize(&gentee.Custom{
        Embedded: customLib,
    })
    if err != nil {
        log.Fatal(err)
    }
    workspace := gentee.New()
    exec, _, err := workspace.Compile(`run {
    Println("Sum = %{sum(10, 6)}")
    Println("InitSum = " + InitSum(4, 67, 4, 22))
    ShortLen("this string is too long")
}`, ``)
    ...
}
```


# Playground

If you want to allow third parties to run Gentee scripts on your computer, use the *Playground* mode when running the scripts. This mode is convenient to run scripts for demonstration or educational purposes and protects the data on your computer from accidental or intentional damage. To enable this mode, specify the *IsPlayground* field as *true* in the [*Settings*](/golang/reference) structure when launching a script using the *Run* function. In addition, it is recommended to reduce the *Cycle* and *Depth* parameters to set limits on resources consumed.

Scripts working in the *Playground* mode have the following restrictions:

* **Processes**. Disabled launches of any processes, including opening files in the corresponding applications. In other words, the functions *Open, OpenWith, Run, Start* will not work. The **$** command will not work too.
* **File system**. The files could be written and read only in the directory, which is specified in the Playground settings. If it is not specified, the subdirectory is created in the temporary directory. This subdirectory becomes current at script start. In addition, there are restrictions on:
  * the total number of files (by default, 100).
  * total file size (by default, 10 MB).
  * maximum file size (by default, 5 MB).
* **Network**. *HTTPRequest* function is disabled. Calling the *Download, HTTPGet, HTTPPage* functions virtually adds a file with the corresponding size to the playground directory. Thus, these functions are also restricted by the file system restrictions.

If an error occurs during the script operation due to *Playground* mode restrictions, the script will stop working. In this case, the error text will begin with **\[Playground]**.

```go
run {
    $ echo "ooops"
}
// ERROR: [2:5] [Playground] starting any processes is disabled
run {
    AppendFile(".../out.txt", "this is a test message")
}
// ERROR: [2:5] [Playground] access denied [.../out.txt]
run {
    for i in 1...110 {
        CreateFile(`%{i}.txt`, false)
    }
}
// ERROR: [3:9] [Playground] file limit reached [100]
```


