courses/compiler/chapter_2.md
Simon From Jakobsen 44aae17334 init
2024-08-22 13:04:41 +00:00

221 lines
3.6 KiB
Markdown

## 2 Specifying a language
**You can skip this chapter and come back to it, if you need.**
The language will at first consist of these features.
- Literals
- Expressions
- Variables
- Blocks
- If-conditions
- Loops
- Function calls
- Function definitions
## 2.1 Literals
Integers (ints) are numbers without decimal point.
Strings are text enclosed in double-quotes `" "`. Backslash `\` can be used to escape `"` and invoke specialt characters `\n` and `\t` for newline and tab characters.
Booleans (bools) represent logical true and false and are the symbols `true` and `false`.
Null represents a non-value (null value) and is the symbol `null`.
Examples:
```
0
123
"hello"
"{ \"key\": 123 }"
true
false
null
```
## 2.2 Expressions
I'll be reusing the prefix notation expressions from chapter 1. These are also called S-expressions.
I'll be using logical expressions (`or`, `and` and `not`), comparison expressions (`==`, `!=`, `<` and `>`), arithmetic expressions (`+`, `-`, `*`, `/`) and group expressions (`(...)`).
The grammer, meaning the rules for the structure of the code, is the following:
```
expr ->
...
| "or" expr expr
| "and" expr expr
| "not" expr
| "==" expr expr
| "!=" expr expr
| "<" expr expr
| ">" expr expr
| "+" expr expr
| "-" expr expr
| "*" expr expr
| "/" expr expr
| "(" expr ")"
...
| literal
```
Notice `not` only has 1 operand.
Examples:
```
+ 1 * 2 3
+ + + 1 2 3 4
* 3 (* 3 3)
```
## 2.3 Variables
A variable is a storage container for a value.
A variable is defined using a `let`-statement. A variable is used by refering to its name. A variable can be reassigned after definition.
Variables are block-scoped, more on this later.
Grammar:
```
let -> "let" ident "=" expr ";"
assign -> ident "=" expr ";"
expr ->
...
| ident
...
```
Examples:
```
let a = 5;
a = 10;
+ a 10
```
## 2.4 Blocks
A block is code enclosed in curly-braces (`{` and `}`). They can be used as both statements and expressions. Single-line statements in a block need semicolon (`;`) at the end. Expressions can be used as statements.
If the last entry in a block is an expression and the semicolon is omitted, the block as a whole yields that value.
Grammar:
```
block -> "{" statements expr:? "}"
expr ->
...
| block
...
```
Examples:
```
{}
{
let a = 5;
}
let a = {
let b = 5;
+ b 5
};
```
## 2.5 If-statements
An `if`-statement has a condition and a block it runs, if the condition evaluates to `true` ("truthy"), and an optional `else`-block, if it the condition evaluates to `false`.
Grammar:
```
if -> "if" expr block ("else" block):?
expr ->
...
| if
...
```
I've added `if` to `expr`, because, in addition to a statement, I want to be able to use `if` as an expression just like blocks.
Examples:
```
let a = 5;
if == b 5 {
a = 5;
}
let value = if > a b { c } else { d };
```
## 2.6 Loops
`loop`-statements are blocks that run continually (from top to bottom, then from the top again) until a `break`-statement is evaluated.
Loops can also be expressions, as a value can be supplied when breaking.
Grammar:
```
loop -> "loop" block
break -> "break" expr:? ";"
expr ->
...
| loop
...
```
Examples:
```
let i = 0;
let v = 1;
loop {
if not < i 10 {
break;
}
v = * v 2;
i = + i 1;
}
let v = loop {
break 5;
};
```
## 2.7 Function calls
Grammar:
```
expr ->
...
| expr "(" args ")"
...
```
Examples:
```
let a = pow(2, 3);
exit();
```
## 2.8 Function definition
Grammar:
```
fn -> "fn" ident "(" params ")" block
return -> "return" expr:? ";"
```