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
use std::fmt;
use crate::building_block_generators::*;
use crate::setup::*;

pub struct IfStatement {
    content: HeaderPlusBody<JoinedCode>,
}

impl IfStatement {
    pub fn new<CT>(condition: CT, body: CodeBody) -> IfStatement
    where CT: CodeGenerate + 'static {
        IfStatement {
            content: HeaderPlusBody::new(
                JoinedCode::new(
                    vec![
                        Box::new(String::from("if (")),
                        Box::new(condition),
                        Box::new(String::from(")"))
                    ]
                ),
                body
            )
        }
    }
}

impl CodeGenerate for IfStatement {
    fn generate(&self, f: &mut fmt::Formatter<'_>, mut info: CodeGenerationInfo) -> fmt::Result {
        info.context = GeneratorContext::If;
        self.content.generate(f, info)
    }
}

pub struct WhileStatement {
    content: HeaderPlusBody<JoinedCode>,
}

impl WhileStatement {
    pub fn new<CT>(condition: CT, body: CodeBody) -> WhileStatement 
    where CT: CodeGenerate + 'static {
        WhileStatement {
            content: HeaderPlusBody::new(
                JoinedCode::new(
                    vec![
                        Box::new(String::from("while (")),
                        Box::new(condition),
                        Box::new(String::from(")"))
                    ]
                ),
                body
            )
        }
    }
}

impl CodeGenerate for WhileStatement {
    fn generate(&self, f: &mut fmt::Formatter<'_>, mut info: CodeGenerationInfo) -> fmt::Result {
        info.context = GeneratorContext::While;
        self.content.generate(f, info)
    }
}

pub struct ForLoop {
    content: HeaderPlusBody<JoinedCode>,
}

impl ForLoop {
    pub fn new<IT, CT, UT>(init_code: IT, continuation_code: CT, update_code: UT, body: Vec<Box<dyn CodeGenerate>>) -> ForLoop
    where IT: CodeGenerate + 'static,
        CT: CodeGenerate + 'static,
        UT: CodeGenerate + 'static {
        ForLoop { content: HeaderPlusBody::new(
            JoinedCode::new(vec![
                Box::new(String::from("for (")),
                Box::new(init_code),
                Box::new(String::from("; ")),
                Box::new(continuation_code),
                Box::new(String::from("; ")),
                Box::new(update_code),
                Box::new(String::from(")")),
            ]),
            CodeBody::new(body)
        ) }
    }
}

impl CodeGenerate for ForLoop {
    fn generate(&self, f: &mut fmt::Formatter<'_>, mut info: CodeGenerationInfo) -> fmt::Result {
        info.context = GeneratorContext::ForLoop;
        self.content.generate(f, info)
    }
}