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