mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00
prepare to publish to crates.io
This commit is contained in:
parent
c08e08f8a9
commit
5be264e63c
@ -1,10 +1,16 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mers"
|
name = "mers"
|
||||||
version = "0.1.0"
|
version = "0.3.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
description = "dynamically typed but type-checked programming language"
|
||||||
|
keywords = ["scripting"]
|
||||||
|
readme = "README.md"
|
||||||
|
repository = "https://github.com/Dummi26/mers"
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
mers_lib = { path = "../mers_lib", features = ["parse"] }
|
mers_lib = "0.3.1"
|
||||||
|
# mers_lib = { path = "../mers_lib", features = ["parse"] }
|
||||||
clap = { version = "4.3.19", features = ["derive"] }
|
clap = { version = "4.3.19", features = ["derive"] }
|
||||||
|
87
mers/README.md
Normal file
87
mers/README.md
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
# mers
|
||||||
|
|
||||||
|
Mers is a high-level programming language.
|
||||||
|
It is designed to be safe (it doesn't crash at runtime) and as simple as possible.
|
||||||
|
|
||||||
|
See also:
|
||||||
|
[Quickstart](Quickstart.md),
|
||||||
|
|
||||||
|
## what makes it special
|
||||||
|
|
||||||
|
### Simplicity
|
||||||
|
|
||||||
|
Mers is simple. There are only few expressions:
|
||||||
|
|
||||||
|
- Values (`1`, `"my string"`, ...)
|
||||||
|
- Blocks (`{}`)
|
||||||
|
- Tuples (`()`) and Objects (`{}`)
|
||||||
|
- Assignments (`=`)
|
||||||
|
- Variable initializations (`:=`)
|
||||||
|
- Variables (`my_var`, `&my_var`)
|
||||||
|
- If statements (`if <condition> <then> [else <else>]`)
|
||||||
|
- Functions (`arg -> <do something>`)
|
||||||
|
- Function calls `arg.function` or `arg1.function(arg2, arg3)` (= `(arg1, arg2, arg3).function`)
|
||||||
|
|
||||||
|
Everything else is implemented as a function.
|
||||||
|
|
||||||
|
### Types and Safety
|
||||||
|
|
||||||
|
Mers is built around a type-system where a value could be one of multiple types.
|
||||||
|
```
|
||||||
|
x := if condition { 12 } else { "something went wrong" }
|
||||||
|
```
|
||||||
|
|
||||||
|
In mers, the compiler tracks all the types in your program,
|
||||||
|
and it will catch every possible crash before the program even runs:
|
||||||
|
If we tried to use `x` as an int, the compiler would complain since it might be a string, so this **does not compile**:
|
||||||
|
|
||||||
|
```
|
||||||
|
list := (1, 2, if true 3 else "not an int")
|
||||||
|
list.sum.println
|
||||||
|
```
|
||||||
|
|
||||||
|
Type-safety for functions is different from what you might expect.
|
||||||
|
You don't need to tell mers what type your function's argument has - you just use it however you want as if mers was a dynamically typed language:
|
||||||
|
|
||||||
|
```
|
||||||
|
sum_doubled := iter -> {
|
||||||
|
one := iter.sum
|
||||||
|
(one, one).sum
|
||||||
|
}
|
||||||
|
(1, 2, 3).sum_doubled.println
|
||||||
|
```
|
||||||
|
|
||||||
|
We could try to use the function improperly by passing a string instead of an int:
|
||||||
|
|
||||||
|
```
|
||||||
|
(1, 2, "3").sum_doubled.println
|
||||||
|
```
|
||||||
|
|
||||||
|
But mers will catch this and show an error, because the call to `sum` inside of `sum_doubled` would fail.
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
Errors in mers are normal values.
|
||||||
|
For example, `("ls", ("/")).run_command` has the return type `({Int/()}, String, String)/RunCommandError`.
|
||||||
|
This means it either returns the result of the command (exit code, stdout, stderr) or an error (a value of type `RunCommandError`).
|
||||||
|
|
||||||
|
So, if we want to print the programs stdout, we could try
|
||||||
|
|
||||||
|
```
|
||||||
|
(s, stdout, stderr) := ("ls", ("/")).run_command
|
||||||
|
stdout.println
|
||||||
|
```
|
||||||
|
|
||||||
|
But if we encountered a `RunCommandError`, mers wouldn't be able to assign the value to `(s, stdout, stderr)`, so this doesn't compile.
|
||||||
|
Instead, we need to handle the error case, using the `try` function:
|
||||||
|
|
||||||
|
```
|
||||||
|
("ls", ("/")).run_command.try((
|
||||||
|
(s, stdout, stderr) -> stdout.println,
|
||||||
|
error -> error.println,
|
||||||
|
))
|
||||||
|
```
|
||||||
|
|
||||||
|
## docs
|
||||||
|
|
||||||
|
docs will be available in some time. for now, check mers_lib/src/program/configs/*
|
6
mers/curl.mers
Normal file
6
mers/curl.mers
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
url -> "curl".run_command((url)).try((
|
||||||
|
(s, o, e) -> if (s.eq(0), s.eq(())).any {
|
||||||
|
(o)
|
||||||
|
} else ((), e)
|
||||||
|
e -> (e, ())
|
||||||
|
))
|
1
mers/fail.mers
Executable file
1
mers/fail.mers
Executable file
@ -0,0 +1 @@
|
|||||||
|
(a, b) := ()
|
3
mers/t.mers
Executable file
3
mers/t.mers
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
print_sum := iter -> iter.sum.println
|
||||||
|
|
||||||
|
(1, 2, 3, "a").print_sum
|
11
mers/test.mers
Executable file
11
mers/test.mers
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
t := {() -> {
|
||||||
|
1.sleep
|
||||||
|
"test".println
|
||||||
|
1.sleep
|
||||||
|
}}.thread
|
||||||
|
|
||||||
|
t.thread_finished.println
|
||||||
|
|
||||||
|
t.thread_await
|
||||||
|
|
||||||
|
t.thread_finished.println
|
12
mers/try.mers
Executable file
12
mers/try.mers
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
(
|
||||||
|
(if true 1 else (), 2, "a", "b", 3, "c", 12.5),
|
||||||
|
(
|
||||||
|
// why is this RTL instead of LTR???? (starts with float)
|
||||||
|
(a, b, c, d, e, f, g) -> {
|
||||||
|
(a, b, e).sum
|
||||||
|
(a, b, e, g).sum
|
||||||
|
(c, d, f).concat
|
||||||
|
}
|
||||||
|
x -> 1
|
||||||
|
)
|
||||||
|
).try
|
@ -1,8 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mers_lib"
|
name = "mers_lib"
|
||||||
version = "0.3.0"
|
version = "0.3.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
description = "library to use the mers language in other projects"
|
||||||
|
keywords = ["scripting"]
|
||||||
|
readme = "README.md"
|
||||||
|
repository = "https://github.com/Dummi26/mers"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["parse"]
|
default = ["parse"]
|
||||||
|
87
mers_lib/README.md
Normal file
87
mers_lib/README.md
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
# mers
|
||||||
|
|
||||||
|
Mers is a high-level programming language.
|
||||||
|
It is designed to be safe (it doesn't crash at runtime) and as simple as possible.
|
||||||
|
|
||||||
|
See also:
|
||||||
|
[Quickstart](Quickstart.md),
|
||||||
|
|
||||||
|
## what makes it special
|
||||||
|
|
||||||
|
### Simplicity
|
||||||
|
|
||||||
|
Mers is simple. There are only few expressions:
|
||||||
|
|
||||||
|
- Values (`1`, `"my string"`, ...)
|
||||||
|
- Blocks (`{}`)
|
||||||
|
- Tuples (`()`) and Objects (`{}`)
|
||||||
|
- Assignments (`=`)
|
||||||
|
- Variable initializations (`:=`)
|
||||||
|
- Variables (`my_var`, `&my_var`)
|
||||||
|
- If statements (`if <condition> <then> [else <else>]`)
|
||||||
|
- Functions (`arg -> <do something>`)
|
||||||
|
- Function calls `arg.function` or `arg1.function(arg2, arg3)` (= `(arg1, arg2, arg3).function`)
|
||||||
|
|
||||||
|
Everything else is implemented as a function.
|
||||||
|
|
||||||
|
### Types and Safety
|
||||||
|
|
||||||
|
Mers is built around a type-system where a value could be one of multiple types.
|
||||||
|
```
|
||||||
|
x := if condition { 12 } else { "something went wrong" }
|
||||||
|
```
|
||||||
|
|
||||||
|
In mers, the compiler tracks all the types in your program,
|
||||||
|
and it will catch every possible crash before the program even runs:
|
||||||
|
If we tried to use `x` as an int, the compiler would complain since it might be a string, so this **does not compile**:
|
||||||
|
|
||||||
|
```
|
||||||
|
list := (1, 2, if true 3 else "not an int")
|
||||||
|
list.sum.println
|
||||||
|
```
|
||||||
|
|
||||||
|
Type-safety for functions is different from what you might expect.
|
||||||
|
You don't need to tell mers what type your function's argument has - you just use it however you want as if mers was a dynamically typed language:
|
||||||
|
|
||||||
|
```
|
||||||
|
sum_doubled := iter -> {
|
||||||
|
one := iter.sum
|
||||||
|
(one, one).sum
|
||||||
|
}
|
||||||
|
(1, 2, 3).sum_doubled.println
|
||||||
|
```
|
||||||
|
|
||||||
|
We could try to use the function improperly by passing a string instead of an int:
|
||||||
|
|
||||||
|
```
|
||||||
|
(1, 2, "3").sum_doubled.println
|
||||||
|
```
|
||||||
|
|
||||||
|
But mers will catch this and show an error, because the call to `sum` inside of `sum_doubled` would fail.
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
Errors in mers are normal values.
|
||||||
|
For example, `("ls", ("/")).run_command` has the return type `({Int/()}, String, String)/RunCommandError`.
|
||||||
|
This means it either returns the result of the command (exit code, stdout, stderr) or an error (a value of type `RunCommandError`).
|
||||||
|
|
||||||
|
So, if we want to print the programs stdout, we could try
|
||||||
|
|
||||||
|
```
|
||||||
|
(s, stdout, stderr) := ("ls", ("/")).run_command
|
||||||
|
stdout.println
|
||||||
|
```
|
||||||
|
|
||||||
|
But if we encountered a `RunCommandError`, mers wouldn't be able to assign the value to `(s, stdout, stderr)`, so this doesn't compile.
|
||||||
|
Instead, we need to handle the error case, using the `try` function:
|
||||||
|
|
||||||
|
```
|
||||||
|
("ls", ("/")).run_command.try((
|
||||||
|
(s, stdout, stderr) -> stdout.println,
|
||||||
|
error -> error.println,
|
||||||
|
))
|
||||||
|
```
|
||||||
|
|
||||||
|
## docs
|
||||||
|
|
||||||
|
docs will be available in some time. for now, check mers_lib/src/program/configs/*
|
Loading…
Reference in New Issue
Block a user