the_super_tiny_rusty_compiler/
codegen.rs

1use std::cell::RefCell;
2use std::rc::Rc;
3
4use crate::ast::c_ast;
5
6pub fn codegen(new_ast: &Rc<RefCell<c_ast::Node>>) -> String {
7    use c_ast::{Callee, Node};
8
9    let mut code = String::from("");
10
11    match *new_ast.borrow_mut() {
12        Node::Program(ref node_ref) => node_ref
13            .body
14            .iter()
15            .map(|node| format!("{}{}", code, codegen(node)))
16            .collect::<Vec<String>>()
17            .join("\n"),
18        Node::ExpressionStatement(ref node_ref) => codegen(&node_ref.expression),
19        Node::CallExpression(ref call_expr) => {
20            let Callee::Identifier(ref identifier) = call_expr.callee;
21
22            code = format!(
23                "{})",
24                call_expr.arguments.iter().enumerate().fold(
25                    format!("{}{}(", code, identifier),
26                    |code, (index, arg)| {
27                        let mut new_code = format!("{}{}", code, codegen(arg));
28                        if index != (&call_expr.arguments.len() - 1) {
29                            new_code = format!("{}, ", new_code)
30                        }
31                        new_code
32                    }
33                )
34            );
35
36            code
37        }
38        Node::NumberLiteral(ref num) => format!("{}{}", code, num.value),
39    }
40}