diff --git a/analyzer/src/lib.rs b/analyzer/src/lib.rs index eb3e52c..cb1f168 100644 --- a/analyzer/src/lib.rs +++ b/analyzer/src/lib.rs @@ -31,7 +31,7 @@ impl LanguageServer for Backend { .await; } - async fn completion(&self, params: CompletionParams) -> Result> { + async fn completion(&self, _params: CompletionParams) -> Result> { self.client .log_message(MessageType::INFO, "getting completion") .await; diff --git a/codegen/src/expr.rs b/codegen/src/expr.rs index 6a23e14..a0e2b10 100644 --- a/codegen/src/expr.rs +++ b/codegen/src/expr.rs @@ -4,6 +4,29 @@ use crate::Context; use crate::{GenRust, GetRust, RustCodegen}; +impl GetRust for ExprPath { + fn get_rust(&self) -> String { + self.0 + .iter() + .map(ExprPathSegment::get_rust) + .collect::>() + .join("::") + } +} + +impl GetRust for ExprPathSegment { + fn get_rust(&self) -> String { + format!( + "{}{}", + self.ident.get_rust(), + self.generics + .as_ref() + .map(|v| format!("::{}", v.get_rust())) + .unwrap_or_default() + ) + } +} + impl GenRust for Literal { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { match self { @@ -46,8 +69,8 @@ impl GenRust for Literal { impl GenRust for Expression { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { match self { - Expression::Path(path) => unimplemented!(), - Expression::Literal(literal) => unimplemented!(), + Expression::Path(path) => cg.add(&path.get_rust()), + Expression::Literal(literal) => literal.gen_rust(ctx, cg), Expression::Statement(stmt) => stmt.gen_rust(ctx, cg), Expression::Fix { initial, diff --git a/src/_header.rs b/src/_header.rs index c8b912b..749d126 100644 --- a/src/_header.rs +++ b/src/_header.rs @@ -1,5 +1,4 @@ pub mod builder; -pub mod codegen; pub mod transpiler; fn main() {} diff --git a/src/codegen.rs b/src/codegen.rs deleted file mode 100644 index d449efd..0000000 --- a/src/codegen.rs +++ /dev/null @@ -1,730 +0,0 @@ -use mist_parser::ast::{ - Attribute, Block, ClassItem, EnumItem, ExprPath, ExprPathSegment, Expression, FieldDecl, - FunctionDecl, Generic, GenericDecl, Generics, GenericsDecl, Identifier, ImplDecl, Literal, - Path, Pattern, Postfix, Prefix, Spanned, Statement, StatementBranch, TopLevel, TopLevelKind, - TypeExpr, TypeExprKind, TypePostfix, VarDecl, VarDeclStmt, Visibility, -}; - -// --------------------------------------------------------------------------- -// Traits -// --------------------------------------------------------------------------- - -/// Implemented by nodes that *write* into the codegen output buffer. -/// Requires `&mut RustCodegen` because it calls `add` / `addln` / indentation helpers. -pub trait ToRust { - fn to_rust(self, cg: &mut RustCodegen); -} - -/// Implemented by nodes that *produce* a `String` without mutating the codegen. -/// Only needs `&RustCodegen` (e.g. for indent level or helper access). -pub trait GetRust { - fn get_rust(self) -> String; -} - -// --------------------------------------------------------------------------- -// Codegen struct -// --------------------------------------------------------------------------- - -pub struct RustCodegen { - output: String, - indent: usize, -} - -impl RustCodegen { - pub fn new() -> Self { - Self { - output: String::new(), - indent: 0, - } - } - - fn indent_str(&self) -> String { - " ".repeat(self.indent) - } - - fn add(&mut self, s: &str) { - self.output.push_str(s); - } - - fn addln(&mut self, s: &str) { - self.add(s); - self.add("\n"); - } - - fn add_indentedln(&mut self, s: &str) { - let line = format!("{}{}\n", self.indent_str(), s); - self.add(&line); - } - - pub fn generate(&mut self, toplevels: Vec) -> String { - for tl in toplevels { - tl.to_rust(self); - } - - self.output.clone() - } - - pub fn ensure_brackets(&mut self, stmt: Box) { - match *stmt { - Statement::Block(_) => stmt.to_rust(self), - _ => { - self.add_indentedln("{"); - self.indent += 1; - stmt.to_rust(self); - self.indent -= 1; - self.add_indentedln("}"); - } - } - } -} - -impl Default for RustCodegen { - fn default() -> Self { - Self::new() - } -} - -// --------------------------------------------------------------------------- -// GetRust — pure string production (expressions, types) -// --------------------------------------------------------------------------- - -impl GetRust for Spanned { - fn get_rust(self) -> String { - format!( - "/* {}:{} */ {}", - self.line, - self.column, - self.item.get_rust() - ) - } -} - -impl GetRust for TypeExpr { - fn get_rust(self) -> String { - get_type_postfixes(self.1) + &self.0.get_rust() - } -} - -impl GetRust for TypeExprKind { - fn get_rust(self) -> String { - match self { - TypeExprKind::Path(path) => get_static_type_path(path), - TypeExprKind::Lifetime(name) => format!("'{}", name.get_rust()), - TypeExprKind::PathParams(path, params) => { - format!( - "{}<{}>", - get_static_type_path(path), - params - .into_iter() - .map(|t| t.get_rust()) - .collect::>() - .join(", ") - ) - } - TypeExprKind::Tuple(types) => format!( - "({})", - types - .into_iter() - .map(|t| t.get_rust()) - .collect::>() - .join(", ") - ), - } - } -} - -impl GetRust for Expression { - fn get_rust(self) -> String { - match self { - Expression::Path(path) => path.get_rust(), - Expression::Literal(literal) => literal.get_rust(), - Expression::Statement(stmt) => { - let mut cg = RustCodegen::new(); - cg.indent += 1; - stmt.to_rust(&mut cg); - cg.output - } - Expression::Fix { - initial, - prefixes, - postfixes, - } => { - prefixes.clone().get_rust() - + &initial.get_rust() - + &Some(prefixes).get_rust() - + &postfixes.get_rust() - } - // Safely integrated to handle the tree structure built by the Pratt Parser - Expression::Binary { lhs, op, rhs } => { - format!("{} {} {}", lhs.get_rust(), op, rhs.get_rust()) - } - } - } -} - -impl GetRust for Prefix { - fn get_rust(self) -> String { - match self { - Self::Deref => "*", - Self::Ref => "&", - Self::RefMut => "&mut ", - Self::Not => "!", - Self::New(_) => "", - Self::Neg => "-", - } - .to_string() - } -} - -impl GetRust for Vec { - fn get_rust(self) -> String { - self.into_iter().map(Prefix::get_rust).collect() - } -} - -impl GetRust for ExprPath { - fn get_rust(self) -> String { - self.0 - .into_iter() - .map(ExprPathSegment::get_rust) - .collect::>() - .join("::") - } -} - -impl GetRust for ExprPathSegment { - fn get_rust(self) -> String { - format!( - "{}{}", - self.ident.get_rust(), - self.generics - .map(|v| format!("::{}", v.get_rust())) - .unwrap_or_default() - ) - } -} - -impl GetRust for Option> { - fn get_rust(self) -> String { - self.map(|prefixes| { - prefixes - .into_iter() - .last() - .map(|p| match p { - Prefix::New(generics) => format!( - "::new{}", - generics - .map(|v| format!("::{}", v.get_rust())) - .unwrap_or_default(), - ), - _ => String::new(), - }) - .unwrap_or_default() - .to_string() - }) - .unwrap_or_default() - } -} - -impl GetRust for Postfix { - fn get_rust(self) -> String { - match self { - Postfix::FieldAccess(field, generics) => format!( - ".{}{}", - field.get_rust(), - generics - .map(|v| format!("::{}", v.get_rust())) - .unwrap_or_default() - ), - - Postfix::Call(args) => { - let args = args - .into_iter() - .map(|a| a.get_rust()) - .collect::>() - .join(", "); - format!("({})", args) - } - - Postfix::MacroCall(inner) => { - format!("!({})", inner) - } - - Postfix::StructCall(fields) => { - let fields = fields - .into_iter() - .map(|(k, v)| format!("{}: {}", k.get_rust(), v.get_rust())) - .collect::>() - .join(", "); - format!("{{ {} }}", fields) - } - - Postfix::Index(idx) => { - format!("[{}]", idx.get_rust()) - } - - Postfix::As(ty) => format!(" as {}", ty.get_rust()), - - Postfix::Try => String::from("?"), - - Postfix::Assign(cmp, expr) => format!("{cmp} {}", expr.get_rust()), - Postfix::Increment => "+=1".to_string(), - Postfix::Decrement => "-=1".to_string(), - } - } -} - -impl GetRust for Vec { - fn get_rust(self) -> String { - self.into_iter().map(Postfix::get_rust).collect() - } -} -// --------------------------------------------------------------------------- -// ToRust — output-writing (top-level, statements, blocks) -// --------------------------------------------------------------------------- - -impl ToRust for Spanned { - fn to_rust(self, cg: &mut RustCodegen) { - cg.add_indentedln(&format!("/* {}:{} */", self.line, self.column)); - self.item.to_rust(cg); - } -} - -impl ToRust for Block { - fn to_rust(self, cg: &mut RustCodegen) { - for stmt in self.0 { - cg.add_indentedln(&(stmt.get_rust() + ";")); - } - - if let Some(soft_return) = self.1 { - cg.add_indentedln(&soft_return.get_rust()); - } - } -} - -impl ToRust for TopLevel { - fn to_rust(self, cg: &mut RustCodegen) { - if let TopLevelKind::ModAttribute = self.0.item { - for attr in self.1 { - cg.addln(&format!("#![{}]", attr.get_rust())); - } - } else { - for attr in self.1 { - cg.addln(&format!("#[{}]", attr.get_rust())); - } - } - - self.0.to_rust(cg); - } -} - -impl GetRust for Attribute { - fn get_rust(self) -> String { - match self { - Self::Path(path) => path.get_rust(), - Self::NameValue { path, value } => { - format!("{} = {}", path.get_rust(), value.get_rust()) - } - Self::List { path, items } => { - format!( - "{}({})", - path.get_rust(), - items - .into_iter() - .map(Attribute::get_rust) - .collect::>() - .join(", ") - ) - } - } - } -} - -impl ToRust for Statement { - fn to_rust(self, cg: &mut RustCodegen) { - match self { - Statement::Block(block) => { - cg.add_indentedln("{"); - cg.indent += 1; - block.to_rust(cg); - cg.indent -= 1; - cg.add_indentedln("}"); - } - - Statement::VarDecl(VarDeclStmt { decl, init }) => { - let init = init - .map(|e| format!(" = {}", e.get_rust())) - .unwrap_or_default(); - - cg.add_indentedln(&format!("let {}{}", decl.get_rust(), init)); - } - - 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 - .into_iter() - .map(Pattern::get_rust) - .collect::>() - .join(" | ") - )); - 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, - else_branch, - } => { - cg.add_indentedln(&format!("if {}", initial.condition.get_rust())); - cg.ensure_brackets(initial.body); - - for else_if_branch in else_if { - cg.add_indentedln(&format!("else if {}", else_if_branch.condition.get_rust())); - cg.ensure_brackets(else_if_branch.body); - } - - if let Some(else_br) = else_branch { - cg.add_indentedln("else"); - cg.ensure_brackets(else_br); - } - } - - Statement::While(StatementBranch { condition, body }) => { - cg.add_indentedln(&format!("while {}", condition.get_rust())); - cg.ensure_brackets(body); - } - - Statement::CStyleFor { - init, - condition, - update, - body, - } => { - cg.add_indentedln("{"); - cg.indent += 1; - - init.to_rust(cg); - - cg.add_indentedln(&format!("while {}", condition.get_rust())); - - cg.add_indentedln("{"); - cg.indent += 1; - - cg.ensure_brackets(body); - - update.to_rust(cg); - - cg.indent -= 1; - cg.add_indentedln("}"); - - cg.indent -= 1; - cg.add_indentedln("}"); - } - - Statement::For { - mutable, - pattern, - iterator, - body, - } => { - cg.add_indentedln(&format!( - "for {}{} in {}", - get_mutable(mutable), - pattern.get_rust(), - iterator.get_rust() - )); - cg.ensure_brackets(body); - } - - Statement::Return(expr) => { - let val = expr.map(|e| e.get_rust()).unwrap_or_default(); - cg.add_indentedln(&format!("return {}", val)); - } - - Statement::Break => cg.add_indentedln("break"), - Statement::Continue => cg.add_indentedln("continue"), - } - } -} - -impl ToRust for FunctionDecl { - fn to_rust(self, cg: &mut RustCodegen) { - let params_str = self - .params - .0 - .into_iter() - .map(VarDecl::get_rust) - .collect::>() - .join(", "); - - cg.add_indentedln(&format!( - "{}fn {}{}({}) -> {}", - self.visibility.get_rust(), - self.name.get_rust(), - self.generics.get_rust(), - params_str, - self.return_type.get_rust() - )); - if let Some(body) = self.body { - cg.add_indentedln("{\n"); - cg.indent += 1; - body.to_rust(cg); - cg.indent -= 1; - cg.add_indentedln("}\n"); - } else { - cg.add(";"); - } - } -} - -impl ToRust for ImplDecl { - fn to_rust(self, cg: &mut RustCodegen) { - if let Some(trait_) = self.trait_ { - cg.add_indentedln(&format!( - "impl{} {} for {} {{", - self.generics.get_rust(), - trait_.get_rust(), - self.target.get_rust() - )); - } else { - cg.add_indentedln(&format!( - "impl{} {} {{", - self.generics.get_rust(), - self.target.get_rust() - )); - } - cg.indent += 1; - - for method in self.methods { - method.to_rust(cg); - } - - cg.indent -= 1; - cg.add_indentedln("}"); - } -} - -impl GetRust for VarDecl { - fn get_rust(self) -> String { - let ty = self - .type_ - .map(|t| format!(": {}", t.get_rust())) - .unwrap_or_default(); - - format!( - "{}{}{}", - get_mutable(self.mutable), - self.name.get_rust(), - ty - ) - } -} - -impl GetRust for Path { - fn get_rust(self) -> String { - self.0 - .into_iter() - .map(Identifier::get_rust) - .collect::>() - .join("::") - } -} - -impl GetRust for TypePostfix { - fn get_rust(self) -> String { - match self { - TypePostfix::Ref => format!("&"), - TypePostfix::RefMut => format!("&mut "), - TypePostfix::RefLifetime(lifetime) => format!("&'{} ", lifetime.get_rust()), - TypePostfix::RefMutLifetime(lifetime) => format!("&'{} mut ", lifetime.get_rust()), - TypePostfix::Dyn => format!("dyn "), - } - } -} - -impl GetRust for Visibility { - fn get_rust(self) -> String { - match self { - Visibility::Public => "pub ".to_string(), - Visibility::PublicTarget(path) => format!("pub({}) ", path.get_rust()), - Visibility::Private => "".to_string(), - } - } -} - -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.into_iter() - .map(|field| format!("{}: {}", field.name.get_rust(), field.type_.get_rust())) - .collect::>() - .join(", ") - ), - Self::Tuple(id, t) => format!( - "{} ({})", - id.get_rust(), - t.into_iter() - .map(TypeExpr::get_rust) - .collect::>() - .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.into_iter() - .map(Identifier::get_rust) - .collect::>() - .join(", ") - ), - Self::Tuple(ids) => format!( - "({})", - ids.into_iter() - .map(Identifier::get_rust) - .collect::>() - .join(", ") - ), - Self::NamedTuple(path, ids) => { - format!( - "{} ({})", - path.get_rust(), - ids.into_iter() - .map(Identifier::get_rust) - .collect::>() - .join(", ") - ) - } - } - } -} - -impl GetRust for GenericsDecl { - fn get_rust(self) -> String { - if self.0.len() == 0 { - String::new() - } else { - format!( - "<{}>", - self.0 - .into_iter() - .map(|v| v.get_rust()) - .collect::>() - .join(", ") - ) - } - } -} - -impl GetRust for GenericDecl { - fn get_rust(self) -> String { - match self { - GenericDecl::Lifetime(name) => format!("'{}", name.get_rust()), - GenericDecl::Type(name, requirements) => { - name.get_rust() - + &(if requirements.len() != 0 { - format!( - ": {}", - requirements - .into_iter() - .map(TypeExpr::get_rust) - .collect::>() - .join("+") - ) - } else { - String::new() - }) - } - } - } -} - -impl GetRust for Generics { - fn get_rust(self) -> String { - if self.0.len() == 0 { - String::new() - } else { - format!( - "<{}>", - self.0 - .into_iter() - .map(Generic::get_rust) - .collect::>() - .join(", ") - ) - } - } -} - -impl GetRust for Generic { - fn get_rust(self) -> String { - match self { - Self::Lifetime(name) => format!("'{}", name.get_rust()), - Self::Type(ty) => ty.get_rust(), - } - } -} - -impl GetRust for FieldDecl { - fn get_rust(self) -> String { - format!( - "{}{}: {},", - self.visibility.get_rust(), - self.name.get_rust(), - self.type_.get_rust() - ) - } -} - -pub fn get_static_type_path(path: Path) -> String { - let rust_path = path.get_rust(); - - if rust_path == "void" { - format!("()") - } else { - rust_path - } -} - -pub fn get_type_postfixes(postfixes: Vec) -> String { - postfixes - .into_iter() - .map(TypePostfix::get_rust) - .rev() - .collect() -} - -pub fn get_mutable(mutable: bool) -> String { - if mutable { "mut " } else { "" }.to_string() -} diff --git a/src/main.mist b/src/main.mist index a86389b..59c2d3b 100644 --- a/src/main.mist +++ b/src/main.mist @@ -3,7 +3,6 @@ use ; use ; pub mod builder; -pub mod codegen; pub mod transpiler; void main() { diff --git a/src/transpiler.rs b/src/transpiler.rs index 349b7c4..77b2522 100644 --- a/src/transpiler.rs +++ b/src/transpiler.rs @@ -141,7 +141,7 @@ fn build_dir(root: &Path, base_src: &Path, current_dir: &Path, out_dir: &Path) { // semantic::walk_ast(semantic::scope::Scope::from_top(root, &ast), &mut ast); - let mut gc = crate::codegen::RustCodegen::new(); + let mut gc = mist_codegen::RustCodegen::new(); let output = gc.generate(ast); if let Err(e) = fs::write(&output_path, output) {