Merge pull request #23 from mist-go/enums-matching

Enums matching
This commit is contained in:
2026-05-07 23:47:28 +02:00
committed by GitHub
6 changed files with 350 additions and 70 deletions
+38 -10
View File
@@ -1,7 +1,10 @@
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
pub struct FieldList(pub Vec<(String, Visibility, TypeExpr)>);
pub struct Identifier(pub String);
#[derive(Debug, Clone, Serialize)]
pub struct FieldList(pub Vec<(Identifier, Visibility, TypeExpr)>);
#[derive(Debug, Clone, Serialize)]
pub struct ParamList(pub Vec<VarDecl>);
@@ -44,7 +47,7 @@ pub enum TypeExprKind {
pub struct TypeExpr(pub TypeExprKind, pub Vec<TypePostfix>);
#[derive(Debug, Clone, Serialize)]
pub struct Path(pub Vec<String>);
pub struct Path(pub Vec<Identifier>);
#[derive(Debug, Clone, Serialize)]
pub enum BinaryOp {
@@ -67,22 +70,45 @@ pub struct TopLevel(pub TopLevelKind, pub Vec<Attribute>);
#[derive(Debug, Clone, Serialize)]
pub enum TopLevelKind {
ModAttribute,
Include(Path),
Import(Path),
Mod(Identifier),
EnumDecl {
visibility: Visibility,
name: Identifier,
fields: Vec<EnumItem>,
},
StructDecl {
visibility: Visibility,
name: String,
name: Identifier,
fields: FieldList,
},
FunctionDecl(FunctionDecl),
ClassDecl {
visibility: Visibility,
name: String,
name: Identifier,
fields: Vec<VarDeclStmt>,
constructor: ClassConstructor,
methods: Vec<FunctionDecl>,
},
}
#[derive(Debug, Clone, Serialize)]
pub enum Pattern {
NamedTuple(Path, Vec<Identifier>),
Struct(Path, Vec<Identifier>),
Tuple(Vec<Identifier>),
Literal(Literal),
Path(Path),
Id(Identifier),
}
#[derive(Debug, Clone, Serialize)]
pub enum EnumItem {
Named(Identifier),
Tuple(Identifier, Vec<TypeExpr>),
Struct(Identifier, FieldList),
}
#[derive(Debug, Clone, Serialize)]
pub struct ClassConstructor {
pub visibility: Visibility,
@@ -93,7 +119,7 @@ pub struct ClassConstructor {
#[derive(Debug, Clone, Serialize)]
pub struct FunctionDecl {
pub visibility: Visibility,
pub name: String,
pub name: Identifier,
pub params: ParamList,
pub return_type: TypeExpr,
pub body: Block,
@@ -101,10 +127,10 @@ pub struct FunctionDecl {
#[derive(Debug, Clone, Serialize)]
pub enum Postfix {
FieldAccess(String),
FieldAccess(Identifier),
Call(Vec<Expression>),
MacroCall(String),
StructCall(Vec<(String, Expression)>),
StructCall(Vec<(Identifier, Expression)>),
Index(Expression),
Binary(BinaryOp, Expression),
}
@@ -138,10 +164,12 @@ pub enum Statement {
body: Box<Statement>,
},
For {
pattern: String,
mutable: bool,
pattern: Pattern,
iterator: Expression,
body: Box<Statement>,
},
Match(Expression, Vec<(Pattern, Block)>),
Return(Option<Expression>),
Break,
@@ -151,7 +179,7 @@ pub enum Statement {
#[derive(Debug, Clone, Serialize)]
pub struct VarDecl {
pub mutable: bool,
pub name: String,
pub name: Pattern,
pub type_: Option<TypeExpr>,
}
+36 -8
View File
@@ -12,11 +12,16 @@ string_lit = { "\"" ~ inner_str ~ "\"" }
inner_str = @{ (!"\"" ~ ("\\\"" | ANY))* }
static_path = { identifier ~ ("::" ~ identifier)* }
// pattern
tuple_pattern = { "(" ~ (identifier ~ ("," ~ identifier)*)? ~ ")" }
named_tuple_pattern = { static_path ~ "(" ~ (identifier ~ ("," ~ identifier)*)? ~ ")" }
struct_pattern = { static_path ~ "{" ~ (identifier ~ ("," ~ identifier)*)? ~ "}" }
pattern = _{ named_tuple_pattern | tuple_pattern | struct_pattern | literal | static_path }
export = { "public" }
mutable = { "mut" }
sharp = _{ "#" }
var = { "var" }
var_decl = { (var | type_expr) ~ mutable? ~ identifier }
var_decl = { (var | type_expr) ~ mutable? ~ pattern }
semicolon = _{ ";" }
// ================= CLASS =================
@@ -33,12 +38,22 @@ method = {
}
class_decl = {
"class" ~ identifier ~ "{" ~ class_fields ~ class_constructor ~ method* ~ "}"
export? ~ "class" ~ identifier ~ "{" ~ class_fields ~ class_constructor ~ method* ~ "}"
}
// ================= TOP LEVEL =================
top_level = { (attributes ~ (import | function_decl | struct_decl | class_decl)) | mod_attribute }
enum_named = { identifier }
enum_tuple = { identifier ~ tuple_type }
enum_struct = { identifier ~ "{" ~ field_list ~ "}" }
enum_field = _{ enum_tuple | enum_struct | enum_named }
enum_fields = _{ enum_field ~ ("," ~ enum_field)* ~ ","? }
enum_decl = { export? ~ "enum" ~ identifier ~ "{" ~ enum_fields ~ "}" }
top_level = { (attributes ~ (import | function_decl | struct_decl | enum_decl | class_decl | mod_package)) | mod_attribute }
attribute = {
"#" ~ "[" ~ meta ~ "]"
@@ -49,7 +64,7 @@ mod_attribute = {
}
meta = {
static_path ~ ("=" ~ primary | "(" ~ meta_list? ~ ")")?
static_path ~ ("=" ~ literal | "(" ~ meta_list? ~ ")")?
}
meta_list = {
@@ -58,7 +73,9 @@ meta_list = {
attributes = { attribute* }
import = { sharp ~ "include" ~ "<" ~ static_path ~ ">" }
import = { "use" ~ "<" ~ static_path ~ ">" ~ semicolon }
mod_package = { "mod" ~ identifier ~ semicolon }
field_list = { field ~ ("," ~ field)* ~ ","? }
field = { export? ~ type_expr ~ identifier }
@@ -81,6 +98,7 @@ statement_list = { statement* }
statement = _{
expr_stmt
| match_stmt
| var_decl_statement
| assign_statement
| if_stmt
@@ -124,7 +142,13 @@ c_for_stmt = {
}
for_stmt = {
"for" ~ "(" ~ identifier ~ "in" ~ expr ~ ")" ~ statement
"for" ~ "(" ~ mutable? ~ pattern ~ "in" ~ expr ~ ")" ~ statement
}
match_item = { pattern ~ "=>" ~ block }
match_stmt = {
"match" ~ "(" ~ expr ~ ")" ~ "{" ~ match_item* ~ "}"
}
// ================= EXPRESSIONS =================
@@ -140,11 +164,15 @@ macro_inner_v = {
tuple = { "(" ~ (expr ~ ("," ~ expr)*)? ~ ")" }
primary = {
literal = {
float
| integer
| boolean
| string_lit
}
primary = {
literal
| static_path
| tuple
}
+100 -19
View File
@@ -84,7 +84,7 @@ impl From<pest::iterators::Pair<'_, Rule>> for TypeExprKind {
impl From<pest::iterators::Pair<'_, Rule>> for Path {
fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
match pair.as_rule() {
Rule::static_path => Path(pair.into_inner().map(|i| i.as_str().to_string()).collect()),
Rule::static_path => Path(pair.into_inner().map(Identifier::from).collect()),
_ => unimplemented!("{pair:#?}"),
}
}
@@ -98,7 +98,7 @@ impl From<pest::iterators::Pair<'_, Rule>> for FieldList {
let mut param_inner = p.into_inner();
let visibility = Visibility::from(&mut param_inner);
let param_type = TypeExpr::from(param_inner.next().unwrap());
let param_name = param_inner.next().unwrap().as_str().to_string();
let param_name = Identifier::from(param_inner.next().unwrap());
(param_name, visibility, param_type)
})
.collect();
@@ -229,13 +229,13 @@ impl From<pest::iterators::Pair<'_, Rule>> for TopLevelKind {
let mut inner = pair.clone().into_inner();
match rule {
Rule::import => TopLevelKind::Include(Path::from(inner.next().unwrap())),
Rule::import => TopLevelKind::Import(Path::from(inner.next().unwrap())),
Rule::function_decl => TopLevelKind::FunctionDecl(FunctionDecl::from(pair)),
Rule::struct_decl => {
let visibility = Visibility::from(&mut inner);
let name = inner.next().unwrap().as_str().to_string();
let name = Identifier::from(inner.next().unwrap());
let fields_pair = inner.next().unwrap();
let fields = FieldList::from(fields_pair);
@@ -248,7 +248,7 @@ impl From<pest::iterators::Pair<'_, Rule>> for TopLevelKind {
Rule::class_decl => TopLevelKind::ClassDecl {
visibility: Visibility::from(&mut inner),
name: inner.next().unwrap().as_str().to_string(),
name: Identifier::from(inner.next().unwrap()),
fields: inner
.next()
.unwrap()
@@ -259,6 +259,42 @@ impl From<pest::iterators::Pair<'_, Rule>> for TopLevelKind {
methods: inner.into_iter().map(FunctionDecl::from).collect(),
},
Rule::enum_decl => TopLevelKind::EnumDecl {
visibility: Visibility::from(&mut inner),
name: Identifier::from(inner.next().unwrap()),
fields: inner.map(EnumItem::from).collect(),
},
Rule::mod_package => TopLevelKind::Mod(Identifier::from(inner.next().unwrap())),
_ => unimplemented!("{rule:#?}"),
}
}
}
impl From<pest::iterators::Pair<'_, Rule>> for EnumItem {
fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
let rule = pair.as_rule();
let mut inner = pair.clone().into_inner();
match rule {
Rule::enum_named => EnumItem::Named(Identifier::from(inner.next().unwrap())),
Rule::enum_tuple => EnumItem::Tuple(
Identifier::from(inner.next().unwrap()),
inner
.next()
.unwrap()
.into_inner()
.map(TypeExpr::from)
.collect(),
),
Rule::enum_struct => EnumItem::Struct(
Identifier::from(inner.next().unwrap()),
FieldList::from(inner.next().unwrap()),
),
_ => unimplemented!("{rule:#?}"),
}
}
@@ -329,7 +365,8 @@ impl From<pest::iterators::Pair<'_, Rule>> for Statement {
},
Rule::for_stmt => Statement::For {
pattern: inner.next().unwrap().as_str().to_string(),
mutable: listen_rule(&mut inner, Rule::mutable),
pattern: Pattern::from(inner.next().unwrap()),
iterator: inner.next().unwrap().into(),
body: Box::new(Statement::from(inner.next().unwrap())),
},
@@ -339,6 +376,19 @@ impl From<pest::iterators::Pair<'_, Rule>> for Statement {
value: Expression::from(inner.next().unwrap()),
}),
Rule::match_stmt => Statement::Match(
Expression::from(inner.next().unwrap()),
inner
.map(|match_itms| {
let mut match_inner = match_itms.into_inner();
(
Pattern::from(match_inner.next().unwrap()),
Block::from(match_inner.next().unwrap()),
)
})
.collect(),
),
_ => unimplemented!("{rule:#?}"),
}
}
@@ -351,6 +401,7 @@ impl From<pest::iterators::Pair<'_, Rule>> for Literal {
match rule {
Rule::primary => Self::from(inner.next().unwrap()),
Rule::literal => Self::from(inner.next().unwrap()),
Rule::integer => Literal::Int(pair.as_str().parse::<i64>().unwrap()),
Rule::float => Literal::Float(pair.as_str().parse::<f64>().unwrap()),
Rule::boolean => Literal::Bool(pair.as_str().parse::<bool>().unwrap()),
@@ -387,9 +438,7 @@ impl From<pest::iterators::Pair<'_, Rule>> for Expression {
}
Rule::primary => Expression::from(inner.next().unwrap()),
Rule::static_path => Expression::Path(Path::from(pair)),
Rule::integer | Rule::float | Rule::boolean | Rule::string_lit | Rule::tuple => {
Expression::Literal(Literal::from(pair))
}
Rule::literal => Expression::Literal(Literal::from(pair)),
_ => unimplemented!("{rule:#?}"),
}
}
@@ -417,10 +466,7 @@ impl From<pest::iterators::Pair<'_, Rule>> for Postfix {
match rule {
Rule::postfix => Postfix::from(inner.next().unwrap()),
Rule::field_px => {
let field_name = inner.next().unwrap().as_str().to_string();
Postfix::FieldAccess(field_name)
}
Rule::field_px => Postfix::FieldAccess(Identifier::from(inner.next().unwrap())),
Rule::call_px => Postfix::Call(inner.map(Expression::from).collect()),
@@ -429,7 +475,7 @@ impl From<pest::iterators::Pair<'_, Rule>> for Postfix {
.map(|p| {
let mut pi = p.into_inner();
(
pi.next().unwrap().as_str().to_string(),
Identifier::from(pi.next().unwrap()),
Expression::from(pi.next().unwrap()),
)
})
@@ -485,6 +531,35 @@ impl From<pest::iterators::Pair<'_, Rule>> for VarDeclStmt {
}
}
impl From<pest::iterators::Pair<'_, Rule>> for Pattern {
fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
let rule = pair.as_rule();
let mut inner = pair.clone().into_inner();
match rule {
Rule::tuple_pattern => Pattern::Tuple(inner.map(Identifier::from).collect()),
Rule::named_tuple_pattern => Pattern::NamedTuple(
Path::from(inner.next().unwrap()),
inner.map(Identifier::from).collect(),
),
Rule::struct_pattern => Pattern::Struct(
Path::from(inner.next().unwrap()),
inner.map(Identifier::from).collect(),
),
Rule::literal => Pattern::Literal(Literal::from(pair)),
Rule::identifier => Pattern::Id(Identifier::from(pair)),
Rule::static_path => Pattern::Path(Path::from(pair)),
_ => unimplemented!("{rule:?}"),
}
}
}
impl From<pest::iterators::Pair<'_, Rule>> for VarDecl {
fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
match pair.as_rule() {
@@ -500,7 +575,7 @@ impl From<pest::iterators::Pair<'_, Rule>> for VarDecl {
});
let mutable = listen_rule(&mut inner, Rule::mutable);
let name = inner.next().unwrap().as_str().to_string();
let name = Pattern::from(inner.next().unwrap());
VarDecl {
mutable,
@@ -522,10 +597,10 @@ impl From<pest::iterators::Pair<'_, Rule>> for FunctionDecl {
let return_type = TypeExpr::from(inner.next().unwrap());
let name = inner.next().unwrap().as_str().to_string();
let name = Identifier::from(inner.next().unwrap());
let self_param = consume_rule(&mut inner, Rule::self_param).map(|param| {
let mut param_inner = param.into_inner();
let name = format!("self");
let name = Pattern::Id(Identifier(String::from("self")));
let mutable = listen_rule(&mut param_inner, Rule::mutable);
@@ -533,9 +608,9 @@ impl From<pest::iterators::Pair<'_, Rule>> for FunctionDecl {
VarDecl {
mutable: mutable && !is_ref,
name,
name: name.clone(),
type_: Some(TypeExpr(
TypeExprKind::Path(Path(vec![format!("Self")])),
TypeExprKind::Path(Path(vec![Identifier("Self".to_string())])),
if is_ref {
vec![if mutable {
TypePostfix::RefMut
@@ -608,3 +683,9 @@ pub fn consume_rule<'a>(
if consumed { pairs.next() } else { None }
}
impl From<pest::iterators::Pair<'_, Rule>> for Identifier {
fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
Identifier(pair.as_str().to_string())
}
}
+146 -21
View File
@@ -1,7 +1,7 @@
use parser::ast::{
Attribute, BinaryOp, Block, Expression, FunctionDecl, Literal, Path, Postfix, Prefix,
Statement, StatementBranch, TopLevel, TopLevelKind, TypeExpr, TypeExprKind, TypePostfix,
VarAssignStmt, VarDecl, VarDeclStmt, Visibility,
Attribute, BinaryOp, Block, EnumItem, Expression, FunctionDecl, Identifier, Literal, Path,
Pattern, Postfix, Prefix, Statement, StatementBranch, TopLevel, TopLevelKind, TypeExpr,
TypeExprKind, TypePostfix, VarAssignStmt, VarDecl, VarDeclStmt, Visibility,
};
// ---------------------------------------------------------------------------
@@ -197,7 +197,7 @@ impl GetRust for Option<&Vec<Prefix>> {
impl GetRust for Postfix {
fn get_rust(&self) -> String {
match self {
Postfix::FieldAccess(field) => format!(".{}", field),
Postfix::FieldAccess(field) => format!(".{}", field.get_rust()),
Postfix::Call(args) => {
let args = args
@@ -215,7 +215,7 @@ impl GetRust for Postfix {
Postfix::StructCall(fields) => {
let fields = fields
.iter()
.map(|(k, v)| format!("{}: {}", k, v.get_rust()))
.map(|(k, v)| format!("{}: {}", k.get_rust(), v.get_rust()))
.collect::<Vec<_>>()
.join(", ");
format!("{{ {} }}", fields)
@@ -308,21 +308,43 @@ impl ToRust for TopLevelKind {
fn to_rust(&self, cg: &mut RustCodegen) {
match self {
Self::ModAttribute => {}
Self::Include(path) => {
cg.addln(&format!("use {};", path.get_rust()));
}
Self::Import(path) => cg.addln(&format!("use {};", path.get_rust())),
Self::Mod(id) => cg.addln(&format!("mod {};", id.get_rust())),
Self::FunctionDecl(decl) => decl.to_rust(cg),
Self::StructDecl {
visibility,
name,
fields,
} => {
cg.addln(&format!("{}struct {} {{", visibility.get_rust(), name));
cg.addln(&format!(
"{}struct {} {{",
visibility.get_rust(),
name.get_rust()
));
cg.indent += 1;
for (field_name, _, ty) in &fields.0 {
let ty = ty.get_rust();
cg.add_indentedln(&format!("pub {}: {},", field_name, ty));
cg.add_indentedln(&format!("pub {}: {},", field_name.get_rust(), ty));
}
cg.indent -= 1;
cg.addln("}\n");
}
Self::EnumDecl {
visibility,
name,
fields,
} => {
cg.addln(&format!(
"{}enum {} {{",
visibility.get_rust(),
name.get_rust()
));
cg.indent += 1;
for field in fields {
cg.add_indentedln(&(format!("{}", field.get_rust()) + ","));
}
cg.indent -= 1;
@@ -336,19 +358,23 @@ impl ToRust for TopLevelKind {
methods,
} => {
// Struct decl
cg.addln(&format!("{}struct {} {{", visibility.get_rust(), name));
cg.addln(&format!(
"{}struct {} {{",
visibility.get_rust(),
name.get_rust()
));
cg.indent += 1;
for field in fields {
let ty = field.decl.type_.clone().unwrap().get_rust();
cg.add_indentedln(&format!("pub {}: {},", field.decl.name, ty));
cg.add_indentedln(&format!("pub {}: {},", field.decl.name.get_rust(), ty));
}
cg.indent -= 1;
cg.addln("}\n");
// Constructor
cg.addln(&format!("impl {} {{", name));
cg.addln(&format!("impl {} {{", name.get_rust()));
cg.indent += 1;
let params_str = constructor
@@ -372,7 +398,7 @@ impl ToRust for TopLevelKind {
if let Some(init) = &field.init {
cg.add_indentedln(&format!(
"this.{} = {};",
field.decl.name,
field.decl.name.get_rust(),
init.get_rust()
));
}
@@ -384,7 +410,7 @@ impl ToRust for TopLevelKind {
.params
.0
.iter()
.map(|e| e.name.to_string())
.map(|e| e.name.get_rust())
.collect::<Vec<_>>()
.join(", ")
));
@@ -446,6 +472,23 @@ impl ToRust for Statement {
cg.add_indentedln(&format!("{} = {};", target.get_rust(), value.get_rust(),));
}
Statement::Match(expr, match_items) => {
cg.add_indentedln(&format!("match {} {{", expr.get_rust()));
cg.indent += 1;
for itm in match_items {
cg.add_indentedln(&format!("{} =>", itm.0.get_rust()));
cg.add_indentedln("{");
cg.indent += 1;
itm.1.to_rust(cg);
cg.indent -= 1;
cg.add_indentedln("}");
}
cg.indent -= 1;
cg.add_indentedln("}");
}
Statement::If {
initial,
else_if,
@@ -498,11 +541,17 @@ impl ToRust for Statement {
}
Statement::For {
mutable,
pattern,
iterator,
body,
} => {
cg.add_indentedln(&format!("for {} in {}", pattern, iterator.get_rust()));
cg.add_indentedln(&format!(
"for {}{} in {}",
get_mutable(*mutable),
pattern.get_rust(),
iterator.get_rust()
));
cg.ensure_brackets(body);
}
@@ -530,7 +579,7 @@ impl ToRust for FunctionDecl {
cg.add_indentedln(&format!(
"{}fn {}({}) -> {} {{",
self.visibility.get_rust(),
self.name,
self.name.get_rust(),
params_str,
self.return_type.get_rust()
));
@@ -543,21 +592,28 @@ impl ToRust for FunctionDecl {
impl GetRust for VarDecl {
fn get_rust(&self) -> String {
let mutability = if self.mutable { "mut " } else { "" };
let ty = self
.type_
.as_ref()
.map(|t| format!(": {}", t.get_rust()))
.unwrap_or_default();
format!("{}{}{}", mutability, self.name, ty)
format!(
"{}{}{}",
get_mutable(self.mutable),
self.name.get_rust(),
ty
)
}
}
impl GetRust for Path {
fn get_rust(&self) -> String {
self.0.join("::")
self.0
.iter()
.map(Identifier::get_rust)
.collect::<Vec<String>>()
.join("::")
}
}
@@ -580,6 +636,71 @@ impl GetRust for Visibility {
}
}
impl GetRust for Identifier {
fn get_rust(&self) -> String {
self.0.clone()
}
}
impl GetRust for EnumItem {
fn get_rust(&self) -> String {
match self {
Self::Named(id) => id.get_rust(),
Self::Struct(id, s) => format!(
"{} {{{}}}",
id.get_rust(),
s.0.iter()
.map(|(id, _, ty)| format!("{}: {}", id.get_rust(), ty.get_rust()))
.collect::<Vec<_>>()
.join(", ")
),
Self::Tuple(id, t) => format!(
"{} ({})",
id.get_rust(),
t.iter()
.map(TypeExpr::get_rust)
.collect::<Vec<_>>()
.join(", ")
),
}
}
}
impl GetRust for Pattern {
fn get_rust(&self) -> String {
match self {
Self::Id(id) => id.get_rust(),
Self::Path(path) => path.get_rust(),
Self::Literal(lit) => lit.get_rust(),
Self::Struct(path, ids) => format!(
"{} {{{}}}",
path.get_rust(),
ids.iter()
.map(Identifier::get_rust)
.collect::<Vec<_>>()
.join(", ")
),
Self::Tuple(ids) => format!(
"({})",
ids.iter()
.map(Identifier::get_rust)
.collect::<Vec<_>>()
.join(", ")
),
Self::NamedTuple(path, ids) => {
format!(
"{} ({})",
path.get_rust(),
ids.iter()
.map(Identifier::get_rust)
.collect::<Vec<_>>()
.join(", ")
)
}
}
}
}
pub fn get_static_type_path(path: &Path) -> String {
let rust_path = path.get_rust();
@@ -593,3 +714,7 @@ pub fn get_static_type_path(path: &Path) -> String {
pub fn get_type_postfixes(postfixes: &[TypePostfix]) -> String {
postfixes.iter().map(TypePostfix::get_rust).collect()
}
pub fn get_mutable(mutable: bool) -> String {
if mutable { "mut " } else { "" }.to_string()
}
+13 -12
View File
@@ -1,17 +1,18 @@
class MyClass {
String message;
public constructor(str* name) {
self.message = format!("Hello {}!", name);
}
public void greet(self*) {
println!("{}", self.message);
}
}
mod my_class;
use <my_class::MyClass>;
use <my_class::MyEnum>;
void main() {
var my_class = new MyClass("World");
my_class.greet();
var x = 1 + 2 + 3;
match (MyEnum::Tuple(10, String::new())) {
MyEnum::Tuple(i, _) => {
println!("{i}");
}
MyEnum::Named => {
}
_ => {}
}
}
+17
View File
@@ -0,0 +1,17 @@
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 }
}