# Cordial Language Reference Guide Cordial is a simple, expression-based programming language embedded in Swiftly. This guide documents every working feature. ## Evaluation Prefix All evaluation in the editor uses the `/=` prefix: ``` /= 2 + 3 ``` Output: ``` 5 ``` ## Types Cordial has five value types: - **number**: floating-point numbers (internally f64). Displayed as integers when they have no fractional part. - **bool**: `true` or `false` - **str**: strings in double quotes, with escape sequences (`\n`, `\t`, `\\`, `\"`) - **array**: ordered collections of values - **void**: the value returned by statements with no explicit value ## Variables ### Declaration Use `let` to declare and initialize a variable: ``` let x = 5 /= x ``` Output: ``` 5 ``` ### Type Annotations Optionally annotate the type after the variable name: ``` let x: int = 3.7 /= x ``` Output: ``` 3 ``` Supported type annotations: - `int`: truncates numbers to integers - `float`: accepts any number (no coercion) - `bool`: converts 0 to `false`, 1 to `true`; rejects other numbers - `str`: only accepts strings ``` let b: bool = 1 /= b ``` Output: ``` true ``` ### Assignment Reassign an existing variable without `let`: ``` let x = 5 x = 10 /= x ``` Output: ``` 10 ``` ## Operators ### Arithmetic - `+`: addition or string concatenation - `-`: subtraction - `*`: multiplication - `/`: division (errors on division by zero) - `%`: modulo - `^`: exponentiation (right-associative) ``` /= 2 ^ 3 ^ 2 ``` Output: ``` 512 ``` (Evaluated as 2 ^ (3 ^ 2) = 2 ^ 9 = 512) ### Comparison All comparison operators return booleans: - `<`: less than - `>`: greater than - `<=`: less than or equal - `>=`: greater than or equal - `==`: equality - `!=`: inequality ``` /= 5 > 3 ``` Output: ``` true ``` ### Logical - `&&`: logical AND (short-circuits) - `||`: logical OR (short-circuits) - `!`: logical NOT ``` /= true && false ``` Output: ``` false ``` ``` /= !true ``` Output: ``` false ``` ### Operator Precedence From lowest to highest: 1. `||` 2. `&&` 3. `==`, `!=`, `<`, `>`, `<=`, `>=` 4. `+`, `-` 5. `*`, `/`, `%` 6. `^` (right-associative) 7. unary `-`, `!` 8. function calls, array literals ## Strings String literals use double quotes: ``` /= "hello" ``` Output: ``` hello ``` Escape sequences: - `\n`: newline - `\t`: tab - `\\`: backslash - `\"`: double quote ### String Concatenation Strings concatenate with the `+` operator. Numbers and booleans are automatically converted: ``` /= "value: " + 42 ``` Output: ``` value: 42 ``` ``` /= 100 + " items" ``` Output: ``` 100 items ``` ## Arrays ### Literals Create arrays with square brackets: ``` /= [1, 2, 3] ``` Output: ``` [1, 2, 3] ``` Arrays can contain mixed types: ``` /= [1, "two", true] ``` Output: ``` [1, "two", true] ``` Empty arrays: ``` /= [] ``` Output: ``` [] ``` ### Indexing Access elements by index (zero-based): ``` let arr = [10, 20, 30] /= arr[1] ``` Output: ``` 20 ``` Negative indices count from the end: ``` /= [10, 20, 30][-1] ``` Output: ``` 30 ``` Out-of-bounds access returns an error. ### String Indexing Strings support the same index syntax, returning individual characters: ``` /= "hello"[0] ``` Output: ``` h ``` ## Functions ### Definition Define functions with the `fn` keyword: ``` fn add(a, b) { a + b } ``` The last expression in the function body is returned implicitly. An explicit `return` statement is also available for early exit. ``` fn square(x) { x * x } /= square(5) ``` Output: ``` 25 ``` ### Scope Function parameters are local to the function. The function saves and restores the variable scope: ``` let x = 10 fn modify() { x = 5 } modify() /= x ``` Output: ``` 10 ``` (x inside the function is a separate variable; the outer x is unchanged) ### Recursion Functions can call themselves recursively, up to a maximum call depth of 256: ``` fn fib(n) { let a = 0 let b = 1 let i = 0 while (i < n) { let tmp = b b = a + b a = tmp i = i + 1 } a } /= fib(10) ``` Output: ``` 55 ``` ## Control Flow ### While Loops Loop while a condition is truthy: ``` let i = 0 let sum = 0 while (i < 10) { sum = sum + i i = i + 1 } /= sum ``` Output: ``` 45 ``` Parentheses around the condition are optional (but recommended for clarity). Loop safety: while loops are limited to 10,000 iterations to prevent infinite loops. ### If/Else Conditional branching with optional else clause: ``` let x = 10 if x > 5 { x = 1 } else { x = 0 } /= x ``` Output: ``` 1 ``` Parentheses around the condition are optional. Else-if chaining works: ``` let grade = 85 let letter = "F" if grade >= 90 { letter = "A" } else if grade >= 80 { letter = "B" } else if grade >= 70 { letter = "C" } /= letter ``` Output: ``` B ``` ### For Loops Iterate over arrays or ranges: ``` let sum = 0 for x in [1, 2, 3, 4, 5] { sum = sum + x } /= sum ``` Output: ``` 15 ``` Using a range expression (`start..end`, exclusive of end): ``` let sum = 0 for i in 0..5 { sum = sum + i } /= sum ``` Output: ``` 10 ``` The `range(start, end)` builtin function also works: ``` let sum = 0 for i in range(1, 6) { sum = sum + i } /= sum ``` Output: ``` 15 ``` For loops are limited to 10,000 iterations. ### Return Statements Use `return` for early exit from functions: ``` fn abs_val(x) { if x < 0 { return -x } x } /= abs_val(-7) ``` Output: ``` 7 ``` Bare `return` (with no value) returns `false`. ## Builtin Functions ### Math Functions All math functions accept a single number and return a number: - `sin(x)`: sine - `cos(x)`: cosine - `tan(x)`: tangent - `asin(x)`: arc sine - `acos(x)`: arc cosine - `atan(x)`: arc tangent - `sqrt(x)`: square root - `abs(x)`: absolute value - `floor(x)`: round down - `ceil(x)`: round up - `round(x)`: round to nearest integer - `ln(x)`: natural logarithm - `log(x)`: base-10 logarithm ``` /= sqrt(16) ``` Output: ``` 4 ``` ``` /= abs(-5) ``` Output: ``` 5 ``` ``` /= floor(3.7) ``` Output: ``` 3 ``` ### Range Function `range(start, end)` returns an array of numbers from start to end (exclusive): ``` /= range(0, 5) ``` Output: ``` [0, 1, 2, 3, 4] ``` ### Length Function `len()` returns the length of a string or array: ``` /= len("hello") ``` Output: ``` 5 ``` ``` /= len([1, 2, 3]) ``` Output: ``` 3 ``` ## Truthiness In boolean contexts (conditions, logical operators), values are truthy or falsy: - **bool**: `true` is truthy, `false` is falsy - **number**: 0 is falsy, all other numbers are truthy - **string**: empty string is falsy, all other strings are truthy - **array**: empty array is falsy, all other arrays are truthy - **void**: falsy - **error**: falsy Truthiness matters for `if`, `while`, `for` conditions and `&&`/`||` operators. ## Ranges The `..` operator creates an array from start to end (exclusive): ``` /= 0..5 ``` Output: ``` [0, 1, 2, 3, 4] ``` Ranges are primarily useful with `for` loops and can be stored in variables. ## Negative Numbers Negative number literals are recognized in appropriate contexts: ``` /= -5 ``` Output: ``` -5 ``` ``` /= 10 + -3 ``` Output: ``` 7 ``` The unary minus operator also works: ``` /= -(5 + 3) ``` Output: ``` -8 ``` ## Error Handling Errors are propagated as error values and displayed with an `error:` prefix: ``` /= undefined_var ``` Output: ``` error: undefined variable 'undefined_var' ``` ``` /= 1 / 0 ``` Output: ``` error: division by zero ``` Multiple statements execute in sequence, and errors in one statement don't prevent subsequent statements from executing. ## Comments Single-line comments use `//`: ``` // This is a comment let x = 5 /= x ``` Comments can appear at the end of lines too. ## Examples ### Multi-step Calculation ``` let principal = 1000 let rate = 0.05 let years = 10 let amount = principal * (1 + rate) ^ years /= amount ``` Output: ``` 1628.89462382... ``` ### Fibonacci ``` fn fib(n) { let a = 0 let b = 1 let i = 0 while (i < n) { let tmp = b b = a + b a = tmp i = i + 1 } a } /= fib(15) ``` Output: ``` 610 ``` ### String Building ``` let greeting = "Hello" let name = "World" /= greeting + ", " + name + "!" ``` Output: ``` Hello, World! ``` ## Display Formats ### Inline (default) The standard `/=` prefix displays the result as a single value on the right edge of the editor: ``` let x = 42 /= x ``` Result appears as: `→ 42` Arrays display inline: ``` /= [1, 2, 3] ``` Result: `→ [1, 2, 3]` ### Table (`/=|`) The `/=|` prefix renders a 2D array (array of arrays) as a visual table overlay: ``` let data = [["Name", "Age"], ["Alice", 30], ["Bob", 25]] /=| data ``` The first row is treated as the header (rendered bold). Each subsequent row becomes a table row. Non-array values fall back to inline display. Works with any 2D array: ``` let matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] /=| matrix ``` ### Tree (`/=\`) The `/=\` prefix renders nested data as an indented tree overlay: ``` let tree = [1, [2, 3], [4, [5, 6]]] /=\ tree ``` Nested arrays are expanded with tree-drawing characters showing depth. Leaf values display inline. The root shows the total element count. ## Limitations - **No array mutation**: Arrays cannot be modified after creation (no `arr[i] = val`) - **No mutable references**: Variable reassignment creates new bindings in the current scope - **Maximum call depth**: 256 function calls deep - **Maximum loop iterations**: 10,000 iterations per while/for loop - **No user-defined types or structs** - **No imports or modules** - **No pattern matching or destructuring** - **No closures or lambdas**