# Flash Basic Syntax Flash syntax blends Go's clean readability with Zig's powerful systems-level constructs. --- ## Semicolons Like Go, **Flash does not use semicolons** to terminate statements. The compiler parser automatically detects statement boundaries by parsing newlines and structure layout. --- ## Code Blocks & Braces Flash requires braces `{}` for all structures, functions, and control flow blocks. Single-statement conditions must be wrapped in braces. ```flash // Correct syntax: if x < 10 { return x } // INCORRECT (will fail compiler parse): if x < 10 return x ``` --- ## Function Declarations Functions are declared using the `fn` keyword. * **Return Type:** Written directly after the parameter list. The type follows the closing `)` on the same line — Flash has no return arrow. * **Visibility:** Public functions are prefixed with `pub`. * **Exporting:** To expose a function to the C ABI (such as our `main` function), use `export fn`. ```flash // A private function that adds two 32-bit integers fn add(a i32, b i32) i32 { return a + b } // A public function that does nothing pub fn nop() { // Returns void implicitly } ``` --- ## The Entry Point (`main`) Every standalone executable in Flash begins at the `main` function. It is exported to the standard C calling convention and returns a `noreturn` type (as it exits the OS process via a syscall). ```flash use flibc export fn main(_ usize, _ argv) noreturn { // Write your code here flibc.exit() } ``` --- ## Comments & Documentation Flash supports two styles of comments: * **Single-line Comments (`//`):** Treated as compiler trivia. They are stripped during compilation and will not appear in the generated Zig code. * **Doc Comments (`///`):** Documentation comments are preserved through transpiration. A run of `///` lines attaches to the declaration it leads (such as a top-level `const`, `fn`, or a struct member) and is re-emitted verbatim in the generated Zig output. ```flash // This is a normal comment. It is stripped from the output. x := 42 // Inline comments are also stripped. /// Calculate the square of an integer. pub fn square(x i32) i32 { return x * x } ``` --- ## Test Blocks Flash source can declare string-named `test` blocks at file scope. Each block lowers one-to-one to a Zig `test` block, so the emitted file is directly runnable with the downstream toolchain — Flash code testing itself. ```flash use std fn add(a i32, b i32) i32 { return a + b } test "add sums two integers" { try std.testing.expectEqual(5, add(2, 3)) } ``` A test body is an ordinary block with its own scope; the expectation helpers come from the `std` cross-import. In the Flash repository, `zig build test-flash` transpiles every file under `tests/flash/` and runs the emitted test blocks as part of the regular test suite. --- ## Reserved Words Flash keeps a small, fixed set of reserved words — the v1 surface freezes the list. They fall into four classes: * **Structural keywords** — `use as link fn export extern callconv align pub inline comptime const var orelse if else while for in break continue return try catch defer errdefer struct enum union switch asm error test`. Each is valid only in its grammatical position and can never be a binding name. * **Value words** — `true false null undefined unreachable`. These parse only in value position and cannot be shadowed. * **Primitive-type keywords** — `noreturn anytype anyopaque`. The only reserved *type* names. Every other primitive (`u8`, `i32`, `usize`, `bool`, …) is an ordinary identifier, so shadowing one is a downstream error, not a parse error. * **Contextual words** — `mut` and `volatile`. Reserved only inside pointer and slice types (and `volatile` in an `asm volatile` block); anywhere else they are ordinary identifiers.