# Intermediate Cairo Cheatsheet
## Types
There are 5 possible types
- felt
- felt*
- felt**
- codeoffset
- tuple
Structs are like aliases to tuples and a tuple can be easily cast into a struct with `cast((1,2,3), MyTuple)`
## `codeoffset`
`codeoffset`s are pc's of labels in Cairo programs.
A **label** is either a function name or a custom label that can be defined with:
```cairo=
my_code_offset:
```
There are not many ways to use them but they have an useful property where `typeof (codeoffset - codeoffset) == felt`.
`get_label_position` function in standard library uses it:
```cairo=
let (_, pc_val) = get_fp_and_pc()
ret_pc_label:
return (res=pc_val + (label_value - ret_pc_label))
```
It works something like this:
1. `get_fp_and_pc` returns the pc at the start of the function
2. `ret_pc_label:` defines a label and a codeoffset wrt the program base (pb + $1)
3. `label_value - ret_pc_label` returns the distance between target function and the current function, adding it to the current function's pc gives us the actual pc location (which is a felt* by the way)
## jmp
Jumps to the given instruction. This instruction can be a label, a relative position `rel <number>` or an absolute position `abs <number>`.
## call
Makes a call to given instruction. This instruction can be a label, a relative position `rel <number>` or an absolute position `abs <number>`.
Arguments are received from the stack and return values are pushed to the stack.
So this statement
```r
let (x: felt) = add(1,2)
```
is the equivalent of
```r
[ap] = 1
[ap+1] = 2
ap += 2
call add
let x = [ap-1]
```
## Expressions
Possible expressions are:
- `+`, `-`, `*`, `/` and `**` (power operator)
- `&`, gets address of the felt, can't get address of a felt**
- `-` to negate something
- `new` to create a struct.
> `tempvar x = new (1+2)` is also legal but doesn't do anything different than `tempvar x = 1+2`
## Literals
Integers, hex ints and short strings (<32 characters, uses single quotes) are allowed.
Compiler errors when a string is longer than 31 characters, so you don't need to worry about it.
## `tempvar`, `let`, `local`
- Using `tempvar` is equal to using
```cairo=
[ap] = ...; ap++
let x = [ap-1]
```
- `let` expressions are inlined in the compiled code
- `local` expressions require either `alloc_locals` keyword or the usage of `ap += SIZEOF_LOCALS` in the function, which is what alloc_locals does in the background. Using a literal instead of `SIZEOF_LOCALS` is not allowed.
A `local` expression is equivalent of
```cairo=
[fp] = ...
ap += 1
let x = [fp]
```
- `local`s can be assigned after they have been declared
```cairo=
local x
x = 5
```
## Implicit Arguments
It's possible to add implicit parameters to a function, this way you won't need to use them again on subsequent calls.
```cairo=
func a{
imp_arg_1: felt
imp_arg_2: felt
}():
...
a()
end
```
Working on more details
## static_assert
This is an assert that is done in compile-time. Takes a boolean expression on RHS.
```cairo
static_assert 1 == 1
```
## addap instruction
According to compiler, ap++ is not an instruction, but a flag. There is an another instruction that allows us to increase the ap though. It is called `addap` inside the compiler and the syntax is
```cairo
[ap] = 1234
ap += 1
```
As the name suggests, it can't be used with other registers.
## @known_ap_change
known_ap_change means compiler can deduce the change in ap by itself. Don't have all the details clear atm but in library contracts, but it is used for pure functions that don't change the [ap]
## Misc.
- `assert 100 = 100` is equivalent of `tempvar x = 100`
- Even if you don't use a function, it is included in the compiled program as each function changes the pc
- Structs can be used as tuples as MyStruct.my_member gives the index of the my_member.
- You can use `and` between boolean expressions
- "The Cairo Syntax" is defined in `cairo.ebnf` file in lang/compiler directory
## TODO:
How does Starknet specific code translate to Cairo? I know that storage variables are translated into namespaces, but nothing more 😩
Revoked references, they are not that hard, and compiler helps a lot but should have a section