Syntax ====== This page describes the lexical and syntactic structure of Symbolic source files. ---- Source Files ------------ Symbolic source files use the ``.sym`` extension. Files are UTF-8 encoded. Statements are separated by semicolons or newlines where the boundary is unambiguous. The parser uses a recursive-descent strategy and processes the entire file before execution. ---- Comments -------- Three comment styles are supported: .. code-block:: symbolic # This is a single-line comment (Python style) // This is also a single-line comment (C++ style) /** * This is a multi-line comment. * It continues until the closing delimiter. */ x = 42; # End-of-line comment Comments are stripped during lexical analysis and do not appear in the AST. ---- Identifiers ----------- Identifiers must begin with a letter (Unicode category L*) or underscore, followed by any combination of letters, digits (0–9), and underscores: .. code-block:: symbolic variable_name = 1 camelCase = 2 PascalCase = 3 _private = 4 name123 = 5 # Greek letters are valid identifiers α = 3.14159 θ = pi / 4 Δx = 0.001 Identifiers are case-sensitive. ``Name`` and ``name`` are distinct. ---- Keywords -------- The following identifiers are reserved and may not be used as variable or function names: .. code-block:: text all alias and as assert async await block catch class const default dephantom domain else ensures enum extends fast final fn for from if import in is loop match or parallel phantom raise repeat requires return skip spawn static stop terminate to try until using wait whenever where while yield ---- Literals -------- Numeric Literals ~~~~~~~~~~~~~~~ .. list-table:: :widths: 30 25 45 :header-rows: 1 * - Form - Example - Notes * - Decimal integer - ``42``, ``-17`` - Underscores allowed: ``1_000_000`` * - Hexadecimal integer - ``0xFF``, ``0xDEAD_BEEF`` - Case-insensitive prefix and digits * - Octal integer - ``0o755`` - Digits 0–7 only * - Binary integer - ``0b1010``, ``0b1111_0000`` - Digits 0–1 only * - Floating point - ``3.14``, ``-2.5``, ``6.022e23`` - Scientific notation supported * - Complex - ``3 + 4i``, ``1i``, ``2.5 - 1.7i`` - Imaginary unit is ``i``, not ``j`` * - Magnitude suffix - ``10k``, ``2M``, ``1B``, ``4T`` - Multipliers: k=10³, M=10⁶, B=10⁹, T=10¹² Underscores may appear within any run of digits for readability and are ignored by the parser. .. note:: Symbolic uses arbitrary-precision arithmetic via ``mpmath``. Floating-point precision adapts to the number of significant digits in the literal. The ``@$precision`` directive controls the working precision for a block. String Literals ~~~~~~~~~~~~~~ .. code-block:: symbolic # Double or single quotes s1 = "Hello, World!" s2 = 'Hello, World!' # Escape sequences escaped = "Line one\nLine two\tTabbed" quote = "She said \"hello\"." # Raw strings — no escape processing path = r"C:\Users\name\file.txt" # Multi-line strings block_str = """ First line Second line Third line """ # Interpolated strings name = "Alice" age = 30 msg = f"Name: {name}, Age: {age}" expr = f"2 + 2 = {2 + 2}" fmt = f"Pi is approximately {3.14159:.4f}" Supported escape sequences: ``\n``, ``\t``, ``\\``, ``\"``. Collection Literals ~~~~~~~~~~~~~~~~~~ .. code-block:: symbolic # List — ordered, mutable nums = [1, 2, 3, 4, 5] mixed = [1, "hello", 3.14, true] # Tuple — ordered, immutable pair = (10, 20) triple = (1, "x", 3.14) # Trailing comma creates a single-element tuple singleton = (42,) # Set — unordered, unique elements unique = {1, 2, 3, 2, 1} # result: {1, 2, 3} # Dictionary — key-value pairs cfg = { "host": "localhost", "port": 8080, "debug": true, } # Empty collections empty_list = [] empty_dict = {} empty_tuple = () ---- Operators --------- Arithmetic Operators ~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 15 20 65 :header-rows: 1 * - Operator - Name - Description * - ``+`` - Addition - Sum of two values; unary positive prefix * - ``-`` - Subtraction - Difference; unary negation prefix * - ``*``, ``×`` - Multiplication - Product of two values * - ``/``, ``÷`` - True division - Returns a ``Fraction`` when dividing two integers; ``Float`` otherwise * - ``//`` - Floor division - Integer quotient, rounded toward negative infinity * - ``%`` - Modulo - Remainder after floor division; postfix usage returns a percentage value * - ``^`` - Exponentiation - Right-associative: ``2^3^2`` is ``2^(3^2)`` * - ``√`` - Square root - Prefix operator: ``√x`` is equivalent to ``x.sqrt()`` * - ``+/-`` - Plus-or-minus - Represents a symmetric range or uncertainty bound Comparison Operators ~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 15 25 60 :header-rows: 1 * - Operator - Name - Description * - ``==`` - Equal - Structural equality * - ``!=`` - Not equal - * - ``<`` - Less than - * - ``>`` - Greater than - * - ``<=`` - Less than or equal - * - ``>=`` - Greater than or equal - * - ``===`` - Strict equal - Equal and same type * - ``<=>`` - Spaceship - Returns ``-1``, ``0``, or ``1`` Logical Operators ~~~~~~~~~~~~~~~~ .. list-table:: :widths: 15 20 65 :header-rows: 1 * - Operator - Name - Description * - ``and`` - Logical AND - Short-circuit evaluation * - ``or`` - Logical OR - Short-circuit evaluation * - ``!``, ``not`` - Logical NOT - Prefix; ``!`` also used as postfix factorial (see below) Bitwise Operators ~~~~~~~~~~~~~~~~ .. list-table:: :widths: 15 20 65 :header-rows: 1 * - Operator - Name - Description * - ``&`` - Bitwise AND - * - ``|`` - Bitwise OR - Also used as prefix absolute-value: ``|x|`` * - ``^^`` - Bitwise XOR - * - ``~`` - Bitwise NOT - Prefix * - ``<<`` - Left shift - * - ``>>`` - Right shift - * - ``<<<`` - Unsigned left shift - * - ``>>>`` - Unsigned right shift - * - ``~&`` - NAND - * - ``~|`` - NOR - * - ``~^`` - XNOR - Assignment Operators ~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 15 20 65 :header-rows: 1 * - Operator - Name - Notes * - ``=`` - Assignment - Binds a name to a value * - ``:=`` - Walrus assignment - * - ``<-`` - Arrow assignment - Alternative binding syntax * - ``+=`` - Add-assign - * - ``-=`` - Subtract-assign - * - ``*=`` - Multiply-assign - * - ``/=`` - Divide-assign - * - ``//=`` - Floor-divide-assign - * - ``%=`` - Modulo-assign - * - ``^=`` - Power-assign - * - ``^^=`` - XOR-assign - * - ``|=`` - Bitwise-OR-assign - * - ``<<=`` - Left-shift-assign - * - ``>>=`` - Right-shift-assign - * - ``?=`` - Conditional assign - Assigns only if the current value is ``null`` * - ``??`` - Null-coalesce assign - Returns left operand if not null, otherwise right Miscellaneous Operators ~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :widths: 15 25 60 :header-rows: 1 * - Operator - Name - Description * - ``..`` - Inclusive range - ``1..5`` produces the range [1, 5] * - ``..<`` - Exclusive range - ``0..<5`` produces [0, 1, 2, 3, 4] * - ``|>`` - Forward pipe - Passes the left value as the first argument to the right function * - ``<|`` - Backward pipe - * - ``??`` - Null coalesce - Returns left if not null, otherwise evaluates and returns right * - ``?.`` - Optional chaining - Short-circuits to ``null`` if the receiver is ``null`` * - ``!`` - Factorial (postfix) - ``n!`` computes the factorial of ``n`` * - ``°`` - Degree (postfix) - Unit annotation for angular degrees * - ``'`` - Complement (postfix) - Denotes complement or derivative in mathematical contexts * - ``|x|`` - Absolute value - Pipe-prefix/postfix form: ``|expression|`` Matrix Operators ~~~~~~~~~~~~~~~ .. list-table:: :widths: 15 20 65 :header-rows: 1 * - Operator - Name - Description * - ``@+`` - Matrix addition - * - ``@-`` - Matrix subtraction - * - ``@*`` - Matrix multiplication - * - ``@/`` - Matrix division - * - ``@@`` - Matrix dot product - ---- Operator Precedence ------------------- Higher precedence values bind more tightly. Within the same level, the associativity column determines the evaluation order. .. list-table:: :widths: 10 45 20 :header-rows: 1 * - Level - Operators - Associativity * - 15 - ``.``, ``?.``, ``[]``, ``()`` - Left-to-right * - 10 - ``!``, ``°``, ``'``, ``%`` (postfix) - Left-to-right * - 9 - ``^``, ``√`` (right-associative for ``^``) - Right-to-left * - 7 - ``*``, ``×``, ``/``, ``÷``, ``//``, ``%`` - Left-to-right * - 6 - ``+/-`` - Left-to-right * - 5 - ``+``, ``-``, ``<<``, ``>>``, ``&``, ``|``, ``^^``, ``~^``, ``~|``, ``~&`` - Left-to-right * - 4 - ``|x|`` (prefix absolute value) - Left-to-right * - 3 - ``!`` (prefix), ``~``, ``<``, ``>``, ``<=``, ``>=``, ``==``, ``!=``, ``===``, ``is``, ``in``, ``and``, ``<=>`` - Left-to-right * - 2 - ``or``, ``??``, ``|>``, ``<|`` - Left-to-right * - 1 - ``=``, ``:=``, ``+=``, ``-=``, ``*=``, ``/=``, ``%=``, and all other assignments - Right-to-left ---- Implicit Multiplication ----------------------- A numeric literal immediately followed by an identifier or opening parenthesis is parsed as multiplication: .. code-block:: symbolic 2x # equivalent to 2 * x 3(x + 1) # equivalent to 3 * (x + 1) This applies only when the number precedes the identifier with no whitespace and no intervening operator. ---- Statements and Expressions -------------------------- Every syntactic form in Symbolic is an expression. Statements are expressions whose value is typically discarded. Semicolons delimit statements and are required when two statements appear on the same line: .. code-block:: symbolic x = 10; y = 20 # two statements on one line # Equivalent when on separate lines: x = 10 y = 20 The value of a block is the value of its last expression: .. code-block:: symbolic result = if x > 0 { x * 2 } else { 0 } ---- String Interpolation -------------------- Interpolated strings use the ``f"..."`` prefix. Expressions inside ``{...}`` are evaluated at runtime: .. code-block:: symbolic name = "Alice" score = 97.5 print(f"Player: {name}") print(f"Score: {score:.1f}") print(f"Passed: {score >= 60}") print(f"Double: {score * 2}") Format specifiers follow a colon inside the braces, using Python-compatible format mini-language: ``.2f`` for two decimal places, ``,`` for thousands separator, ``d`` for integer, etc. .. seealso:: :doc:`types` — Numeric types and their behavior. :doc:`functions` — Function definitions and parameter syntax.