cxgraph/docs/language.md

267 lines
11 KiB
Markdown
Raw Normal View History

2024-09-07 22:59:55 +00:00
# CXGraph language
2023-06-15 04:27:09 +00:00
2024-09-07 22:59:55 +00:00
CXGraph uses a custom expression language that is compiled to WGSL.
2023-06-15 04:27:09 +00:00
2024-09-07 22:59:55 +00:00
## Names
2023-06-15 04:27:09 +00:00
2024-09-07 22:59:55 +00:00
Names must begin with any alphabetic character (lowercase or capital letters,
Greek letters, etc.) and may contain alphanumeric chararcters as well as
underscores (`_`) and apostrophes (`'`). The words `sum`, `prod`, `iter`,
and `if` may not be used for names. Names may refer to either functions
or variables.
2023-06-15 04:27:09 +00:00
2024-09-07 22:59:55 +00:00
Examples of names include:
2023-06-15 04:27:09 +00:00
```
a A aaa ω z_3 __5__ f' Кαl'けx焼__검
```
2024-09-07 22:59:55 +00:00
Names may either be **built-in**, **global**, or **local**. global or local names
may shadow built-in names, and local names may shadow global ones.
2023-06-15 04:27:09 +00:00
2024-09-07 22:59:55 +00:00
## Declarations
2023-06-15 04:27:09 +00:00
2024-09-07 22:59:55 +00:00
A **function declaration** declares a new function. Functions may have zero
or more arguments.
2023-06-15 04:27:09 +00:00
```
f(x) = 3
```
2024-09-07 22:59:55 +00:00
A **constant declaration** declares a new constant.
2023-06-15 04:27:09 +00:00
```
n = 5
```
2024-09-07 22:59:55 +00:00
Declarations are separated by newlines. Declarations may only reference functions
and constants in declarations that precede them. The name used in a declaration
(`f` and `n` in the above examples) is in the global scope.
2023-06-15 04:27:09 +00:00
2024-09-07 22:59:55 +00:00
The `plot` function is special and serves as the entry point. It must exist and have exactly one argument.
2023-06-15 04:27:09 +00:00
2024-09-07 22:59:55 +00:00
## Operators
Below is a reference to all operators in the CXGraph language.
| operator | description | precedence |
|----------|----------------------------|------------|
| `,` | separate expressions | 0 |
| `->` | assign to | 1 |
| `==` | equal | 2 |
| `!=` | not equal | 2 |
| `>` | real part greater | 3 |
| `<` | real part less | 3 |
| `>=` | real part greater or equal | 3 |
| `<=` | real part less or equal | 3 |
| `+` | addition | 4 |
| `-` | subtraction | 4 |
| `*` | multiplication | 5 |
| `/` | division | 5 |
| `^` | power | 6 |
The comma `,` separates expressions in locations where multiple are allowed (ie.
in a definition or block).
The arrow `->` stores the value of the expression to its left to the local
variable on the right.
The equality operators `==` and `!=` compare two values, considering both their
real and imaginary components. The comparison operators `>`, `<`, `>=`, and `<=`
2024-09-17 21:45:56 +00:00
only consider the real component. These all produce `0` if the equality or comparison
is false and `1` if it is true.
2024-09-07 22:59:55 +00:00
`+`, `-`, and `*` also function as the unary plus, minus, and conugation operators.
Multiplication can also be done via juxtaposition - `2x(x+1)` is equivalent to `2*x*(x+1)`.
Juxtaposition takes precedence over other operations, so `1/2x` is `1/(2*x)`, not `1/2*x`,
and `z^5(x+1)` is `z^(5*(x+1))`, not `z^5*(x+1)`.
## Grouping
Parentheses `( )` can be used to group within an expression. Braces `{ }` can be used to group multiple expressions, separated by commas. Newlines, which ordinarily separate declarations, are treated as whitespace between grouping symbols, allowing for multiline definitions.
## Repetition and conditionals
To allow for finite sums and products, the `sum` and `prod` expressions can be used.
```
plot(z) = sum(n: 0, 20) { z^n / n }
```
The first parameter to `sum` or `prod` is the name of the summation index, the next two
values are the lower and upper bounds (inclusive). These may be arbitrary expressions,
they are converted to integers by rounding down the real component. The value of the body
for each index value is summed or multiplied and the result is returned.
`iter` works similarly:
```
plot(c) = iter(20, 0 -> z) { z^2 + c }
```
The first parameter is the number of iterations, the second is an assignment to initialize
the iteration variable. For each iteration, the iteration variable will be updated to the
new value of the body.
`if` can be used to choose between two expressions based on a condition:
```
if(z > 0) { z^2 } { 2z }
```
If the argument's real part is positive, the first body will be evaluated, and otherwise the
second will be.
2024-09-17 21:45:56 +00:00
`while` can be used to repeat while a condition is met. Care should be taken to ensure the loop will always end eventually.
```
0 -> n, while(n < 10) { n + 1 -> n }
```
2024-09-07 22:59:55 +00:00
## Built-in functions and constants
2023-06-15 04:27:09 +00:00
arithmetic functions:
| name | description |
|---------------|-------------------------------------------------------|
2024-09-07 22:59:55 +00:00
| `pos(z)` | identity, equivalent to unary `+` |
2023-06-15 04:27:09 +00:00
| `neg(z)` | equivalent to unary `-` |
| `conj(z)` | complex conjugate, equivalent to unary `*` |
| `re(z)` | real part |
| `im(z)` | imaginary part |
| `abs(z)` | absolute value (distance from `0`) |
| `abs_sq(z)` | square of absolute value |
| `arg(z)` | argument (angle about `0`) in the range `(-τ/2, τ/2]` |
| `argbr(z,br)` | argument in the range `(-τ/2, τ/2] + br` |
| `add(z,w)` | equivalent to `z + w` |
| `sub(z,w)` | equivalent to `z - w` |
| `mul(z,w)` | equivalent to `z * w` |
| `div(z,w)` | equivalent to `z / w` |
| `recip(z)` | reciprocal, equivalent to `1/z` |
power/exponential functions:
2024-09-07 22:59:55 +00:00
| name | description |
|----------------|-------------------------------------------|
| `exp(z)` | Exponential function, equivalent to `e^z` |
| `log(z)` | Natural logarithm |
2024-09-17 21:45:56 +00:00
| `log2(z)` | Logarithm base 2 |
| `log10(z)` | Logarithm base 10 |
| `logb(b,z)` | Logarithm base b |
2024-09-07 22:59:55 +00:00
| `logbr(z,br)` | Natural logarithm with specified branch |
| `pow(z)` | Power, equivalent to `^` |
| `powbr(z,br)` | `pow` with specified branch |
| `sqrt(z)` | square root, equivalent to `z^0.5` |
| `sqrtbr(z,br)` | square root with specified branch |
| `cbrt(z)` | cube root, equivalent to `z^0.5` |
| `cbrtbr(z,br)` | cube root with specified branch |
2023-06-15 04:27:09 +00:00
trigonometric functions:
| name | description |
|------------|-------------------------------------|
2024-09-07 22:59:55 +00:00
| `sin(z)` | Sine function |
| `cos(z)` | Cosine function |
| `tan(z)` | Tangent function |
| `sinh(z)` | Hyperbolic sine function |
| `cosh(z)` | Hyperbolic cosine function |
| `tanh(z)` | Hyperbolic tangent function |
| `asin(z)` | Inverse sine function |
| `acos(z)` | Inverse cosine function |
| `atan(z)` | Inverse tangent function |
| `asinh(z)` | Inverse hyperbolic sine function |
| `acosh(z)` | Inverse hyperbolic cosine function |
| `atanh(z)` | Inverse hyperbolic tangent function |
2023-06-15 04:27:09 +00:00
special functions:
2024-09-07 22:59:55 +00:00
| function | description |
|--------------------------|------------------------------------------------------------------------|
| `gamma(z)`, `Γ(z)` | [gamma function](https://en.wikipedia.org/wiki/Gamma_function) |
| `invgamma(z)`, `invΓ(z)` | reciprocal of the gamma function |
| `loggamma(z)`, `logΓ(z)` | logarithm of the gamma function |
| `digamma(z)`, `ψ(z)` | [digamma function](https://en.wikipedia.org/wiki/Digamma_function) |
| `lambertw(z)` | [Lambert W function](https://en.wikipedia.org/wiki/Lambert_W_function) |
| `lambertwbr(z,br)` | Lambert W function on specfied branch |
| `erf(z)` | The [Error function](https://en.wikipedia.org/wiki/Error_function) |
2023-06-15 04:27:09 +00:00
logic functions:
2024-09-07 22:59:55 +00:00
| function | description |
|-------------|----------------------------------------------------------------------------|
| `signre(z)` | Sign of real part (1 if `re(z) > 0`, -1 if `re(z) < 0`, 0 if `re(z) == 0`) |
| `signim(z)` | Sign of imaginary part |
| `absre(z)` | Absolute value of real part |
| `absim(z)` | Absolute value of imaginary part |
| `isnan(z)` | 1 if `z` is NaN, 0 otherwise |
2024-09-17 21:45:56 +00:00
other functions:
| function | description |
|--------------|----------------------------------|
| `mix(u,v,a)` | `u*(1-a) + v*a` |
2023-06-15 04:27:09 +00:00
constants:
| name | description |
|----------------|--------------------------------------------------------------------------------------------------------|
2024-09-07 22:59:55 +00:00
| `i` | The imaginary constant, equal to `sqrt(-1)` |
| `e` | The [exponential constant](https://en.wikipedia.org/wiki/E_(mathematical_constant)), equal to `exp(1)` |
| `tau`, `τ` | The [circle constant](https://tauday.com/tau-manifesto) |
| `emgamma`, `γ` | The [Euler-Mascheroni](https://en.wikipedia.org/wiki/Euler%27s_constant) constant, equal to `-ψ(1)` |
| `phi`, `φ` | The [golden ratio](https://en.wikipedia.org/wiki/Golden_ratio), equal to `1/2 + sqrt(5)/2` |
2023-06-15 04:27:09 +00:00
## ebnf grammar
```
Program := Definitions
Definitions := NEWLINE* (Definition NEWLINE+)* Definition?
Definition := NAME "(" (NAME ",") NAME? ")" "=" Exprs
| NAME "=" Exprs
Exprs := (Expr ",")* Expr ","?
Expr := Store
2024-09-07 22:59:55 +00:00
Store := Equality "->" NAME | Equality
Equality := Compare "==" Compare
| Compare "!=" Compare
| Compare
Compare := Sum ">" Sum
| Sum "<" Sum
| Sum ">=" Sum
| Sum "<=" Sum
| Sum
2023-06-15 04:27:09 +00:00
Sum := Sum "+" Product
| Sum "-" Product
| Product
Product := Product "*" Unary
| Product "/" Unary
| Unary
Unary := "+" Unary
| "-" Unary
| "*" Unary
| Juxtapose Power
| Power
Juxtapose := Juxtapose PreJuxtapose | PreJuxtapose
Power := FnCall "^" Unary | FnCall
FnCall := NAME "(" Exprs ")" | Item
2024-09-07 22:59:55 +00:00
PreJuxtapose := NUMBER | "(" <Expr> ")"
Block := "{" Exprs "}"
2023-06-15 04:27:09 +00:00
2024-09-07 22:59:55 +00:00
Item := NUMBER
2023-06-15 04:27:09 +00:00
| NAME
| "(" Expr ")"
2024-09-07 22:59:55 +00:00
| Block
| "sum" "(" NAME ":" Expr "," Expr ")" Block
| "prod" "(" NAME ":" Expr "," Expr ")" block
| "iter" "(" Expr "," Expr "->" NAME ")" Block
| "if" "(" Expr ")" Block Block
2023-06-15 04:27:09 +00:00
```