Merge pull request #4 from mist-go/memory-proposition

Memory proposition
This commit is contained in:
2026-05-14 01:34:14 +02:00
committed by GitHub
16 changed files with 394 additions and 83 deletions
@@ -0,0 +1,66 @@
---
title: New Memory System Proposition
author: Klesti Selimaj
date: 2026-05-14
---
First of all i want to thank anyone who used or tried Mist, it's a literal dream project of mine that i attempted many times, years ago.
And i also released the syntax highlighting VSCode extension: https://marketplace.visualstudio.com/items?itemName=selimaj-dev.mist-syntax
## Current problem
As i'm developing this language for Rust, i keep noticing the amount of posts of frustration i see online, just like the ones i would make, and i impulsively check out other languages, maybe it's not worth using Rust after all?
The pattern is clear:
- Lifetimes have terrible syntax, and they are hard to understand, even for experienced Rust developers.
- Lifetimes are limiting, making it difficult to express certain patterns where in other languages this would be straightforward.
- The borrow checker can be frustrating, especially for newcomers, and it can lead to a lot of trial and error to get the code to compile.
## New proposition (Scope Counting)
I want to propose a new memory system (to my understanding), Scope Counting, which you have to see in action to understand it.
```mist
{
var x = new Box(10); // sc = 0
// sc is 0, drop it
}
```
```mist
var r; // sc = 0
{
// sc of r = -1 (relative to current scope)
var x = new Box(10); // sc = 0
r = &x; // sc of x = -(sc of r) aka 1
// sc is 1, don't drop it, decrement by 1
}
// sc is 0, drop it
```
This system fixes what Rust couldn't, that is maintaining the same level of safety, without compromising performance and ergonomics, because it's still at the compiler level.
What makes this better is that it can still live with Rust's lifetime model when needed.
## More examples
In rust this is a very limiting issue, but with SC, it goes how it's supposed to go
```mist
str* longest(str* x, str* y) {
if (x.len() > y.len()) return x;
else return y;
}
```
Why? because both x and y are already a level higher.
if x is an outer scope of y (generally means lives longer), y would actually push it's sc to live as long as x, a better example is this:
```mist
str* greet() {
return "hello, world!"; // Impossible in Rust
}
```
By default, any refrence/allocation is a sc of 0, meaning it's going to last until the current scope ends, but it detected that we are returning it, therefore it increased the sc by 1.
+9 -9
View File
@@ -10,11 +10,11 @@ Classes in Mist bridge the gap between Java's organizational structure and Rust'
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 follow the `type name` convention, and methods define their logic directly within the class body.
```cpp ```mist
public class Logger { pub class Logger {
String prefix; String prefix;
public void info(self*, str* message) { pub void info(self*, str* message) {
self.log(LogLevel::Info, message); self.log(LogLevel::Info, message);
} }
@@ -28,8 +28,8 @@ public class Logger {
Unlike languages that use the class name for initialization, Mist uses the explicit `constructor` keyword. This makes the entry point of the class unmistakable. Unlike languages that use the class name for initialization, Mist uses the explicit `constructor` keyword. This makes the entry point of the class unmistakable.
```cpp ```mist
public constructor(str* prefix) { pub constructor(str* prefix) {
self.prefix = prefix.to_string(); self.prefix = prefix.to_string();
} }
``` ```
@@ -38,8 +38,8 @@ public constructor(str* prefix) {
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. 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.
```cpp ```mist
public void warning(self*, str* message) { pub void warning(self*, str* message) {
self.log(LogLevel::Warning, message); self.log(LogLevel::Warning, message);
} }
``` ```
@@ -48,7 +48,7 @@ public void warning(self*, str* message) {
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. 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.
```cpp ```mist
impl fmt::Display { impl fmt::Display {
std::fmt::Result fmt(self*, std::fmt::Formatter<'_> mut* f) { std::fmt::Result fmt(self*, std::fmt::Formatter<'_> mut* f) {
return write!(f, "logger ({})", self.prefix); return write!(f, "logger ({})", self.prefix);
@@ -60,5 +60,5 @@ impl fmt::Display {
- **Unified Scope**: Data, behavior, and trait logic live in one place, eliminating the friction of jumping between `struct` and `impl` blocks. - **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. - **Explicit Context**: The use of `self*` ensures that the relationship between a method and its instance is always transparent.
- **Encapsulation**: Visibility modifiers (`public`) allow you to expose a clean API while keeping internal helper methods and state private to the class. - **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. - **Zero-Cost Classes**: Under the hood, Mist desugars these into idiomatic Rust structs and implementation blocks, ensuring no runtime overhead compared to raw Rust.
+6 -6
View File
@@ -10,8 +10,8 @@ Enums in Mist serve as powerful algebraic data types (ADTs), maintaining the exa
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, or struct-like variants. Following Mist's core philosophy, struct-like variants place the type before the identifier.
```rust ```mist
public enum TaskState { pub enum TaskState {
Pending, Pending,
InProgress, InProgress,
Completed, Completed,
@@ -26,7 +26,7 @@ public enum TaskState {
Mist supports all standard variant shapes, ensuring a 1:1 mapping to the underlying Rust execution model. Mist supports all standard variant shapes, ensuring a 1:1 mapping to the underlying Rust execution model.
```rust ```mist
enum Message { enum Message {
Quit, // Unit Quit, // Unit
Move(i32, i32), // Tuple Move(i32, i32), // Tuple
@@ -40,8 +40,8 @@ enum Message {
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. 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.
```rust ```mist
public enum Validation<'a, T> { pub enum Validation<'a, T> {
Valid(T), Valid(T),
Invalid { Invalid {
str'a* message, str'a* message,
@@ -53,5 +53,5 @@ public enum Validation<'a, T> {
- **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. - **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. - **Rust-Native ADTs**: Enums compile directly to Rust enums, allowing for exhaustive pattern matching and zero-cost abstraction.
- **Shared Visibility**: The `public` modifier at the enum level exports all variants for use in other modules, matching Rust's visibility rules for enums. - **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. - **Comma-Separated Members**: Fields within struct-like variants are separated by commas, mirroring the syntax used in standard Mist structs.
+9 -9
View File
@@ -10,7 +10,7 @@ Functions are the primary unit of execution in Mist. They prioritize a tradition
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 requires a return type, a name, and a body. Use the `void` keyword for functions that do not return a value.
```cpp ```mist
i32 add(i32 a, i32 b) { i32 add(i32 a, i32 b) {
return a + b; return a + b;
} }
@@ -22,10 +22,10 @@ void log_status(str* message) {
## Visibility & Exports ## Visibility & Exports
Functions are private to their module by default. The `public` modifier exports the function for cross-module access. Functions are private to their module by default. The `pub` modifier exports the function for cross-module access.
```cpp ```mist
public i32 get_version() { pub i32 get_version() {
return 1; return 1;
} }
``` ```
@@ -34,7 +34,7 @@ public i32 get_version() {
Parameters follow Rust’s ownership rules but use Mist’s local variable syntax. Use `mut` to allow a function to modify its local binding of a value. Parameters follow Rust’s ownership rules but use Mist’s local variable syntax. Use `mut` to allow a function to modify its local binding of a value.
```cpp ```mist
void update_score(i32 mut current_score, i32 bonus) { void update_score(i32 mut current_score, i32 bonus) {
current_score = current_score + bonus; current_score = current_score + bonus;
} }
@@ -44,8 +44,8 @@ void update_score(i32 mut current_score, i32 bonus) {
Mist integrates type abstraction and memory management into a single generic block. Lifetimes and type parameters share the `< >` bracket following the identifier. Mist integrates type abstraction and memory management into a single generic block. Lifetimes and type parameters share the `< >` bracket following the identifier.
```rust ```mist
public str'a* choose_longer<'a, T: Display>(str'a* s1, str'a* s2, T meta) { pub str'a* choose_longer<'a, T: Display>(str'a* s1, str'a* s2, T meta) {
println!("Metadata: {}", meta); println!("Metadata: {}", meta);
return if (s1.len() > s2.len()) { s1 } else { s2 }; return if (s1.len() > s2.len()) { s1 } else { s2 };
} }
@@ -55,9 +55,9 @@ public str'a* choose_longer<'a, T: Display>(str'a* s1, str'a* s2, T meta) {
Metadata is applied via the `#[attr]` syntax directly above the declaration for compiler hints or testing. Metadata is applied via the `#[attr]` syntax directly above the declaration for compiler hints or testing.
```cpp ```mist
#[inline] #[inline]
public bool is_active(u32 id) { pub bool is_active(u32 id) {
return id > 0; return id > 0;
} }
``` ```
@@ -10,7 +10,7 @@ Mist simplifies Rust’s reference system by using a pointer-style syntax. While
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. 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.
```cpp ```mist
void increment(i32 mut* value, i32* limit) { void increment(i32 mut* value, i32* limit) {
if (value < limit) { if (value < limit) {
value = value + 1; value = value + 1;
@@ -22,10 +22,10 @@ void increment(i32 mut* value, i32* limit) {
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 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.
```cpp ```mist
public struct Inspector<'a> { pub struct Inspector<'a> {
public str'a* target, pub str'a* target,
public u32'a mut* counter, pub u32'a mut* counter,
} }
``` ```
+15 -15
View File
@@ -10,21 +10,21 @@ Structs in Mist follow the same structural logic as Rust, but apply the language
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 follows the Mist convention of placing the type before the identifier, separated by commas.
```rust ```mist
public struct Task { pub struct Task {
public String name, pub String name,
public TaskState state, pub TaskState state,
public i32 executions, pub i32 executions,
} }
``` ```
## Visibility ## Visibility
Use the `public` modifier to make the struct or its individual fields accessible from other modules. Use the `pub` modifier to make the struct or its individual fields accessible from other modules.
```cpp ```mist
public struct NetworkNode { pub struct NetworkNode {
public u32 id, pub u32 id,
str* address, str* address,
} }
``` ```
@@ -33,7 +33,7 @@ public struct NetworkNode {
Structs are instantiated using the standard brace syntax. Structs are instantiated using the standard brace syntax.
```cpp ```mist
var task = Task { var task = Task {
name: "Initialize".to_string(), name: "Initialize".to_string(),
state: TaskState::Pending, state: TaskState::Pending,
@@ -45,10 +45,10 @@ var task = Task {
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. Lifetimes are associated with the reference/pointer type within the field declarations.
```cpp ```mist
public struct Buffer<'a, T> { pub struct Buffer<'a, T> {
public T'a* data, pub T'a* data,
public usize len, pub usize len,
} }
``` ```
@@ -57,4 +57,4 @@ public struct Buffer<'a, T> {
- **Type-First Declaration**: Fields use the `type name` order to match function parameters and variable declarations. - **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. - **Comma-Separated Members**: Fields are separated by commas, maintaining a clean and consistent delimiter style.
- **Rust Compatibility**: Maps 1:1 to Rust structs, ensuring zero-cost abstraction and full ecosystem interoperability. - **Rust Compatibility**: Maps 1:1 to Rust structs, ensuring zero-cost abstraction and full ecosystem interoperability.
- **Direct Visibility**: The `public` keyword replaces `pub` for a more consistent modifier language across the codebase. - **Direct Visibility**: The `pub` keyword replaces `pub` for a more consistent modifier language across the codebase.
+7 -7
View File
@@ -10,8 +10,8 @@ Traits in Mist define a set of methods that a type must implement, facilitating
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 definition lists method signatures that implementing types must satisfy. Like functions, these signatures place the return type before the method name.
```rust ```mist
public trait Drawable { pub trait Drawable {
void draw(self*); void draw(self*);
str* metadata(self*); str* metadata(self*);
} }
@@ -20,7 +20,7 @@ public trait Drawable {
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. 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.
```rust ```mist
impl Drawable for Task { impl Drawable for Task {
void draw(self*) { void draw(self*) {
println!("Drawing task: {}", self.name); println!("Drawing task: {}", self.name);
@@ -35,8 +35,8 @@ impl Drawable for Task {
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. Types implementing the trait can choose to override these defaults or use the provided implementation.
```rust ```mist
public trait Identifiable { pub trait Identifiable {
u32 get_id(self*); u32 get_id(self*);
bool is_valid(self*) { bool is_valid(self*) {
@@ -48,8 +48,8 @@ public trait Identifiable {
Traits can build upon other traits. If a trait requires another trait to be implemented first, use the colon `:` syntax. Traits can build upon other traits. If a trait requires another trait to be implemented first, use the colon `:` syntax.
```rust ```mist
public trait Animated : Drawable { pub trait Animated : Drawable {
void animate(self*, f32 delta_time); void animate(self*, f32 delta_time);
} }
``` ```
+1 -1
View File
@@ -64,7 +64,7 @@ path = "build/main.rs"
Now for the fun part! Create a new file at `src/main.mist` and add the following code: Now for the fun part! Create a new file at `src/main.mist` and add the following code:
```cpp title="src/main.mist" ```mist title="src/main.mist"
void main() { void main() {
println!("Hello World!"); println!("Hello World!");
} }
+1 -1
View File
@@ -53,7 +53,7 @@ Inheritance is a major planned feature but is currently **not implemented**.
Be aware that because we are focusing on syntax, keywords and structures may change between minor versions. Currently: Be aware that because we are focusing on syntax, keywords and structures may change between minor versions. Currently:
* **Access Modifiers:** `public` and private defaults are being tested for various contexts (classes vs. structs, or `public(crate)`). * **Access Modifiers:** `pub` and private defaults are being tested for various contexts (classes vs. structs, or `pub(crate)`).
* **Pointers vs. References:** The `*` syntax for references (e.g., `self mut*`) is the current standard but is subject to refinement based on ecosystem feedback. * **Pointers vs. References:** The `*` syntax for references (e.g., `self mut*`) is the current standard but is subject to refinement based on ecosystem feedback.
+5 -5
View File
@@ -10,7 +10,7 @@ Control flow in Mist provides a bridge between C-style procedural logic and Rust
The `if` statement evaluates a boolean expression. It supports multiple `else if` branches and an optional `else` block. The `if` statement evaluates a boolean expression. It supports multiple `else if` branches and an optional `else` block.
```cpp ```mist
if (score > 50) { if (score > 50) {
println!("Pass"); println!("Pass");
} else if (score == 50) { } else if (score == 50) {
@@ -24,7 +24,7 @@ if (score > 50) {
The `match` statement provides exhaustive pattern matching. Currently, every match arm requires a block `{}` following the `=>` operator. The `match` statement provides exhaustive pattern matching. Currently, every match arm requires a block `{}` following the `=>` operator.
```cpp ```mist
match (task_state) { match (task_state) {
TaskState::Pending => { TaskState::Pending => {
println!("Queued"); println!("Queued");
@@ -46,7 +46,7 @@ Mist supports both functional iteration and traditional low-level loop control.
For manual iteration control, Mist supports the standard three-part `for` loop: initialization, condition, and post-iteration statement. For manual iteration control, Mist supports the standard three-part `for` loop: initialization, condition, and post-iteration statement.
```cpp ```mist
for (var mut i = 0; i < 10; i = i + 1;) { for (var mut i = 0; i < 10; i = i + 1;) {
println!("Index: {}", i); println!("Index: {}", i);
} }
@@ -56,7 +56,7 @@ for (var mut i = 0; i < 10; i = i + 1;) {
The `for-in` loop iterates over collections or iterators using Mist's pattern matching system. The `for-in` loop iterates over collections or iterators using Mist's pattern matching system.
```cpp ```mist
for (var item in collection) { for (var item in collection) {
process(item); process(item);
} }
@@ -71,7 +71,7 @@ for ((i32 x, i32 y) in coordinates) {
The `while` loop continues execution as long as the parenthesized expression evaluates to `true`. The `while` loop continues execution as long as the parenthesized expression evaluates to `true`.
```cpp ```mist
while (active) { while (active) {
wait_for_event(); wait_for_event();
} }
+4 -4
View File
@@ -10,7 +10,7 @@ Expressions in Mist are the fundamental units that evaluate to a value. The synt
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 static members, or grouped expressions in tuples.
```java ```mist
// Literals and paths // Literals and paths
var x = 42; var x = 42;
var y = Math::PI; var y = Math::PI;
@@ -24,7 +24,7 @@ var coordinates = (10, 20, 30);
Postfix expressions allow you to build on a primary value. This includes calling functions, accessing fields, indexing arrays, or initializing structs. Postfix expressions allow you to build on a primary value. This includes calling functions, accessing fields, indexing arrays, or initializing structs.
```java ```mist
// Field access and method/function calls // Field access and method/function calls
var len = list.length(); var len = list.length();
@@ -44,7 +44,7 @@ println!("Value: {}", first); // Macro call via '!'
Prefixes modify the primary expression that follows them. Mist uses these for logical negation, dereferencing, and creating references. Prefixes modify the primary expression that follows them. Mist uses these for logical negation, dereferencing, and creating references.
```java ```mist
var mut value = 10; var mut value = 10;
var ref = &value; // Reference var ref = &value; // Reference
@@ -58,7 +58,7 @@ var is_false = !true; // Logical NOT
Binary operations are applied as postfixes to an expression, following a `bin_op ~ expr` pattern. This supports all standard arithmetic, comparison, and logical operators. Binary operations are applied as postfixes to an expression, following a `bin_op ~ expr` pattern. This supports all standard arithmetic, comparison, and logical operators.
```java ```mist
var sum = 10 + 20; var sum = 10 + 20;
var is_equal = (x == y); var is_equal = (x == y);
var complex = (a + b) * (c / d); var complex = (a + b) * (c / d);
+5 -5
View File
@@ -10,7 +10,7 @@ In Mist, variables follow the language-wide `type name` convention. For local sc
Variables are declared using the `var` keyword for automatic type inference. Like Rust, variables are immutable by default. Variables are declared using the `var` keyword for automatic type inference. Like Rust, variables are immutable by default.
```java ```mist
var message = "Hello Mist"; // Inferred as str* var message = "Hello Mist"; // Inferred as str*
var count = 42; // Inferred as i32 var count = 42; // Inferred as i32
``` ```
@@ -19,7 +19,7 @@ var count = 42; // Inferred as i32
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 the `mut` modifier after the `var` keyword or the explicit type.
```rust ```mist
var mut score = 0; var mut score = 0;
score = 100; score = 100;
@@ -31,7 +31,7 @@ price = 14.99;
While `var` handles inference, you can explicitly define the type before the identifier. This is often used for clarity in complex logic or when the specific numeric width (e.g., `u8` vs `i32`) matters. While `var` handles inference, you can explicitly define the type before the identifier. This is often used for clarity in complex logic or when the specific numeric width (e.g., `u8` vs `i32`) matters.
```rust ```mist
u64 large_id = 1000234; u64 large_id = 1000234;
bool is_active = true; bool is_active = true;
``` ```
@@ -40,7 +40,7 @@ bool is_active = true;
Because variable declarations are patterns, you can destructure tuples or structures directly. This keeps data extraction clean and avoids manual indexing. Because variable declarations are patterns, you can destructure tuples or structures directly. This keeps data extraction clean and avoids manual indexing.
```rust ```mist
// Destructuring a tuple into local variables // Destructuring a tuple into local variables
(i32, i32) (x, y) = get_coordinates(); (i32, i32) (x, y) = get_coordinates();
@@ -52,7 +52,7 @@ Because variable declarations are patterns, you can destructure tuples or struct
Constants are immutable values that are evaluated at compile time. They require an explicit type and follow the `const` keyword. Constants are immutable values that are evaluated at compile time. They require an explicit type and follow the `const` keyword.
```rust ```mist
const i32 MAX_RETRIES = 5; const i32 MAX_RETRIES = 5;
const str* VERSION = "1.0.4"; const str* VERSION = "1.0.4";
``` ```
+231
View File
@@ -0,0 +1,231 @@
{
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
"name": "mist",
"scopeName": "source.mist",
"patterns": [
{
"include": "#comments"
},
{
"include": "#keywords"
},
{
"include": "#attributes"
},
{
"include": "#strings"
},
{
"include": "#macros"
},
{
"include": "#type_declarations"
},
{
"include": "#constants"
},
{
"include": "#lifetimes"
},
{
"include": "#generics"
},
{
"include": "#types"
},
{
"include": "#namespaces"
},
{
"include": "#functions"
},
{
"include": "#numbers"
},
{
"include": "#operators"
},
{
"include": "#punctuation"
}
],
"repository": {
"comments": {
"match": "//.*",
"name": "comment.line.double-slash.mist"
},
"attributes": {
"begin": "#!?\\[",
"beginCaptures": {
"0": {
"name": "punctuation.definition.attribute.begin.mist"
}
},
"end": "\\]",
"endCaptures": {
"0": {
"name": "punctuation.definition.attribute.end.mist"
}
},
"name": "meta.attribute.mist",
"patterns": [
{
"include": "$self"
}
]
},
"strings": {
"begin": "\"",
"beginCaptures": {
"0": {
"name": "punctuation.definition.string.begin.mist"
}
},
"end": "\"",
"endCaptures": {
"0": {
"name": "punctuation.definition.string.end.mist"
}
},
"name": "string.quoted.double.mist",
"patterns": [
{
"match": "\\\\.",
"name": "constant.character.escape.mist"
}
]
},
"macros": {
"match": "\\b([a-zA-Z_][a-zA-Z0-9_]*)(!)",
"captures": {
"1": {
"name": "entity.name.function.macro.mist"
},
"2": {
"name": "keyword.operator.macro.mist"
}
}
},
"type_declarations": {
"match": "\\b(struct|enum|class|trait)\\s+([a-zA-Z_][a-zA-Z0-9_]*)",
"captures": {
"1": {
"name": "storage.type.mist"
},
"2": {
"name": "entity.name.type.mist"
}
}
},
"keywords": {
"patterns": [
{
"match": "\\b(if|else|while|for|in|return|break|continue|match)\\b",
"name": "keyword.control.mist"
},
{
"match": "\\b(struct|enum|class|trait|var)\\b",
"name": "storage.type.mist"
},
{
"match": "\\b(pub|mut|constructor)\\b",
"name": "storage.modifier.mist"
},
{
"match": "\\b(impl|use|mod|new|void|self)\\b",
"name": "keyword.other.mist"
}
]
},
"constants": {
"match": "\\b(true|false)\\b",
"name": "constant.language.boolean.mist"
},
"lifetimes": {
"match": "'[a-zA-Z_][a-zA-Z0-9_]*\\b",
"name": "storage.modifier.lifetime.mist"
},
"generics": {
"begin": "<",
"beginCaptures": {
"0": {
"name": "punctuation.brackets.angle.mist"
}
},
"end": ">",
"endCaptures": {
"0": {
"name": "punctuation.brackets.angle.mist"
}
},
"patterns": [
{
"include": "#lifetimes"
},
{
"match": "\\b[a-zA-Z_][a-zA-Z0-9_]*\\b",
"name": "entity.name.type.mist"
},
{
"match": ",",
"name": "punctuation.separator.mist"
},
{
"match": ":|\\+",
"name": "keyword.operator.mist"
},
{
"include": "#generics"
}
]
},
"types": {
"patterns": [
{
"match": "(?<![A-Za-z])(f32|f64|i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)\\b",
"name": "entity.name.type.numeric.mist"
},
{
"match": "(?<![A-Za-z])(str|char|bool)\\b",
"name": "entity.name.type.other.mist"
},
{
"match": "\\b_?[A-Z][A-Za-z0-9_]*\\b(?!!)",
"name": "entity.name.type.mist"
}
]
},
"namespaces": {
"match": "\\b([a-zA-Z_][a-zA-Z0-9_]*)(?=\\s*::)",
"captures": {
"1": {
"name": "entity.name.namespace.mist"
}
}
},
"functions": {
"match": "\\b([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?=\\()",
"name": "entity.name.function.mist"
},
"numbers": {
"patterns": [
{
"match": "\\b\\d+\\.\\d+\\b",
"name": "constant.numeric.float.mist"
},
{
"match": "\\b\\d+\\b",
"name": "constant.numeric.integer.mist"
}
]
},
"operators": {
"match": "(<=|>=|==|!=|&&|\\|\\||\\+|-|\\*|/|%|<|>|=|=>|!)",
"name": "keyword.operator.mist"
},
"punctuation": {
"match": "::|:|;|,|\\.|\\{|\\}|\\(|\\)|\\[|\\]",
"name": "punctuation.mist"
}
}
}
+8 -1
View File
@@ -5,6 +5,7 @@ import {
} from "fumadocs-mdx/config"; } from "fumadocs-mdx/config";
import { metaSchema, pageSchema } from "fumadocs-core/source/schema"; import { metaSchema, pageSchema } from "fumadocs-core/source/schema";
import { z } from "zod"; import { z } from "zod";
import mist from "./public/mist.tmLanguage.json";
// You can customize Zod schemas for frontmatter and `meta.json` here // You can customize Zod schemas for frontmatter and `meta.json` here
// see https://fumadocs.dev/docs/mdx/collections // see https://fumadocs.dev/docs/mdx/collections
@@ -33,6 +34,12 @@ export const blogPosts = defineCollections({
export default defineConfig({ export default defineConfig({
mdxOptions: { mdxOptions: {
// MDX options rehypeCodeOptions: {
langs: [mist],
themes: {
light: "github-light",
dark: "github-dark",
},
},
}, },
}); });
+9 -9
View File
@@ -21,7 +21,7 @@ export const mistShowcase = [
greet("Developer"); greet("Developer");
} }
public void greet(str* name) { pub void greet(str* name) {
// Familiar pointer ergonomics with Rust safety // Familiar pointer ergonomics with Rust safety
String greeting = name.to_string(); String greeting = name.to_string();
println!("Hello, {}!", greeting); println!("Hello, {}!", greeting);
@@ -46,19 +46,19 @@ void process_data() {
title: "Class and Type System", title: "Class and Type System",
description: description:
"Classes are syntactic sugar for Rust structs. Using 'extends' provides inheritance-style syntax over struct composition, compiling into the underlying Rust type system.", "Classes are syntactic sugar for Rust structs. Using 'extends' provides inheritance-style syntax over struct composition, compiling into the underlying Rust type system.",
code: `public struct PluginInfo { code: `pub struct PluginInfo {
public String name, pub String name,
public String version, pub String version,
} }
public class PluginRegistry<T> { pub class PluginRegistry<T> {
T plugins; T plugins;
public constructor(T plugins) { pub constructor(T plugins) {
self.plugins = plugins; self.plugins = plugins;
} }
public T plugins(self) { pub T plugins(self) {
return self.plugins; return self.plugins;
} }
}`, }`,
@@ -68,10 +68,10 @@ public class PluginRegistry<T> {
title: "Better Developer Experience", title: "Better Developer Experience",
description: description:
"While Rust can already be a great DX, Mist implements concepts that are proven to improve structure.", "While Rust can already be a great DX, Mist implements concepts that are proven to improve structure.",
code: `public class Logger { code: `pub class Logger {
String prefix; String prefix;
public constructor(str* prefix) { pub constructor(str* prefix) {
self.prefix = prefix.to_string(); self.prefix = prefix.to_string();
} }
+13 -6
View File
@@ -1,21 +1,28 @@
"use client"; "use client";
import { BundledLanguage, codeToTokens } from "shiki"; import { BundledLanguage, codeToTokens, createHighlighter } from "shiki";
import { motion, AnimatePresence } from "framer-motion"; import { motion, AnimatePresence } from "framer-motion";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import mist from "../../public/mist.tmLanguage.json";
interface Props { interface Props {
code: string; code: string;
lang?: BundledLanguage;
} }
export default function MorphCode({ code, lang = "rust" }: Props) { const highlighterPromise = createHighlighter({
themes: ["github-dark"],
langs: [mist],
});
export default function MorphCode({ code }: Props) {
const [lines, setLines] = useState<any[][]>([]); const [lines, setLines] = useState<any[][]>([]);
useEffect(() => { useEffect(() => {
async function run() { async function run() {
const result = await codeToTokens(code, { const highlighter = await highlighterPromise;
lang,
const result = highlighter.codeToTokens(code, {
lang: "mist" as any,
theme: "github-dark", theme: "github-dark",
}); });
@@ -36,7 +43,7 @@ export default function MorphCode({ code, lang = "rust" }: Props) {
} }
run(); run();
}, [code, lang]); }, [code]);
return ( return (
<pre className="text-sm overflow-x-scroll overflow-y-hidden"> <pre className="text-sm overflow-x-scroll overflow-y-hidden">