diff --git a/src/c/write_c.rs b/src/c/write_c.rs index 7cad180..0e118d0 100644 --- a/src/c/write_c.rs +++ b/src/c/write_c.rs @@ -1,5 +1,7 @@ +use core::panic; use std::io::{Result, Write}; +use itertools::Itertools; use lang_c::ast::*; use lang_c::span::Node; @@ -20,12 +22,899 @@ impl WriteString for Node { impl WriteLine for TranslationUnit { /// VERY BIG HINT: You should start by understanding the [`writeln!`](https://doc.rust-lang.org/std/macro.writeln.html) macro. fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> { - todo!() + self.0 + .iter() + .try_for_each(|ext_decl| ext_decl.write_line(indent, write)) + } +} + +impl WriteLine for ExternalDeclaration { + fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> { + match self { + Self::Declaration(decl) => decl.write_line(indent, write), + Self::StaticAssert(_) => todo!(), + Self::FunctionDefinition(fn_def) => fn_def.write_line(indent, write), + } + } +} + +impl WriteLine for Declaration { + fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> { + write_indent(indent, write); + writeln!(write, "{};", self.write_string()) + } +} + +impl WriteString for Declaration { + fn write_string(&self) -> String { + format!( + "{} {}", + self.specifiers.write_string(), + self.declarators.write_string() + ) + } +} + +impl WriteString for Vec> { + fn write_string(&self) -> String { + self.iter().map(|s| s.write_string()).join(" ") + } +} + +impl WriteString for DeclarationSpecifier { + fn write_string(&self) -> String { + match self { + Self::StorageClass(class_spec) => class_spec.write_string(), + Self::TypeSpecifier(type_spec) => type_spec.write_string(), + Self::TypeQualifier(type_qual) => type_qual.write_string(), + Self::Function(func_spec) => func_spec.write_string(), + _ => todo!(), + } + } +} + +impl WriteString for StorageClassSpecifier { + fn write_string(&self) -> String { + String::from(match self { + Self::Typedef => "typedef", + Self::Extern => "extern", + Self::Static => "static", + Self::ThreadLocal => "_Thread_local", + Self::Auto => "auto", + Self::Register => "register", + }) + } +} + +impl WriteString for TypeSpecifier { + fn write_string(&self) -> String { + match self { + Self::Void => String::from("void"), + Self::Char => String::from("char"), + Self::Short => String::from("short"), + Self::Int => String::from("int"), + Self::Long => String::from("long"), + Self::Float => String::from("float"), + Self::Double => String::from("double"), + Self::Signed => String::from("signed"), + Self::Unsigned => String::from("unsigned"), + Self::Bool => String::from("bool"), + Self::Complex => String::from("_Complex"), + Self::Struct(struct_type) => struct_type.write_string(), + Self::TypedefName(id) => id.write_string(), + _ => todo!(), + } + } +} + +impl WriteString for StructType { + fn write_string(&self) -> String { + let declarations = if let Some(decls) = &self.declarations { + format!("{{ {} }}", decls.iter().map(|d| d.write_string()).join(" ")) + } else { + String::new() + }; + match self.kind.node { + StructKind::Struct => { + format!("struct {} {declarations}", self.identifier.write_string()) + } + StructKind::Union => format!("union {} {declarations}", self.identifier.write_string()), + } + } +} + +impl WriteString for StructDeclaration { + fn write_string(&self) -> String { + match self { + Self::Field(field) => field.write_string(), + Self::StaticAssert(_) => todo!(), + } + } +} + +impl WriteString for StructField { + fn write_string(&self) -> String { + format!( + "{} {};", + self.specifiers.write_string(), + self.declarators.iter().map(|d| d.write_string()).join(", ") + ) + } +} + +impl WriteString for StructDeclarator { + fn write_string(&self) -> String { + let bit_width = if let Some(expr) = &self.bit_width { + format!(": {}", expr.write_string()) + } else { + String::new() + }; + format!("{}{}", self.declarator.write_string(), bit_width) + } +} + +impl WriteString for TypeQualifier { + fn write_string(&self) -> String { + String::from(match self { + Self::Const => "const", + Self::Restrict => "restrict", + Self::Volatile => "volatile", + Self::Nonnull | Self::NullUnspecified | Self::Nullable => panic!("Extension"), + Self::Atomic => "_Atomic", + }) + } +} + +impl WriteString for FunctionSpecifier { + fn write_string(&self) -> String { + String::from(match self { + Self::Inline => "inline", + Self::Noreturn => "_Noreturn", + }) + } +} + +impl WriteString for Vec> { + fn write_string(&self) -> String { + self.iter().map(|d| d.write_string()).join(", ") + } +} + +impl WriteString for InitDeclarator { + fn write_string(&self) -> String { + format!( + "{}{}", + self.declarator.write_string(), + self.initializer + .as_ref() + .map(|i| format!(" = {}", i.write_string())) + .unwrap_or_default() + ) + } +} + +impl WriteString for Declarator { + fn write_string(&self) -> String { + match &self.kind.node { + DeclaratorKind::Abstract => { + // println!("DEBUG: ABSTRACT {}", self.derived.write_string()); + self.derived.write_string() + } + DeclaratorKind::Identifier(id) => { + // println!( + // "DEBUG: IDENTIFIER({}) {}", + // id.write_string(), + // self.derived.write_string() + // ); + let mut result = String::new(); + let mut id_used = false; + for declarator in &self.derived { + if let DerivedDeclarator::Pointer(_) = declarator.node { + result += format!(" {}", declarator.write_string()).as_str(); + } else { + if !id_used { + id_used = true; + result += format!(" {}", id.write_string()).as_str(); + } + result += format!(" {}", declarator.write_string()).as_str(); + } + } + if !id_used { + result += format!(" {}", id.write_string()).as_str(); + } + result + } + DeclaratorKind::Declarator(decl) => { + // println!("DEBUG: DECLARATOR {}", self.derived.write_string()); + let mut result = String::new(); + let mut id_used = false; + for declarator in &self.derived { + if let DerivedDeclarator::Pointer(_) = declarator.node { + result += format!(" {}", declarator.write_string()).as_str(); + } else { + if !id_used { + id_used = true; + result += format!("({})", decl.write_string()).as_str(); + } + result += format!(" {}", declarator.write_string()).as_str(); + } + } + if !id_used { + result += format!("({})", decl.write_string()).as_str(); + } + result + } + } + } +} + +impl WriteString for Vec> { + fn write_string(&self) -> String { + self.iter().map(|d| d.write_string()).join(" ") + } +} + +impl WriteString for DerivedDeclarator { + fn write_string(&self) -> String { + match self { + Self::Pointer(ptr_quals) => { + format!("* {}", ptr_quals.iter().map(|q| q.write_string()).join(" ")) + } + Self::Array(arr_decl) => arr_decl.write_string(), + Self::Function(func_params) => format!("({})", func_params.write_string()), + Self::KRFunction(func_params) => format!( + "({})", + func_params.iter().map(|i| i.write_string()).join(", ") + ), + Self::Block(_) => panic!("Extension"), + } + } +} + +impl WriteString for PointerQualifier { + fn write_string(&self) -> String { + match self { + Self::TypeQualifier(type_qual) => type_qual.write_string(), + Self::Extension(_) => panic!("Extension"), + } + } +} + +impl WriteString for ArrayDeclarator { + fn write_string(&self) -> String { + let qualifiers = self.qualifiers.iter().map(|q| q.write_string()).join(" "); + match &self.size { + ArraySize::Unknown => format!("[{qualifiers}]"), + ArraySize::VariableUnknown => format!("[{qualifiers} *]"), + ArraySize::VariableExpression(expr) => { + format!("[{qualifiers} {}]", expr.write_string()) + } + ArraySize::StaticExpression(expr) => { + format!("[{qualifiers} static {}]", expr.write_string()) + } + } + } +} + +impl WriteString for FunctionDeclarator { + fn write_string(&self) -> String { + let ellipsis = if let Ellipsis::Some = self.ellipsis { + String::from(", ...") + } else { + String::new() + }; + format!( + "{}{ellipsis}", + self.parameters.iter().map(|p| p.write_string()).join(", ") + ) + } +} + +impl WriteString for ParameterDeclaration { + fn write_string(&self) -> String { + let declarator = self + .declarator + .as_ref() + .map(|d| d.write_string()) + .unwrap_or_default(); + format!( + "{} {declarator}", + self.specifiers.iter().map(|d| d.write_string()).join(" ") + ) + } +} + +impl WriteLine for FunctionDefinition { + fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> { + write_indent(indent, write); + writeln!( + write, + "{} {} {}", + self.specifiers.write_string(), + self.declarator.write_string(), + self.declarations.iter().map(|d| d.write_string()).join(" ") + ); + self.statement.write_line(indent, write) + } +} + +impl WriteLine for Statement { + fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> { + match self { + Self::Labeled(stat) => stat.write_line(indent, write), + Self::Compound(blks) => { + write_indent(indent, write); + writeln!(write, "{{"); + blks.iter() + .try_for_each(|b| b.write_line(indent + 1, write))?; + write_indent(indent, write); + writeln!(write, "}}"); + Ok(()) + } + Self::Expression(expr) => { + write_indent(indent, write); + writeln!(write, "{};", expr.write_string()); + Ok(()) + } + Self::If(if_stat) => if_stat.write_line(indent, write), + Self::Switch(switch_stat) => switch_stat.write_line(indent, write), + Self::While(while_stat) => while_stat.write_line(indent, write), + Self::DoWhile(dowhile_stat) => dowhile_stat.write_line(indent, write), + Self::For(for_stat) => for_stat.write_line(indent, write), + Self::Continue => { + write_indent(indent, write); + writeln!(write, "continue;") + } + Self::Break => { + write_indent(indent, write); + writeln!(write, "break;") + } + Self::Return(expr) => { + write_indent(indent, write); + writeln!( + write, + "return {};", + expr.as_ref().map_or(String::from(""), |e| e.write_string()) + ) + } + Self::Asm(_) => panic!("Extension"), + _ => { + write_indent(indent, write); + writeln!(write, "TODO"); + Ok(()) + } + } + } +} + +impl WriteLine for LabeledStatement { + fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> { + write_indent(indent, write); + writeln!(write, "{}\n", self.label.write_string()); + self.statement.write_line(indent + 1, write) + } +} + +impl WriteString for Label { + fn write_string(&self) -> String { + match self { + Self::Identifier(id) => format!("{}:", id.write_string()), + Self::Case(expr) => format!("case {}:", expr.write_string()), + Self::CaseRange(_) => panic!("Extension"), + Self::Default => String::from("default:"), + } + } +} + +impl WriteLine for BlockItem { + fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> { + match self { + Self::Declaration(decl) => decl.write_line(indent, write), + Self::StaticAssert(_) => todo!(), + Self::Statement(stat) => stat.write_line(indent, write), + } + } +} + +impl WriteLine for IfStatement { + fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> { + write_indent(indent, write); + writeln!(write, "if ({})", self.condition.write_string()); + self.then_statement.write_line(indent, write)?; + if let Some(else_statement) = &self.else_statement { + write_indent(indent, write); + writeln!(write, "else"); + else_statement.write_line(indent, write)?; + } + Ok(()) + } +} + +impl WriteLine for SwitchStatement { + fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> { + write_indent(indent, write); + writeln!(write, "switch ({})", self.expression.write_string()); + self.statement.write_line(indent, write) + } +} + +impl WriteLine for WhileStatement { + fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> { + write_indent(indent, write); + writeln!(write, "while ({})", self.expression.write_string()); + self.statement.write_line(indent, write) + } +} + +impl WriteLine for DoWhileStatement { + fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> { + write_indent(indent, write); + writeln!(write, "do"); + self.statement.write_line(indent, write)?; + write_indent(indent, write); + writeln!(write, "while ({});", self.expression.write_string()) + } +} + +impl WriteLine for ForStatement { + fn write_line(&self, indent: usize, write: &mut dyn Write) -> Result<()> { + write_indent(indent, write); + writeln!( + write, + "for ({}; {}; {})", + self.initializer.write_string(), + self.condition.write_string(), + self.step.write_string() + ); + self.statement.write_line(indent, write) + } +} + +impl WriteString for ForInitializer { + fn write_string(&self) -> String { + match self { + Self::Empty => String::new(), + Self::Expression(expr) => expr.write_string(), + Self::Declaration(decl) => decl.write_string(), + Self::StaticAssert(_) => todo!(), + } } } impl WriteString for Initializer { fn write_string(&self) -> String { - todo!() + match self { + Self::Expression(expr) => expr.write_string(), + Self::List(items) => format!( + "{{ {} }}", + items.iter().map(|item| item.write_string()).join(", ") + ), + } + } +} + +impl WriteString for InitializerListItem { + fn write_string(&self) -> String { + let designation = if !self.designation.is_empty() { + format!( + "{} = ", + self.designation.iter().map(|d| d.write_string()).join(" ") + ) + } else { + String::new() + }; + format!("{designation}{}", self.initializer.write_string()) + } +} + +impl WriteString for Designator { + fn write_string(&self) -> String { + match self { + Self::Index(expr) => expr.write_string(), + Self::Member(id) => id.write_string(), + Self::Range(range) => panic!("Extension"), + } + } +} + +impl WriteString for Expression { + fn write_string(&self) -> String { + match self { + Self::Identifier(id) => id.write_string(), + Self::Constant(c) => c.write_string(), + Self::Member(mem_expr) => mem_expr.write_string(), + Self::Call(call_expr) => call_expr.write_string(), + Self::SizeOfTy(sizeof_expr) => sizeof_expr.write_string(), + Self::SizeOfVal(sizeof_expr) => sizeof_expr.write_string(), + Self::AlignOf(alginof_expr) => alginof_expr.write_string(), + Self::UnaryOperator(un_op) => un_op.write_string(), + Self::Cast(cast_expr) => cast_expr.write_string(), + Self::BinaryOperator(bin_op) => bin_op.write_string(), + Self::Conditional(cond_expr) => cond_expr.write_string(), + Self::Comma(exprs) => { + format!("({})", exprs.iter().map(|e| e.write_string()).join(", ")) + } + _ => String::from("TODO"), + } + } +} + +impl WriteString for Identifier { + fn write_string(&self) -> String { + self.name.clone() + } +} + +impl WriteString for Constant { + fn write_string(&self) -> String { + match self { + Self::Integer(i) => i.write_string(), + Self::Float(f) => f.write_string(), + Self::Character(c) => format!("'{}'", c), + } + } +} + +impl WriteString for Integer { + fn write_string(&self) -> String { + match self.base { + IntegerBase::Decimal => format!("{}{}", self.number, self.suffix.write_string()), + IntegerBase::Octal => format!("0{}{}", self.number, self.suffix.write_string()), + IntegerBase::Hexadecimal => format!("0x{}{}", self.number, self.suffix.write_string()), + IntegerBase::Binary => format!("0b{}{}", self.number, self.suffix.write_string()), + } + } +} + +impl WriteString for IntegerSuffix { + fn write_string(&self) -> String { + format!( + "{}{}", + match self.size { + IntegerSize::Int => "", + IntegerSize::Long => "l", + IntegerSize::LongLong => "ll", + }, + if self.unsigned { "u" } else { "" } + ) + } +} + +impl WriteString for Float { + fn write_string(&self) -> String { + match self.base { + FloatBase::Decimal => format!("{}{}", self.number, self.suffix.write_string()), + FloatBase::Hexadecimal => format!("0x{}{}", self.number, self.suffix.write_string()), + } + } +} + +impl WriteString for FloatSuffix { + fn write_string(&self) -> String { + String::from(match self.format { + FloatFormat::Float => "f", + FloatFormat::Double => "", + FloatFormat::LongDouble => "l", + _ => todo!(), + }) + } +} + +impl WriteString for MemberExpression { + fn write_string(&self) -> String { + format!( + "({}{}{})", + self.expression.write_string(), + match self.operator.node { + MemberOperator::Direct => ".", + MemberOperator::Indirect => "->", + }, + self.identifier.write_string() + ) + } +} + +impl WriteString for SizeOfTy { + fn write_string(&self) -> String { + format!("sizeof({})", self.0.write_string()) + } +} + +impl WriteString for TypeName { + fn write_string(&self) -> String { + format!( + "{} {}", + self.specifiers.write_string(), + self.declarator.write_string() + ) + } +} + +impl WriteString for Vec> { + fn write_string(&self) -> String { + self.iter().map(|s| s.write_string()).join(" ") + } +} + +impl WriteString for SpecifierQualifier { + fn write_string(&self) -> String { + match self { + Self::TypeSpecifier(type_spec) => type_spec.write_string(), + Self::TypeQualifier(type_qual) => type_qual.write_string(), + Self::Extension(_) => panic!("Extension"), + } + } +} + +impl WriteString for SizeOfVal { + fn write_string(&self) -> String { + format!("sizeof({})", self.0.write_string()) + } +} + +impl WriteString for AlignOf { + fn write_string(&self) -> String { + format!("_Alignof({})", self.0.write_string()) + } +} + +impl WriteString for UnaryOperatorExpression { + fn write_string(&self) -> String { + match self.operator.node { + UnaryOperator::PostIncrement => format!("{}++", self.operand.write_string()), + UnaryOperator::PostDecrement => format!("{}--", self.operand.write_string()), + UnaryOperator::PreIncrement => format!("++{}", self.operand.write_string()), + UnaryOperator::PreDecrement => format!("--{}", self.operand.write_string()), + UnaryOperator::Address => format!("&{}", self.operand.write_string()), + UnaryOperator::Indirection => format!("*{}", self.operand.write_string()), + UnaryOperator::Plus => format!("+{}", self.operand.write_string()), + UnaryOperator::Minus => format!("-{}", self.operand.write_string()), + UnaryOperator::Complement => format!("~{}", self.operand.write_string()), + UnaryOperator::Negate => format!("!{}", self.operand.write_string()), + } + } +} + +impl WriteString for CastExpression { + fn write_string(&self) -> String { + format!( + "({})({})", + self.type_name.write_string(), + self.expression.write_string() + ) + } +} + +impl WriteString for BinaryOperatorExpression { + fn write_string(&self) -> String { + match self.operator.node { + BinaryOperator::Index => { + format!("{}[{}]", self.lhs.write_string(), self.rhs.write_string()) + } + BinaryOperator::Multiply => { + format!( + "({} * {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::Divide => { + format!( + "({} / {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::Modulo => { + format!( + "({} % {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::Plus => { + format!( + "({} + {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::Minus => { + format!( + "({} - {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::ShiftLeft => { + format!( + "({} << {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::ShiftRight => { + format!( + "({} >> {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::Less => { + format!( + "({} < {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::Greater => { + format!( + "({} > {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::LessOrEqual => { + format!( + "({} <= {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::GreaterOrEqual => { + format!( + "({} >= {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::Equals => { + format!( + "({} == {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::NotEquals => { + format!( + "({} != {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::BitwiseAnd => { + format!( + "({} & {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::BitwiseXor => { + format!( + "({} ^ {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::BitwiseOr => { + format!( + "({} | {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::LogicalAnd => { + format!( + "({} && {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::LogicalOr => { + format!( + "({} || {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::Assign => { + format!( + "({} = {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::AssignMultiply => { + format!( + "({} *= {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::AssignDivide => { + format!( + "({} /= {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::AssignModulo => { + format!( + "({} %= {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::AssignPlus => { + format!( + "({} += {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::AssignMinus => { + format!( + "({} -= {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::AssignShiftLeft => { + format!( + "({} <<= {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::AssignShiftRight => { + format!( + "({} >>= {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::AssignBitwiseAnd => { + format!( + "({} &= {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::AssignBitwiseXor => { + format!( + "({} ^= {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + BinaryOperator::AssignBitwiseOr => { + format!( + "({} |= {})", + self.lhs.write_string(), + self.rhs.write_string() + ) + } + } + } +} + +impl WriteString for CallExpression { + fn write_string(&self) -> String { + format!( + "{}({})", + self.callee.write_string(), + self.arguments.iter().map(|a| a.write_string()).join(", ") + ) + } +} + +impl WriteString for ConditionalExpression { + fn write_string(&self) -> String { + format!( + "({} ? {} : {})", + self.condition.write_string(), + self.then_expression.write_string(), + self.else_expression.write_string() + ) } }