Compare commits

..

1 Commits
main ... docs

Author SHA1 Message Date
b7d152be91 Write docs; Update logging and error messages 2024-02-19 17:00:33 -05:00
10 changed files with 31 additions and 76 deletions

2
Cargo.lock generated
View File

@ -369,7 +369,7 @@ dependencies = [
[[package]] [[package]]
name = "dust-lang" name = "dust-lang"
version = "0.4.2" version = "0.4.1"
dependencies = [ dependencies = [
"cc", "cc",
"clap", "clap",

View File

@ -1,7 +1,7 @@
[package] [package]
name = "dust-lang" name = "dust-lang"
description = "General purpose programming language" description = "General purpose programming language"
version = "0.4.2" version = "0.4.1"
repository = "https://git.jeffa.io/jeff/dust.git" repository = "https://git.jeffa.io/jeff/dust.git"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"

View File

@ -2,24 +2,19 @@
High-level programming language with effortless concurrency, automatic memory management, type safety and strict error handling. High-level programming language with effortless concurrency, automatic memory management, type safety and strict error handling.
![Dust version of an example from The Rust Programming Language.](https://git.jeffa.io/jeff/dust/raw/branch/main/docs/assets/example_0.png) ![Dust version of an example from The Rust Programming Language.](https://git.jeffa.io/jeff/dust/docs/assets/example_0.png)
<!--toc:start--> <!--toc:start-->
- [Dust](#dust) - [Dust](#dust)
- [Features](#features)
- [Easy to Read and Write](#easy-to-read-and-write) - [Easy to Read and Write](#easy-to-read-and-write)
- [Effortless Concurrency](#effortless-concurrency) - [Effortless Concurrency](#effortless-concurrency)
- [Helpful Errors](#helpful-errors) - [Helpful Errors](#helpful-errors)
- [Static analysis](#static-analysis)
- [Debugging](#debugging) - [Debugging](#debugging)
- [Automatic Memory Management](#automatic-memory-management) - [Automatic Memory Management](#automatic-memory-management)
- [Error Handling](#error-handling)
- [Installation and Usage](#installation-and-usage) - [Installation and Usage](#installation-and-usage)
<!--toc:end--> <!--toc:end-->
## Features ## Easy to Read and Write
### Easy to Read and Write
Dust has simple, easy-to-learn syntax. Dust has simple, easy-to-learn syntax.
@ -27,7 +22,7 @@ Dust has simple, easy-to-learn syntax.
output('Hello world!') output('Hello world!')
``` ```
### Effortless Concurrency ## Effortless Concurrency
Write multi-threaded code as easily as you would write code for a single thread. Write multi-threaded code as easily as you would write code for a single thread.
@ -39,62 +34,26 @@ async {
} }
``` ```
### Helpful Errors ## Helpful Errors
Dust shows you exactly where your code went wrong and suggests changes. Dust shows you exactly where your code went wrong and suggests changes.
![Example of syntax error output.](https://git.jeffa.io/jeff/dust/raw/branch/main/docs/assets/syntax_error.png) ![Example of syntax error output.](https://git.jeffa.io/jeff/dust/docs/assets/syntax_error.png)
### Static analysis ## Static analysis
Your code is always validated for safety before it is run. Your code is always validated for safety before it is run. Other interpreted languages can fail halfway through, but Dust is able to avoid runtime errors by analyzing the program *before* it is run
![Example of type error output.](https://git.jeffa.io/jeff/dust/raw/branch/main/docs/assets/type_error.png) ![Example of type error output.](https://git.jeffa.io/jeff/dust/docs/assets/type_error.png)
Dust ## Debugging
### Debugging Just set the environment variable `DUST_LOG=info` and Dust will tell you exactly what your code is doing while it's doing it. If you set `DUST_LOG=trace`, it will output detailed logs about parsing, abstraction, validation, memory management and runtime.
Just set the environment variable `DUST_LOG=info` and Dust will tell you exactly what your code is doing while it's doing it. If you set `DUST_LOG=trace`, it will output detailed logs about parsing, abstraction, validation, memory management and runtime. Here are some of the logs from the end of a simple [fizzbuzz example](https://git.jeffa.io/jeff/dust/src/branch/main/examples/fizzbuzz.ds). ![Example of debug output.](https://git.jeffa.io/jeff/dust/docs/assets/debugging.png)
![Example of debug output.](https://git.jeffa.io/jeff/dust/raw/branch/main/docs/assets/debugging.png) ## Automatic Memory Management
### Automatic Memory Management ## Error Handling
Thanks to static analysis, Dust knows exactly how many times each variable is used. This allows Dust to free memory as soon as the variable will no longer be used, without any help from the user.
### Error Handling
Runtime errors are no problem with Dust. The `Result` type represents the output of an operation that might fail. The user must decide what to do in the case of an error.
```dust
match io:stdin() {
Result::Ok(input) -> output("We read this input: " + input)
Result::Error(message) -> output("We got this error: " + message)
}
```
## Installation and Usage ## Installation and Usage
There are two ways to compile Dust. **It is best to clone the repository and compile the latest code**, otherwise the program may be a different version than the one shown on GitHub. Either way, you must have `rustup`, `cmake` and a C compiler installed.
To install from the git repository:
```fish
git clone https://git.jeffa.io/jeff/dust
cd dust
cargo run --release
```
To install with cargo:
```fish
cargo install dust-lang
dust
```
## Benchmarks
## Development Status
Currently, Dust is being prepared for version 1.0. Until then, there may be breaking changes to the language and CLI.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -4,22 +4,22 @@
output("Guess the number.") output("Guess the number.")
secret_number = int:random_range(0..=100) secret_number = int:random_range(0..=100);
loop { loop {
output("Please input your guess.") output("Please input your guess.")
input = io:stdin():expect("Failed to read line.") input = io:stdin():expect("Failed to read line.")
guess = int:parse(input) guess = int:parse(input);
output("You guessed: " + guess) output("You guessed: " + guess)
match cmp(guess, secret_number) { match cmp(guess, secret_number) {
Ordering::Less -> output("Too small!") Ordering::Less -> output("Too small!"),
Ordering::Greater -> output("Too big!") Ordering::Greater -> output("Too big!"),
Ordering::Equal -> { Ordering::Equal -> {
output("You win!") output("You win!");
break break;
} }
} }
} }

View File

@ -11,7 +11,7 @@ hyperfine \
--shell none \ --shell none \
--parameter-list data_path examples/assets/seaCreatures.json \ --parameter-list data_path examples/assets/seaCreatures.json \
--warmup 3 \ --warmup 3 \
"target/release/dust -c 'length(json:parse(fs:read_file(\"{data_path}\")))'" \ "dust -c 'length(json:parse(input))' -p {data_path}" \
"jq 'length' {data_path}" \ "jq 'length' {data_path}" \
"node --eval \"require('node:fs').readFile('{data_path}', (err, data)=>{console.log(JSON.parse(data).length)})\"" \ "node --eval \"require('node:fs').readFile('{data_path}', (err, data)=>{console.log(JSON.parse(data).length)})\"" \
"nu -c 'open {data_path} | length'" "nu -c 'open {data_path} | length'"
@ -20,7 +20,7 @@ hyperfine \
--shell none \ --shell none \
--parameter-list data_path examples/assets/jq_data.json \ --parameter-list data_path examples/assets/jq_data.json \
--warmup 3 \ --warmup 3 \
"target/release/dust -c 'length(json:parse(fs:read_file(\"{data_path}\")))'" \ "dust -c 'length(json:parse(input))' -p {data_path}" \
"jq 'length' {data_path}" \ "jq 'length' {data_path}" \
"node --eval \"require('node:fs').readFile('{data_path}', (err, data)=>{console.log(JSON.parse(data).length)})\"" \ "node --eval \"require('node:fs').readFile('{data_path}', (err, data)=>{console.log(JSON.parse(data).length)})\"" \
"nu -c 'open {data_path} | length'" "nu -c 'open {data_path} | length'"
@ -29,7 +29,7 @@ hyperfine \
--shell none \ --shell none \
--parameter-list data_path dielectron.json \ --parameter-list data_path dielectron.json \
--warmup 3 \ --warmup 3 \
"target/release/dust -c 'length(json:parse(fs:read_file(\"{data_path}\")))'" \ "dust -c 'length(json:parse(input))' -p {data_path}" \
"jq 'length' {data_path}" \ "jq 'length' {data_path}" \
"node --eval \"require('node:fs').readFile('{data_path}', (err, data)=>{console.log(JSON.parse(data).length)})\"" \ "node --eval \"require('node:fs').readFile('{data_path}', (err, data)=>{console.log(JSON.parse(data).length)})\"" \
"nu -c 'open {data_path} | length'" "nu -c 'open {data_path} | length'"

View File

@ -1,4 +1,4 @@
use std::{fs::File, io::Read}; use std::fs::read_to_string;
use enum_iterator::{all, Sequence}; use enum_iterator::{all, Sequence};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -46,11 +46,7 @@ impl Callable for Fs {
RuntimeError::expect_argument_amount(self.name(), 1, arguments.len())?; RuntimeError::expect_argument_amount(self.name(), 1, arguments.len())?;
let path = arguments.first().unwrap().as_string()?; let path = arguments.first().unwrap().as_string()?;
let mut file = File::open(path)?; let file_content = read_to_string(path.as_str())?;
let file_size = file.metadata()?.len() as usize;
let mut file_content = String::with_capacity(file_size);
file.read_to_string(&mut file_content)?;
Ok(Value::string(file_content)) Ok(Value::string(file_content))
} }