# Functions

Functions are the entry points to a virtual machine. They can be called from another machine or from the outside.

In this section, we describe functions with this simple virtual machine:

``````
machine Machine {

degree 256;

reg pc[@pc];
reg X[<=];
reg Y[<=];
reg Z[<=];
reg CNT;
reg A;
reg B;

// an instruction to assert that a number is zero
instr assert_zero X {
X = 0
}

instr jmp l: label {
pc' = l
}

// an instruction to jump to a label iff `X` is `0`, otherwise continue
instr jmpz X, l: label {
pc' = XIsZero * l + (1 - XIsZero) * (pc + 1)
}

// an instruction to return the square of an input as well as its double
instr square_and_double X -> Y, Z {
Y = X * X,
Z = 2 * X
}

function main {
// initialise `A` to 2
A <=X= 2;
// initialise `CNT` to `3`
CNT <=X= 3;
start::
jmpz CNT, end;
// decrement `CNT`
CNT <=X= CNT - 1;
// get the square and the double of `A`
A, B <== square_and_double(A);
// jump back to `start`
jmp start;
end::
// check that `A == ((2**2)**2)**2`
assert_zero A - ((2**2)**2)**2;
// check that `B == ((2**2)**2)*2`
assert_zero B - ((2**2)**2)*2;
return;
}

// some superpowers on `X` to allow us to check if it's 0
col witness XInv;
col witness XIsZero;
XIsZero  = 1 - X * XInv;
XIsZero * X = 0;
XIsZero * (1 - XIsZero) = 0;
}

``````

## Function inputs and outputs

Function inputs and outputs are not supported yet

## Statements

### Labels

Labels allow referring to a location in a function by name.

``````        start::
``````

### Assignments

Assignments allow setting the values of some write registers to the values of some expressions expression using assignment registers.

``````        CNT <=X= 3;
``````

If the right-hand side of the assignment is an instruction, assignment registers can be inferred and are optional:

``````        A, B <== square_and_double(A);
``````

This will be inferred to be the same as `A, B <=Y, Z= square_and_double(A);` from the definition of the instruction:

``````    instr square_and_double X -> Y, Z {
Y = X * X,
Z = 2 * X
}
``````

### Instructions

Instructions which do not return outputs can be used as statements.

``````        assert_zero A - ((2**2)**2)**2;
``````