# PIR Operator Reference

This section is a quick reference to PIR instructions. For more details and the latest changes, see imcc/docs/syntax.pod or dive into the source code in imcc/imcc.l and imcc/imcc.y.

### =

`  R<DEST> = R<VAL>`

Assign a value to a particular register, temporary register, or named variable.

### +, +=

```  R<DEST> = R<VAL> + R<VAL>
R<DEST> += R<VAL>```

Add two numbers or PMCs.

### -, -=

```  R<DEST> = R<VAL1> - R<VAL2>
R<DEST> -= R<VAL1>
R<DEST> = - R<VAL>```

Subtract VAL1 from VAL2. The unary "`-`" negates a number.

### *, *=

```  R<DEST> = R<VAL> * R<VAL>
R<DEST> *= R<VAL>```

Multiply two numbers or PMCs.

### /, /=

```  R<DEST> = R<VAL1> / R<VAL2>
R<DEST> /= R<VAL1>```

Divide VAL1 by VAL2.

### **

`  R<DEST> = R<VAL1> ** R<VAL2>`

Raise VAL1 to the power of VAL2.

### %, %=

```  R<DEST> = R<VAL1> % R<VAL2>
R<DEST> %= R<VAL1>```

Divide VAL1 by VAL2 and return the (`mod`) remainder.

### ., .=

```  R<DEST> = R<VAL> . R<VAL>
R<DEST> .= R<VAL>```

Concatenate two strings. The concat operator must be surrounded by whitespace.

### <

`  if R<VAL1> E<lt> R<VAL2> goto R<LABEL>`

Conditionally branch to a label if VAL1 is less than VAL2.

### <=

`  if R<VAL1> E<lt>= R<VAL2> goto R<LABEL>`

Conditionally branch to a label if VAL1 is less than or equal to VAL2.

### >

`  if R<VAL1> E<gt> R<VAL2> goto R<LABEL>`

Conditionally branch to a label if VAL1 is greater than VAL2.

### >=

`  if R<VAL1> E<gt>= R<VAL2> goto R<LABEL>`

Conditionally branch to a label if VAL1 is greater than or equal to VAL2.

### ==

`  if R<VAL1> == R<VAL2> goto R<LABEL>`

Conditionally branch to a label if VAL1 is equal to VAL2.

### !=

`  if R<VAL1> != R<VAL2> goto R<LABEL>`

Conditionally branch to a label if VAL1 is not equal to VAL2.

### &&

`  R<DEST> = R<VAL1> && R<VAL2>`

Logical AND. Return VAL1 if it's false, otherwise return VAL2.

### ||

`  R<DEST> = R<VAL1> || R<VAL2>`

Logical OR. Return VAL1 if it's true, otherwise return VAL2.

### ~~

`  R<DEST> = R<VAL1> ~~ R<VAL2>`

Logical XOR. If VAL1 is true and VAL2 is false, return VAL1. If VAL1 is false and VAL2 is true, return VAL2. Otherwise, return a false value.

### !

`  R<DEST> = ! R<VAL>`

Logical NOT. Return a true value if VAL is false.

### &, &=

```  R<DEST> = R<VAL> & R<VAL>
R<DEST> &= R<VAL>```

Bitwise AND on two values.

### |, |=

```  R<DEST> = R<VAL> | R<VAL>
R<DEST> |= R<VAL>```

Bitwise OR on two values.

### ~, ~=

```  R<DEST> = R<VAL> ~ R<VAL>
R<DEST> ~= R<VAL>
R<DEST> = ~ R<VAL>```

Bitwise XOR on two values. The unary form is a bitwise NOT on a value.

### <<, <<=

```  R<DEST> = R<VAL1> E<lt>E<lt> R<VAL2>
R<DEST> E<lt>E<lt>= R<VAL2>```

Bitwise shift VAL1 left by VAL2 number of bits.

### >>, >>=

```  R<DEST> = R<VAL1> E<gt>E<gt> R<VAL2>
R<DEST> E<gt>E<gt>= R<VAL2>```

Bitwise shift VAL1 right by VAL2 number of bits.

### >>>, >>>=

```  R<DEST> = R<VAL1> E<gt>E<gt>E<gt> R<VAL2>
R<DEST> E<gt>E<gt>E<gt>= R<VAL2>```

Logically shift VAL1 right by VAL2 number of bits.

### [ ]

```  R<DEST> = R<PMC> [ R<KEY> ]
R<PMC> [ R<KEY> ] = R<VAL>```

Indexed access to a PMC and indexed assignment to a PMC.

```  DEST = STRING [ OFFSET ]
STRING [ OFFSET ]  = VAL```

Access a one-character substring on a string, starting at a particular offset, or assign to that substring.

### call

`  call R<NAME>`

Call the named subroutine (a `.sub` label).

### global

```  R<DEST> = global R<NAME>
global R<NAME> = R<VAL>```

Access a global variable for read or write.

### goto

`  goto R<NAME>`

Jump to the named identifier (label or subroutine name).

### if

`  if R<EXPR> goto R<NAME>`

If the value or expression evaluates as true, jump to the named identifier.

### unless

`  unless R<VAL> goto R<NAME>`

Unless the value evaluates as true, jump to the named identifier.