+38
-10
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 => {
|
||||
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
Reference in New Issue
Block a user