/wor·tiks/
Strange dynamic programming and scripting language that performs mathematical computations on a connected Raspberry Pi Pico (RP2040) through UART connectivity.
The Uartix programming language features a comprehensive and intricate grammar as described in its Backus-Naur Form (BNF). The grammar delineates the syntax rules for various constructs within the language, ranging from fundamental data types to complex expressions and control structures. Uartix supports multiple numeric bases including binary (0b
), trinary (0t
), octadecimal (0c
), and hexadecimal (0x
), providing a versatile foundation for numerical operations. These are encapsulated under the DIGIT
rule, which allows for a broad range of numeric representations, enhancing the language's flexibility in handling computational tasks.
The global
rule is a sequence of statements
, indicating that a Uartix program is essentially a series of statements executed sequentially. Statements in Uartix can be simple control flow directives like use
, test
, break
, continue
, return (ret
), and throw
, each followed by a semicolon. These basic statements enable control over the program's execution flow, allowing developers to implement loops, conditional logic, and error handling effectively.
Expressions form the backbone of Uartix's syntax, includes a wide array of operations and constructs. These include type_expr
for type annotations, block_expr
for grouping statements within braces, and render_expr
for output operations. The catch_expr
provides a mechanism for exception handling, encapsulating the catch
, handle
, and then
keywords to manage errors gracefully. Control flow is further enriched with constructs like do_expr
and while_expr
for loop operations, if_expr
for conditional branching, random_expr
for probabilistic decision making, loop_expr for traditional for-loops, unless_expr
for negated conditions, and when_expr
for pattern matching.
grammar.bnf
binary := "0b" ("0" | "1")*
trinary := "0t" ("0" - "2")*
octadecimal := "0c" ("0" - "7")*
hexadecimal := "0x" ("0" - "9" | "a" - "f" | "A" - "F")*
DIGIT :=
("0" - "9")* |
binary |
trinary |
octadecimal |
hexadecimal
global := (statement)*
statement :=
use_stmt |
test_stmt |
break_stmt |
continue_stmt |
ret_stmt |
throw_stmt |
expr_stmt
use_stmt :=
"use" expression
[expression ("," expression)*]
";"
test_stmt :=
"test" "(" expression ")"
expression ";"
break_stmt := "break" ";"
continue_stmt := "continue" ";"
ret_stmt := "ret" expression ";"
throw_stmt := "throw" expression ";"
expr_stmt := expression ";"
expression :=
type_expr |
block_expr |
render_expr |
catch_expr |
do_expr |
while_expr |
if_expr |
random_expr |
loop_expr |
unless_expr |
when_expr |
func_expr |
maybe_expr |
array_expr |
logic_or_expr
type_expr := "type" expression
block_expr := "{" (statement)* "}"
render_expr := "render" expression
catch_expr :=
"catch" block_expr
"handle" <IDENTIFIER> block_expr
"then" block_expr
do_expr :=
"do" expression
"while" "(" expression ")"
while_expr :=
"while" "(" expression ")" expression
if_expr :=
"if" "(" expression ")" expression
["else" expression]
random_expr :=
"random" expression
["else" expression]
loop_expr :=
"loop" "("
expression ";"
expression ";"
expression
")" expression
unless_expr :=
"unless" "(" expression ")" expression
["else" expression]
when_expr :=
"when" "(" expression ")" "{"
[
"if" "(" expression ")" expression
("," "if" "(" expression ")" expression)*
]
["else" expression]
"}"
maybe_expr := "maybe"
func_expr :=
"func" "(" [<IDENTIFIER> ("," <IDENTIFIER>)*] ")"
expression
array_expr :=
"[" [expression ("," expression)*] "]"
logic_or_expr :=
logic_and_expr ["||" logic_and_expr]
logic_and_expr :=
bitwise_or_expr ["&&" bitwise_or_expr]
bitwise_or_expr :=
bitwise_xor_expr ["|" bitwise_xor_expr]
bitwise_xor_expr :=
bitwise_and_expr ["^" bitwise_and_expr]
bitwise_and_expr :=
null_coalesce_expr ["&" null_coalesce_expr]
null_coalesce_expr :=
equality_expr ["?" equality_expr]
equality_expr :=
comparison_expr [("==" | "!=" | "=") comparison_expr]
comparison_expr :=
shift_expr [("<" | "<=" | ">" | ">=") shift_expr]
shift_expr :=
term_expr [("<<" | ">>") term_expr]
term_expr :=
factor_expr [("+" | "-") factor_expr]
factor_expr :=
primary_expr [("*" | "/" | "%) primary_expr]
primary_expr :=
(
("+" | "-" | "~") expression |
"(" expression ")" |
<IDENTIFIER> ("[" expression "]")* |
literal_expr
)
(
"(" [expression ("," expression)*] ")" |
"[" expression"]"
)*
literal_expr :=
"true" | "false" | "nil" |
<STRING> |
<DIGIT>
Functionality in Uartix is extended through func_expr
, which defines functions with optional parameters, facilitating modular and reusable code. Arrays are managed using array_expr, which allows for the creation and manipulation of indexed collections. Logical operations are handled through logic_or_expr
and logic_and_expr
, with further support for bitwise operations (bitwise_or_expr
, bitwise_xor_expr
, bitwise_and_expr
) and comparison operators (equality_expr
, comparison_expr
). The grammar also includes expressions for arithmetic operations (term_expr
, factor_expr
) and primary expressions (primary_expr
), which can be literals, identifiers, or complex nested expressions.
Literal values in Uartix, defined under literal_expr, include boolean values (true
, false
), a null value (nil
), strings, and digits, offering a fundamental set of data types to work with. The grammar ensures that these literals can be used flexibly within expressions to construct more complex computations.