# Statements

Statements are separated into two groups: operations and control flow. Operations are assignments and procedure calls. Control flow includes `if`, `each` and `while` statements. Statements can be grouped into statemenet block using `do` and `end`. Statement block is treated like a single statement.

``````do
a := a + 1;
b := b + 1;
end;``````

Each statement inside statement block must be ended with `;`. Statement block without statements inside is empty statement block and does nothing. Also some statements can have their own inner variables. These variables are accessible only inside their statements, but are declared in function scope so their names should not conflict with local variables.

## Expressions

Expressions in Jarog represents relations between constants, variables and values, declared using math operations.

### Operations

To express relations between variables and constants Jarog has unary and binary operations. Unary operations have the highest priority.

Symbol Operand types Description
`-` `int`, `float` Minus
`!` `bool` Logical Not
`@` `list`, `set` List length or set power

Binary operations have different priority. Jarog supports next operations given in order by their priority. Higher operations have higher priority.

Symbol Operand types Description
`^` `int`, `float` Power
`*` `int`, `float`, `set` Multiplication
`/` `int`, `float`, `set` Division
`%` `int`, `float` Modulo
`+` `int`, `float`, `set` Addition
`-` `int`, `float` Subtraction
`:` `int` Range
`=` any type Equals
`<>` any type Not equals
`>` `int`, `float`, `set` Is greater
`<` `int`, `float`, `set` Is less
`>=` `int`, `float` Is greater or equal
`<=` `int`, `float` Is less or equal
`&` `bool` Logical And
`|` `bool` Logical Or
• Length operation (`@`) is applicable to lists or sets, it returns length of list or set power (number of elements in set).
• Power, multiplication, modulo, addition and subtraction keeps result `int` if both operands are `int`.
• Division always results `float`.
• Range is a special operation, it constructs list of integers from first value to last with step 1, both values are included. If first value is bigger than last then list is reversed.

## Procedure call

Procedures are functions, that return no results, procedures unlike functions can be called instantly.

``````const proc := \$() do
# do smth here
end;

...
proc();``````

Functions and any other expressions can not be called instantly cause they all have results, which must be assigned to some variable (or logged). On the other hand procedures can not be used in expressions or logged.

``log proc();           # will cause an error``

## Assignment

Assignment calculates expression result and assigns it to a variable. Unlike the most of languages Jarog uses symbol `:=` to assign values.

``<var1> := <expr1>;``

Also there is a way to assign multiple values at once.

``````var a, b, c: int;
...
{a, b} := {0, 1};
{a, b} := {b, a};          # swap values
[a, b] := [0, 1];          # lists are fine too
[{a, b}, c] := [{1, 2}, 3] # even combined values``````

Structures and lists are automatically destructed into tuple of variables and tuple of values can be composed into a struct and assigned to it as a single value. For better understanding see Structs and Lists

## If statement

If statement has next syntax structure:

``````if (<expression>)
<statement1>
else
<statement2>;``````

Expression must be bool, first branch is executed if expression results true otherwise second branch is executed.

Second branch is optional.

``````if (<expression>) do
<statement1>;
<statement2>;
...
end;``````

## While statement

While statement is the generic way to declare loops in Jarog. Expression must return boolean. Loop body is repeated while expression is true.

``````while (<expression>)
<statement1>;``````

### Break and Continue

Like the most other languages, Jarog has `break` and `continue` statements, used to interrupt loop execution. `break` stops loop execution and `continue` stops current iteration of the loop and moves to next one.

``````while (true) do
n := n + 1;
if (n > 10)
break;
end;``````

## Each statement

Each statement is a special loop construction designed to walk through list or set. Example of declaration is next:

``````each (<list> -> <var>: <type>)
<statement>;``````

It accepts two arguments - `<list>` and `<var>`. `<var>` is inner variable, it is declared and accessible only inside each statements. `<type>` must be compatible with `<list>` item type. Loop is executed as many times as many items `<list>` contains. Each time next item of list is assigned to `<var>`. `<var>` is writable inside loop but this doesnвЂ™t affects `<list>` items. Also list items can be changed during loop execution but it wouldnвЂ™t take any effect on loop execution as it uses a copy of `<list>` during all iterations. Loop execution can be interrupted with `break` and `continue` statements. After loop ends `item` preserves itвЂ™s value assigned to it during the last iteration. Example:

``````each([1, 2, 3] -> n: int)
log n;                    ``````

There is alternative form of `each` when no variable is declared.

``````each (<list> -> <expression>)
<statement>;``````

`<expression>` must be assignable to use it inside each. In this case after the last iteration last value of expression is preserved outside of `each`. For example this code will print `1 is one, 2 is two, 3 is three,`:

``````var n: int;
var s: string;
...
each([{1, "one"}, {2, "two"}, {3, "three"}] -> {n, s})
io::put(str::fmt("%d is %s, ", [n, s]));``````

## With statement

With statement syntax is displayed below:

``````with (<expression> -> <var>: <type>)
<statement>;``````

This statement declartes a variable visible in next statement only similar to `each` statement. See more in statement variables

## Exception handling

Exceptions can be handled with next syntax construction:

``````try
<statement>
catch(<var>: <type>)
<catch statement>;``````

Variable `<var>` shouldnвЂ™t be declared in function scope as it is inner variable. There is no special type Exception to be thrown in Jarog. Value of any type can be thrown. Standard exceptions throw string.

Here is some examples for better understanding.

``````var f: float;
try
f := f / 0      # division by zero throws string
catch(e: string)    # which can be caught here
io::print(e);``````

There is also an ability to use try with multiple catches and throw own exceptions.

``````try
throw 5         # int exception is thrown
catch(e1: string)
io::print(e1)   # this catch will be ignored
catch(e2: int) do
if (e2 = 5)
io::put("Error 5")
else
io::put("Unknown error");
end;``````

When the exception is thrown interpreter searches first catch clause, which has compatible type and executes it. If no suitable catch clauses found, exception is thrown again. Also if there is two or more clauses with compatible types, only first one is executed. Never move catch with int type below catch with float, otherwise float will eat all int exceptions.

``````try
throw 5                  # int exception is thrown
catch(e1: float)            # int can be assigned to float
io::put("float error")   # so this will be called
catch(e2: int)
io::put("int error");    # is never called``````

Catch section can has no variables at all. In this case it will catch all exceptions, but it will have no information about it.

``````try
throw "I'm exception!"
catch
io::put("Some terrible exception happened but we don't know which :(");``````

Exception handling does not support finally section. Instead of this Jarog has binded functions.

### Try Finally

Instead of catch `try` statement can have `finally` section. This statement is executed always, even if exception is thrown inside or return statement is called. It does not eats exception so it can be used inside try-catch statement.

## Log

Log prints expression value to stdout. It can be used for debug purposes. It accepts expressions with any result types. Expression is executed and itвЂ™s result is printed to console.

``log "Hello, world!"; ``

## Run

Run accepts procedure. It calls the procedure and runs in a new thread. When the procedure is executed thread is terminated.

``````const proc := \$() do
# do smth here
end;

run proc();     ``````

Threads can interact with other threads and share data among them using global variables, closures or pipes, but accessing a global variable or closure without synchronization can cause undefined behavior and data corruption.

## Sync

Sync statements wraps an instruction into critical section and ensures that only one thread at a time can execute it. Sync can have a name - string variable. If there are few blocks with the same name, only one of them can be executed at a time. Name is optional.

``````sync("<name>") do
<statement>;
...
end;``````