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::variable("internal_name"), Statement::variable("name"))));
let arguments = vec![Statement::unnamed_variable("Hello"),
Statement::variable("internal_name")];
let function_call = Statement::function_call("print", arguments);
function.add_statement(function_call);
program.add_function(function);
let function_call = FunctionCall::new("hello",
vec![Statement::unnamed_variable("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)
}
}