Update README

This commit is contained in:
Daniel M 2022-02-10 23:02:40 +01:00
parent 742d6706b0
commit abefe32300

188
README.md
View File

@ -1,9 +1,9 @@
# NEK-Lang # NEK-Lang
## Variables ## 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. The variables are all contained in scopes. Variables defined in an outer scope can be accessed in
inner scoped. All variables defined in a scope that has ended do no longer exist and can't be
All variables are currently of type `i64` (64-bit signed integer) accessed.
### Declaration ### Declaration
- Declare and initialize a new variable - Declare and initialize a new variable
@ -25,6 +25,61 @@ a = 123;
``` ```
The value `123` is assigned to the variable named `a`. `a` needs to be declared before this. The value `123` is assigned to the variable named `a`. `a` needs to be declared before this.
## Datatypes
The available variable datatypes are `i64` (64-bit signed integer), `string` (`"this is a string"`) and `array` (`[10]`)
### I64
- The normal default datatype is `i64` which is a 64-bit signed integer
- Can be created by just writing an integer literal like `546`
- Inside the number literal `_` can be inserted for visual separation `100_000`
- The i64 values can be used as expected in calculations, conditions and so on
-
```
my_i64 <- 123_456;
```
### String
- Strings mainly exist for formatting the text output of a program
- Strings can be created by using doublequotes like in other languages `"Hello world"`
- There is no way to access or change the characters of the string
- Unicode characters are supported `"Hello 🌎"`
- Escape characters `\n`, `\r`, `\t`, `\"`, `\\` are supported
- String can still be assigned to variables, just like i64
```
world <- "🌎";
print "Hello ";
print world;
print "\n";
```
### Array
- Arrays can contain any other datatypes and don't need to have the same type in all cells
- Arrays can be created by using brackets with the size in between `[size]`
- Arrays must be assigned to a variable to be used
- All cells will be initialized with i64 0 values
- The size can be any expression that results in a positive i64 value
- The array size can't be changed after creation
- The arrays data is always allocated on the heap
- The array cells can be accessed by using the variable name and brackets `my_arr[index]`
- The index can be any expression that results in a positive i64 value in the range of the arrays
indices
- The indices start with 0
- When an array is passed to a function, it is passed by reference
```
width <- 5;
heigt <- 5;
// Initialize array of size 25 with 25x 0
my_array = [width * height];
// Modify first value
my_array[0] = 5;
// Print first value
print my_array[0];
```
## Expressions ## Expressions
The operator precedence is the same order as in `C` for all implemented operators. The operator precedence is the same order as in `C` for all implemented operators.
Refer to the Refer to the
@ -72,24 +127,38 @@ The equality and relational operations result in `1` if the condition is evaluat
For conditions like in if or loops, every non zero value is equal to `true`, and `0` is `false`. For conditions like in if or loops, every non zero value is equal to `true`, and `0` is `false`.
### Loop ### 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 can be used as an infinite loop, as a while loop or as a while loop with advancement (an expression that is executed after the loop body)
- If only `loop` is used, directly followed by the body, it is an infinite loop that needs to be
terminated by using the `break` keyword
- The `loop` keyword is followed by the condition (an expression) without needing parentheses - 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 - *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++ - The loops body is wrapped in braces (`{ }`) just like in C/C++
- The `continue` keyword can be used to end the current loop iteration early
- The `break` keyword can be used to fully break out of the current loop
``` ```
// Print the numbers from 0 to 9 // Print the numbers from 0 to 9
// With endless loop
i <- 0;
loop {
if i >= 10 {
break;
}
print i;
i = i + 1;
}
// Without advancement // Without advancement
i <- 0; i <- 0;
loop i < 10 { loop i < 10 {
print i; print i;
i = i - 1; i = i + 1;
} }
// With advancement // With advancement
k <- 0; k <- 0;
loop k < 10; k = k - 1 { loop k < 10; k = k + 1 {
print k; print k;
} }
``` ```
@ -112,6 +181,69 @@ if a == b {
} }
``` ```
### Block Scopes
- It is possible to create a limited scope for local variables that will no longer exist once the
scope ends
- Shadowing variables by redefining a variable in an inner scope is supported
```
var_in_outer_scope <- 5;
{
var_in_inner_scope <- 3;
// Inner scope can access both vars
print var_in_outer_scope;
print var_in_inner_scope;
}
// Outer scope is still valid
print var_in_outer_scope;
// !!! THIS DOES NOT WORK !!!
// The inner scope has ended
print var_in_inner_scope;
```
## Functions
### Function definition
- Functions can be defined by using the `fun` keyword, followed by the function name and the
parameters in parentheses. After the parentheses, the body is specified inside a braces block
- The function parameters are specified by only the names
- The function body has its own scope
- Parameters are only accessible inside the body
- Variables from the outer scope can be accessed and modified if the are defined before the function
- Variables from the outer scope are shadowed by parameters with the same name
- The `return` keyword can be used to return a value from the function and exit it immediately
- If no return is specified, a `void` value is returned
```
fun add_maybe(a, b) {
if a < 100 {
return a;
} else {
return a + b;
}
}
fun println(val) {
print val;
print "\n";
}
```
### Function calls
- Function calls are primary expressions, so they can be directly used in calculations (if they
return appropriate values)
- Function calls are performed by writing the function name, followed by the arguments in parentheses
- The arguments can be any expressions, separated by commas
```
b <- 100;
result <- add_maybe(250, b);
// Prints 350 + new-line
println(result);
```
## IO ## IO
### Print ### Print
@ -140,6 +272,8 @@ Line comments can be initiated by using `//`
- [x] Lexer: Transforms text into Tokens - [x] Lexer: Transforms text into Tokens
- [x] Parser: Transforms Tokens into Abstract Syntax Tree - [x] Parser: Transforms Tokens into Abstract Syntax Tree
- [x] Interpreter (tree-walk-interpreter): Walks the tree and evaluates the expressions / statements - [x] Interpreter (tree-walk-interpreter): Walks the tree and evaluates the expressions / statements
- [x] Simple optimizer: Apply trivial optimizations to the Ast
- [x] Precalculate binary ops / unary ops that have only literal operands
## Language features ## Language features
@ -149,7 +283,7 @@ Line comments can be initiated by using `//`
- [x] Subtraction `a - b` - [x] Subtraction `a - b`
- [x] Multiplication `a * b` - [x] Multiplication `a * b`
- [x] Division `a / b` - [x] Division `a / b`
- [x] Modulo `a % b - [x] Modulo `a % b`
- [x] Negate `-a` - [x] Negate `-a`
- [x] Parentheses `(a + b) * c` - [x] Parentheses `(a + b) * c`
- [x] Logical boolean operators - [x] Logical boolean operators
@ -173,23 +307,43 @@ Line comments can be initiated by using `//`
- [x] Variables - [x] Variables
- [x] Declaration - [x] Declaration
- [x] Assignment - [x] Assignment
- [x] Local variables (for example inside loop, if, else, functions)
- [x] Scoped block for specific local vars `{ ... }`
- [x] Statements with semicolon & Multiline programs - [x] Statements with semicolon & Multiline programs
- [x] Control flow - [x] Control flow
- [x] While loop `while X { ... }` - [x] Loops
- [x] While-style loop `loop X { ... }`
- [x] For-style loop without with `X` as condition and `Y` as advancement `loop X; Y { ... }`
- [x] Infinite loop `loop { ... }`
- [x] Break `break`
- [x] Continue `continue`
- [x] If else statement `if X { ... } else { ... }` - [x] If else statement `if X { ... } else { ... }`
- [x] If Statement - [x] If Statement
- [x] Else statement - [x] Else statement
- [x] Line comments `//` - [x] Line comments `//`
- [x] Strings - [x] Strings
- [x] Arrays
- [x] Creating array with size `X` as a variable `arr <- [X]`
- [x] Accessing arrays by index `arr[X]`
- [x] IO Intrinsics - [x] IO Intrinsics
- [x] Print - [x] Print
- [x] Functions
- [x] Function declaration `fun f(X, Y, Z) { ... }`
- [x] Function calls `f(1, 2, 3)`
- [x] Function returns `return X`
- [x] Local variables
- [x] Pass arrays by-reference, i64 by-vale, string is a const ref
## Grammar ## Grammar
### Expressions ### Expressions
``` ```
LITERAL = I64_LITERAL | STR_LITERAL ARRAY_LITERAL = "[" expr "]"
expr_primary = LITERAL | IDENT | "(" expr ")" | "-" expr_primary | "~" expr_primary ARRAY_ACCESS = IDENT "[" expr "]"
FUN_CALL = IDENT "(" (expr ",")* expr? ")"
LITERAL = I64_LITERAL | STR_LITERAL | ARRAY_LITERAL
expr_primary = LITERAL | IDENT | FUN_CALL | ARRAY_ACCESS | "(" expr ")" | "-" expr_primary
| "~" expr_primary
expr_mul = expr_primary (("*" | "/" | "%") expr_primary)* expr_mul = expr_primary (("*" | "/" | "%") expr_primary)*
expr_add = expr_mul (("+" | "-") expr_mul)* expr_add = expr_mul (("+" | "-") expr_mul)*
expr_shift = expr_add ((">>" | "<<") expr_add)* expr_shift = expr_add ((">>" | "<<") expr_add)*
@ -205,8 +359,16 @@ expr = expr_lor
### Statements ### Statements
``` ```
stmt_if = "if" expr "{" stmt* "}" ("else" "{" stmt* "}")? stmt_return = "return" expr ";"
stmt_loop = "loop" expr (";" expr)? "{" stmt* "}" stmt_break = "break" ";"
stmt_continue = "continue" ";"
stmt_var_decl = IDENT "<-" expr ";"
stmt_fun_decl = "fun" IDENT "(" (IDENT ",")* IDENT? ")" "{" stmt* "}"
stmt_expr = expr ";" stmt_expr = expr ";"
stmt = stmt_expr | stmt_loop stmt_block = "{" stmt* "}"
stmt_loop = "loop" (expr (";" expr)?)? "{" stmt* "}"
stmt_if = "if" expr "{" stmt* "}" ("else" "{" stmt* "}")?
stmt_print = "print" expr ";"
stmt = stmt_return | stmt_break | stmt_continue | stmt_var_decl | stmt_fun_decl
| stmt_expr | stmt_block | stmt_loop | stmt_if | stmt_print
``` ```