Updated docs to 0.3.1
This commit is contained in:
@@ -4,21 +4,21 @@ description: Unified data and behavior with Java-style organization and Rust-pow
|
||||
icon: Shapes
|
||||
---
|
||||
|
||||
Classes in Mist bridge the gap between Java's organizational structure and Rust's performance. They allow you to define data fields, constructors, instance methods, and trait implementations within a single, cohesive block.
|
||||
Classes in Mist bridge the gap between Java's organizational structure and Rust's performance. They group fields, constructors, and methods within a single cohesive block, using `fn` for methods and `*self` for the instance parameter.
|
||||
|
||||
## Basic Syntax
|
||||
|
||||
A class groups fields and methods together. Fields follow the `type name` convention, and methods define their logic directly within the class body.
|
||||
A class groups fields and methods together. Fields use semicolons and the `name Type` convention. Methods use `fn` and take `*self` as the first parameter for shared access.
|
||||
|
||||
```mist
|
||||
pub class Logger {
|
||||
String prefix;
|
||||
prefix String;
|
||||
|
||||
pub void info(self*, str* message) {
|
||||
pub fn info(*self, message *str) {
|
||||
self.log(LogLevel::Info, message);
|
||||
}
|
||||
|
||||
void log(self*, LogLevel level, str* message) {
|
||||
fn log(*self, level LogLevel, message *str) {
|
||||
println!("{level} {} {}", self.prefix, message);
|
||||
}
|
||||
}
|
||||
@@ -26,39 +26,87 @@ pub class Logger {
|
||||
|
||||
## The Constructor
|
||||
|
||||
Unlike languages that use the class name for initialization, Mist uses the explicit `constructor` keyword. This makes the entry point of the class unmistakable.
|
||||
Mist uses the explicit `constructor` keyword for initialization:
|
||||
|
||||
```mist
|
||||
pub constructor(str* prefix) {
|
||||
self.prefix = prefix.to_string();
|
||||
pub constructor() {
|
||||
self.prefix = "default".to_string();
|
||||
}
|
||||
```
|
||||
|
||||
## Instance Methods & `self`
|
||||
|
||||
Mist maintains Rust's explicit context handling. Any method that needs to access or modify class data must include `self*` (or `self mut*` for mutations) as its first parameter.
|
||||
Constructors can take parameters:
|
||||
|
||||
```mist
|
||||
pub void warning(self*, str* message) {
|
||||
pub constructor(prefix String) {
|
||||
self.prefix = prefix;
|
||||
}
|
||||
```
|
||||
|
||||
## Instance Methods & `*self`
|
||||
|
||||
Methods use `*self` (shared reference) or `*mut self` (mutable reference) as the first parameter. The return type is placed after the parameter list.
|
||||
|
||||
```mist
|
||||
pub fn warning(*self, message *str) {
|
||||
self.log(LogLevel::Warning, message);
|
||||
}
|
||||
|
||||
pub fn reset(*mut self) {
|
||||
self.prefix = String::new();
|
||||
}
|
||||
```
|
||||
|
||||
## Trait Implementations
|
||||
## Inheritance
|
||||
|
||||
One of Mist's most powerful features is the ability to nest trait implementations directly within the class block. This keeps the logic for how a type behaves (e.g., how it is displayed) physically coupled with the type definition.
|
||||
Classes support single inheritance with the `:` syntax. Use `super -> Super::new()` in the constructor to call the parent constructor. Override methods with `override` or `override(Parent)`.
|
||||
|
||||
```mist
|
||||
impl fmt::Display {
|
||||
std::fmt::Result fmt(self*, std::fmt::Formatter<'_> mut* f) {
|
||||
return write!(f, "logger ({})", self.prefix);
|
||||
pub class Animal {
|
||||
pub name String;
|
||||
|
||||
constructor() {
|
||||
self.name = "Rex".to_string();
|
||||
}
|
||||
|
||||
pub fn speak(*self) {
|
||||
println!("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
pub class Dog : Animal {
|
||||
constructor() {
|
||||
super -> Super::new();
|
||||
}
|
||||
|
||||
pub override fn speak(*self) {
|
||||
println!("Woof!");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Generics
|
||||
|
||||
Classes support generic type parameters:
|
||||
|
||||
```mist
|
||||
pub class Container<T> {
|
||||
pub value T;
|
||||
|
||||
constructor(val T) {
|
||||
self.value = val;
|
||||
}
|
||||
|
||||
pub fn get(*self) *T {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Key Characteristics
|
||||
|
||||
- **Unified Scope**: Data, behavior, and trait logic live in one place, eliminating the friction of jumping between `struct` and `impl` blocks.
|
||||
- **Explicit Context**: The use of `self*` ensures that the relationship between a method and its instance is always transparent.
|
||||
- **Encapsulation**: Visibility modifiers (`pub`) allow you to expose a clean API while keeping internal helper methods and state private to the class.
|
||||
- **Zero-Cost Classes**: Under the hood, Mist desugars these into idiomatic Rust structs and implementation blocks, ensuring no runtime overhead compared to raw Rust.
|
||||
- **Unified Scope**: Data and behavior live in one class block.
|
||||
- **`fn` Methods**: Methods use the `fn` keyword, consistent with free functions.
|
||||
- **`*self` Parameter**: The self reference is explicit and uses prefix `*` syntax.
|
||||
- **Inheritance**: Single inheritance with `override` for polymorphic dispatch.
|
||||
- **Encapsulation**: Visibility modifiers (`pub`) control API exposure.
|
||||
- **Zero-Cost Classes**: Under the hood, Mist desugars these into idiomatic Rust structs and implementation blocks.
|
||||
|
||||
@@ -1,57 +1,85 @@
|
||||
---
|
||||
title: Enums
|
||||
description: Defining algebraic data types with Mist's type-first convention.
|
||||
description: Defining algebraic data types with Mist's data-first convention.
|
||||
icon: Layers
|
||||
---
|
||||
|
||||
Enums in Mist serve as powerful algebraic data types (ADTs), maintaining the exact behavior and safety of Rust enums while applying the language-wide `type name` convention for variants that contain data.
|
||||
Enums in Mist serve as powerful algebraic data types (ADTs), maintaining the exact behavior and safety of Rust enums while using square brackets for tuple variant types and `name Type` for struct-like fields.
|
||||
|
||||
## Basic Syntax
|
||||
|
||||
An enum can contain unit variants, tuple variants, or struct-like variants. Following Mist's core philosophy, struct-like variants place the type before the identifier.
|
||||
An enum can contain unit variants, tuple variants (with types in square brackets), or struct-like variants.
|
||||
|
||||
```mist
|
||||
pub enum TaskState {
|
||||
Pending,
|
||||
InProgress,
|
||||
Completed,
|
||||
// Struct-like variant using 'type name'
|
||||
Failed {
|
||||
String reason,
|
||||
i32 code,
|
||||
reason String,
|
||||
code i32,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Variant Types
|
||||
|
||||
Mist supports all standard variant shapes, ensuring a 1:1 mapping to the underlying Rust execution model.
|
||||
Mist supports all standard variant shapes:
|
||||
|
||||
```mist
|
||||
enum Message {
|
||||
Quit, // Unit
|
||||
Move(i32, i32), // Tuple
|
||||
Write(String), // Tuple
|
||||
ChangeColor { // Struct-like
|
||||
u8 r, u8 g, u8 b,
|
||||
},
|
||||
enum OptionInt {
|
||||
None, // Unit
|
||||
Some[i32], // Tuple (square brackets)
|
||||
}
|
||||
|
||||
enum Shape {
|
||||
Circle { radius i32 }, // Struct-like
|
||||
Rect { w i32, h i32 },
|
||||
}
|
||||
```
|
||||
|
||||
### Instantiation & Matching
|
||||
|
||||
Tuple variants are created with parentheses and matched with brackets:
|
||||
|
||||
```mist
|
||||
let x = OptionInt::Some(42);
|
||||
|
||||
match (x) {
|
||||
OptionInt::None => { println!("none"); }
|
||||
OptionInt::Some[v] => { println!("{}", v); }
|
||||
}
|
||||
```
|
||||
|
||||
Struct variants use brace notation:
|
||||
|
||||
```mist
|
||||
let c = Shape::Circle { radius: 5 };
|
||||
|
||||
match (c) {
|
||||
Shape::Circle { radius } => { println!("{}", radius); }
|
||||
Shape::Rect { .. } => { /* ignore */ }
|
||||
}
|
||||
```
|
||||
|
||||
## Generics & Lifetimes
|
||||
|
||||
Just like structs and functions, enums declare generics and lifetimes in a unified block. This is particularly useful for defining custom Result or Option types that handle references.
|
||||
Enums declare generics and lifetimes in angle brackets after the name. Reference types use the `*` prefix.
|
||||
|
||||
```mist
|
||||
pub enum Validation<'a, T> {
|
||||
Valid(T),
|
||||
Invalid {
|
||||
str'a* message,
|
||||
u32 error_id,
|
||||
message *'a str,
|
||||
error_id u32,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Key Characteristics
|
||||
|
||||
- **Consistent Member Declaration**: Struct-like variants maintain the `type name` order, ensuring that data modeling feels identical whether you are defining a top-level `struct` or an `enum` variant.
|
||||
- **Rust-Native ADTs**: Enums compile directly to Rust enums, allowing for exhaustive pattern matching and zero-cost abstraction.
|
||||
- **Shared Visibility**: The `pub` modifier at the enum level exports all variants for use in other modules, matching Rust's visibility rules for enums.
|
||||
- **Comma-Separated Members**: Fields within struct-like variants are separated by commas, mirroring the syntax used in standard Mist structs.
|
||||
- **Consistent Declaration**: Struct-like variants use the `name Type` order, consistent with Mist structs.
|
||||
- **Square Bracket Tuples**: Tuple variant types use `[]` brackets, distinct from function calls.
|
||||
- **Rust-Native ADTs**: Enums compile directly to Rust enums, allowing exhaustive pattern matching and zero-cost abstraction.
|
||||
- **Shared Visibility**: The `pub` modifier at the enum level exports all variants.
|
||||
- **Comma-Separated Members**: Fields within struct-like variants are separated by commas.
|
||||
|
||||
@@ -4,19 +4,19 @@ description: Defining execution blocks with C-style ergonomics and Rust-powered
|
||||
icon: SquareFunction
|
||||
---
|
||||
|
||||
Functions are the primary unit of execution in Mist. They prioritize a traditional declaration order, placing the return type before the identifier.
|
||||
Functions are the primary unit of execution in Mist, declared with the `fn` keyword. Parameters follow the `name Type` convention and the return type is placed after the parameter list.
|
||||
|
||||
## Basic Syntax
|
||||
|
||||
A standard function requires a return type, a name, and a body. Use the `void` keyword for functions that do not return a value.
|
||||
A standard function begins with `fn`, followed by its name, parameters, and an optional return type. The last expression in a block is implicitly returned.
|
||||
|
||||
```mist
|
||||
i32 add(i32 a, i32 b) {
|
||||
return a + b;
|
||||
fn add(a i32, b i32) i32 {
|
||||
a + b
|
||||
}
|
||||
|
||||
void log_status(str* message) {
|
||||
println!("{}", message);
|
||||
fn greet() {
|
||||
println!("Hello!");
|
||||
}
|
||||
```
|
||||
|
||||
@@ -25,48 +25,48 @@ void log_status(str* message) {
|
||||
Functions are private to their module by default. The `pub` modifier exports the function for cross-module access.
|
||||
|
||||
```mist
|
||||
pub i32 get_version() {
|
||||
return 1;
|
||||
pub fn get_version() i32 {
|
||||
1
|
||||
}
|
||||
|
||||
pub(crate) i32 internal_use() {
|
||||
return 0;
|
||||
pub(crate) fn internal_use() i32 {
|
||||
0
|
||||
}
|
||||
```
|
||||
|
||||
## Mutable Parameters
|
||||
|
||||
Use `mut` to allow a function to modify its local binding of a value.
|
||||
Use `mut` on a parameter to allow reassignment within the function body.
|
||||
|
||||
```mist
|
||||
void update_score(i32 mut current_score, i32 bonus) {
|
||||
fn update_score(mut current_score i32, bonus i32) i32 {
|
||||
current_score = current_score + bonus;
|
||||
current_score
|
||||
}
|
||||
```
|
||||
|
||||
## Generics & Lifetimes
|
||||
|
||||
Mist integrates type abstraction and memory management into a single generic block. Lifetimes and type parameters share the `< >` bracket following the identifier.
|
||||
Generics and lifetimes are declared in angle brackets after the function name. Lifetimes are placed before the `*` in reference types.
|
||||
|
||||
```mist
|
||||
pub str'a* choose_longer<'a, T: Display>(str'a* s1, str'a* s2, T meta) {
|
||||
println!("Metadata: {}", meta);
|
||||
return if (s1.len() > s2.len()) { s1 } else { s2 };
|
||||
fn choose_longer<'a>(s1 *'a str, s2 *'a str) *'a str {
|
||||
if (s1.len() > s2.len()) { s1 } else { s2 }
|
||||
}
|
||||
```
|
||||
|
||||
## Closures
|
||||
|
||||
Closures are anonymous functions that can capture their environment. The return type before the pipe is optional — when omitted, the closure body uses curly braces:
|
||||
Closures are anonymous functions defined with the `fn` keyword followed by parameters, an optional return type, and a body or expression.
|
||||
|
||||
```mist
|
||||
var add = |i32 a, i32 b| { a + b };
|
||||
let add = fn(a, b) -> a + b;
|
||||
add(2, 3);
|
||||
|
||||
// With explicit return type
|
||||
Option<i32> |var v| { Some(v) }
|
||||
|
||||
// Without return type
|
||||
var greet = |str* name| { println!("Hello {}", name) };
|
||||
// With a block body
|
||||
let greet = fn(name *str) {
|
||||
println!("Hello {}", name);
|
||||
};
|
||||
```
|
||||
|
||||
## Attributes & Metadata
|
||||
@@ -75,14 +75,15 @@ Metadata is applied via the `#[attr]` syntax directly above the declaration.
|
||||
|
||||
```mist
|
||||
#[inline]
|
||||
pub bool is_active(u32 id) {
|
||||
return id > 0;
|
||||
pub fn is_active(id u32) bool {
|
||||
id > 0
|
||||
}
|
||||
```
|
||||
|
||||
## Key Characteristics
|
||||
|
||||
- **Scannable Signatures**: Return types first for rapid identification of a function's output.
|
||||
- **`fn` Keyword**: Every function starts with `fn`, making declarations instantly recognizable.
|
||||
- **Implicit Returns**: The final expression in a block is automatically returned.
|
||||
- **Unified Abstraction**: Lifetimes and type constraints are declared in one location.
|
||||
- **Closure Support**: Anonymous functions with optional return type annotations.
|
||||
- **Zero-Cost Mapping**: Every function maps directly to a Rust `fn`.
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Organizing code across files with module declarations and path-base
|
||||
icon: FolderTree
|
||||
---
|
||||
|
||||
Mist organizes code through a file-system based module system with explicit path imports, similar to Rust but with a cleaner import syntax.
|
||||
Mist organizes code through a file-system based module system with explicit path imports.
|
||||
|
||||
## The Module System
|
||||
|
||||
@@ -12,7 +12,7 @@ Each `.mist` file in `src/` corresponds to a module. The module tree mirrors the
|
||||
|
||||
### File-Based Modules
|
||||
|
||||
The file `src/main.mist` is the crate root. Other files are discovered through `mod` declarations or by name — no explicit declaration is needed when a file exists at a matching path.
|
||||
The file `src/main.mist` is the crate root. Other files are discovered through `mod` declarations or by name.
|
||||
|
||||
### Declaring Submodules
|
||||
|
||||
@@ -24,16 +24,16 @@ mod database;
|
||||
|
||||
## Imports
|
||||
|
||||
Use the `use` keyword with angle brackets to bring items from other modules or external crates into scope.
|
||||
Use the `use` keyword with a path to bring items from other modules or external crates into scope.
|
||||
|
||||
```mist
|
||||
use <std::fs>;
|
||||
use <std::process>;
|
||||
use <std::path::Path>;
|
||||
use <std::collections::HashMap>;
|
||||
use std::fs;
|
||||
use std::process;
|
||||
use std::path::Path;
|
||||
use std::collections::HashMap;
|
||||
|
||||
// Import specific items
|
||||
use <my_module::Helper>;
|
||||
use my_module::Helper;
|
||||
```
|
||||
|
||||
### Visibility
|
||||
@@ -41,7 +41,7 @@ use <my_module::Helper>;
|
||||
Items can be re-exported with a visibility modifier on the import:
|
||||
|
||||
```mist
|
||||
pub use <internal::format>;
|
||||
pub use internal::format;
|
||||
```
|
||||
|
||||
## Sidefiles
|
||||
|
||||
@@ -1,37 +1,49 @@
|
||||
---
|
||||
title: Pointers & References
|
||||
description: Explicit memory access with C-style ergonomics and Rust-native safety.
|
||||
description: Explicit memory access with prefix pointer syntax and Rust-native safety.
|
||||
icon: MousePointer2
|
||||
---
|
||||
|
||||
Mist simplifies Rust’s reference system by using a pointer-style syntax. While the symbols look like C-style pointers, they adhere strictly to Rust’s ownership and borrowing rules.
|
||||
Mist uses a prefix `*` syntax for reference types. While the symbols look like C-style pointers, they adhere strictly to Rust's ownership and borrowing rules.
|
||||
|
||||
## Basic Syntax
|
||||
|
||||
References are defined by placing a `*` after the type. By default, pointers are immutable (shared). To allow modification of the underlying data, use the `mut*` modifier.
|
||||
Reference types are written with `*` before the type. Use `*mut` for mutable references. The `&` and `&mut` operators create references from values.
|
||||
|
||||
```mist
|
||||
void increment(i32 mut* value, i32* limit) {
|
||||
if (value < limit) {
|
||||
value = value + 1;
|
||||
let x i32 = 42;
|
||||
let r *i32 = &x;
|
||||
|
||||
let mut y = 42;
|
||||
let r *mut i32 = &mut y;
|
||||
*r = 100;
|
||||
```
|
||||
|
||||
In function parameters:
|
||||
|
||||
```mist
|
||||
fn increment(value *mut i32, limit *i32) {
|
||||
if (*value < *limit) {
|
||||
*value = *value + 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Lifetimes
|
||||
|
||||
Lifetimes are attached directly to the type before the pointer symbol. This maintains a clean visual flow where the "type-contract" (identity, duration, and mutability) is read from left to right.
|
||||
Lifetimes are placed between `*` and the type, reading as "pointer with lifetime to type":
|
||||
|
||||
```mist
|
||||
pub struct Inspector<'a> {
|
||||
pub str'a* target,
|
||||
pub u32'a mut* counter,
|
||||
pub target *'a str,
|
||||
pub counter *'a mut u32,
|
||||
}
|
||||
```
|
||||
|
||||
## Key Characteristics
|
||||
|
||||
- **Explicit Intent:** The `mut*` syntax clearly distinguishes between a reference that can read and one that can write, mapping 1:1 to Rust's `&` and `&mut`.
|
||||
- **Visual Consistency:** Lifetimes (`'a`) and mutability modifiers are integrated into the type declaration, keeping function signatures and struct fields compact.
|
||||
- **Safety Guaranteed:** Despite the "pointer" appearance, the Mist compiler enforces Rust’s borrow checker. You cannot have multiple `mut*` references to the same data, and references cannot outlive their owners.
|
||||
- **Zero Overhead:** Mist pointers are "thin" or "fat" exactly like Rust references; they carry no extra runtime metadata and compile to identical machine code.
|
||||
- **Prefix Pointer Syntax**: `*Type` for shared references, `*mut Type` for mutable references.
|
||||
- **Explicit Intent**: The `*mut` syntax clearly distinguishes read-only from writable references, mapping 1:1 to Rust's `&` and `&mut`.
|
||||
- **Visual Consistency**: Lifetimes (`'a`) are placed before the type in `*'a Type`, keeping the declaration flow left-to-right.
|
||||
- **Safety Guaranteed**: Despite the "pointer" appearance, the Mist compiler enforces Rust's borrow checker.
|
||||
- **Zero Overhead**: Mist pointers compile to identical machine code as Rust references.
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
---
|
||||
title: Structs
|
||||
description: Data modeling using Mist's type-first convention.
|
||||
description: Data modeling with Mist's name-first field convention.
|
||||
icon: Form
|
||||
---
|
||||
|
||||
Structs in Mist follow the same structural logic as Rust, but apply the language-wide `type name` declaration style and allow for comma-separated field grouping.
|
||||
Structs in Mist follow the same structural logic as Rust, with fields using the language-wide `name Type` convention and comma-separated grouping.
|
||||
|
||||
## Basic Syntax
|
||||
|
||||
A struct is defined by its name followed by a block of fields. Each field follows the Mist convention of placing the type before the identifier, separated by commas.
|
||||
A struct is defined by its name followed by a block of fields. Each field places the identifier before the type.
|
||||
|
||||
```mist
|
||||
pub struct Task {
|
||||
pub String name,
|
||||
pub TaskState state,
|
||||
pub i32 executions,
|
||||
pub name String,
|
||||
pub state TaskState,
|
||||
pub executions i32,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -24,8 +24,8 @@ Use the `pub` modifier to make the struct or its individual fields accessible fr
|
||||
|
||||
```mist
|
||||
pub struct NetworkNode {
|
||||
pub u32 id,
|
||||
str* address,
|
||||
pub id u32,
|
||||
address *str,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -34,27 +34,36 @@ pub struct NetworkNode {
|
||||
Structs are instantiated using the standard brace syntax.
|
||||
|
||||
```mist
|
||||
var task = Task {
|
||||
let task = Task {
|
||||
name: "Initialize".to_string(),
|
||||
state: TaskState::Pending,
|
||||
executions: 0,
|
||||
};
|
||||
```
|
||||
|
||||
## Destructuring
|
||||
|
||||
Struct patterns use `let` with the struct name and field bindings:
|
||||
|
||||
```mist
|
||||
let p = Point { x: 3, y: 4 };
|
||||
let Point { x, y } = p;
|
||||
```
|
||||
|
||||
## Generics & Lifetimes
|
||||
|
||||
Generics and lifetimes are declared in angle brackets after the struct name. Lifetimes are associated with the reference/pointer type within the field declarations.
|
||||
Generics and lifetimes are declared in angle brackets after the struct name. Reference types use the `*` prefix.
|
||||
|
||||
```mist
|
||||
pub struct Buffer<'a, T> {
|
||||
pub T'a* data,
|
||||
pub usize len,
|
||||
pub data *'a T,
|
||||
pub len usize,
|
||||
}
|
||||
```
|
||||
|
||||
## Key Characteristics
|
||||
|
||||
- **Type-First Declaration**: Fields use the `type name` order to match function parameters and variable declarations.
|
||||
- **Comma-Separated Members**: Fields are separated by commas, maintaining a clean and consistent delimiter style.
|
||||
- **Name-First Declaration**: Fields use `name Type` order, consistent with function parameters and variable declarations.
|
||||
- **Comma-Separated Members**: Fields are separated by commas, maintaining a clean delimiter style.
|
||||
- **Rust Compatibility**: Maps 1:1 to Rust structs, ensuring zero-cost abstraction and full ecosystem interoperability.
|
||||
- **Direct Visibility**: The `pub` modifier controls access at the struct and field level.
|
||||
|
||||
@@ -4,58 +4,67 @@ description: Defining shared behavior and contracts with Mist's signature ergono
|
||||
icon: Sparkles
|
||||
---
|
||||
|
||||
Traits in Mist define a set of methods that a type must implement, facilitating polymorphism and shared behavior. While they mirror the logic of Rust traits, they utilize Mist’s **type-first** declaration style for method signatures.
|
||||
Traits in Mist define a set of methods that a type must implement, facilitating polymorphism and shared behavior. Method signatures use the `fn` keyword with `*self` for the instance parameter.
|
||||
|
||||
## Defining a Trait
|
||||
|
||||
A trait definition lists method signatures that implementing types must satisfy. Like functions, these signatures place the return type before the method name.
|
||||
A trait lists method signatures using `fn`, with `*self` as the instance parameter and the return type after the parameter list.
|
||||
|
||||
```mist
|
||||
pub trait Drawable {
|
||||
void draw(self*);
|
||||
str* metadata(self*);
|
||||
fn draw(*self);
|
||||
fn metadata(*self) *str;
|
||||
}
|
||||
```
|
||||
|
||||
## Implementing a Trait
|
||||
|
||||
To implement a trait for a specific type, use the `impl` keyword followed by the trait name and the target type. This block must contain all required methods defined in the trait.
|
||||
Use `impl Trait for Type` to provide implementations:
|
||||
|
||||
```mist
|
||||
impl Drawable for Task {
|
||||
void draw(self*) {
|
||||
fn draw(*self) {
|
||||
println!("Drawing task: {}", self.name);
|
||||
}
|
||||
|
||||
str* metadata(self*) {
|
||||
return self.name;
|
||||
fn metadata(*self) *str {
|
||||
self.name
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Default Implementations
|
||||
|
||||
Traits can provide default behavior for methods. Types implementing the trait can choose to override these defaults or use the provided implementation.
|
||||
Traits can provide default behavior for methods that implementing types may override:
|
||||
|
||||
```mist
|
||||
pub trait Identifiable {
|
||||
u32 get_id(self*);
|
||||
fn get_id(*self) u32;
|
||||
|
||||
bool is_valid(self*) {
|
||||
return self.get_id() > 0;
|
||||
fn is_valid(*self) bool {
|
||||
self.get_id() > 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Super-traits
|
||||
|
||||
Traits can build upon other traits. If a trait requires another trait to be implemented first, use the colon `:` syntax.
|
||||
A trait can require another trait using the colon `:` syntax:
|
||||
|
||||
```mist
|
||||
pub trait Animated : Drawable {
|
||||
void animate(self*, f32 delta_time);
|
||||
pub trait Speak {
|
||||
fn speak(*self) String;
|
||||
}
|
||||
|
||||
pub trait Greet : Speak {
|
||||
fn greet(*self) String;
|
||||
}
|
||||
```
|
||||
|
||||
## Key Characteristics
|
||||
|
||||
- **Consistent Signatures**: Method signatures within traits follow the language-wide `return_type name(params)` convention.
|
||||
- **Explicit Context**: Methods use `self*` or `self mut*` as the first parameter to define how the instance is accessed, mapping directly to Rust's reference rules.
|
||||
- **Static Dispatch**: By default, Mist traits leverage Rust's zero-cost generics and monomorphization, ensuring high performance.
|
||||
- **Predictable Contracts**: Traits act as strict blueprints; the Mist compiler ensures every implementation perfectly matches the interface before generating the corresponding Rust code.
|
||||
- **`fn` Signatures**: Method signatures use `fn`, consistent with free functions.
|
||||
- **Explicit Context**: Methods use `*self` as the first parameter, mapping directly to Rust's reference rules.
|
||||
- **Default Methods**: Traits can provide default implementations.
|
||||
- **Super-traits**: Colon syntax for expressing trait requirements.
|
||||
- **Static Dispatch**: By default, Mist traits leverage Rust's zero-cost generics and monomorphization.
|
||||
|
||||
@@ -11,7 +11,7 @@ Mist is currently distributed as a Cargo crate. To get started, you'll need to h
|
||||
Run the following command to install the Mist compiler:
|
||||
|
||||
```bash title="Terminal"
|
||||
cargo install mist-lang@0.0.5-alpha0
|
||||
cargo install mist-lang@0.3.1-alpha.0
|
||||
```
|
||||
|
||||
Once the installation finishes, verify it by checking the version:
|
||||
@@ -54,7 +54,7 @@ Source files go in `src/` and the transpiled output goes to `.mist/src/`. Non-Mi
|
||||
Create a new file at `src/main.mist` and add the following code:
|
||||
|
||||
```mist title="src/main.mist"
|
||||
void main() {
|
||||
fn main() {
|
||||
println!("Hello World!");
|
||||
}
|
||||
```
|
||||
|
||||
@@ -4,11 +4,11 @@ description: Directing execution with expression-based logic, pattern matching,
|
||||
icon: Split
|
||||
---
|
||||
|
||||
Control flow in Mist provides a bridge between C-style procedural logic and Rust's expression-oriented design. Blocks, if statements, while/for/loop loops, and match expressions all support statement bodies — meaning braces can be omitted for single-statement branches.
|
||||
Control flow in Mist provides a bridge between C-style procedural logic and Rust's expression-oriented design. Blocks, if statements, while/for/loop loops, and match expressions all support statement bodies.
|
||||
|
||||
## Conditionals
|
||||
|
||||
The `if` statement evaluates a boolean expression. Single-statement bodies don't need braces:
|
||||
The `if` statement evaluates a boolean expression:
|
||||
|
||||
```mist
|
||||
if (score > 50) {
|
||||
@@ -22,8 +22,8 @@ if (score > 50) {
|
||||
// Single-statement body (no braces needed)
|
||||
if (is_active) println!("Running");
|
||||
|
||||
// Expression body (soft return)
|
||||
var result = if (valid) "ok" else "err";
|
||||
// Expression body (implicit return)
|
||||
let result = if (valid) { "ok" } else { "err" };
|
||||
```
|
||||
|
||||
## Match
|
||||
@@ -32,18 +32,28 @@ The `match` statement provides exhaustive pattern matching with support for mult
|
||||
|
||||
```mist
|
||||
match (task_state) {
|
||||
TaskState::Pending => {
|
||||
println!("Queued");
|
||||
}
|
||||
TaskState::Pending => { println!("Queued"); }
|
||||
TaskState::Failed { reason, code } => {
|
||||
println!("Error {}: {}", code, reason);
|
||||
}
|
||||
TaskState::NotResponding | TaskState::Progress => {
|
||||
draw_loading();
|
||||
}
|
||||
_ => {
|
||||
println!("Other state");
|
||||
_ => { println!("Other state"); }
|
||||
}
|
||||
```
|
||||
|
||||
Patterns support destructuring, or-patterns, and wildcards:
|
||||
|
||||
```mist
|
||||
let x = 2;
|
||||
let result;
|
||||
|
||||
match (x) {
|
||||
1 => { result = 10; }
|
||||
2 => { result = 20; }
|
||||
3 => { result = 30; }
|
||||
_ => panic!();
|
||||
}
|
||||
```
|
||||
|
||||
@@ -60,35 +70,31 @@ loop {
|
||||
}
|
||||
```
|
||||
|
||||
### C-Style For Loop
|
||||
|
||||
```mist
|
||||
for (var mut i = 0; i < 10; i++;)
|
||||
println!("Index: {}", i);
|
||||
```
|
||||
|
||||
### For-In Loop
|
||||
|
||||
For loops iterate over an expression using the `pattern : expr` syntax:
|
||||
|
||||
```mist
|
||||
for (var item in collection)
|
||||
process(item);
|
||||
for (i : 0..4) {
|
||||
sum += i;
|
||||
}
|
||||
|
||||
for ((i32 x, i32 y) in coordinates)
|
||||
draw_point(x, y);
|
||||
|
||||
// Range iteration
|
||||
for (var i in 0..10)
|
||||
println!("{}", i);
|
||||
// With pattern destructuring
|
||||
for ([k, _] : pairs) {
|
||||
keys += k;
|
||||
}
|
||||
```
|
||||
|
||||
### While Loop
|
||||
|
||||
```mist
|
||||
while (count < 5) {
|
||||
count++;
|
||||
}
|
||||
|
||||
while (active) {
|
||||
wait_for_event();
|
||||
}
|
||||
|
||||
while (count > 0) process(count--);
|
||||
```
|
||||
|
||||
## Jump Statements
|
||||
@@ -100,6 +106,6 @@ while (count > 0) process(count--);
|
||||
## Key Characteristics
|
||||
|
||||
- **Statement Bodies**: If, while, for, and loop branches can omit braces for single statements or expressions.
|
||||
- **Soft Returns**: Expression bodies (without `;`) implicitly return their value.
|
||||
- **Implicit Returns**: Expression bodies (without `;`) implicitly return their value.
|
||||
- **Pattern Integration**: Loops and match arms utilize Mist's pattern system for data destructuring.
|
||||
- **Multiple Patterns**: Match arms support `|` for matching multiple patterns.
|
||||
|
||||
@@ -4,16 +4,16 @@ description: The building blocks of logic, from literals to complex postfix chai
|
||||
icon: Binary
|
||||
---
|
||||
|
||||
Expressions in Mist are the fundamental units that evaluate to a value. The syntax follows a clean **prefix -> primary -> postfix** chain, providing a predictable structure that maps closely to Rust's mental model.
|
||||
Expressions in Mist are the fundamental units that evaluate to a value. The syntax follows a clean **prefix -> primary -> postfix** chain, providing a predictable structure.
|
||||
|
||||
## Primary Expressions
|
||||
|
||||
Primary expressions are the starting point of any logic chain. These include literal values, paths to static members, or grouped expressions in tuples.
|
||||
Primary expressions are the starting point of any logic chain. These include literal values, paths to members, tuples, arrays, and basic statements.
|
||||
|
||||
```mist
|
||||
var x = 42;
|
||||
var y = Math::PI;
|
||||
var coordinates = (10, 20, 30);
|
||||
let x = 42;
|
||||
let y = Math::PI;
|
||||
let coordinates = (10, 20, 30);
|
||||
```
|
||||
|
||||
## Postfix Operations
|
||||
@@ -21,21 +21,23 @@ var coordinates = (10, 20, 30);
|
||||
Postfix expressions allow you to build on a primary value with field access, calls, indexing, type casting, error propagation, and mutation operators.
|
||||
|
||||
```mist
|
||||
var len = list.length();
|
||||
let len = list.length();
|
||||
s.len();
|
||||
s.to_uppercase();
|
||||
|
||||
var task = Task {
|
||||
let task = Task {
|
||||
name: "Drafting",
|
||||
priority: 1,
|
||||
};
|
||||
|
||||
var first = items[0];
|
||||
let first = items[0];
|
||||
println!("Value: {}", first);
|
||||
```
|
||||
|
||||
### Increment & Decrement
|
||||
|
||||
```mist
|
||||
var mut i = 0;
|
||||
let mut i = 0;
|
||||
i++;
|
||||
i--;
|
||||
```
|
||||
@@ -56,8 +58,8 @@ flags |= 0x01;
|
||||
Use `as` to convert between compatible types:
|
||||
|
||||
```mist
|
||||
var x = 42;
|
||||
var y = x as f64;
|
||||
let x = 42;
|
||||
let y = x as f64;
|
||||
```
|
||||
|
||||
### Try Operator
|
||||
@@ -65,7 +67,7 @@ var y = x as f64;
|
||||
Propagate errors with the `?` postfix operator:
|
||||
|
||||
```mist
|
||||
var content = fs::read_to_string(path)?;
|
||||
let content = fs::read_to_string(path)?;
|
||||
```
|
||||
|
||||
### Range Operators
|
||||
@@ -80,30 +82,30 @@ var content = fs::read_to_string(path)?;
|
||||
Arrays are initialized with brackets, with an optional repeat notation:
|
||||
|
||||
```mist
|
||||
var arr = [1, 2, 3];
|
||||
var zeros = [0; 10]; // ten zeroes
|
||||
let arr = [1, 2, 3];
|
||||
let zeros = [0; 10]; // ten zeroes
|
||||
```
|
||||
|
||||
## Prefix Operations
|
||||
|
||||
Prefixes modify the primary expression that follows them.
|
||||
Prefixes modify the primary expression that follows them — dereference, reference, negation, and logical not.
|
||||
|
||||
```mist
|
||||
var mut value = 10;
|
||||
let mut value = 10;
|
||||
|
||||
var ref = &value;
|
||||
var mref = &mut value;
|
||||
var val = *ref;
|
||||
var is_false = !true;
|
||||
var neg = -42;
|
||||
let ref = &value;
|
||||
let mref = &mut value;
|
||||
let val = *ref;
|
||||
let is_false = !true;
|
||||
let neg = -42;
|
||||
```
|
||||
|
||||
## Binary Operations
|
||||
|
||||
```mist
|
||||
var sum = 10 + 20;
|
||||
var is_equal = (x == y);
|
||||
var complex = (a + b) * (c / d);
|
||||
let sum = 10 + 20;
|
||||
let is_equal = (x == y);
|
||||
let complex = (a + b) * (c / d);
|
||||
```
|
||||
|
||||
## Operator Table
|
||||
|
||||
@@ -4,62 +4,55 @@ description: Local state management with type inference and explicit mutability.
|
||||
icon: Variable
|
||||
---
|
||||
|
||||
In Mist, variables follow the language-wide `type name` convention. For local scope, the `var` keyword provides type inference, while explicit types can be used for clarity or strictness.
|
||||
Variables in Mist are declared with the `let` keyword. Like Rust, variables are immutable by default, and types are written after the name for scannability.
|
||||
|
||||
## Basic Declaration
|
||||
|
||||
Variables are declared using the `var` keyword for automatic type inference. Like Rust, variables are immutable by default.
|
||||
Variables use `let` for automatic type inference. The type annotation is optional — when omitted, the compiler infers the type from the value.
|
||||
|
||||
```mist
|
||||
var message = "Hello Mist";
|
||||
var count = 42;
|
||||
let x = 42;
|
||||
let greeting = "Hello Mist";
|
||||
```
|
||||
|
||||
## Mutability
|
||||
|
||||
To allow a variable to be reassigned, use the `mut` modifier after the `var` keyword or the explicit type.
|
||||
To allow a variable to be reassigned, use `let mut`:
|
||||
|
||||
```mist
|
||||
var mut score = 0;
|
||||
let mut score = 0;
|
||||
score = 100;
|
||||
|
||||
f32 mut price = 19.99;
|
||||
price = 14.99;
|
||||
```
|
||||
|
||||
## Explicit Typing
|
||||
|
||||
Type annotations are placed after the name:
|
||||
|
||||
```mist
|
||||
u64 large_id = 1000234;
|
||||
bool is_active = true;
|
||||
let id u64 = 1000234;
|
||||
let is_active bool = true;
|
||||
let name *str = "mist";
|
||||
```
|
||||
|
||||
## Arrays
|
||||
|
||||
```mist
|
||||
var list = [1, 2, 3]; // Standard init
|
||||
var zeros = [0; 10]; // Repeat notation: ten zeroes
|
||||
let list = [1, 2, 3]; // Standard init
|
||||
let zeros = [0; 10]; // Repeat notation: ten zeroes
|
||||
```
|
||||
|
||||
## Pattern Destructuring
|
||||
|
||||
```mist
|
||||
(i32, i32) (x, y) = get_coordinates();
|
||||
(String, i32) (name, age) = get_user_info();
|
||||
```
|
||||
|
||||
## Constants
|
||||
|
||||
Constants are immutable values evaluated at compile time with an explicit type.
|
||||
Tuples are destructured using square brackets:
|
||||
|
||||
```mist
|
||||
const i32 MAX_RETRIES = 5;
|
||||
const str* VERSION = "1.0.4";
|
||||
let [a, b] = (10, "hello");
|
||||
let [a, [b, c]] = (1, (2, 3));
|
||||
```
|
||||
|
||||
## Key Characteristics
|
||||
|
||||
- **Predictable Order**: Whether using `var` or an explicit type, the name always follows the "source" of its data.
|
||||
- **Predictable Order**: The `let` keyword signals a binding, followed by the name, optional type, and optional value.
|
||||
- **Safety First**: Immutability by default prevents accidental state changes.
|
||||
- **Zero-Cost Inference**: Type inference is handled entirely at compile time.
|
||||
- **Shadowing**: Mist supports variable shadowing within the same scope.
|
||||
|
||||
@@ -18,9 +18,9 @@ Writing Mist should feel intentional and deeply satisfying. It is built on the b
|
||||
|
||||
Complexity often arises from "expression overhead"—the mental energy spent navigating intricate syntax and symbols. Mist reduces this friction by:
|
||||
|
||||
* **Predictable Flow:** By adopting a consistent `type name` convention, code follows a natural rhythm that is easy to write and instantly scannable.
|
||||
* **Predictable Flow:** By adopting a consistent `name: Type` convention, code follows a natural rhythm that is easy to write and instantly scannable.
|
||||
* **Structural Clarity:** Features like unified `class` blocks and explicit `constructor` keywords provide a clear, organized home for your logic, reducing the need to jump between disparate files or implementation blocks.
|
||||
* **Tactile Precision:** Every symbol, from `mut*` pointers to pattern-based variables, is designed to feel physically connected to the data it represents, making the "mechanics" of the language feel like a well-calm tool in your hand.
|
||||
* **Tactile Precision:** Every symbol, from `*mut` pointers to pattern-based variables, is designed to feel physically connected to the data it represents, making the "mechanics" of the language feel like a well-calm tool in your hand.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user