1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
use std::fmt::{Display, Formatter, Result}; use std::iter; use Function; use Statement; #[cfg(test)] mod tests { use {Argument, Assignment, Block, Function, FunctionCall, Statement}; #[test] fn it_makes_a_complex_function() { let mut program = Block::new(); let mut function = Function::new("hello", vec![Argument::new("name", Some("\"World\""), None, None)], &program); function.add_statement( Statement::Assignment( Assignment::new( Argument::input("internal_name"), Statement::Argument(Argument::input("name"))))); let arguments = vec![Statement::Argument(Argument::bare("Hello")), Statement::Argument(Argument::input("internal_name"))]; let function_call = FunctionCall::new("print", arguments); function.add_statement(Statement::FunctionCall(function_call)); program.add_function(function); let function_call = FunctionCall::new("hello", vec![Statement::Argument(Argument::bare("Chris"))]); program.add_statement(Statement::FunctionCall(function_call)); let expected = r#"def hello(name="World"): internal_name = name print("Hello", internal_name) hello("Chris") "#; let actual = format!("{}", program); println!("expected:"); println!("\"{}\"", expected); println!("actual:"); println!("\"{}\"", actual); assert_eq!(expected, actual); } } #[derive(Debug, Clone)] pub struct Block { pub indentation: usize, pub statements: Vec<Statement>, } impl Block { pub fn new() -> Block { Block { indentation: 0, statements: vec![], } } pub fn new_with_parent(parent: &Block) -> Block { Block { indentation: parent.indentation + 1, statements: vec![], } } pub fn add_function(&mut self, function: Function) { self.add_statement(Statement::Function(function)); } pub fn add_statement(&mut self, statement: Statement) { self.statements.push(statement); } pub fn indentation(&self) -> String { iter::repeat(" ").take(self.indentation).collect() } } impl Display for Block { fn fmt(&self, f: &mut Formatter) -> Result { let indent: String = iter::repeat(" ").take(self.indentation).collect(); let statements = self.statements .iter() .map(|s| format!("{}{}", indent, s)) .collect::<Vec<String>>() .join("\n"); write!(f, "{}\n", statements) } }