examples/c 디렉터리 아래에 있는 예제에 대해 통과하는 상태
This commit is contained in:
static
2025-03-11 07:28:02 +00:00
parent 7a95032d43
commit 873987829f

View File

@@ -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<T: WriteString> WriteString for Node<T> {
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<Node<DeclarationSpecifier>> {
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<Node<InitDeclarator>> {
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<Node<DerivedDeclarator>> {
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<Node<SpecifierQualifier>> {
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()
)
}
}