mirror of
				https://github.com/Dummi26/mers.git
				synced 2025-10-31 03:45:26 +01:00 
			
		
		
		
	update readme, docs, site, and version to 0.2.0.
This commit is contained in:
		
							parent
							
								
									db0be51fa4
								
							
						
					
					
						commit
						8c6f8c17f1
					
				| @ -21,7 +21,7 @@ mers has... | |||||||
|   + many strings: `[string ...]` (a list) |   + many strings: `[string ...]` (a list) | ||||||
|   + Either a string or nothing (Rust's `Option<String>`): `string/[]` |   + Either a string or nothing (Rust's `Option<String>`): `string/[]` | ||||||
|   + Either an int or an error: (Rust's `Result<isize, String>`): `int/string` (better: `int/Err(string)`) |   + Either an int or an error: (Rust's `Result<isize, String>`): `int/string` (better: `int/Err(string)`) | ||||||
| - compile-time execution through (explicit) macro syntax | - compile-time execution through (explicit) macro syntax: `!(mers {<code>})` or `!(mers "file")` | ||||||
| 
 | 
 | ||||||
| ## How mers? | ## How mers? | ||||||
| 
 | 
 | ||||||
| @ -36,3 +36,5 @@ Now, create a new text file (or choose one from the examples) and run it: `mers | |||||||
| [intro](docs/intro.md) | [intro](docs/intro.md) | ||||||
| 
 | 
 | ||||||
| [builtins](docs/builtins.md) | [builtins](docs/builtins.md) | ||||||
|  | 
 | ||||||
|  | [statements](docs/statements.md) | ||||||
|  | |||||||
| @ -14,10 +14,10 @@ To write a comment that spans multiple lines or ends before the end of the line, | |||||||
|     if 10 != 15 /* pretend this actually meant something... */ { |     if 10 != 15 /* pretend this actually meant something... */ { | ||||||
|         // does something |         // does something | ||||||
|     } else { |     } else { | ||||||
|         // TODO: implement this! |         // do something else | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| To declare a new variable, `:=` is used. | To declare a new variable, use `:=`. | ||||||
| 
 | 
 | ||||||
|     println("Hello! Please enter your name.") |     println("Hello! Please enter your name.") | ||||||
|     username := read_line() |     username := read_line() | ||||||
| @ -79,7 +79,7 @@ By adding `else <what to do>` after an if statement, we can define what should h | |||||||
| 
 | 
 | ||||||
| Let's force the user to give us their name. | Let's force the user to give us their name. | ||||||
| 
 | 
 | ||||||
| For this, we'll do what any not-insane person would do: Ask them repeatedly until they listen to us. | For this, we'll do what any not-insane person would do: Ask them repeatedly until they answer. | ||||||
| 
 | 
 | ||||||
|     username := "" |     username := "" | ||||||
|     loop { |     loop { | ||||||
| @ -136,6 +136,8 @@ Since the value we want to get out of the loop is the `username`, not just `true | |||||||
| 
 | 
 | ||||||
| If the input isn't empty, we return it from the loop since a value of type `string` will match. The value is then assigned to `username` and printed. | If the input isn't empty, we return it from the loop since a value of type `string` will match. The value is then assigned to `username` and printed. | ||||||
| 
 | 
 | ||||||
|  | If the input was still empty, `input.len() > 0` will return `false`, causing the `if` statement to return `[]`, which doesn't match, so the loop will continue. | ||||||
|  | 
 | ||||||
| # Match statements | # Match statements | ||||||
| 
 | 
 | ||||||
| Match statements let you define multiple conditions in a row. | Match statements let you define multiple conditions in a row. | ||||||
| @ -146,7 +148,7 @@ One of my favorite examples for mers' strength is this: | |||||||
|     number := match { |     number := match { | ||||||
|         input.parse_int() n n |         input.parse_int() n n | ||||||
|         input.parse_float() n n |         input.parse_float() n n | ||||||
|         [true] [] [] |         [true] [] Err: "couldn't parse" | ||||||
|     } |     } | ||||||
|     number.debug() |     number.debug() | ||||||
| 
 | 
 | ||||||
| @ -155,7 +157,7 @@ Unfortunately, this needs quite a lengthy explanation. | |||||||
| First, `parse_int()` and `parse_float()`. These are functions that take a string as their argument and return `[]/int` or `[]/float`. | First, `parse_int()` and `parse_float()`. These are functions that take a string as their argument and return `[]/int` or `[]/float`. | ||||||
| They try to read a number from the text and return it. If this fails, they return `[]`. | They try to read a number from the text and return it. If this fails, they return `[]`. | ||||||
| 
 | 
 | ||||||
| Conveniently (except not - this is obviously on purpose), `[]` doesn't match while `int` and `float` values do. | Conveniently, `[]` doesn't match while `int` and `float` values do. | ||||||
| 
 | 
 | ||||||
