# Openbirch Rust Openbirch rewritten in rust. Very messy and bad, im gonna start the umpteenth rewrite soon. # Features [x] Constants (numbers) [x] Addition [x] Subtraction [x] Multiplication [x] Division [x] Arbitrary float precision [ ] Sets (or lists, arrays, etc) [x] Definition [x] Multiplication with constants [x] Concattenation [ ] Index operator [x] Functions [x] Native functions [x] User defined functions [x] Currying [x] Closures [x] Calling [x] Scopes [x] Shadowing variables [ ] Ranges [x] Defining ranges (`1..5` is a range of `[1..5)`) [ ] Iterating ranges [x] Evaluating ranges (very hacky, but defining a Set of length 1 with a range expands said range into the set, eg `[1..3]` becomes `[1,2]`) [ ] Loops [x] Infinite loops (`loop ... end` block) [ ] For loops (`for x in y ... end` block) [x] Break keyword [ ] Match expression [x] If expression [x] If expression [x] If-else expression ## Wanted [ ] More concise syntax, i dont like how it is right now [ ] Fix stack overflow with recursive functions (internally convert to loops) [ ] Generally implement more [ ] Implicit multiplication (may not be possible to implement non-ambiguously) [ ] Differentiation [ ] Integration [ ] Better error handling (i was lazy and skimped on errors, bad move) # Syntax Every Openbirch program is made up of 0 or more *expressions*. An expression is anything from a binary operation like `2+2` to function calls `f(x)` and even assignments `x := 5`. All expressions return a value. For expressions that "dont" they return an `Empty`, which cant be used for anything and will error if used in other operations (eg. `2+{Empty}`). ## Definition Variables can be defined with a `define` expression. ``` x := 5 # define x as 5 print(x+x) # prints 10 ``` As openbirch is a symbolic language variables can be used before assignment ``` y := x^2 print(y) # prints x^2 x := 5 print(y) # prints 25 ``` ### Scopes Some expressions define a *scope*, where all defined variables inside will be deleted once the scope ends. Expressions that create a scope include, but are not limited to, - If-else - Loop - Functions - Closures If a variable is defined outside a scope it will be *shadowed* inside the scope. What this means is that inside the scope the variable will have the shadowed value, while outside the scope it will have the previous value. ``` x := 5 # Global scope print(x) # prints 5 if true then # Define a new scope x := 5000 # Shadow the value of x print(x) # prints 5000 end # Scope ends here print(x) # prints 5 ``` ### Assignment Since you may want to change the value of a variable outside the current scope you can use an `assignment` rather than a definition. ``` x := 5 if true then x <- 500 # Assign to x rather than defining it and shadowing it end print(x) # prints 500 ``` ## If-else If expressions are defined as such ``` if {condition} then # 0 or more statements end ``` and if-else as ``` if {condition} then # 0 or more statements else {expression} end ``` Since `if` is an expression the body of the else branch can be another if expression, in which case only 1 `end` keyword is needed. ``` if {condition} then # 0 or more statements else if {condition} then # 0 or more statements end ``` Since all expressions evaluate to a value the value of the if expression is the resulting value of the last statement in the chosen branch, eg. ``` x := if true then # Evaluate some expressions 2+2 f(x) y := f(f(x)) # Last expression is returned 5 else 0 end print(x) # prints 5 ``` if a branch is empty then `Empty` is returned. ## Loops Currently the only type of loop is an infinite loop. ``` loop # This will repeat forever end ``` # Running ## Linux ```sh $ cargo run ``` ### Nixos ```sh $ nix develop $ cargo run ``` ## Windows idfk, havent used that shit in years, but probably just `cargo run`. ## MacOS never used, but again probably `cargo run`