Skip to content
Snippets Groups Projects
Commit e3ef4fda authored by Per Lindgren's avatar Per Lindgren
Browse files

some readme updates

parent 280fdd5b
No related branches found
No related tags found
No related merge requests found
fn main() {}
fn main() {
let a = false;
let a = {
let b = 1 + 1;
// extra `;` are allowed
if a {} // no trialing `;`
b // return value
};
while false {
// do something here
}
let _b = if a < 5 { 1 } else { 2 };
}
fn a(a: i32, mut b: bool) {
let a = 5;
while b {}
}
fn main() {}
......@@ -22,12 +22,13 @@ fn main() {
}
```
At the top level, we have a *block* (sequence of statements). We also see, that the `let` statement accepts a *block* of statements as part of an assignment. Notice, Rust allows allow assignment to refer to the result of an `if then else` construct.
The *body* of a function is a *block* (sequence of statements). We also see, that the `let` statement accepts a *block* of statements as part of an assignment. Notice, Rust allows allow assignment to refer to the result of an `if then else` construct. As shown in the at the end.
Inside a *block*, statements are typically separated by `;`, with the following exceptions.
- `if` statements, and
- `while` statements may omit the trailing `;`.
- `while` statements may omit the trailing `;`, and
- `{ ... }` inner blocks.
Additionally Rust allows for additional `;` in between statements (but extra `;` are considered non-idiomatic and thus removed by `rustfmt`).
......@@ -39,6 +40,8 @@ The example grammar in `ast/parser.lalrpop` covers a minimal subset of Rust, suf
Some interesting design decisions:
- A *block* of statements is sequence of `;` separated statements followed by an optional trailing statement.
- We treat statements that may be considered as expressions by a special rule `ExprBlock`, where we accept either `if then else` or a `block` (statments). (This is where we likely add `match` and similar statements later.)
Recall that a statement can be a return value, thus must somehow accept an expression. Now, here is the crux, since we want `if then else` and `blocks` (statements) to be treated as expression for assignments, it would cause ambiguities between statements as part of an expression or inside a *block*. We can resolve this by the adopting `ExprNoBlock`, inside of `stmt`. `ExprNoBlock` accepts expression besides those that are matched by `ExprBlock` (`if then else` and `block`).
......
......@@ -37,3 +37,8 @@ fn syntax2() {
fn syntax3() {
parse("examples/syntax3.rs");
}
#[test]
fn syntax4() {
parse("examples/syntax4.rs");
}
......@@ -54,8 +54,7 @@ Type:() = {
}
Block: () = {
"{" StmtSeq* "}",
"{" StmtSeq* Stmt "}",
"{" StmtSeq* Stmt? "}",
}
StmtSeq: () = {
......@@ -131,8 +130,6 @@ UnaryOp: () = {
"&" "mut",
}
Num: i32 = {
r"[0-9]+" => i32::from_str(<>).unwrap(),
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment