made syntax cheat sheet a bit clearer

This commit is contained in:
mark 2023-05-26 20:18:09 +02:00
parent 45f6f30de3
commit 4356858ab2
4 changed files with 24 additions and 21 deletions

View File

@ -62,6 +62,9 @@
* this is why `&<var_name> = <statement>` is the way it is. * this is why `&<var_name> = <statement>` is the way it is.
+ `***<statement_left> = <statement_right>` + `***<statement_left> = <statement_right>`
* same as before, but performs dereferences: `&&&&int` becomes `&int` (minus 3 references because 3 `*`s), so a value of type `int` can be assigned to it. * same as before, but performs dereferences: `&&&&int` becomes `&int` (minus 3 references because 3 `*`s), so a value of type `int` can be assigned to it.
- destructuring
+ values can be destructured into tuples or lists (as of right now):
+ `[a, b] := [10, "some text"]` is effectively the same as `a := 10, b := "some text"`
## Statements ## Statements
@ -89,26 +92,26 @@
+ if the statement returns a value that matches, the loop will end and return the matched value + if the statement returns a value that matches, the loop will end and return the matched value
+ the loop's return type is the match of the return type of the statement + the loop's return type is the match of the return type of the statement
- for loop - for loop
+ `for <var_name> <iterator> <statement>` + `for <assign_to> <iterator> <statement>`
+ in each iteration, the variable will be initialized with a value from the iterator. + in each iteration, the variable will be initialized with a value from the iterator.
+ iterators can be lists, tuples, or functions. + iterators can be lists, tuples, or functions.
+ for function iterators, as long as the returned value matches, the matched value will be used. if the value doesn't match, the loop ends. + for function iterators, as long as the returned value matches, the matched value will be used. if the value doesn't match, the loop ends.
+ if the statement returns a value that matches, the loop will end and return the matched value + if the statement returns a value that matches, the loop will end and return the matched value
+ the loop's return type is the match of the return type of the statement or `[]` (if the loop ends because the iterator ended) + the loop's return type is the match of the return type of the statement or `[]` (if the loop ends because the iterator ended)
- switch - switch
+ `switch <var_name> { <arm1> <arm2> <...> }` + `switch <value> { <arm1> <arm2> <...> }`
* where `<armn>` is `<typen> <statementn>` * where `<armn>` is `<typen> <assign_to> <statementn>`
* if the variable's value is of type `<typen>`, `<statementn>` will be executed. * if the variable's value is of type `<typen>`, `<statementn>` will be executed with `<value>` assigned to `<assign_to>`.
* if the variables type is included multiple times, only the first match will be executed. * if the variables type is included multiple times, only the first match will be executed.
* within the statement of an arm, the variables type is that specified in `<typen>`, and not its original type (which may be too broad to work with) * within the statement of an arm, the variables type is that specified in `<typen>`, and not its original type (which may be too broad to work with)
+ `switch! <var_name> { <arm1> <arm2> <...> }` + `switch! <var_name> { <arm1> <arm2> <...> }`
* same as above, but all types the variable could have must be covered * same as above, but all types the variable could have must be covered
* the additional `[]` in the return type isn't added here since it is impossible not to run the statement of one of the arms. * the additional `[]` in the return type isn't added here since it is impossible not to run the statement of one of the arms.
- match - match
+ `match <var_name> { <arm1> <arm2> <...> }` + `match { <arm1> <arm2> <...> }`
* where `<armn>` is `<statement> <statement>` * where `<armn>` is `<(condition) statement> <assign_to> <(action) statement>`
* each arm has a condition statement an an action statement. * each arm has a condition statement, something that the matched value will be assigned to, and an action statement.
* if the value returned by the condition statement matches, the matched value is assigned to the variable and the action statement is executed. * if the value returned by the condition statement matches, the matched value is assigned to `<assign_to>` and the action statement is executed.
* only the first matching arm will be executed. if no arm was executed, `[]` is returned. * only the first matching arm will be executed. if no arm was executed, `[]` is returned.
- fixed-indexing - fixed-indexing
+ `<statement>.n` where `n` is a fixed number (not a variable, just `0`, `1`, `2`, ...) + `<statement>.n` where `n` is a fixed number (not a variable, just `0`, `1`, `2`, ...)

View File

