From 856c9dfdfaa9112c07e8415bfa5ba10956e99699 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 05:26:52 +0200 Subject: [PATCH 01/15] Rewriting mist project structure --- .gitignore | 2 ++ src/builder.rs | 6 ++---- src/main.mist | 7 +++++-- src/transpiler.rs | 23 ++++------------------- 4 files changed, 13 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index e4cd9b8..6351270 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ target /target **/build + +.mist/ diff --git a/src/builder.rs b/src/builder.rs index a65983a..34afc8a 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -8,8 +8,6 @@ use std::{ use cargo_metadata::{CompilerMessage, Message}; use mist_parser::rev_mapper::{RustMap, find_mapping, get_mapping}; -use crate::transpiler::Config; - #[derive(Debug, Clone)] pub struct MistDiagnosticMessage { pub message: String, @@ -26,7 +24,7 @@ pub enum MistDiagnostic { Rust(CompilerMessage), } -pub fn build(mut args: Vec, config: Config, root: PathBuf) -> bool { +pub fn build(mut args: Vec, root: PathBuf) -> bool { args.remove(0); args.insert(1, "--message-format=json".to_string()); @@ -55,7 +53,7 @@ pub fn build(mut args: Vec, config: Config, root: PathBuf) -> bool { let mist_file = span .file_name - .replacen(&config.output, &config.src, 1) + .replacen(".mist/src", "src", 1) .replace(".rs", ".mist"); let mist_path = root.join(&mist_file); diff --git a/src/main.mist b/src/main.mist index 8171d3b..48b47c6 100644 --- a/src/main.mist +++ b/src/main.mist @@ -15,9 +15,12 @@ void main() { match (args[1].as_str()) { "run" | "build" | "check" | "r" | "b" | "c" => { - var (config, root) = transpiler::build(); + + var root = transpiler::build(); + println!(""); - if (builder::build(args, config, root)) { + + if (builder::build(args, root)) { println!("\x1b[32m\nBuild successful\x1b[0m"); } else { println!("\x1b[31m\nBuild failed\x1b[0m"); diff --git a/src/transpiler.rs b/src/transpiler.rs index ec282c2..e1abf52 100644 --- a/src/transpiler.rs +++ b/src/transpiler.rs @@ -6,25 +6,16 @@ use std::{ }; use mist_parser::error::ParseError; -use serde::Deserialize; -#[derive(Deserialize)] -pub struct Config { - pub src: String, - pub output: String, -} - -pub fn build() -> (Config, PathBuf) { +pub fn build() -> PathBuf { let start = Instant::now(); let root = find_project_root().unwrap_or_else(|| { panic!("error: could not find project root (mist.json)"); }); - let config = load_config(&root); - - let src_dir = root.join(&config.src); - let out_dir = root.join(&config.output); + let src_dir = root.join("src"); + let out_dir = root.join(".mist/src"); build_dir(&root, &src_dir, &src_dir, &out_dir); @@ -35,7 +26,7 @@ pub fn build() -> (Config, PathBuf) { elapsed ); - (config, root) + root } fn build_dir(root: &Path, base_src: &Path, current_dir: &Path, out_dir: &Path) { @@ -187,9 +178,3 @@ pub fn find_project_root() -> Option { } } } - -fn load_config(root: &Path) -> Config { - let content = fs::read_to_string(root.join("mist.json")).expect("failed to read mist.json"); - - serde_json::from_str(&content).expect("invalid mist.json format") -} From d408d010028ee25832d4403e803eb8e370cd864b Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 05:33:23 +0200 Subject: [PATCH 02/15] Using .mist/src --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 55367dc..e4e5dc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ cargo_metadata = "0.23.1" [[bin]] name = "mist" -path = "build/main.rs" +path = ".mist/src/main.rs" [[bin]] name = "mist-header" @@ -33,4 +33,4 @@ path = "src/_header.rs" [[bin]] name = "mist-analyzer" -path = "build/analyzer.rs" +path = ".mist/src/analyzer.rs" From da819c22f6b9c5eaecc060f08d3819fe44c3558c Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 05:43:10 +0200 Subject: [PATCH 03/15] Init project --- src/main.mist | 18 ++++++++++++++++++ src/transpiler.rs | 20 +++----------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/main.mist b/src/main.mist index 48b47c6..27bf7af 100644 --- a/src/main.mist +++ b/src/main.mist @@ -1,5 +1,6 @@ use ; use ; +use ; pub mod builder; pub mod codegen; @@ -29,6 +30,9 @@ void main() { "transpile" | "t" => { transpiler::build(); } + "init" => { + init_project(); + } "version" | "--version" | "-v" => { println!("mist {}", env!("CARGO_PKG_VERSION")); } @@ -61,3 +65,17 @@ void print_usage() { println!(" \x1b[36m mist version \x1b[0m print the compiler version\n"); println!(" \x1b[36m mist help\x1b[0m print this message\n"); } + +void init_project(Vec args) { + new process::Command("cargo") + .args(args) + .stdout(process::Stdio::piped()) + .stderr(process::Stdio::piped()) + .stdin(process::Stdio::piped()) + .spawn() + .expect("Failed to run cargo"); + + fs::remove("src/main.rs").expect("Failed to remove src/main.rs"); + + fs::write("src/main.mist", "void main() {\n println!(\"Hello, World!\")\n}").expect("Failed to create src/main.mist"); +} diff --git a/src/transpiler.rs b/src/transpiler.rs index e1abf52..349b7c4 100644 --- a/src/transpiler.rs +++ b/src/transpiler.rs @@ -10,9 +10,9 @@ use mist_parser::error::ParseError; pub fn build() -> PathBuf { let start = Instant::now(); - let root = find_project_root().unwrap_or_else(|| { - panic!("error: could not find project root (mist.json)"); - }); + let root = std::env::current_dir() + .ok() + .expect("Unable to find project root"); let src_dir = root.join("src"); let out_dir = root.join(".mist/src"); @@ -164,17 +164,3 @@ fn should_skip(source: &Path, output: &Path) -> bool { } false } - -pub fn find_project_root() -> Option { - let mut dir = std::env::current_dir().ok()?; - - loop { - if dir.join("mist.json").exists() { - return Some(dir); - } - - if !dir.pop() { - return None; - } - } -} From 959f786dc808a17c1f3229c117cc50e155db19ca Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 06:14:50 +0200 Subject: [PATCH 04/15] Working init --- mist-test/mist.json | 4 ---- parser/src/grammar.pest | 4 ++-- src/main.mist | 44 ++++++++++++++++++++++++++++++++--------- 3 files changed, 37 insertions(+), 15 deletions(-) delete mode 100644 mist-test/mist.json diff --git a/mist-test/mist.json b/mist-test/mist.json deleted file mode 100644 index 6632b01..0000000 --- a/mist-test/mist.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "src": "src", - "output": "build" -} \ No newline at end of file diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index 7e480d5..d982ce6 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -143,11 +143,11 @@ literal = { // ====================================================== tuple_pattern = { - "(" ~ (identifier ~ ("," ~ identifier)*) ~ ")" + "[" ~ (identifier ~ ("," ~ identifier)*) ~ "]" } named_tuple_pattern = { - static_path ~ "(" ~ (identifier ~ ("," ~ identifier)*)? ~ ")" + static_path ~ "[" ~ (identifier ~ ("," ~ identifier)*)? ~ "]" } struct_pattern = { diff --git a/src/main.mist b/src/main.mist index 27bf7af..d1109ee 100644 --- a/src/main.mist +++ b/src/main.mist @@ -31,7 +31,7 @@ void main() { transpiler::build(); } "init" => { - init_project(); + init_project(args); } "version" | "--version" | "-v" => { println!("mist {}", env!("CARGO_PKG_VERSION")); @@ -66,16 +66,42 @@ void print_usage() { println!(" \x1b[36m mist help\x1b[0m print this message\n"); } -void init_project(Vec args) { +void init_project(Vec mut args) { + args.remove(0); + new process::Command("cargo") .args(args) - .stdout(process::Stdio::piped()) - .stderr(process::Stdio::piped()) - .stdin(process::Stdio::piped()) + .stdout(process::Stdio::inherit()) + .stderr(process::Stdio::inherit()) + .stdin(process::Stdio::inherit()) .spawn() - .expect("Failed to run cargo"); - - fs::remove("src/main.rs").expect("Failed to remove src/main.rs"); + .expect("Failed to run cargo").wait().expect("Unable to wait"); - fs::write("src/main.mist", "void main() {\n println!(\"Hello, World!\")\n}").expect("Failed to create src/main.mist"); + bool is_lib = fs::metadata("src/lib.rs").is_ok(); + + if (is_lib) { + fs::remove_file("src/lib.rs").expect("Failed to remove src/lib.rs"); + fs::write("src/lib.mist", "void test() {\n}").expect("Failed to create src/lib.mist"); + } else { + fs::remove_file("src/main.rs").expect("Failed to remove src/main.rs"); + fs::write("src/main.mist", "void main() {\n println!(\"Hello, World!\");\n}\n").expect("Failed to create src/main.mist"); + } + + inject_mist_target(is_lib); + + println!("\n\x1b[34minfo\x1b[0m: Please open Cargo.toml and adjust `\x1b[35mname\x1b[0m = ` as needed, Thank you for using Mist!\n"); +} + +void inject_mist_target(bool is_lib) { + String toml_content = fs::read_to_string("Cargo.toml").expect("Failed to read Cargo.toml"); + + str* inject; + + if (is_lib) { + inject = "\n[lib]\nname = \"my_lib\"\npath = \".mist/src/lib.rs\"\n"; + } else { + inject = "\n[[bin]]\nname = \"my_bin\"\npath = \".mist/src/main.rs\"\n"; + } + + fs::write("Cargo.toml", toml_content+inject).expect("Failed to create src/main.mist"); } From cc7bc49efe97e74996775dbb2799c510e7626e66 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 06:16:51 +0200 Subject: [PATCH 05/15] Added init to list --- src/main.mist | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.mist b/src/main.mist index d1109ee..a86389b 100644 --- a/src/main.mist +++ b/src/main.mist @@ -62,6 +62,9 @@ void print_usage() { println!( " \x1b[36m mist check\x1b[0m,\x1b[36m c\x1b[0m check the project in the current directory\n" ); + println!( + " \x1b[36m mist init\x1b[0m initialize a project in the current folder\n" + ); println!(" \x1b[36m mist version \x1b[0m print the compiler version\n"); println!(" \x1b[36m mist help\x1b[0m print this message\n"); } From 0c8dc53617656d79e6dab9d8cfce28f965445be9 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 06:34:27 +0200 Subject: [PATCH 06/15] Rewriting statement system for expr statements --- mist-test/Cargo.toml | 2 +- mist-test/src/app.mist | 95 --------------------------- mist-test/src/event.mist | 7 -- mist-test/src/logger.mist | 78 ---------------------- mist-test/src/main.mist | 16 +---- mist-test/src/plugin.mist | 16 ----- mist-test/src/task.mist | 20 ------ parser/src/grammar.pest | 45 ++++++------- parser/src/parser/common/statement.rs | 4 -- 9 files changed, 24 insertions(+), 259 deletions(-) delete mode 100644 mist-test/src/app.mist delete mode 100644 mist-test/src/event.mist delete mode 100644 mist-test/src/logger.mist delete mode 100644 mist-test/src/plugin.mist delete mode 100644 mist-test/src/task.mist diff --git a/mist-test/Cargo.toml b/mist-test/Cargo.toml index a02d622..3973e4b 100644 --- a/mist-test/Cargo.toml +++ b/mist-test/Cargo.toml @@ -5,6 +5,6 @@ edition = "2024" [[bin]] name = "main" -path = "build/main.rs" +path = ".mist/src/main.rs" [dependencies] diff --git a/mist-test/src/app.mist b/mist-test/src/app.mist deleted file mode 100644 index 42072ac..0000000 --- a/mist-test/src/app.mist +++ /dev/null @@ -1,95 +0,0 @@ -use ; -use ; -use ; - -pub class Application { - String name; - - Vec tasks; - Vec plugins; - - logger::Logger logger; - - bool running; - i32 ticks; - - pub constructor(str* name) { - self.name = name.to_string(); - - self.tasks = new Vec(); - self.plugins = new Vec(); - - self.logger = new logger::Logger("app"); - - self.running = false; - self.ticks = 0; - } - - pub void boot(self mut*) { - self.logger.info("booting application"); - - self.running = true; - - self.emit(event::Event::Startup); - } - - pub void run(self mut*) { - while(self.running) { - self.tick(); - - if(self.ticks >= 5) { - self.shutdown(); - } - } - } - - void tick(self mut*) { - self.logger.info("tick"); - - self.ticks++; - - var task = task::create_task("background-job"); - - self.tasks.push(task); - - println!("tasks: {}", self.tasks.len()); - } - - pub void shutdown(self mut*) { - self.emit(event::Event::Shutdown); - - self.logger.warning("shutdown"); - - self.running = false; - } - - pub void register_plugin(self mut*, String name) { - self.plugins.push(name.clone()); - - self.emit(event::Event::PluginLoaded(name)); - } - - void emit(self*, event::Event event) { - match(event) { - event::Event::Startup => { - self.logger.info("startup event"); - } - - event::Event::Shutdown => { - self.logger.info("shutdown event"); - } - - event::Event::PluginLoaded(name) => { - println!("plugin loaded: {}", name); - } - - event::Event::TaskExecuted(name) => { - println!("task executed: {}", name); - } - - event::Event::Error(message) => { - self.logger.error(&message); - } - } - } -} \ No newline at end of file diff --git a/mist-test/src/event.mist b/mist-test/src/event.mist deleted file mode 100644 index 6340bf4..0000000 --- a/mist-test/src/event.mist +++ /dev/null @@ -1,7 +0,0 @@ -pub enum Event { - Startup, - Shutdown, - TaskExecuted(String), - PluginLoaded(String), - Error(String), -} \ No newline at end of file diff --git a/mist-test/src/logger.mist b/mist-test/src/logger.mist deleted file mode 100644 index ab194cd..0000000 --- a/mist-test/src/logger.mist +++ /dev/null @@ -1,78 +0,0 @@ -use ; -use ; - -pub trait TestLogging: fmt::Display { - String get(self*); -} - -pub enum LogLevel { - Info, - Warning, - Error, -} - -impl fmt::Display for LogLevel { - fmt::Result fmt(self*, Formatter<'_> mut* f) { - match (self) { - LogLevel::Info => { - return write!(f, "[INFO]"); - } - - LogLevel::Warning => { - return write!(f, "[WARN]"); - } - - LogLevel::Error => { - return write!(f, "[ERROR]"); - } - } - } -} - -impl TestLogging for LogLevel { - String get(self*) { - return format!("{self}"); - } -} - -pub class Logger { - String prefix; - - pub constructor(str* prefix) { - self.prefix = prefix.to_string(); - } - - pub void info(self*, str* message) { - self.log(LogLevel::Info, message); - } - - pub void warning(self*, str* message) { - self.log(LogLevel::Warning, message); - } - - pub void error(self*, str* message) { - self.log(LogLevel::Error, message); - } - - void log(self*, LogLevel level, str* message) { - match(level) { - LogLevel::Info => { - println!("{level} {} {}", self.prefix, message); - } - - LogLevel::Warning => { - println!("{} {} {}", level.get(), self.prefix, message); - } - - LogLevel::Error => { - println!("{level} {} {}", self.prefix, message); - } - } - } - - impl fmt::Display { - fmt::Result fmt(self*, Formatter<'_> mut* f) { - return write!(f, "logger ({})", self.prefix); - } - } -} \ No newline at end of file diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index 853e686..5a7a1cb 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -1,15 +1,3 @@ -pub mod app; -pub mod task; -pub mod plugin; -pub mod logger; -pub mod event; - void main() { - var mut app_instance = new app::Application("mist-app"); - - // greeting::register(&mut app_instance); - // statistics::register(&mut app_instance); - - app_instance.boot(); - app_instance.run(); -} \ No newline at end of file + println!("hello, world"); +} diff --git a/mist-test/src/plugin.mist b/mist-test/src/plugin.mist deleted file mode 100644 index a3d16ba..0000000 --- a/mist-test/src/plugin.mist +++ /dev/null @@ -1,16 +0,0 @@ -pub struct PluginInfo { - pub String name, - pub String version, -} - -pub class PluginRegistry { - T plugins; - - pub constructor(T plugins) { - self.plugins = plugins; - } - - pub T plugins(self) { - return self.plugins; - } -} \ No newline at end of file diff --git a/mist-test/src/task.mist b/mist-test/src/task.mist deleted file mode 100644 index d902258..0000000 --- a/mist-test/src/task.mist +++ /dev/null @@ -1,20 +0,0 @@ -pub enum TaskState { - Pending, - Running, - Finished, - Failed, -} - -pub struct Task { - pub String name, - pub TaskState state, - pub i32 executions, -} - -pub Task create_task(str* name) { - return Task { - name: name.to_string(), - state: TaskState::Pending, - executions: 0, - }; -} \ No newline at end of file diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index d982ce6..4b3758d 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -342,53 +342,49 @@ block = { "{" ~ (statement | unexpected_statement)* ~ "}" } -statement = _{ - match_stmt - | if_stmt - | while_stmt - | c_for_stmt - | for_stmt - | return_stmt - | break_stmt - | continue_stmt - | block - | increment_statement - | decrement_statement - | var_decl_statement - | assign_statement - | expr_stmt +statement = { + (expr | basic_stmt_left_recurse) ~ semicolon } // ------------------------------------------------------ // BASIC STATEMENTS // ------------------------------------------------------ -expr_stmt = { - expr ~ semicolon +basic_stmt = { + return_stmt + | break_stmt + | continue_stmt + | var_decl_statement +} + +basic_stmt_left_recurse = { + increment_statement + | decrement_statement + | assign_statement } return_stmt = { - "return" ~ expr? ~ semicolon + "return" ~ expr? } break_stmt = { - "break" ~ semicolon + "break" } continue_stmt = { - "continue" ~ semicolon + "continue" } var_decl_statement = { - var_decl ~ ("=" ~ expr)? ~ semicolon + var_decl ~ ("=" ~ expr)? } increment_statement = { - expr ~ "++" ~ semicolon + expr ~ "++" } decrement_statement = { - expr ~ "--" ~ semicolon + expr ~ "--" } compound_assign = { @@ -497,7 +493,8 @@ expr_path = { } primary = { - literal + basic_stmt + | literal | expr_path | tuple | array diff --git a/parser/src/parser/common/statement.rs b/parser/src/parser/common/statement.rs index 3b3f7ad..af9e1a2 100644 --- a/parser/src/parser/common/statement.rs +++ b/parser/src/parser/common/statement.rs @@ -41,10 +41,6 @@ impl<'a> TryFrom> for Statement { match rule { Rule::statement => Statement::try_from(inner.next().unwrap()), - Rule::expr_stmt => { - ast_expr!(Statement::Expression(inner.next().unwrap().try_into())) - } - Rule::block => ast_expr!(Statement::Block(pair.try_into())), Rule::var_decl_statement => ast_expr!(Statement::VarDecl(pair.try_into())), From b28591f9e6850ab769dcf473e38548e4e7893995 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 06:51:34 +0200 Subject: [PATCH 07/15] Working expr statements --- mist-test/src/main.mist | 2 ++ parser/src/ast/expr.rs | 1 + parser/src/ast/statement.rs | 4 +--- parser/src/grammar.pest | 4 ++-- parser/src/parser/common/expr.rs | 6 ++++++ parser/src/parser/common/statement.rs | 2 +- src/codegen.rs | 12 +++++++----- 7 files changed, 20 insertions(+), 11 deletions(-) diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index 5a7a1cb..1292b05 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -1,3 +1,5 @@ void main() { + i32 x; + println!("hello, world"); } diff --git a/parser/src/ast/expr.rs b/parser/src/ast/expr.rs index 257448d..56e0584 100644 --- a/parser/src/ast/expr.rs +++ b/parser/src/ast/expr.rs @@ -30,6 +30,7 @@ pub enum BinaryOp { pub enum Expression { Literal(Literal), Path(ExprPath), + Statement(Box), Fix { initial: Box, prefixes: Vec, diff --git a/parser/src/ast/statement.rs b/parser/src/ast/statement.rs index 7ec8ccd..0e9c056 100644 --- a/parser/src/ast/statement.rs +++ b/parser/src/ast/statement.rs @@ -3,13 +3,11 @@ use serde::Serialize; use super::*; #[derive(Debug, Clone, Serialize, Default)] -pub struct Block(pub Vec>); +pub struct Block(pub Vec>); #[derive(Debug, Clone, Serialize)] pub enum Statement { - Expression(Expression), Block(Block), - VarDecl(VarDeclStmt), Assign { target: Expression, diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index 4b3758d..1315e6f 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -342,8 +342,8 @@ block = { "{" ~ (statement | unexpected_statement)* ~ "}" } -statement = { - (expr | basic_stmt_left_recurse) ~ semicolon +statement = _{ + ((expr | basic_stmt_left_recurse) ~ semicolon) } // ------------------------------------------------------ diff --git a/parser/src/parser/common/expr.rs b/parser/src/parser/common/expr.rs index 312a406..ddc83fb 100644 --- a/parser/src/parser/common/expr.rs +++ b/parser/src/parser/common/expr.rs @@ -117,6 +117,12 @@ impl<'a> TryFrom> for Expression { Rule::static_path => ast_expr!(Expression::Path(pair.try_into())), Rule::literal => ast_expr!(Expression::Literal(pair.try_into())), Rule::expr_path => ast_expr!(Expression::Path(pair.try_into())), + Rule::statement => ast_expr!(Expression::Statement( + pair.try_into().get_map(Box::new).map(Box::new) + )), + Rule::basic_stmt => ast_expr!(Expression::Statement( + pair.try_into().get_map(Box::new).map(Box::new) + )), _ => AstError::bug_unimplemented(pair), } diff --git a/parser/src/parser/common/statement.rs b/parser/src/parser/common/statement.rs index af9e1a2..6d369f6 100644 --- a/parser/src/parser/common/statement.rs +++ b/parser/src/parser/common/statement.rs @@ -39,7 +39,7 @@ impl<'a> TryFrom> for Statement { let mut inner = pair.clone().into_inner(); match rule { - Rule::statement => Statement::try_from(inner.next().unwrap()), + Rule::statement | Rule::basic_stmt => Statement::try_from(inner.next().unwrap()), Rule::block => ast_expr!(Statement::Block(pair.try_into())), diff --git a/src/codegen.rs b/src/codegen.rs index f8524f1..de58d2e 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -169,6 +169,12 @@ impl GetRust for Expression { match self { Expression::Path(path) => path.get_rust(), Expression::Literal(literal) => literal.get_rust(), + Expression::Statement(stmt) => { + let mut cg = RustCodegen::new(); + cg.indent += 1; + stmt.to_rust(&mut cg); + cg.output + } Expression::Fix { initial, prefixes, @@ -336,7 +342,7 @@ impl ToRust for Spanned { impl ToRust for Block { fn to_rust(self, cg: &mut RustCodegen) { for stmt in self.0 { - stmt.to_rust(cg); + cg.add_indentedln(&(stmt.get_rust() + ";")); } } } @@ -608,10 +614,6 @@ impl ToRust for TopLevelKind { impl ToRust for Statement { fn to_rust(self, cg: &mut RustCodegen) { match self { - Statement::Expression(expr) => { - cg.add_indentedln(&format!("{};", expr.get_rust())); - } - Statement::Block(block) => { cg.add_indentedln("{"); cg.indent += 1; From 0878b9f0b9e91bfe972a8f78c63e7c0a3b6fb72a Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 07:05:58 +0200 Subject: [PATCH 08/15] Improving operators and suffix --- mist-test/src/main.mist | 6 ++- parser/src/ast/expr.rs | 3 ++ parser/src/ast/statement.rs | 8 ---- parser/src/grammar.pest | 61 +++++++++++++-------------- parser/src/parser/common/expr.rs | 3 ++ parser/src/parser/common/statement.rs | 14 ------ src/codegen.rs | 20 ++------- 7 files changed, 43 insertions(+), 72 deletions(-) diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index 1292b05..9bf7b6a 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -1,5 +1,7 @@ void main() { - i32 x; + i32 mut x = 10; - println!("hello, world"); + x++; + + println!("hello, world {x}"); } diff --git a/parser/src/ast/expr.rs b/parser/src/ast/expr.rs index 56e0584..0ecdaca 100644 --- a/parser/src/ast/expr.rs +++ b/parser/src/ast/expr.rs @@ -70,8 +70,11 @@ pub enum Postfix { Call(Vec), MacroCall(String), StructCall(Vec<(Identifier, Expression)>), + Assign(String, Box), Index(Expression), As(TypeExpr), + Increment, + Decrement, Try, } diff --git a/parser/src/ast/statement.rs b/parser/src/ast/statement.rs index 0e9c056..ea00353 100644 --- a/parser/src/ast/statement.rs +++ b/parser/src/ast/statement.rs @@ -9,11 +9,6 @@ pub struct Block(pub Vec>); pub enum Statement { Block(Block), VarDecl(VarDeclStmt), - Assign { - target: Expression, - compound: String, - value: Expression, - }, If { initial: StatementBranch, else_if: Vec, @@ -37,9 +32,6 @@ pub enum Statement { Return(Option), Break, Continue, - - Increment(Expression), - Decrement(Expression), } #[derive(Debug, Clone, Serialize)] diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index 1315e6f..5f25152 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -343,7 +343,7 @@ block = { } statement = _{ - ((expr | basic_stmt_left_recurse) ~ semicolon) + (expr ~ semicolon) } // ------------------------------------------------------ @@ -357,12 +357,6 @@ basic_stmt = { | var_decl_statement } -basic_stmt_left_recurse = { - increment_statement - | decrement_statement - | assign_statement -} - return_stmt = { "return" ~ expr? } @@ -379,31 +373,6 @@ var_decl_statement = { var_decl ~ ("=" ~ expr)? } -increment_statement = { - expr ~ "++" -} - -decrement_statement = { - expr ~ "--" -} - -compound_assign = { - "=" - | "+=" - | "-=" - | "/=" - | "%=" - | "&=" - | "|=" - | "^=" - | "<<=" - | ">>=" -} - -assign_statement = { - expr ~ compound_assign ~ expr ~ semicolon -} - // ------------------------------------------------------ // CONDITIONALS // ------------------------------------------------------ @@ -536,6 +505,31 @@ try_px = { "?" } +increment = { + "++" +} + +decrement = { + "--" +} + +compound_assign = { + "=" + | "+=" + | "-=" + | "/=" + | "%=" + | "&=" + | "|=" + | "^=" + | "<<=" + | ">>=" +} + +assign = { + compound_assign ~ expr +} + postfix = { field_px | call_px @@ -544,6 +538,9 @@ postfix = { | index_px | as_px | try_px + | increment + | decrement + | assign } // ------------------------------------------------------ diff --git a/parser/src/parser/common/expr.rs b/parser/src/parser/common/expr.rs index ddc83fb..107c8e8 100644 --- a/parser/src/parser/common/expr.rs +++ b/parser/src/parser/common/expr.rs @@ -191,6 +191,9 @@ impl<'a> TryFrom> for Postfix { Rule::try_px => Ok(Postfix::Try), + Rule::increment => Ok(Postfix::Increment), + Rule::decrement => Ok(Postfix::Decrement), + _ => AstError::bug_unimplemented(pair), } } diff --git a/parser/src/parser/common/statement.rs b/parser/src/parser/common/statement.rs index 6d369f6..1aec7c0 100644 --- a/parser/src/parser/common/statement.rs +++ b/parser/src/parser/common/statement.rs @@ -84,12 +84,6 @@ impl<'a> TryFrom> for Statement { body: inner.next().unwrap().try_into().map(Box::new), }), - Rule::assign_statement => ast_expr!(Statement::Assign { - target: inner.next().unwrap().try_into(), - compound: Ok(inner.next().unwrap().as_str().trim().to_string()) - as AstResult<'_, String>, - value: inner.next().unwrap().try_into(), - }), Rule::match_stmt => ast_expr!(Statement::Match( inner.next().unwrap().try_into(), inner @@ -103,14 +97,6 @@ impl<'a> TryFrom> for Statement { .collect::>>(), )), - Rule::increment_statement => { - ast_expr!(Statement::Increment(inner.next().unwrap().try_into())) - } - - Rule::decrement_statement => { - ast_expr!(Statement::Decrement(inner.next().unwrap().try_into())) - } - Rule::unexpected_statement => { return Err(AstError { span: pair.as_span(), diff --git a/src/codegen.rs b/src/codegen.rs index de58d2e..2c8e296 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -319,6 +319,10 @@ impl GetRust for Postfix { Postfix::As(ty) => format!(" as {}", ty.get_rust()), Postfix::Try => String::from("?"), + + Postfix::Assign(cmp, expr) => format!("{cmp} {}", expr.get_rust()), + Postfix::Increment => "+=1".to_string(), + Postfix::Decrement => "-=1".to_string(), } } } @@ -630,19 +634,6 @@ impl ToRust for Statement { cg.add_indentedln(&format!("let {}{};", decl.get_rust(), init)); } - Statement::Assign { - target, - compound, - value, - } => { - cg.add_indentedln(&format!( - "{} {} {};", - target.get_rust(), - compound, - value.get_rust(), - )); - } - Statement::Match(expr, match_items) => { cg.add_indentedln(&format!("match {} {{", expr.get_rust())); cg.indent += 1; @@ -740,9 +731,6 @@ impl ToRust for Statement { Statement::Break => cg.add_indentedln("break;"), Statement::Continue => cg.add_indentedln("continue;"), - - Statement::Increment(e) => cg.add_indentedln(&format!("{}+=1;", e.get_rust())), - Statement::Decrement(e) => cg.add_indentedln(&format!("{}-=1;", e.get_rust())), } } } From 197afbfb35481a4b1a89504995a59920708f16db Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 07:23:11 +0200 Subject: [PATCH 09/15] bin op stuff --- mist-test/src/main.mist | 2 + parser/src/ast/expr.rs | 26 +-------- parser/src/grammar.pest | 93 +++++++++++--------------------- parser/src/parser/common/expr.rs | 49 ++--------------- src/codegen.rs | 32 ++--------- 5 files changed, 45 insertions(+), 157 deletions(-) diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index 9bf7b6a..9e77692 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -1,6 +1,8 @@ void main() { i32 mut x = 10; + x = 1 + 1; + x++; println!("hello, world {x}"); diff --git a/parser/src/ast/expr.rs b/parser/src/ast/expr.rs index 0ecdaca..77962cb 100644 --- a/parser/src/ast/expr.rs +++ b/parser/src/ast/expr.rs @@ -2,30 +2,6 @@ use serde::Serialize; use super::*; -#[derive(Debug, Clone, Serialize)] -pub enum BinaryOp { - Plus, - Minus, - Multiply, - Divide, - Modulo, - Equal, - NotEqual, - LessThan, - GreaterThan, - LessThanOrEqual, - GreaterThanOrEqual, - And, - Or, - ShiftLeft, - ShiftRight, - RangeInclusive, - RangeExclusive, - BitAnd, - BitOr, - BitXor, -} - #[derive(Debug, Clone, Serialize)] pub enum Expression { Literal(Literal), @@ -38,7 +14,7 @@ pub enum Expression { }, Binary { lhs: Box, - op: BinaryOp, + op: String, rhs: Box, }, } diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index 5f25152..e8e4d9b 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -513,23 +513,6 @@ decrement = { "--" } -compound_assign = { - "=" - | "+=" - | "-=" - | "/=" - | "%=" - | "&=" - | "|=" - | "^=" - | "<<=" - | ">>=" -} - -assign = { - compound_assign ~ expr -} - postfix = { field_px | call_px @@ -540,7 +523,6 @@ postfix = { | try_px | increment | decrement - | assign } // ------------------------------------------------------ @@ -564,51 +546,40 @@ prefix = { } // ------------------------------------------------------ -// OPERATORS (Arranged carefully for PEG priority matching) +// OPERATORS // ------------------------------------------------------ -shl = { "<<" } -shr = { ">>" } -range_inc = { "..=" } -range_exc = { ".." } -lte = { "<=" } -gte = { ">=" } -eq = { "==" } -neq = { "!=" } -and = { "&&" } -or = { "||" } -add = { "+" } -sub = { "-" } -mul = { "*" } -div = { "/" } -rem = { "%" } -lt = { "<" } -gt = { ">" } -bitand = { "&" } -bitor = { "|" } -bitxor = { "^" } - -bin_op = _{ - shl - | shr - | range_inc - | range_exc - | lte - | gte - | eq - | neq - | and - | or - | lt - | gt - | add - | sub - | mul - | div - | rem - | bitand - | bitor - | bitxor +bin_op = { + "+=" + | "-=" + | "/=" + | "%=" + | "&=" + | "|=" + | "^=" + | "<<=" + | ">>=" + | "<<" + | ">>" + | "..=" + | ".." + | "<=" + | ">=" + | "==" + | "!=" + | "&&" + | "||" + | "+" + | "-" + | "*" + | "/" + | "%" + | "<" + | ">" + | "&" + | "|" + | "^" + | "=" } // ------------------------------------------------------ diff --git a/parser/src/parser/common/expr.rs b/parser/src/parser/common/expr.rs index 107c8e8..06b26dd 100644 --- a/parser/src/parser/common/expr.rs +++ b/parser/src/parser/common/expr.rs @@ -18,57 +18,18 @@ impl<'a> TryFrom> for Expression { Rule::expr => { static PRATT_PARSER: OnceLock> = OnceLock::new(); let pratt = PRATT_PARSER.get_or_init(|| { - use Rule::*; use pest::pratt_parser::{Assoc::*, Op}; - PrattParser::new() - .op(Op::infix(range_inc, Left) | Op::infix(range_exc, Left)) - .op(Op::infix(or, Left)) - .op(Op::infix(and, Left)) - .op(Op::infix(bitor, Left)) - .op(Op::infix(bitxor, Left)) - .op(Op::infix(bitand, Left)) - .op(Op::infix(eq, Left) | Op::infix(neq, Left)) - .op(Op::infix(lt, Left) - | Op::infix(lte, Left) - | Op::infix(gt, Left) - | Op::infix(gte, Left)) - .op(Op::infix(shl, Left) | Op::infix(shr, Left)) - .op(Op::infix(add, Left) | Op::infix(sub, Left)) - .op(Op::infix(mul, Left) | Op::infix(div, Left) | Op::infix(rem, Left)) + PrattParser::new().op(Op::infix(Rule::bin_op, Left)) }); pratt .map_primary(|primary_pair| Expression::try_from(primary_pair)) - .map_infix(|lhs, op, rhs| { - let bin_op = match op.as_rule() { - Rule::shl => BinaryOp::ShiftLeft, - Rule::shr => BinaryOp::ShiftRight, - Rule::range_inc => BinaryOp::RangeInclusive, - Rule::range_exc => BinaryOp::RangeExclusive, - Rule::lte => BinaryOp::LessThanOrEqual, - Rule::gte => BinaryOp::GreaterThanOrEqual, - Rule::eq => BinaryOp::Equal, - Rule::neq => BinaryOp::NotEqual, - Rule::and => BinaryOp::And, - Rule::or => BinaryOp::Or, - Rule::add => BinaryOp::Plus, - Rule::sub => BinaryOp::Minus, - Rule::mul => BinaryOp::Multiply, - Rule::div => BinaryOp::Divide, - Rule::rem => BinaryOp::Modulo, - Rule::lt => BinaryOp::LessThan, - Rule::gt => BinaryOp::GreaterThan, - Rule::bitand => BinaryOp::BitAnd, - Rule::bitor => BinaryOp::BitOr, - Rule::bitxor => BinaryOp::BitXor, - _ => return AstError::bug_unimplemented(op), - }; - + .map_infix(|expr, op, rhs| { ast_expr!(Expression::Binary { - lhs: lhs.map(Box::new), - op: Ok(bin_op) as AstResult<'_, BinaryOp>, - rhs: rhs.map(Box::new), + lhs: expr.map(Box::new).get_map(Box::new), + op: Ok(op.as_str().to_string()) as AstResult<'_, String>, + rhs: rhs.map(Box::new).get_map(Box::new), }) }) .parse(inner) diff --git a/src/codegen.rs b/src/codegen.rs index 2c8e296..61f4486 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -1,8 +1,8 @@ use mist_parser::ast::{ - Attribute, BinaryOp, Block, ClassItem, EnumItem, ExprPath, ExprPathSegment, Expression, - FieldDecl, FunctionDecl, Generic, GenericDecl, Generics, GenericsDecl, Identifier, ImplDecl, - Literal, Path, Pattern, Postfix, Prefix, Spanned, Statement, StatementBranch, TopLevel, - TopLevelKind, TypeExpr, TypeExprKind, TypePostfix, VarDecl, VarDeclStmt, Visibility, + Attribute, Block, ClassItem, EnumItem, ExprPath, ExprPathSegment, Expression, FieldDecl, + FunctionDecl, Generic, GenericDecl, Generics, GenericsDecl, Identifier, ImplDecl, Literal, + Path, Pattern, Postfix, Prefix, Spanned, Statement, StatementBranch, TopLevel, TopLevelKind, + TypeExpr, TypeExprKind, TypePostfix, VarDecl, VarDeclStmt, Visibility, }; // --------------------------------------------------------------------------- @@ -187,29 +187,7 @@ impl GetRust for Expression { } // Safely integrated to handle the tree structure built by the Pratt Parser Expression::Binary { lhs, op, rhs } => { - let op_str = match op { - BinaryOp::Plus => "+", - BinaryOp::Minus => "-", - BinaryOp::Multiply => "*", - BinaryOp::Divide => "/", - BinaryOp::Modulo => "%", - BinaryOp::Equal => "==", - BinaryOp::NotEqual => "!=", - BinaryOp::LessThan => "<", - BinaryOp::GreaterThan => ">", - BinaryOp::LessThanOrEqual => "<=", - BinaryOp::GreaterThanOrEqual => ">=", - BinaryOp::And => "&&", - BinaryOp::Or => "||", - BinaryOp::ShiftLeft => "<<", - BinaryOp::ShiftRight => ">>", - BinaryOp::RangeInclusive => "..=", - BinaryOp::RangeExclusive => "..", - BinaryOp::BitAnd => "&", - BinaryOp::BitOr => "|", - BinaryOp::BitXor => "^", - }; - format!("{} {} {}", lhs.get_rust(), op_str, rhs.get_rust()) + format!("{} {} {}", lhs.get_rust(), op, rhs.get_rust()) } } } From 70e6eb6276536b1996ec5c55ec0535c1b8d8bfdf Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 07:28:19 +0200 Subject: [PATCH 10/15] Control flow --- mist-test/src/main.mist | 4 ++++ parser/src/grammar.pest | 12 +++++++++++- parser/src/parser/common/expr.rs | 9 +++------ parser/src/parser/common/statement.rs | 2 +- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index 9e77692..cdda4c4 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -5,5 +5,9 @@ void main() { x++; + if (1 == 1) { + println!("Yes!"); + } + println!("hello, world {x}"); } diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index e8e4d9b..3716e1d 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -343,7 +343,8 @@ block = { } statement = _{ - (expr ~ semicolon) + control_flow + | (expr ~ semicolon) } // ------------------------------------------------------ @@ -377,6 +378,15 @@ var_decl_statement = { // CONDITIONALS // ------------------------------------------------------ +control_flow = { + if_stmt + | while_stmt + | c_for_stmt + | for_stmt + | match_stmt + | block +} + statement_branch = { "(" ~ expr ~ ")" ~ statement } else_if = { diff --git a/parser/src/parser/common/expr.rs b/parser/src/parser/common/expr.rs index 06b26dd..de33878 100644 --- a/parser/src/parser/common/expr.rs +++ b/parser/src/parser/common/expr.rs @@ -78,12 +78,9 @@ impl<'a> TryFrom> for Expression { Rule::static_path => ast_expr!(Expression::Path(pair.try_into())), Rule::literal => ast_expr!(Expression::Literal(pair.try_into())), Rule::expr_path => ast_expr!(Expression::Path(pair.try_into())), - Rule::statement => ast_expr!(Expression::Statement( - pair.try_into().get_map(Box::new).map(Box::new) - )), - Rule::basic_stmt => ast_expr!(Expression::Statement( - pair.try_into().get_map(Box::new).map(Box::new) - )), + Rule::statement | Rule::basic_stmt | Rule::control_flow => ast_expr!( + Expression::Statement(pair.try_into().get_map(Box::new).map(Box::new)) + ), _ => AstError::bug_unimplemented(pair), } diff --git a/parser/src/parser/common/statement.rs b/parser/src/parser/common/statement.rs index 1aec7c0..e8d1647 100644 --- a/parser/src/parser/common/statement.rs +++ b/parser/src/parser/common/statement.rs @@ -39,7 +39,7 @@ impl<'a> TryFrom> for Statement { let mut inner = pair.clone().into_inner(); match rule { - Rule::statement | Rule::basic_stmt => Statement::try_from(inner.next().unwrap()), + Rule::statement | Rule::basic_stmt | Rule::control_flow => Statement::try_from(inner.next().unwrap()), Rule::block => ast_expr!(Statement::Block(pair.try_into())), From 7688599504231066a54a4c0b331bb7f8e915472d Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 07:59:00 +0200 Subject: [PATCH 11/15] Working soft return --- mist-test/src/main.mist | 4 ++++ parser/src/ast/statement.rs | 5 ++++- parser/src/grammar.pest | 9 +++++++-- parser/src/parser/common/statement.rs | 8 ++++++-- src/codegen.rs | 4 ++++ 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index cdda4c4..db84371 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -9,5 +9,9 @@ void main() { println!("Yes!"); } + i32 y = if (x == 3) { 1 } else { 0 }; + println!("hello, world {x}"); + + println!("{y}") } diff --git a/parser/src/ast/statement.rs b/parser/src/ast/statement.rs index ea00353..89a2d44 100644 --- a/parser/src/ast/statement.rs +++ b/parser/src/ast/statement.rs @@ -3,7 +3,10 @@ use serde::Serialize; use super::*; #[derive(Debug, Clone, Serialize, Default)] -pub struct Block(pub Vec>); +pub struct Block( + pub Vec>, + pub Option>, +); #[derive(Debug, Clone, Serialize)] pub enum Statement { diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index 3716e1d..a6bac5d 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -339,7 +339,11 @@ top_level = { // ====================================================== block = { - "{" ~ (statement | unexpected_statement)* ~ "}" + "{" ~ statement_list ~ expr? ~ "}" +} + +statement_list = { + (statement | (!expr ~ unexpected_statement))* } statement = _{ @@ -472,7 +476,8 @@ expr_path = { } primary = { - basic_stmt + control_flow + | basic_stmt | literal | expr_path | tuple diff --git a/parser/src/parser/common/statement.rs b/parser/src/parser/common/statement.rs index e8d1647..8e4f4a4 100644 --- a/parser/src/parser/common/statement.rs +++ b/parser/src/parser/common/statement.rs @@ -10,8 +10,10 @@ impl<'a> TryFrom> for Block { type Error = AstError<'a, Self>; fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result { + let mut inner = pair.clone().into_inner(); + ast_ensure!(pair, Rule::block => { - ast_expr!(Block(collect_recovered(pair.into_inner()))) + ast_expr!(Block(collect_recovered(inner.next().unwrap().into_inner()), inner.next().map(Spanned::try_from).transpose())) }) } } @@ -39,7 +41,9 @@ impl<'a> TryFrom> for Statement { let mut inner = pair.clone().into_inner(); match rule { - Rule::statement | Rule::basic_stmt | Rule::control_flow => Statement::try_from(inner.next().unwrap()), + Rule::statement | Rule::basic_stmt | Rule::control_flow => { + Statement::try_from(inner.next().unwrap()) + } Rule::block => ast_expr!(Statement::Block(pair.try_into())), diff --git a/src/codegen.rs b/src/codegen.rs index 61f4486..3cb5ca7 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -326,6 +326,10 @@ impl ToRust for Block { for stmt in self.0 { cg.add_indentedln(&(stmt.get_rust() + ";")); } + + if let Some(soft_return) = self.1 { + cg.add_indentedln(&soft_return.get_rust()); + } } } From 702af9da3b028a166064aac6730f87439d03eb80 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 08:09:26 +0200 Subject: [PATCH 12/15] Fixed self and added tests back --- mist-test/src/app.mist | 95 ++++++++++++++++++++++++++++++++ mist-test/src/event.mist | 7 +++ mist-test/src/logger.mist | 78 ++++++++++++++++++++++++++ mist-test/src/main.mist | 25 ++++----- mist-test/src/plugin.mist | 16 ++++++ mist-test/src/task.mist | 20 +++++++ parser/src/grammar.pest | 3 +- parser/src/parser/common/expr.rs | 2 +- 8 files changed, 228 insertions(+), 18 deletions(-) create mode 100644 mist-test/src/app.mist create mode 100644 mist-test/src/event.mist create mode 100644 mist-test/src/logger.mist create mode 100644 mist-test/src/plugin.mist create mode 100644 mist-test/src/task.mist diff --git a/mist-test/src/app.mist b/mist-test/src/app.mist new file mode 100644 index 0000000..25f64b3 --- /dev/null +++ b/mist-test/src/app.mist @@ -0,0 +1,95 @@ +use ; +use ; +use ; + +pub class Application { + String name; + + Vec tasks; + Vec plugins; + + logger::Logger logger; + + bool running; + i32 ticks; + + pub constructor(str* name) { + self.name; + + self.tasks = new Vec(); + self.plugins = new Vec(); + + self.logger = new logger::Logger("app"); + + self.running = false; + self.ticks = 0; + } + + pub void boot(self mut*) { + self.logger.info("booting application"); + + self.running = true; + + self.emit(event::Event::Startup); + } + + pub void run(self mut*) { + while(self.running) { + self.tick(); + + if(self.ticks >= 5) { + self.shutdown(); + } + } + } + + void tick(self mut*) { + self.logger.info("tick"); + + self.ticks++; + + var task = task::create_task("background-job"); + + self.tasks.push(task); + + println!("tasks: {}", self.tasks.len()); + } + + pub void shutdown(self mut*) { + self.emit(event::Event::Shutdown); + + self.logger.warning("shutdown"); + + self.running = false; + } + + pub void register_plugin(self mut*, String name) { + self.plugins.push(name.clone()); + + self.emit(event::Event::PluginLoaded(name)); + } + + void emit(self*, event::Event event) { + match(event) { + event::Event::Startup => { + self.logger.info("startup event"); + } + + event::Event::Shutdown => { + self.logger.info("shutdown event"); + } + + event::Event::PluginLoaded[name] => { + println!("plugin loaded: {}", name); + } + + event::Event::TaskExecuted[name] => { + println!("task executed: {}", name); + } + + event::Event::Error[message] => { + self.logger.error(&message); + } + } + } +} \ No newline at end of file diff --git a/mist-test/src/event.mist b/mist-test/src/event.mist new file mode 100644 index 0000000..6340bf4 --- /dev/null +++ b/mist-test/src/event.mist @@ -0,0 +1,7 @@ +pub enum Event { + Startup, + Shutdown, + TaskExecuted(String), + PluginLoaded(String), + Error(String), +} \ No newline at end of file diff --git a/mist-test/src/logger.mist b/mist-test/src/logger.mist new file mode 100644 index 0000000..ab194cd --- /dev/null +++ b/mist-test/src/logger.mist @@ -0,0 +1,78 @@ +use ; +use ; + +pub trait TestLogging: fmt::Display { + String get(self*); +} + +pub enum LogLevel { + Info, + Warning, + Error, +} + +impl fmt::Display for LogLevel { + fmt::Result fmt(self*, Formatter<'_> mut* f) { + match (self) { + LogLevel::Info => { + return write!(f, "[INFO]"); + } + + LogLevel::Warning => { + return write!(f, "[WARN]"); + } + + LogLevel::Error => { + return write!(f, "[ERROR]"); + } + } + } +} + +impl TestLogging for LogLevel { + String get(self*) { + return format!("{self}"); + } +} + +pub class Logger { + String prefix; + + pub constructor(str* prefix) { + self.prefix = prefix.to_string(); + } + + pub void info(self*, str* message) { + self.log(LogLevel::Info, message); + } + + pub void warning(self*, str* message) { + self.log(LogLevel::Warning, message); + } + + pub void error(self*, str* message) { + self.log(LogLevel::Error, message); + } + + void log(self*, LogLevel level, str* message) { + match(level) { + LogLevel::Info => { + println!("{level} {} {}", self.prefix, message); + } + + LogLevel::Warning => { + println!("{} {} {}", level.get(), self.prefix, message); + } + + LogLevel::Error => { + println!("{level} {} {}", self.prefix, message); + } + } + } + + impl fmt::Display { + fmt::Result fmt(self*, Formatter<'_> mut* f) { + return write!(f, "logger ({})", self.prefix); + } + } +} \ No newline at end of file diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index db84371..3729e97 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -1,17 +1,12 @@ +pub mod app; +pub mod task; +pub mod plugin; +pub mod logger; +pub mod event; + void main() { - i32 mut x = 10; + var mut app_instance = new app::Application("mist-app"); - x = 1 + 1; - - x++; - - if (1 == 1) { - println!("Yes!"); - } - - i32 y = if (x == 3) { 1 } else { 0 }; - - println!("hello, world {x}"); - - println!("{y}") -} + app_instance.boot(); + app_instance.run(); +} \ No newline at end of file diff --git a/mist-test/src/plugin.mist b/mist-test/src/plugin.mist new file mode 100644 index 0000000..a3d16ba --- /dev/null +++ b/mist-test/src/plugin.mist @@ -0,0 +1,16 @@ +pub struct PluginInfo { + pub String name, + pub String version, +} + +pub class PluginRegistry { + T plugins; + + pub constructor(T plugins) { + self.plugins = plugins; + } + + pub T plugins(self) { + return self.plugins; + } +} \ No newline at end of file diff --git a/mist-test/src/task.mist b/mist-test/src/task.mist new file mode 100644 index 0000000..d902258 --- /dev/null +++ b/mist-test/src/task.mist @@ -0,0 +1,20 @@ +pub enum TaskState { + Pending, + Running, + Finished, + Failed, +} + +pub struct Task { + pub String name, + pub TaskState state, + pub i32 executions, +} + +pub Task create_task(str* name) { + return Task { + name: name.to_string(), + state: TaskState::Pending, + executions: 0, + }; +} \ No newline at end of file diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index a6bac5d..35e60e3 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -29,7 +29,6 @@ keyword = { | "true" | "false" | "dyn" - | "self" } identifier = @{ @@ -343,7 +342,7 @@ block = { } statement_list = { - (statement | (!expr ~ unexpected_statement))* + (statement | (unexpected_statement))* } statement = _{ diff --git a/parser/src/parser/common/expr.rs b/parser/src/parser/common/expr.rs index de33878..86dd684 100644 --- a/parser/src/parser/common/expr.rs +++ b/parser/src/parser/common/expr.rs @@ -78,7 +78,7 @@ impl<'a> TryFrom> for Expression { Rule::static_path => ast_expr!(Expression::Path(pair.try_into())), Rule::literal => ast_expr!(Expression::Literal(pair.try_into())), Rule::expr_path => ast_expr!(Expression::Path(pair.try_into())), - Rule::statement | Rule::basic_stmt | Rule::control_flow => ast_expr!( + Rule::statement | Rule::basic_stmt | Rule::control_flow | Rule::unexpected_statement => ast_expr!( Expression::Statement(pair.try_into().get_map(Box::new).map(Box::new)) ), From 2fcb8c3831f47de2d1b3a087ab29b7f294a2aee4 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 11:05:00 +0200 Subject: [PATCH 13/15] Fixed naming error --- parser/src/grammar.pest | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index 35e60e3..9dbe487 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -32,7 +32,7 @@ keyword = { } identifier = @{ - !keyword ~ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")* + !(keyword ~ !(ASCII_ALPHANUMERIC | "_")) ~ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")* } integer = @{ ASCII_DIGIT+ } @@ -342,7 +342,7 @@ block = { } statement_list = { - (statement | (unexpected_statement))* + statement* } statement = _{ @@ -456,7 +456,7 @@ array = { // MACROS // ------------------------------------------------------ -macro_inner_v = { +macro_inner_v = @{ string_lit | ("(" ~ macro_inner_v* ~ ")") | (!("(" | ")") ~ ANY) From 9da4a50ef51a53d2e64af5994a55ba657ebe1db0 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 11:07:49 +0200 Subject: [PATCH 14/15] Removed invalid statement --- mist-test/src/app.mist | 3 +-- parser/src/grammar.pest | 8 -------- parser/src/parser/common/expr.rs | 2 +- parser/src/parser/common/statement.rs | 11 +---------- 4 files changed, 3 insertions(+), 21 deletions(-) diff --git a/mist-test/src/app.mist b/mist-test/src/app.mist index 25f64b3..5c09745 100644 --- a/mist-test/src/app.mist +++ b/mist-test/src/app.mist @@ -14,8 +14,7 @@ pub class Application { i32 ticks; pub constructor(str* name) { - self.name; - + self.name = name.to_string(); self.tasks = new Vec(); self.plugins = new Vec(); diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index 9dbe487..3b08ce8 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -76,14 +76,6 @@ visibility = { "pub" ~ ("(" ~ static_path ~ ")")? } mutable = { "mut" } var = { "var" } -// ====================================================== -// ERROR RECOVERY -// ====================================================== - -unexpected_statement = { - (!(semicolon | "}" | statement) ~ ANY)+ -} - // ====================================================== // GENERICS // ====================================================== diff --git a/parser/src/parser/common/expr.rs b/parser/src/parser/common/expr.rs index 86dd684..de33878 100644 --- a/parser/src/parser/common/expr.rs +++ b/parser/src/parser/common/expr.rs @@ -78,7 +78,7 @@ impl<'a> TryFrom> for Expression { Rule::static_path => ast_expr!(Expression::Path(pair.try_into())), Rule::literal => ast_expr!(Expression::Literal(pair.try_into())), Rule::expr_path => ast_expr!(Expression::Path(pair.try_into())), - Rule::statement | Rule::basic_stmt | Rule::control_flow | Rule::unexpected_statement => ast_expr!( + Rule::statement | Rule::basic_stmt | Rule::control_flow => ast_expr!( Expression::Statement(pair.try_into().get_map(Box::new).map(Box::new)) ), diff --git a/parser/src/parser/common/statement.rs b/parser/src/parser/common/statement.rs index 8e4f4a4..516d32d 100644 --- a/parser/src/parser/common/statement.rs +++ b/parser/src/parser/common/statement.rs @@ -2,7 +2,7 @@ use crate::{ Rule, ast::*, ast_ensure, ast_expr, - error::{AstError, AstResult, ErrorCode, IntoErr, collect_recovered}, + error::{AstError, AstResult, IntoErr, collect_recovered}, parser::listen_rule, }; @@ -101,15 +101,6 @@ impl<'a> TryFrom> for Statement { .collect::>>(), )), - Rule::unexpected_statement => { - return Err(AstError { - span: pair.as_span(), - error_code: ErrorCode::InvalidStatement, - error_message: "Invalid Statement".to_string(), - recovered: None, - }); - } - _ => AstError::bug_unimplemented(pair), } } From 224b367ff16a4f9962b7303b70fba014f7d0b0b2 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Thu, 21 May 2026 11:10:44 +0200 Subject: [PATCH 15/15] Removed trailing semicolons --- src/codegen.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/codegen.rs b/src/codegen.rs index 3cb5ca7..cc22d83 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -613,7 +613,7 @@ impl ToRust for Statement { .map(|e| format!(" = {}", e.get_rust())) .unwrap_or_default(); - cg.add_indentedln(&format!("let {}{};", decl.get_rust(), init)); + cg.add_indentedln(&format!("let {}{}", decl.get_rust(), init)); } Statement::Match(expr, match_items) => { @@ -708,11 +708,11 @@ impl ToRust for Statement { Statement::Return(expr) => { let val = expr.map(|e| e.get_rust()).unwrap_or_default(); - cg.add_indentedln(&format!("return {};", val)); + cg.add_indentedln(&format!("return {}", val)); } - Statement::Break => cg.add_indentedln("break;"), - Statement::Continue => cg.add_indentedln("continue;"), + Statement::Break => cg.add_indentedln("break"), + Statement::Continue => cg.add_indentedln("continue"), } } }