2. Lexical Structure¶
2.1 Comments and Directives¶
Single-line Comments:
// Single-line comment
Compiler Directives:
The language reserves the # character for implementation-specific compiler directives. The # character cannot appear in identifiers.
#!/usr/bin/env stack_lang
Directives are implementation-specific and not part of the core language specification. Implementations may support various directives for version requirements, optimization hints, or other configuration.
2.2 Identifiers and Constants¶
Regular Identifiers
- Start with letter or underscore:
[a-zA-Z_][a-zA-Z0-9_]* - Case-sensitive
- When encountered, identifiers are executed immediately
- Cannot contain
#, whitespace,{},[],(),.,',", or::
Identifier Literals
- Prefix with
::to push the identifier itself onto the stack instead of executing it - Syntax:
::namepushes the identifiernameas a value - Example:
::Addablepushes the identifierAddableonto the stack - Example:
::Pointpushes the identifierPointonto the stack
Constants
Constants are compile-time values that are immutable and available throughout the scope where they are defined.
Syntax: value ::name const
Examples:
3.1415926535 ::pi const
9.81 ::gravity const
299792458 ::speed_of_light const
// Use constants like any other value
10 pi * 2 / // Calculate circumference / 2
Properties:
- Constants can be evaluated at compile time
- Constants are immutable - they cannot be reassigned
- Constants defined at module scope are accessible via
Module::CONST_NAME(when modules are implemented) - Constants can be any literal value or compile-time expression
Advanced Usage: See Section 11.2 for complete identifier literal rules and context-dependent behavior.
2.3 Literals¶
Integer Literals
42 // i64 (default)
42:i32 // Annotate as i32
0xFF // hexadecimal
0b1010 // binary
0o755 // octal
1_000_000 // underscore separators (ignored)
Overflow Behavior: Integer arithmetic wraps on overflow. For example, adding 1 to 127, the maximum value of an i8, produces -128.
Floating Point Literals
3.14 // f64 (default)
3.14:f32 // Annotate as f32
1_000.5 // underscore separators allowed
Overflow Behavior: Floating point operations follow IEEE 754 semantics, producing infinity or NaN for overflow/undefined operations.
Character Literals
'A' // Single character
'\n' // Escape sequence
'\x41' // Hexadecimal (A)
'\u{1F600}' // Unicode (😀)
String Literals
"hello world"
"escape sequences: \n \t \\ \""
Escape Sequences
\n- Newline (LF)\r- Carriage return (CR)\t- Tab\\- Backslash\"- Double quote\'- Single quote\0- Null character\xNN- Hexadecimal byte (e.g.,\x41for 'A')\u{NNNN}- Unicode code point (e.g.,\u{1F600}for 😀)
Boolean Literals
true
false
Array Literals
[1 2 3 4 5] // array of i64
[1.0 2.0 3.0] // array of f64
[[1 2] [3 4]] // 2D array
// Typed arrays
[1 2 3 :i16] // array of i16
[[1.0 2.0] [3.0 4.0] :f32] // 2D array of f32
// Arrays of structs (when Point is defined)
[{1 2} {3 4} :Point] // array of Point structs