Lexical structure

An ik program is a sequence of tokens produced from UTF-8/ASCII source text. This page defines those tokens: sigils, identifiers, literals, and comments.

Sigils

Every named entity carries a leading sigil that tells the lexer what kind of name it is. The sigil is part of the token, so the same bare word can name a variable, a function, and a register without ambiguity.

Sigil

Names a

Example

$

variable / parameter

$counter, $buf

@

function (or call target)

@main, @delay_ms

%

hardware register alias

%PORTB, %DDRB

A function call uses the function sigil directly: @name(args). An indirect call through a function-pointer variable combines both sigils: @$var(args). Taking the address of a function for a function pointer is written &@name.

Identifiers

After its sigil, an identifier begins with a letter or underscore and continues with letters, digits, underscores, and — to support import paths — / and .:

Identifier ::= (Letter | "_") { Letter | Digit | "_" | "/" | "." }

The / and . characters are what let an import name a nested path such as std/gpio.

Keywords

The following words are reserved and may not be used as identifiers:

  • import

  • target

  • const

  • isr

  • mut

  • imut

  • ram

  • eeprom

  • flash

  • ptr

  • str

  • fn

  • loop

  • switch

  • return

  • true

  • false

  • u8

  • u16

  • i8

  • i16

  • bool

  • char

  • r8

  • r16

  • void

Numeric literals

Integers are decimal or hexadecimal:

Number        ::= DecimalNumber | HexNumber
DecimalNumber ::= ["-"] Digit { Digit }
HexNumber     ::= "0x" HexDigit { HexDigit }

Examples: 42, -7, 0xF0, 0x2A.

A literal containing a decimal point is a fixed-point literal. It is resolved at compile time into the scaled integer representation of an r8 or r16 value — there is no floating-point hardware or type involved:

FloatLiteral ::= ["-"] Digit { Digit } "." Digit { Digit }

Examples: 3.14, -0.5, 1.0.

Boolean literals

true and false are lexed directly as the numeric constants 1 and 0. To the parser they are ordinary Number tokens, which is why a bool is interchangeable with a small integer.

Character literals

A character literal is a single quoted character and evaluates to its byte value:

'A'      # 65
'0'      # 48
'\n'     # 10

Supported escapes inside a character literal are \n, \r, \t, \0, \\ and \'. Hex escapes (\xHH) and \" are not valid in a character literal.

String literals

A string literal is text in double quotes:

"hello"
"line\n"
"byte \x1B here"

String escapes are \n, \r, \t, \0, \\, \" and the hex escape \xHH (two hex digits). Strings are stored NUL-terminated; see Memory model for how a string literal becomes a ram str or flash str.

Comments

A comment runs from # to the end of the line:

0x20 -> %PORTB   # drive PB5 high

There is no block-comment form.

Whitespace

Spaces, tabs, and newlines separate tokens but are otherwise insignificant — ik is not indentation-sensitive. Blocks are delimited by { and }.