+38
-10
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 => {
|
||||||
|
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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