@ -9,7 +9,7 @@
<section class="container"> <section class="container">
<section class="container_left2 code-border"> <section class="container_left2 code-border">
<pre><code class="mers-code-snippet"> <pre><code class="mers-code-snippet">
fn get_number_input(question string) {<br> println(question)<br> input := read_line()<br> // try to parse to an int, then a float.<br> in := match input {<br> input.parse_int() input<br> input.parse_float() input<br> }<br> // 'in' has type int/float/[] because of the match statement<br> switch! in {<br> int/float in<br> // replace [] with an appropriate error before returning<br> [] Err: "input was not a number."<br> }<br> // return type is int/float/Err(string)<br>}<br><br>answer := get_number_input("What is your favorite number?")<br><br>answer.debug() // type: int/float/Err(string)<br>// switch can be used to branch based on a variables type.<br>// switch! indicates that every possible type must be handled.<br>switch! answer {<br> int {<br> println("Entered an integer")<br> answer.debug() // type: int<br> }<br> float {<br> println("Entered a decimal number")<br> answer.debug() // type: float<br> }<br> Err(string) println("Input was not a number!")<br>}<br><br>// wait one second<br>sleep(1)<br><br><br>// function that returns an anonymous function (function object).<br>// anonymous functions can be used as iterators in for-loops.<br>fn square_numbers() {<br> i := 0<br> () {<br> &amp;i = i + 1<br> i * i<br> }<br>}<br><br>for num square_numbers() {<br> println(num.to_string())<br> // once num is greater than 60, the loop stops.<br> num.gt(50)<br>}<br></code></pre> fn get_number_input(question string) {<br> println(question)<br> input := read_line()<br> // try to parse to an int, then a float.<br> in := match {<br> input.parse_int() n n<br> input.parse_float() n n<br> }<br> // 'in' has type int/float/[] because of the match statement<br> switch! in {<br> int/float in in<br> // replace [] with an appropriate error before returning<br> [] [] Err: "input was not a number."<br> }<br> // return type is int/float/Err(string)<br>}<br><br>answer := get_number_input("What is your favorite number?")<br><br>answer.debug() // type: int/float/Err(string)<br>// switch can be used to branch based on a variables type.<br>// switch! indicates that every possible type must be handled.<br>switch! answer {<br> int num {<br> println("Entered an integer")<br> num.debug() // type: int<br> }<br> float num {<br> println("Entered a decimal number")<br> num.debug() // type: float<br> }<br> Err(string) [] println("Input was not a number!")<br>}<br><br>// wait one second<br>sleep(1)<br><br><br>// function that returns an anonymous function (function object).<br>// anonymous functions can be used as iterators in for-loops.<br>fn square_numbers() {<br> i := 0<br> () {<br> &amp;i = i + 1<br> i * i<br> }<br>}<br><br>for num square_numbers() {<br> println(num.to_string())<br> // once num is greater than 60, the loop stops.<br> num.gt(50)<br>}<br></code></pre>
</section> </section>
<section class="container_right"> <section class="container_right">
<image <image

View File

@ -338,9 +338,9 @@ impl RStatementEnum {
let switch_on = switch_on.out(info).types; let switch_on = switch_on.out(info).types;
let mut might_return_empty = switch_on.is_empty(); let mut might_return_empty = switch_on.is_empty();
let mut out = if *force { let mut out = if *force {
VSingleType::Tuple(vec![]).to()
} else {
VType::empty() VType::empty()
} else {
VSingleType::Tuple(vec![]).to()
}; };
for switch_on in switch_on { for switch_on in switch_on {
for (_on_type, _assign_to, case) in cases.iter() { for (_on_type, _assign_to, case) in cases.iter() {

View File

@ -2,15 +2,15 @@ fn get_number_input(question string) {
println(question) println(question)
input := read_line() input := read_line()
// try to parse to an int, then a float. // try to parse to an int, then a float.
in := match input { in := match {
input.parse_int() input input.parse_int() n n
input.parse_float() input input.parse_float() n n
} }
// 'in' has type int/float/[] because of the match statement // 'in' has type int/float/[] because of the match statement
switch! in { switch! in {
int/float in int/float in in
// replace [] with an appropriate error before returning // replace [] with an appropriate error before returning
[] Err: "input was not a number." [] [] Err: "input was not a number."
} }
// return type is int/float/Err(string) // return type is int/float/Err(string)
} }
@ -21,15 +21,15 @@ answer.debug() // type: int/float/Err(string)
// switch can be used to branch based on a variables type. // switch can be used to branch based on a variables type.
// switch! indicates that every possible type must be handled. // switch! indicates that every possible type must be handled.
switch! answer { switch! answer {
int { int num {
println("Entered an integer") println("Entered an integer")
answer.debug() // type: int num.debug() // type: int
} }
float { float num {
println("Entered a decimal number") println("Entered a decimal number")
answer.debug() // type: float num.debug() // type: float
} }
Err(string) println("Input was not a number!") Err(string) [] println("Input was not a number!")
} }
// wait one second // wait one second