diff --git a/parser/src/ast.rs b/parser/src/ast.rs index ca4ca2a..fe5845b 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -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); @@ -44,7 +47,7 @@ pub enum TypeExprKind { pub struct TypeExpr(pub TypeExprKind, pub Vec); #[derive(Debug, Clone, Serialize)] -pub struct Path(pub Vec); +pub struct Path(pub Vec); #[derive(Debug, Clone, Serialize)] pub enum BinaryOp { @@ -68,16 +71,16 @@ pub struct TopLevel(pub TopLevelKind, pub Vec); pub enum TopLevelKind { ModAttribute, Import(Path), - Mod(String), + Mod(Identifier), StructDecl { visibility: Visibility, - name: String, + name: Identifier, fields: FieldList, }, FunctionDecl(FunctionDecl), ClassDecl { visibility: Visibility, - name: String, + name: Identifier, fields: Vec, constructor: ClassConstructor, methods: Vec, @@ -94,7 +97,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, @@ -102,10 +105,10 @@ pub struct FunctionDecl { #[derive(Debug, Clone, Serialize)] pub enum Postfix { - FieldAccess(String), + FieldAccess(Identifier), Call(Vec), MacroCall(String), - StructCall(Vec<(String, Expression)>), + StructCall(Vec<(Identifier, Expression)>), Index(Expression), Binary(BinaryOp, Expression), } @@ -139,7 +142,7 @@ pub enum Statement { body: Box, }, For { - pattern: String, + pattern: Identifier, iterator: Expression, body: Box, }, @@ -152,7 +155,7 @@ pub enum Statement { #[derive(Debug, Clone, Serialize)] pub struct VarDecl { pub mutable: bool, - pub name: String, + pub name: Identifier, pub type_: Option, } diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 50f90e7..8b3783a 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -84,7 +84,7 @@ impl From> for TypeExprKind { impl From> 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> 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(); @@ -235,7 +235,7 @@ impl From> for TopLevelKind { 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> 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,7 +259,7 @@ impl From> for TopLevelKind { methods: inner.into_iter().map(FunctionDecl::from).collect(), }, - Rule::mod_package => TopLevelKind::Mod(inner.next().unwrap().as_str().to_string()), + Rule::mod_package => TopLevelKind::Mod(Identifier::from(inner.next().unwrap())), _ => unimplemented!("{rule:#?}"), } @@ -331,7 +331,7 @@ impl From> for Statement { }, Rule::for_stmt => Statement::For { - pattern: inner.next().unwrap().as_str().to_string(), + pattern: Identifier::from(inner.next().unwrap()), iterator: inner.next().unwrap().into(), body: Box::new(Statement::from(inner.next().unwrap())), }, @@ -419,10 +419,7 @@ impl From> 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()), @@ -431,7 +428,7 @@ impl From> 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()), ) }) @@ -502,7 +499,7 @@ impl From> for VarDecl { }); let mutable = listen_rule(&mut inner, Rule::mutable); - let name = inner.next().unwrap().as_str().to_string(); + let name = Identifier::from(inner.next().unwrap()); VarDecl { mutable, @@ -524,10 +521,10 @@ impl From> 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 = Identifier(String::from("self")); let mutable = listen_rule(&mut param_inner, Rule::mutable); @@ -535,9 +532,9 @@ impl From> for FunctionDecl { VarDecl { mutable: mutable && !is_ref, - name, + name: name.clone(), type_: Some(TypeExpr( - TypeExprKind::Path(Path(vec![format!("Self")])), + TypeExprKind::Path(Path(vec![name])), if is_ref { vec![if mutable { TypePostfix::RefMut @@ -610,3 +607,9 @@ pub fn consume_rule<'a>( if consumed { pairs.next() } else { None } } + +impl From> for Identifier { + fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self { + Identifier(pair.as_str().to_string()) + } +} diff --git a/src/codegen.rs b/src/codegen.rs index 66f8ad0..14c9982 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -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, Expression, FunctionDecl, Identifier, Literal, Path, Postfix, + Prefix, Statement, StatementBranch, TopLevel, TopLevelKind, TypeExpr, TypeExprKind, + TypePostfix, VarAssignStmt, VarDecl, VarDeclStmt, Visibility, }; // --------------------------------------------------------------------------- @@ -197,7 +197,7 @@ impl GetRust for Option<&Vec> { 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::>() .join(", "); format!("{{ {} }}", fields) @@ -309,19 +309,19 @@ impl ToRust for TopLevelKind { match self { Self::ModAttribute => {} Self::Import(path) => cg.addln(&format!("use {};", path.get_rust())), - Self::Mod(id) => cg.addln(&format!("mod {};", id)), + 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; @@ -335,19 +335,19 @@ 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 @@ -371,7 +371,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() )); } @@ -383,7 +383,7 @@ impl ToRust for TopLevelKind { .params .0 .iter() - .map(|e| e.name.to_string()) + .map(|e| e.name.get_rust()) .collect::>() .join(", ") )); @@ -501,7 +501,7 @@ impl ToRust for Statement { iterator, body, } => { - cg.add_indentedln(&format!("for {} in {}", pattern, iterator.get_rust())); + cg.add_indentedln(&format!("for {} in {}", pattern.get_rust(), iterator.get_rust())); cg.ensure_brackets(body); } @@ -529,7 +529,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() )); @@ -550,13 +550,13 @@ impl GetRust for VarDecl { .map(|t| format!(": {}", t.get_rust())) .unwrap_or_default(); - format!("{}{}{}", mutability, self.name, ty) + format!("{}{}{}", mutability, 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::>().join("::") } } @@ -579,6 +579,12 @@ impl GetRust for Visibility { } } +impl GetRust for Identifier { + fn get_rust(&self) -> String { + self.0.clone() + } +} + pub fn get_static_type_path(path: &Path) -> String { let rust_path = path.get_rust();