| This is where the magic happens: the `match` statement. | This is where the magic happens: the `match` statement. | ||||||
| Between the `{` and the `}`, you can put as many "match arms" as you want. | Between the `{` and the `}`, you can put as many "match arms" as you want. | ||||||
| @ -167,16 +169,16 @@ The three statements here are `input.parse_int()` (condition), `n` (assign_to), | |||||||
| If the input isn't a number, `input.parse_int()` will return `[]`. Since this doesn't match, the second match arm (`input.parse_float()`) will try to parse it to a float instead. | If the input isn't a number, `input.parse_int()` will return `[]`. Since this doesn't match, the second match arm (`input.parse_float()`) will try to parse it to a float instead. | ||||||
| 
 | 
 | ||||||
| If the input is a number, `input.parse_int()` will return an `int`. Since this matches, the match arm will be executed. | If the input is a number, `input.parse_int()` will return an `int`. Since this matches, the match arm will be executed. | ||||||
| First, the matched value - the `int` - will be assigned to `n`. the assign_to part behaves like the left side of a `:=` expression, with the matched `int` in the right. | First, the matched value - the `int` - will be assigned to `n`. the assign_to part behaves like the left side of a `:=` expression (it supports destructuring and will declare new variables). | ||||||
| Finally, the action statement uses our new variable `n` which contains the number we have parsed and returns it from the match statement. | Finally, the action statement uses our new variable `n` which contains the number we have parsed and returns it from the match statement. | ||||||
| 
 | 
 | ||||||
| Since the two arms in the match statement return `int` and `float`, the match statement will return `int/float/[]`. | Since the two arms in the match statement return `int` and `float`, the match statement will return `int/float/[]`. | ||||||
| To get rid of the `[]`, we need to add a third arm: `[true] [] "default value"`. `[true]` is a value that the compiler knows will always match - a tuple of length 1. Assigning something to an empty tuple `[]` just gets rid of the value. | To get rid of the `[]`, we need to add a third arm: `[true] [] Err: "couldn't parse"`. `[true]` is a value that the compiler knows will always match - a tuple of length 1. Assigning something to an empty tuple `[]` just gets rid of the value. | ||||||
| The return type is now `int/float/string`. | The return type is now `int/float/Err(string)`. | ||||||
| 
 | 
 | ||||||
| Finally, we `debug()` the variable. Debug is a builtin function that prints the expected type (statically determined at compile-time), the actual type, and the value. | Finally, we `debug()` the variable. Debug is a builtin function that prints the expected type (statically determined at compile-time), the actual type, and the value. | ||||||
| If we input `12.3`, it outputs `int/float/[] :: float :: 12.3`. | If we input `12.3`, it outputs `int/float/Err(string) :: float :: 12.3`. | ||||||
| If we input `9`, it outputs `int/float/[] :: int :: 9`. | If we input `9`, it outputs `int/float/Err(string) :: int :: 9`. | ||||||
| 
 | 
 | ||||||
| # Switch statements | # Switch statements | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| This is the documentation for mers statements. | This is the documentation for mers statements. | ||||||
| In code, statements are represented by `SStatement`, `SStatementEnum`, `RStatement`, and `RStatementEnum`. | In code, statements are represented by `SStatement`, `SStatementEnum`, `RStatement`, and `RStatementEnum`. | ||||||
| 
 | 
 | ||||||
| ## statement prefixes | ## Statement prefixes | ||||||
| 
 | 
 | ||||||
| A statement can be prefixed with any number of stars `*`. This is called dereferencing and turns a reference to a value into the value itself. Modifying the value after a dereference leaves the value the reference was pointing to untouched (the data will be cloned to achieve this). | A statement can be prefixed with any number of stars `*`. This is called dereferencing and turns a reference to a value into the value itself. Modifying the value after a dereference leaves the value the reference was pointing to untouched (the data will be cloned to achieve this). | ||||||
| 
 | 
 | ||||||
| @ -16,6 +16,16 @@ In combination with functions, this is similar to rust's syntax: | |||||||
|         a + b |         a + b | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | ## Assignment | ||||||
|  | 
 | ||||||
|  | Statements can assign their value instead of returning it. | ||||||
|  | The syntax for this is `<ref_statement> = <statement>` or `<assign_to> := <statement>`. | ||||||
|  | 
 | ||||||
|  | If just `=` is used, the left side must return a reference to some value which will then be changed to the value generated on the right. | ||||||
|  | If `:=` is used, new variables can be declared on the left. | ||||||
|  | 
 | ||||||
|  | Destructuring is possible too: `[a, b] := [12, 15]`. | ||||||
|  | 
 | ||||||
| # Different statements | # Different statements | ||||||
| 
 | 
 | ||||||
| ## Value | ## Value | ||||||
|  | |||||||
| @ -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 {<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>        &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>// 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>        &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 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| [package] | [package] | ||||||
| name = "mers" | name = "mers" | ||||||
| version = "0.1.0" | version = "0.2.0" | ||||||
| edition = "2021" | edition = "2021" | ||||||
| 
 | 
 | ||||||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||||
|  | |||||||
| @ -35,7 +35,6 @@ switch! answer { | |||||||
| // wait one second | // wait one second | ||||||
| sleep(1) | sleep(1) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| // function that returns an anonymous function (function object). | // function that returns an anonymous function (function object). | ||||||
| // anonymous functions can be used as iterators in for-loops. | // anonymous functions can be used as iterators in for-loops. | ||||||
| fn square_numbers() { | fn square_numbers() { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 mark
						mark