Merge pull request #25 from mist-go/lifetimes-and-proper-tests
Lifetimes and proper tests
This commit is contained in:
+2
-2
@@ -26,5 +26,5 @@ target
|
||||
|
||||
/target
|
||||
|
||||
/test/build
|
||||
/test/output.json
|
||||
/mist-test/build
|
||||
/mist-test/output.json
|
||||
Generated
+7
@@ -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"
|
||||
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "mist-test"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[[bin]]
|
||||
name = "main"
|
||||
path = "build/main.rs"
|
||||
|
||||
[dependencies]
|
||||
@@ -0,0 +1,95 @@
|
||||
use <super::task>;
|
||||
use <super::logger>;
|
||||
use <super::event>;
|
||||
|
||||
public class Application {
|
||||
String name;
|
||||
|
||||
Vec<task::Task> tasks;
|
||||
Vec<String> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
public enum Event {
|
||||
Startup,
|
||||
Shutdown,
|
||||
TaskExecuted(String),
|
||||
PluginLoaded(String),
|
||||
Error(String),
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
public struct PluginInfo {
|
||||
public String name,
|
||||
public String version,
|
||||
}
|
||||
|
||||
public class PluginRegistry<T> {
|
||||
T plugins;
|
||||
|
||||
public constructor(T plugins) {
|
||||
self.plugins = plugins;
|
||||
}
|
||||
|
||||
public T plugins(self) {
|
||||
return self.plugins;
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
+10
-1
@@ -16,6 +16,8 @@ pub struct Block(pub Vec<Statement>);
|
||||
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<TypeExpr>),
|
||||
Tuple(Vec<TypeExpr>),
|
||||
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<Path>)>);
|
||||
pub struct Generics(pub Vec<Generic>);
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub enum Generic {
|
||||
Lifetime(Identifier),
|
||||
Type(Identifier, Vec<TypeExpr>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub enum Pattern {
|
||||
|
||||
+14
-5
@@ -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
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
|
||||
+29
-8
@@ -36,6 +36,11 @@ impl From<pest::iterators::Pair<'_, Rule>> 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<pest::iterators::Pair<'_, Rule>> for TypeExpr {
|
||||
impl From<pest::iterators::Pair<'_, Rule>> 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<pest::iterators::Pair<'_, Rule>> 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(),
|
||||
),
|
||||
|
||||
+45
-18
@@ -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::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
));
|
||||
cg.indent += 1;
|
||||
|
||||
let params_str = constructor
|
||||
@@ -393,6 +407,7 @@ impl ToRust for TopLevelKind {
|
||||
.collect::<Vec<_>>()
|
||||
.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::<Vec<_>>()
|
||||
.join("+")
|
||||
)
|
||||
}))
|
||||
.map(|v| (true, v).get_rust())
|
||||
.collect::<Vec<_>>()
|
||||
.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::<Vec<_>>()
|
||||
.join("+")
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_static_type_path(path: &Path) -> String {
|
||||
let rust_path = path.get_rust();
|
||||
|
||||
|
||||
+103
-49
@@ -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<PathBuf> {
|
||||
let mut dir = std::env::current_dir().ok()?;
|
||||
|
||||
@@ -87,9 +142,8 @@ pub fn find_project_root() -> Option<PathBuf> {
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
mod my_class;
|
||||
use <my_class::MyClass>;
|
||||
use <my_class::MyEnum>;
|
||||
|
||||
void main() {
|
||||
var my_class = new MyClass("World");
|
||||
my_class.greet();
|
||||
|
||||
match (MyEnum::Tuple(10, String::new())) {
|
||||
MyEnum::Tuple(i, _) => {
|
||||
println!("{i}");
|
||||
}
|
||||
MyEnum::Named => {
|
||||
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -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 }
|
||||
}
|
||||
Reference in New Issue
Block a user