diff --git a/.gitignore b/.gitignore index 2112842..19a716d 100644 --- a/.gitignore +++ b/.gitignore @@ -26,5 +26,5 @@ target /target -/test/build -/test/output.json \ No newline at end of file +/mist-test/build +/mist-test/output.json \ No newline at end of file diff --git a/mist-test/Cargo.lock b/mist-test/Cargo.lock new file mode 100644 index 0000000..d594070 --- /dev/null +++ b/mist-test/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "mist-test" +version = "0.1.0" diff --git a/mist-test/Cargo.toml b/mist-test/Cargo.toml new file mode 100644 index 0000000..a02d622 --- /dev/null +++ b/mist-test/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "mist-test" +version = "0.1.0" +edition = "2024" + +[[bin]] +name = "main" +path = "build/main.rs" + +[dependencies] diff --git a/test/mist.json b/mist-test/mist.json similarity index 100% rename from test/mist.json rename to mist-test/mist.json diff --git a/mist-test/src/app.mist b/mist-test/src/app.mist new file mode 100644 index 0000000..3ffd4ec --- /dev/null +++ b/mist-test/src/app.mist @@ -0,0 +1,95 @@ +use ; +use ; +use ; + +public class Application { + String name; + + Vec tasks; + Vec plugins; + + logger::Logger logger; + + bool running; + i32 ticks; + + public 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; + } + + public void boot(self mut*) { + self.logger.info("booting application"); + + self.running = true; + + self.emit(event::Event::Startup); + } + + public 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 = self.ticks + 1; + + var task = task::create_task("background-job"); + + self.tasks.push(task); + + println!("tasks: {}", self.tasks.len()); + } + + public void shutdown(self mut*) { + self.emit(event::Event::Shutdown); + + self.logger.warning("shutdown"); + + self.running = false; + } + + public 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..2c5cdb2 --- /dev/null +++ b/mist-test/src/event.mist @@ -0,0 +1,7 @@ +public 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..94c4b4a --- /dev/null +++ b/mist-test/src/logger.mist @@ -0,0 +1,41 @@ +public enum LogLevel { + Info, + Warning, + Error, +} + +public class Logger { + String prefix; + + public constructor(str* prefix) { + self.prefix = prefix.to_string(); + } + + public void info(self*, str* message) { + self.log(LogLevel::Info, message); + } + + public void warning(self*, str* message) { + self.log(LogLevel::Warning, message); + } + + public void error(self*, str* message) { + self.log(LogLevel::Error, message); + } + + void log(self*, LogLevel level, str* message) { + match(level) { + LogLevel::Info => { + println!("[INFO] {} {}", self.prefix, message); + } + + LogLevel::Warning => { + println!("[WARN] {} {}", self.prefix, message); + } + + LogLevel::Error => { + println!("[ERROR] {} {}", self.prefix, message); + } + } + } +} diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist new file mode 100644 index 0000000..8b0ab54 --- /dev/null +++ b/mist-test/src/main.mist @@ -0,0 +1,15 @@ +mod app; +mod task; +mod plugin; +mod logger; +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 diff --git a/mist-test/src/plugin.mist b/mist-test/src/plugin.mist new file mode 100644 index 0000000..9a706f0 --- /dev/null +++ b/mist-test/src/plugin.mist @@ -0,0 +1,16 @@ +public struct PluginInfo { + public String name, + public String version, +} + +public class PluginRegistry { + T plugins; + + public constructor(T plugins) { + self.plugins = plugins; + } + + public 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..e3befaa --- /dev/null +++ b/mist-test/src/task.mist @@ -0,0 +1,20 @@ +public enum TaskState { + Pending, + Running, + Finished, + Failed, +} + +public struct Task { + public String name, + public TaskState state, + public i32 executions, +} + +public 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/ast.rs b/parser/src/ast.rs index ac6b1f0..db081d9 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -16,6 +16,8 @@ pub struct Block(pub Vec); pub enum TypePostfix { Ref, RefMut, + RefLifetime(Identifier), + RefMutLifetime(Identifier), } #[derive(Debug, Clone, Serialize)] @@ -41,6 +43,7 @@ pub enum TypeExprKind { Path(Path), PathParams(Path, Vec), Tuple(Vec), + Lifetime(Identifier), } #[derive(Debug, Clone, Serialize)] @@ -98,7 +101,13 @@ pub enum TopLevelKind { } #[derive(Debug, Clone, Serialize, Default)] -pub struct Generics(pub Vec<(Identifier, Vec)>); +pub struct Generics(pub Vec); + +#[derive(Debug, Clone, Serialize)] +pub enum Generic { + Lifetime(Identifier), + Type(Identifier, Vec), +} #[derive(Debug, Clone, Serialize)] pub enum Pattern { diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index c557e5d..5c6e8f7 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -55,7 +55,7 @@ var = { "var" } // ====================================================== // GENERICS // ====================================================== -generic = { identifier ~ (":" ~ static_path ~ ("+" ~ static_path)*)? } +generic = { lifetime | (identifier ~ (":" ~ type_expr_param ~ ("+" ~ type_expr_param)*)?) } generics = { "<" ~ (generic ~ ("," ~ generic)*)? ~ ">" } // ====================================================== @@ -67,17 +67,26 @@ tuple_type = { } path_type = { - static_path ~ ("<" ~ (type_expr ~ ("," ~ type_expr)*)? ~ ">")? + static_path ~ ("<" ~ (type_expr_param ~ ("," ~ type_expr_param)*)? ~ ">")? } ref_type = { - mutable? ~ "*" + mutable? ~ lifetime? ~ "*" } type_expr = { (path_type | tuple_type) ~ ref_type* } +lifetime = { + "'" ~ identifier +} + +type_expr_param = { + type_expr + | lifetime +} + // ====================================================== // LITERALS // ====================================================== @@ -224,7 +233,7 @@ self_param = { } method = { - export? ~ type_expr ~ identifier ~ generics? ~ "(" ~ self_param? ~ param_list? ~ ")" ~ block + export? ~ type_expr ~ identifier ~ generics? ~ "(" ~ self_param? ~ ("," ~ param_list?)? ~ ")" ~ block } class_decl = { @@ -263,7 +272,6 @@ statement_list = { statement = _{ expr_stmt | match_stmt - | var_decl_statement | assign_statement | if_stmt | while_stmt @@ -273,6 +281,7 @@ statement = _{ | break_stmt | continue_stmt | block + | var_decl_statement } // ------------------------------------------------------ diff --git a/parser/src/lib.rs b/parser/src/lib.rs index fa01570..e17057c 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -36,6 +36,11 @@ impl From> for TypeExpr { TypeExprKind::from(inner.next().unwrap()), inner.map(TypePostfix::from).collect(), ), + Rule::type_expr_param => TypeExpr::from(inner.next().unwrap()), + Rule::lifetime => TypeExpr( + TypeExprKind::Lifetime(Identifier::from(inner.next().unwrap())), + Vec::new(), + ), _ => unimplemented!("{rule:#?}"), } } @@ -44,14 +49,26 @@ impl From> for TypeExpr { impl From> for TypePostfix { fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self { let rule = pair.as_rule(); - let inner = pair.into_inner(); + let mut inner = pair.into_inner(); match rule { Rule::ref_type => { - if inner.peek().is_some() { - TypePostfix::RefMut + let mutable = listen_rule(&mut inner, Rule::mutable); + let lifetime = consume_rule(&mut inner, Rule::lifetime) + .map(|pair| Identifier::from(pair.into_inner().next().unwrap())); + + if mutable { + if let Some(lifetime) = lifetime { + TypePostfix::RefMutLifetime(lifetime) + } else { + TypePostfix::RefMut + } } else { - TypePostfix::Ref + if let Some(lifetime) = lifetime { + TypePostfix::RefLifetime(lifetime) + } else { + TypePostfix::Ref + } } } _ => unimplemented!("{rule:#?}"), @@ -238,10 +255,14 @@ impl From> for Generics { inner .map(|pair| { let mut inner = pair.into_inner(); - ( - Identifier::from(inner.next().unwrap()), - inner.map(Path::from).collect(), - ) + if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) { + Generic::Lifetime(Identifier::from(pair.into_inner().next().unwrap())) + } else { + Generic::Type( + Identifier::from(inner.next().unwrap()), + inner.map(TypeExpr::from).collect(), + ) + } }) .collect(), ), diff --git a/src/codegen.rs b/src/codegen.rs index 78299c7..437a99f 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -1,7 +1,7 @@ use parser::ast::{ - Attribute, BinaryOp, Block, EnumItem, Expression, FunctionDecl, Generics, Identifier, Literal, - Path, Pattern, Postfix, Prefix, Statement, StatementBranch, TopLevel, TopLevelKind, TypeExpr, - TypeExprKind, TypePostfix, VarAssignStmt, VarDecl, VarDeclStmt, Visibility, + Attribute, BinaryOp, Block, EnumItem, Expression, FunctionDecl, Generic, Generics, Identifier, + Literal, Path, Pattern, Postfix, Prefix, Statement, StatementBranch, TopLevel, TopLevelKind, + TypeExpr, TypeExprKind, TypePostfix, VarAssignStmt, VarDecl, VarDeclStmt, Visibility, }; // --------------------------------------------------------------------------- @@ -96,6 +96,7 @@ impl GetRust for TypeExprKind { fn get_rust(&self) -> String { match self { TypeExprKind::Path(path) => get_static_type_path(path), + TypeExprKind::Lifetime(name) => format!("'{}", name.get_rust()), TypeExprKind::PathParams(path, params) => { format!( "{}<{}>", @@ -382,7 +383,20 @@ impl ToRust for TopLevelKind { cg.addln("}\n"); // Constructor - cg.addln(&format!("impl {} {{", name.get_rust())); + cg.addln(&format!( + "impl{} {}{} {{", + generics.get_rust(), + name.get_rust(), + format!( + "<{}>", + generics + .0 + .iter() + .map(|v| (false, v).get_rust()) + .collect::>() + .join(", ") + ) + )); cg.indent += 1; let params_str = constructor @@ -393,6 +407,7 @@ impl ToRust for TopLevelKind { .collect::>() .join(", "); + cg.add_indentedln("#[allow(invalid_value)]"); cg.add_indentedln(&format!( "{}fn new{}({}) -> Self {{", constructor.visibility.get_rust(), @@ -633,6 +648,8 @@ impl GetRust for TypePostfix { match self { TypePostfix::Ref => format!("&"), TypePostfix::RefMut => format!("&mut "), + TypePostfix::RefLifetime(lifetime) => format!("&'{} ", lifetime.get_rust()), + TypePostfix::RefMutLifetime(lifetime) => format!("&'{} mut ", lifetime.get_rust()), } } } @@ -721,20 +738,7 @@ impl GetRust for Generics { "<{}>", self.0 .iter() - .map(|generic| generic.0.get_rust() - + &(if generic.1.len() == 0 { - String::new() - } else { - format!( - ": {}", - generic - .1 - .iter() - .map(Path::get_rust) - .collect::>() - .join("+") - ) - })) + .map(|v| (true, v).get_rust()) .collect::>() .join(", ") ) @@ -742,6 +746,29 @@ impl GetRust for Generics { } } +impl GetRust for (bool, &Generic) { + fn get_rust(&self) -> String { + match &self.1 { + Generic::Lifetime(name) => format!("'{}", name.get_rust()), + Generic::Type(name, requirements) => { + name.get_rust() + + &(if !self.0 && requirements.len() == 0 { + String::new() + } else { + format!( + ": {}", + requirements + .iter() + .map(TypeExpr::get_rust) + .collect::>() + .join("+") + ) + }) + } + } + } +} + pub fn get_static_type_path(path: &Path) -> String { let rust_path = path.get_rust(); diff --git a/src/compiler.rs b/src/compiler.rs index db5d31c..adb6e57 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -1,4 +1,9 @@ -use std::{fs, path::PathBuf, process, time::Instant}; +use std::{ + fs, + path::{Path, PathBuf}, + process, + time::Instant, +}; use serde::Deserialize; @@ -21,58 +26,108 @@ pub fn build() { // 2. load config let config = load_config(&root); - let src = root.join(&config.src); + let src_dir = root.join(&config.src); + let out_dir = root.join(&config.output); - for entry in fs::read_dir(src).unwrap() { - if let Ok(entry) = entry { - let entry_path = root.join(&entry.path()); - let out_dir = root.join(&config.output); - let file_name = entry.file_name(); - let file_name = file_name.to_string_lossy(); - - // 3. read entry file - let source = match fs::read_to_string(&entry_path) { - Ok(s) => s, - Err(e) => { - eprintln!("error: failed to read entry file\n {}", e); - process::exit(1); - } - }; - - let parser_result = parser::parse(&source).map_err(|e| e.to_string()); - - let ast = match parser_result { - Ok(ast) => ast, - Err(e) => { - eprintln!("error: parse failed\n{}", e); - process::exit(1); - } - }; - - // semantic::walk_ast(semantic::scope::Scope::from_top(&root, &ast), &mut ast); - - let mut gc = crate::codegen::RustCodegen::new(); - let output = gc.generate(&ast); - - if let Err(e) = fs::create_dir_all(&out_dir) { - eprintln!("error: failed to create build dir\n {}", e); - process::exit(1); - } - - let out_file = out_dir.join(file_name.replace(".mist", ".rs")); - - if let Err(e) = fs::write(&out_file, output) { - eprintln!("error: failed to write output\n {}", e); - process::exit(1); - } - } - } + build_dir(&root, &src_dir, &src_dir, &out_dir); let elapsed = start.elapsed(); println!("build finished in {:.2?}", elapsed); } +fn build_dir(root: &Path, base_src: &Path, current_dir: &Path, out_dir: &Path) { + let entries = match fs::read_dir(current_dir) { + Ok(entries) => entries, + Err(e) => { + eprintln!( + "error: failed to read directory {}\n {}", + current_dir.display(), + e + ); + + process::exit(1); + } + }; + + for entry in entries { + let entry = match entry { + Ok(entry) => entry, + Err(e) => { + eprintln!("error: failed to read directory entry\n {}", e); + + process::exit(1); + } + }; + + let path = entry.path(); + + // recurse into nested directories + if path.is_dir() { + build_dir(root, base_src, &path, out_dir); + continue; + } + + // skip non-mist files + if path.extension().and_then(|e| e.to_str()) != Some("mist") { + continue; + } + + let relative = path.strip_prefix(base_src).unwrap(); + + let output_path = out_dir.join(relative).with_extension("rs"); + + // create parent directories + if let Some(parent) = output_path.parent() { + if let Err(e) = fs::create_dir_all(parent) { + eprintln!( + "error: failed to create output directory {}\n {}", + parent.display(), + e + ); + + process::exit(1); + } + } + + // read source + let source = match fs::read_to_string(&path) { + Ok(s) => s, + Err(e) => { + eprintln!("error: failed to read file {}\n {}", path.display(), e); + + process::exit(1); + } + }; + + let parser_result = parser::parse(&source).map_err(|e| e.to_string()); + + let ast = match parser_result { + Ok(ast) => ast, + Err(e) => { + eprintln!("error: parse failed in {}\n{}", path.display(), e); + + process::exit(1); + } + }; + + // semantic::walk_ast(semantic::scope::Scope::from_top(root, &ast), &mut ast); + + let mut gc = crate::codegen::RustCodegen::new(); + let output = gc.generate(&ast); + + if let Err(e) = fs::write(&output_path, output) { + eprintln!( + "error: failed to write output {}\n {}", + output_path.display(), + e + ); + + process::exit(1); + } + } +} + pub fn find_project_root() -> Option { let mut dir = std::env::current_dir().ok()?; @@ -87,9 +142,8 @@ pub fn find_project_root() -> Option { } } -fn load_config(root: &std::path::Path) -> Config { - let content = - std::fs::read_to_string(root.join("mist.json")).expect("failed to read mist.json"); +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") } diff --git a/test/mist.map.json b/test/mist.map.json deleted file mode 100644 index 529a5df..0000000 --- a/test/mist.map.json +++ /dev/null @@ -1,450 +0,0 @@ -{ - "fmt": { - "package_name": "fmt", - "structs": {}, - "functions": { - "append": { - "export": true, - "name": "Append", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "b": { - "export": true, - "var_type": "[]byte", - "name": "b" - } - }, - "return_types": [ - "[]byte" - ] - }, - "appendf": { - "export": true, - "name": "Appendf", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "b": { - "export": true, - "var_type": "[]byte", - "name": "b" - }, - "format": { - "export": true, - "var_type": "string", - "name": "format" - } - }, - "return_types": [ - "[]byte" - ] - }, - "appendln": { - "export": true, - "name": "Appendln", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "b": { - "export": true, - "var_type": "[]byte", - "name": "b" - } - }, - "return_types": [ - "[]byte" - ] - }, - "errorf": { - "export": true, - "name": "Errorf", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "format": { - "export": true, - "var_type": "string", - "name": "format" - } - }, - "return_types": [ - "error" - ] - }, - "formatString": { - "export": true, - "name": "FormatString", - "params": { - "state": { - "export": true, - "var_type": "fmt.State", - "name": "state" - }, - "verb": { - "export": true, - "var_type": "rune", - "name": "verb" - } - }, - "return_types": [ - "string" - ] - }, - "fprint": { - "export": true, - "name": "Fprint", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "w": { - "export": true, - "var_type": "io.Writer", - "name": "w" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "fprintf": { - "export": true, - "name": "Fprintf", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "format": { - "export": true, - "var_type": "string", - "name": "format" - }, - "w": { - "export": true, - "var_type": "io.Writer", - "name": "w" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "fprintln": { - "export": true, - "name": "Fprintln", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "w": { - "export": true, - "var_type": "io.Writer", - "name": "w" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "fscan": { - "export": true, - "name": "Fscan", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "r": { - "export": true, - "var_type": "io.Reader", - "name": "r" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "fscanf": { - "export": true, - "name": "Fscanf", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "format": { - "export": true, - "var_type": "string", - "name": "format" - }, - "r": { - "export": true, - "var_type": "io.Reader", - "name": "r" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "fscanln": { - "export": true, - "name": "Fscanln", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "r": { - "export": true, - "var_type": "io.Reader", - "name": "r" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "print": { - "export": true, - "name": "Print", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "printf": { - "export": true, - "name": "Printf", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "format": { - "export": true, - "var_type": "string", - "name": "format" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "println": { - "export": true, - "name": "Println", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "scan": { - "export": true, - "name": "Scan", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "scanf": { - "export": true, - "name": "Scanf", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "format": { - "export": true, - "var_type": "string", - "name": "format" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "scanln": { - "export": true, - "name": "Scanln", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "sprint": { - "export": true, - "name": "Sprint", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - } - }, - "return_types": [ - "string" - ] - }, - "sprintf": { - "export": true, - "name": "Sprintf", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "format": { - "export": true, - "var_type": "string", - "name": "format" - } - }, - "return_types": [ - "string" - ] - }, - "sprintln": { - "export": true, - "name": "Sprintln", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - } - }, - "return_types": [ - "string" - ] - }, - "sscan": { - "export": true, - "name": "Sscan", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "str": { - "export": true, - "var_type": "string", - "name": "str" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "sscanf": { - "export": true, - "name": "Sscanf", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "format": { - "export": true, - "var_type": "string", - "name": "format" - }, - "str": { - "export": true, - "var_type": "string", - "name": "str" - } - }, - "return_types": [ - "int", - "error" - ] - }, - "sscanln": { - "export": true, - "name": "Sscanln", - "params": { - "a": { - "export": true, - "var_type": "[]any", - "name": "a" - }, - "str": { - "export": true, - "var_type": "string", - "name": "str" - } - }, - "return_types": [ - "int", - "error" - ] - } - } - } -} \ No newline at end of file diff --git a/test/src/main.mist b/test/src/main.mist deleted file mode 100644 index 602dd59..0000000 --- a/test/src/main.mist +++ /dev/null @@ -1,18 +0,0 @@ -mod my_class; -use ; -use ; - -void main() { - var my_class = new MyClass("World"); - my_class.greet(); - - match (MyEnum::Tuple(10, String::new())) { - MyEnum::Tuple(i, _) => { - println!("{i}"); - } - MyEnum::Named => { - - } - _ => {} - } -} diff --git a/test/src/my_class.mist b/test/src/my_class.mist deleted file mode 100644 index 7cc321d..0000000 --- a/test/src/my_class.mist +++ /dev/null @@ -1,17 +0,0 @@ -public class MyClass { - String message; - - public constructor(str* name) { - self.message = format!("Hello {}!", name); - } - - public void greet(self*) { - println!("{}", self.message); - } -} - -public enum MyEnum { - Named, - Tuple(i32, String), - Struct { i32 x } -}