# Compiler Commands Reference

## Index

- [ADD](#add) - Adds two values
- [AND](#and) - Bitwise AND operation
- [BREAK](#break) - Exits current loop
- [BYTE](#byte) - Declares 8-bit variable or constant
- [CALL](#call) - Calls function with parameters
- [CASE](#case) - Case branch in SWITCH statement
- [DEC](#dec) - Decrements variable or memory location
- [DEFAULT](#default) - Default branch in SWITCH statement
- [ELSE](#else) - Alternative branch in IF statement
- [ENDIF](#endif) - Terminates IF block
- [ENDSWITCH](#endswitch) - Terminates SWITCH block
- [FEND](#fend) - Ends function definition
- [FOR](#for) - Loop with automatic counter increment
- [FUNC](#func) - Defines function with parameters
- [GOSUB](#gosub) - Calls subroutine with register passing
- [GOTO](#goto) - Unconditional jump to label
- [IF](#if) - Conditional execution
- [INC](#inc) - Increments variable or memory location
- [LABEL](#label) - Creates named assembly label
- [LET](#let) - Assigns value to variable
- [NEXT](#next) - Terminates FOR loop
- [OR](#or) - Bitwise OR operation
- [ORIGIN](#origin) - Sets assembly origin address
- [PEEK](#peek) - Reads byte from memory
- [PEEKW](#peekw) - Reads word from memory
- [POINTER](#pointer) - Sets pointer to address
- [POKE](#poke) - Writes byte to memory
- [POKEW](#pokew) - Writes word to memory
- [SUBEND](#subend) - Returns from subroutine
- [SHIFTL](#shiftl) - Logical shift left
- [SHIFTR](#shiftr) - Logical shift right
- [SUBTR](#subtr) - Subtracts values
- [SWITCH](#switch) - Multi-way branching
- [WEND](#wend) - Terminates WHILE loop
- [WHILE](#while) - Loop while condition true
- [WORD](#word) - Declares 16-bit variable or constant
- [XOR](#xor) - Bitwise XOR operation

---

## ADD

Adds two values and stores result in destination.

**Syntax:**
```
<dest> = <param1> + <param2>
```

**Examples:**
```
result = 10 + 5
total = count + offset
sum = var1 + 100
```

---

## AND

Bitwise AND operation between two values.

**Syntax:**
```
<dest> = <param1> & <param2>
```

**Examples:**
```
mask = value & $FF
result = byte1 & byte2
flags = status & $80
```

---

## BREAK

Exits current loop immediately.

**Syntax:**
```
BREAK
```

**Examples:**

```
// BREAK in FOR loop
BYTE i
FOR i = 0 TO 100
    IF i = 50
        BREAK
    ENDIF
NEXT
```

```
// BREAK in WHILE loop
WHILE counter < 1000
    counter++
    IF error
        BREAK
    ENDIF
WEND
```

---

## BYTE

Declares an 8-bit variable, register-hinted temporary, or constant.

**Syntax:**
```
BYTE <varname>
BYTE <varname> = <value>
BYTE REGISTER <varname>
BYTE REGISTER <varname> = <value>
BYTE <varname> @ <address>
BYTE CONST <varname> = <value>
```

**Examples:**
```
BYTE counter
BYTE speed = 5
BYTE REGISTER temp
BYTE REGISTER scratch = 0
BYTE screen @ $D020
BYTE CONST MAX_SPEED = 10
```

`REGISTER` is a storage hint for the optimizer. The variable may be kept in a
CPU register (A/X/Y) and its memory allocation can be eliminated entirely.
Only valid inside `FUNC`/`FEND` blocks; incompatible with `@` and `CONST`.
See the REGISTER section in `language.md` for details.

---

## CALL

Calls a function with optional arguments.

**Syntax:**
```
<funcname>
<funcname>()
<funcname>(<param1>[,<param2>,...])
```

**Arguments can be:**
- Variables: `myvar`
- Constants or literals: `42`, `$FF`
- String literals: `"hello"` (passed as pointer to WORD parameter)
- Label addresses: `@spriteData` (passed as pointer to WORD parameter)

**Examples:**
```
initialize
initialize()
setColor(1,14)
drawSprite(xpos,ypos,@spriteData)
process("hello",42,myvar)
```

---

## CASE

Defines a case branch within SWITCH statement.

See [SWITCH](#switch) for syntax and examples.

---

## DEC

Decrements a variable or memory location by 1.

**Syntax:**
```
<var>--
DEC <target>
DECREMENT <target>
```

**Examples:**

```
// Modern: decrement variables
counter--
lives--
index--
```

```
// Alternative: decrement memory location
DEC $D020
```

```
// Legacy: DECREMENT form
DECREMENT screenColor
```

---

## DEFAULT

Defines the default branch in SWITCH statement.

See [SWITCH](#switch) for syntax and examples.

---

## ELSE

Alternative branch in IF statement.

See [IF](#if) for syntax and examples.

---

## ENDIF

Terminates IF block.

See [IF](#if) for syntax and examples.

---

## ENDSWITCH

Terminates SWITCH block.

See [SWITCH](#switch) for syntax and examples.

---

## FEND

Ends a function definition.

See [FUNC](#func) for syntax and examples.

---

## FOR

Loop with automatic counter increment. The iterator variable must be declared
beforehand.

**Syntax:**
```
FOR <iterator> = <start_value> TO <end_value>
```

**Examples:**

```
// FOR loop with literal values
BYTE i
FOR i = 0 TO 10
    screen = i
NEXT
```

```
// FOR loop with variables
BYTE counter
FOR counter = start TO finish
    process(counter)
NEXT
```

---

## FUNC

Defines a function with optional parameters. Functions must be terminated with `FEND`.

**Modern syntax (recommended):** Use implicit declarations with curly braces for self-contained functions with local parameters.

**Legacy syntax:** Can use pre-declared global variables for direct memory access.

Parameter passing modes: `in:` (default, read-only), `out:` (write-only), `io:` (read-write)

**Syntax:**
```
FUNC name                              # void function
FUNC name ( {BYTE param} )             # single parameter (modern)
FUNC name ( {BYTE a} {BYTE b} )        # multiple parameters (modern)
FUNC name ( in:{BYTE x} out:{BYTE y} io:{BYTE z} ) # all direction modifiers
FUNC name ( {BYTE param @ $fa} )       # parameter at absolute address

FUNC name ( param )                    # single pre-declared variable (legacy)
FUNC name ( a b )                      # multiple pre-declared vars (legacy)
FUNC name ( in:x out:y io:z )          # direction with pre-declared (legacy)
```

**Examples:**

```
// Modern: self-contained function with local parameters
FUNC add({BYTE a} {BYTE b} out:{BYTE result})
    result = a + b
FEND
```

```
// Modern: with direction modifiers  
FUNC process(in:{BYTE input} out:{BYTE output})
    output = input + 1
FEND
```

```
// Modern: io parameter (read-write)
FUNC increment(io:{BYTE counter})
    counter = counter + 1
FEND
```

```
// Modern: absolute address parameter
FUNC read_byte({BYTE data @ $fa})
    BYTE temp
    temp = data  // Reads from $fa
FEND
```

```
// Legacy: uses global variables directly
BYTE x
BYTE y
FUNC swap_legacy ( x y )
    BYTE temp
    temp = x
    x = y
    y = temp
FEND
```

---

## GOSUB

Calls subroutine with optional register passing.

**Syntax:**
```
GOSUB <target>
GOSUB <target> PASSING <var> AS ACC|XREG|YREG [<var> AS XREG|YREG [<var> AS YREG]]
```

**Examples:**
```
GOSUB myRoutine
GOSUB clearScreen
GOSUB processData PASSING value AS ACC
GOSUB multiply PASSING a AS ACC b AS XREG result AS ACC
```

---

## GOTO

Unconditional jump to label or address.

**Syntax:**
```
GOTO <target>
```

**Examples:**
```
GOTO mainLoop
GOTO error
GOTO endProgram
GOTO $9000
GOTO (startAddress+$100)
```

---

## IF

Conditional execution based on comparison.

When single parameter: 0 = false, non-zero = true

**Syntax:**
```
IF <param1> [<operator> <param2>]
```

Operators: `=` `==` `<>` `!=` `>` `<` `>=` `<=`

**Examples:**

```
// Simple IF statement
IF count == 10
    result = 1
ENDIF
```

```
// IF with ELSE branch
IF value > threshold
    process(value)
ELSE
    skip(value)
ENDIF
```

```
// IF-ELSE with actions
IF x < 100
    x++
ELSE
    x = 0
ENDIF
```

---

## INC

Increments a variable or memory location by 1.

**Syntax:**
```
<var>++
INC <target>
INCREMENT <target>
```

**Examples:**

```
// Modern: increment variables
counter++
index++
frameCount++
```

```
// Alternative: increment memory location
INC $D020
```

```
// Legacy: INCREMENT form
INCREMENT screenColor
```

---

## LABEL

Creates a named assembly label.

**Syntax:**
```
LABEL <n>
```

**Examples:**
```
LABEL mainLoop
LABEL skipSection
LABEL errorHandler
```

---

## LET

Assigns value to variable.

Note: expressions not allowed (except constant expressions without spaces)

**Syntax:**
```
<dest> = <source>
```

**Examples:**
```
counter = 0
speed = maxSpeed
result = temp
value = 100+50
```

---

## NEXT

Loop terminator for FOR.

See [FOR](#for) for syntax and examples.

---

## OR

Bitwise OR operation between two values.

**Syntax:**
```
<dest> = <param1> | <param2>
```

**Examples:**
```
flags = flags | $01
result = byte1 | byte2
status = status | errorBit
```

---

## ORIGIN

Sets assembly origin address.

**Syntax:**
```
ORIGIN <address>
```

**Examples:**
```
ORIGIN $0801
ORIGIN $C000
ORIGIN startAddress
```

---

## PEEK

Reads byte from memory location.

For operating with offsets the address parameter must be an absolute WORD variable in the zero page.


**Syntax:**
```
<dest> = PEEK <address>[<offset>]
```

**Examples:**
```
value = PEEK $D020
char = PEEK screenPtr[index]
data = PEEK buffer[5]
byte = PEEK pointer
```

---

## PEEKW

Reads word (16-bit) from memory location at address.

For operating with offsets the address parameter must be an absolute WORD variable in the zero page.


**Syntax:**
```
<dest> = PEEKW <address>[<offset>]
```

**Examples:**

```
// Read from absolute address
reset_addr = PEEKW $FFFE
```

```
// Read with offset (requires WORD variable in zero page)
WORD buffer @ $fd
offset_val = PEEKW buffer[10]
```

```
// Read through pointer
WORD pointer
val = PEEKW pointer
```

---

## POINTER

Sets pointer variable to address of target.

**Syntax:**
```
POINTER <ptrvar> TO <target>
```

**Examples:**
```
POINTER screenPtr TO $0400
POINTER buff_ptr TO buffer // buffer might be a label to some data
POINTER funcPtr TO myFunction
```

---

## POKE

Writes byte to memory location.

For operating with offsets the address parameter must be an absolute WORD variable in the zero page.


**Syntax:**
```
POKE <address>[<offset>], <value>
```

**Examples:**
```
POKE $D020, 0
POKE screenPtr[index], char
POKE buffer[5], data
POKE pointer, value
```

---

## POKEW

Writes word (16-bit) to memory location.

For operating with offsets the address parameter must be an absolute WORD variable in the zero page.


**Syntax:**
```
POKEW <address>[<offset>], <value>
```

**Examples:**
```
POKEW $0314, handler
POKEW dataPtr[0], value
POKEW buffer[10], address
```

---

## SUBEND

Returns from subroutine.

**Syntax:**
```
SUBEND
```
or
```
EXIT
```

**Examples:**

```
// Simple subroutine with SUBEND
LABEL subroutine
    counter = counter + 1
    SUBEND
```

```
// Subroutine with early EXIT
LABEL checkValue
    IF value = 0
        EXIT
    ENDIF
    process(value)
    SUBEND
```

---

## SHIFTL

Logical shift left operation.

**Syntax:**
```
SHIFTL <source> BY <amount> GIVING <dest>
SHIFTL <source> << <amount> -> <dest>
<dest> = <source> << <amount>
```

**Parameters:**
- `source`: BYTE or WORD variable or constant expression
- `amount`: BYTE variable or constant expression (0-255)
- `dest`: BYTE or WORD variable (cannot be constant)

**Notes:**
- Logical shift only (no sign extension)
- Shift amount of 0 copies source to dest unchanged
- Shift amount ≥ bit-width yields zero (≥8 for BYTE, ≥16 for WORD)
- BYTE→WORD conversion zero-extends before shifting
- WORD→BYTE conversion truncates low byte only

**Examples:**

```
// Modern: assignment form
result = value << 3
```

```
// Alternative: arrow form
SHIFTL flags << 2 -> masked
```

```
// Legacy: verbose form
SHIFTL mask BY bits GIVING shifted
```

---

## SHIFTR

Logical shift right operation.

**Syntax:**
```
SHIFTR <source> BY <amount> GIVING <dest>
SHIFTR <source> >> <amount> -> <dest>
<dest> = <source> >> <amount>
```

**Parameters:**
- `source`: BYTE or WORD variable or constant expression
- `amount`: BYTE variable or constant expression (0-255)
- `dest`: BYTE or WORD variable (cannot be constant)

**Notes:**
- Logical shift only (no sign extension)
- Shift amount of 0 copies source to dest unchanged
- Shift amount ≥ bit-width yields zero (≥8 for BYTE, ≥16 for WORD)
- BYTE→WORD conversion zero-extends before shifting
- WORD→BYTE conversion truncates low byte only

**Examples:**

```
// Modern: assignment form
mask = flags >> 2
```

```
// Alternative: arrow form
SHIFTR data >> 4 -> nibble
```

```
// Legacy: verbose form
SHIFTR value BY shift GIVING result
```

---

## SUBTR

Subtracts second value from first.

**Syntax:**
```
<dest> = <param1> - <param2>
```

**Examples:**
```
result = 100 - 5
difference = end - start
remaining = total - used
```

---

## SWITCH

Multi-way branching based on variable value comparison.

Features implicit breaks (automatic jump to ENDSWITCH after each case), supports nesting, and works with BYTE and WORD types.

**Syntax:**
```
SWITCH <variable>
  CASE <value>
    [statements]
  [CASE <value>
    [statements]]
  [DEFAULT
    [statements]]
ENDSWITCH
```

**Notes:**
- Each CASE automatically breaks (jumps to ENDSWITCH) after execution
- CASE values can be literals, constants, or variables
- DEFAULT branch is optional and executes when no CASE matches
- DEFAULT must come after all CASE statements
- Only one DEFAULT per SWITCH
- BYTE variables can only be compared with values 0-255
- Can use `#PRAGMA _P_USE_LONG_JUMP 1` for large switch statements
- Nested SWITCH statements are supported

**Examples:**

```
// Basic switch with default
SWITCH status
  CASE 1
    result = 10
  CASE 2
    result = 20
  DEFAULT
    result = 0
ENDSWITCH
```

```
// Switch with constants
BYTE CONST MAX = 100
SWITCH value
  CASE MAX
    overflow = 1
  CASE 50
    halfway = 1
ENDSWITCH
```

```
// WORD switch
WORD big_val
SWITCH big_val
  CASE 1000
    mode = 1
  CASE 5000
    mode = 2
  DEFAULT
    mode = 0
ENDSWITCH
```

```
// Nested switch
SWITCH outer
  CASE 1
    result = 1
  CASE 2
    SWITCH inner
      CASE 10
        result = 20
      CASE 20
        result = 40
    ENDSWITCH
  DEFAULT
    result = 0
ENDSWITCH
```

```
// Using variables in CASE
BYTE threshold1
BYTE threshold2
LET threshold1 = 50
LET threshold2 = 100
SWITCH temperature
  CASE threshold1
    fan_speed = 1
  CASE threshold2
    fan_speed = 2
  DEFAULT
    fan_speed = 0
ENDSWITCH
```

---

## WEND

Terminates WHILE loop.

See [WHILE](#while) for syntax and examples.

---

## WHILE

Loop that continues while condition is true.

When single parameter: 0 = false, non-zero = true

**Syntax:**
```
WHILE <param1> [<operator> <param2>]
```

Operators: `=` `==` `<>` `!=` `>` `<` `>=` `<=`

**Examples:**

```
// WHILE with numeric comparison
WHILE counter < 100
    counter++
    result = result + counter
WEND
```

```
// WHILE with boolean condition
WHILE running
    processFrame
    checkInput
WEND
```

```
// WHILE with inequality
WHILE x != y
    x++
WEND
```

---

## WORD

Declares a 16-bit variable or constant.

**Syntax:**
```
WORD <varname>
WORD <varname> = <value>
WORD <varname> = "<string>"
WORD <varname> = @<label>
WORD <varname> @ <address>
WORD CONST <varname> = <value>
```

**Examples:**
```
WORD counter
WORD address = $C000
WORD message = "Hello"
WORD spritePtr = @spriteData
WORD irqVector @ $0314
WORD CONST SCREEN = $0400
```

The `@<label>` syntax initializes a WORD variable with the address of a label. This is useful for pointers to data blocks or code labels. The label can be a forward reference (declared later in the source) or an existing variable name. For local variables, the name is automatically expanded to the full scoped name.

---

## XOR

Bitwise XOR operation between two values.

**Syntax:**
```
<dest> = <param1> ^ <param2>
```

**Examples:**
```
result = value ^ $FF
output = byte1 ^ byte2
toggleBits = flags ^ mask
```