nek-lang/README.md

212 lines
6.0 KiB
Markdown

# NEK-Lang
## Variables
Currently all variables are global and completely unscoped. That means no matter where a variable is declared, it remains over the whole remaining runtime of the progam.
All variables are currently of type `i64` (64-bit signed integer)
### Declaration
- Declare and initialize a new variable
- Declaring a previously declared variable again is currently equivalent to an assignment
- Declaration is needed before assignment or other usage
- The variable name is on the left side of the `<-` operator
- The assigned value is on the right side and can be any expression
```
a <- 123;
```
Create a new variable named `a` and assign the value `123` to it.
### Assignment
- Assigning a value to a previously declared variable
- The variable name is on the left side of the `=` operator
- The assigned value is on the right side and can be any expression
```
a = 123;
```
The value `123` is assigned to the variable named `a`. `a` needs to be declared before this.
## Expressions
The operator precedence is the same order as in `C` for all implemented operators.
Refer to the
[C Operator Precedence Table](https://en.cppreference.com/w/c/language/operator_precedence)
to see the different precedences.
### General
- Parentheses `(` and `)` can be used to modify evaluation oder just like in any other
programming language.
- For example `(a + b) * c` will evaluate the addition before the multiplication, despite the multiplication having higher binding power
### Mathematical Operators
Supported mathematical operations:
- Addition `a + b`
- Subtraction `a - b`
- Multiplication `a * b`
- Division `a / b`
- Modulo `a % b`
- Negation `-a`
### Bitwise Operators
- And `a & b`
- Or `a | b`
- Xor `a ^ b`
- Bitshift left (by `b` bits) `a << b`
- Bitshift right (by `b` bits) `a >> b`
- "Bit flip" (One's complement) `~a`
### Logical Operators
The logical operators evaluate the operands as `false` if they are equal to `0` and `true` if they are not equal to `0`
- And `a && b`
- Or `a || b`
- Not `!a`
### Equality & Relational Operators
The equality and relational operations result in `1` if the condition is evaluated as `true` and in `0` if the condition is evaluated as `false`.
- Equality `a == b`
- Inequality `a != b`
- Greater than `a > b`
- Greater or equal than `a >= b`
- Less than `a < b`
- Less or equal than `a <= b`
## Control-Flow
For conditions like in if or loops, every non zero value is equal to `true`, and `0` is `false`.
### Loop
- There is currently only the `loop` keyword that can act like a `while` with optional advancement (an expression that is executed after the loop body)
- The `loop` keyword is followed by the condition (an expression) without needing parentheses
- *Optional:* If there is a `;` after the condition, there must be another expression which is used as the advancement
- The loops body is wrapped in braces (`{ }`) just like in C/C++
```
// Print the numbers from 0 to 9
// Without advancement
i <- 0;
loop i < 10 {
print i;
i = i - 1;
}
// With advancement
k <- 0;
loop k < 10; k = k - 1 {
print k;
}
```
### If / Else
- The language supports `if` and an optional `else`
- After the `if` keyword must be the deciding condition, parentheses are not needed
- The block *if-true* block is wrapped in braces (`{ }`)
- *Optional:* If there is an `else` after the *if-block*, there must be a following *if-false*, aka. else block
```
a <- 1;
b <- 2;
if a == b {
// a is equal to b
print 1;
} else {
// a is not equal to b
print 0;
}
```
## IO
### Print
Printing is implemented via the `print` keyword
- The `print` keyword is followed by an expression, the value of which will be printed to the terminal.
- Print currently automatically adds a linebreak
```
a <- 1;
print a; // Outputs `"1\n"` to the terminal
```
## Comments
### Line comments
Line comments can be initiated by using `//`
- Everything after `//` up to the end of the current line is ignored and not parsed
```
// This is a comment
```
# Feature Tracker
## High level Components
- [x] Lexer: Transforms text into Tokens
- [x] Parser: Transforms Tokens into Abstract Syntax Tree
- [x] Interpreter (tree-walk-interpreter): Walks the tree and evaluates the expressions / statements
## Language features
- [x] General expressions
- [x] Arithmetic operations
- [x] Addition `a + b`
- [x] Subtraction `a - b`
- [x] Multiplication `a * b`
- [x] Division `a / b`
- [x] Modulo `a % b
- [x] Negate `-a`
- [x] Parentheses `(a + b) * c`
- [x] Logical boolean operators
- [x] Equal `a == b`
- [x] Not equal `a != b`
- [x] Greater than `a > b`
- [x] Less than `a < b`
- [x] Greater than or equal `a >= b`
- [x] Less than or equal `a <= b`
- [x] Logical operators
- [x] And `a && b`
- [x] Or `a || b`
- [x] Not `!a`
- [x] Bitwise operators
- [x] Bitwise AND `a & b`
- [x] Bitwise OR `a | b`
- [x] Bitwise XOR `a ^ b`
- [x] Bitwise NOT `~a`
- [x] Bitwise left shift `a << b`
- [x] Bitwise right shift `a >> b`
- [x] Variables
- [x] Declaration
- [x] Assignment
- [x] Statements with semicolon & Multiline programs
- [x] Control flow
- [x] While loop `while X { ... }`
- [x] If else statement `if X { ... } else { ... }`
- [x] If Statement
- [x] Else statement
- [x] Line comments `//`
- [ ] Strings
- [ ] IO Intrinsics
- [x] Print
- [ ] ReadInt
## Grammar
### Expressions
```
expr_primary = LITERAL | IDENT | "(" expr ")" | "-" expr_primary | "~" expr_primary
expr_mul = expr_primary (("*" | "/" | "%") expr_primary)*
expr_add = expr_mul (("+" | "-") expr_mul)*
expr_shift = expr_add ((">>" | "<<") expr_add)*
expr_rel = expr_shift ((">" | ">=" | "<" | "<=") expr_shift)*
expr_equ = expr_rel (("==" | "!=") expr_rel)*
expr_band = expr_equ ("&" expr_equ)*
expr_bxor = expr_band ("^" expr_band)*
expr_bor = expr_bxor ("|" expr_bxor)*
expr_land = expr_bor ("&&" expr_bor)*
expr_lor = expr_land ("||" expr_land)*
expr = expr_lor
```
### Statements
```
stmt_if = "if" expr "{" stmt* "}" ("else" "{" stmt* "}")?
stmt_loop = "loop" expr (";" expr)? "{" stmt* "}"
stmt_expr = expr ";"
stmt = stmt_expr | stmt_loop
```