1 module bamboo.codegen.field_declarations.molecular;
2 
3 import bamboo.codegen.field_declarations;
4 
5 string generateMolecular(MolecularField field)
6 {
7     string format;
8     format ~= "@FieldId(" ~ field.id.to!string ~ ")";
9     format ~= "void ";
10     format ~= field.symbol;
11 
12     format ~= "(";
13 
14     foreach (reference; field.references)
15     {
16         format ~= generateParameterListFor(reference);
17     }
18 
19     format ~= ") {";
20     foreach (reference; field.references)
21     {
22         format ~= generateCallFor(reference) ~ ";";
23     }
24 
25     format ~= "}";
26 
27     return format;
28 }
29 
30 string generateCallFor(FieldDeclaration field)
31 {
32     if (auto molecular = cast(MolecularField) field)
33     {
34         return generateMolecularCall(molecular);
35     }
36     else if (auto atomic = cast(AtomicField) field)
37     {
38         return generateAtomicCall(atomic);
39     }
40     else if (auto parameter = cast(ParameterField) field)
41     {
42         return generateParameterFieldCall(parameter);
43     }
44     else
45     {
46         assert(0);
47     }
48 
49 }
50 
51 string[] flattenArgs(MolecularField field)
52 {
53     string[] args;
54     foreach (reference; field.references)
55     {
56         if (auto molecular = cast(MolecularField) field)
57         {
58             args ~= flattenArgs(molecular);
59         }
60         else if (auto atomic = cast(AtomicField) field)
61         {
62             foreach (arg; atomic.parameters)
63             {
64                 args ~= arg.symbol;
65             }
66         }
67         else if (auto paraField = cast(ParameterField) field)
68         {
69             args ~= paraField.parameter.symbol;
70         }
71     }
72     return args;
73 }
74 
75 string generateMolecularCall(MolecularField field)
76 {
77     string[] args = flattenArgs(field);
78     string format;
79     format ~= field.symbol;
80     format ~= "(";
81     foreach (arg; args)
82     {
83         format ~= arg ~ ",";
84     }
85     format ~= ")";
86 
87     return format;
88 }
89 
90 string generateAtomicCall(AtomicField field)
91 {
92     string format;
93     if (field.parameters.length > 1)
94     {
95         format ~= field.symbol;
96     }
97     else
98     {
99         format ~= "this." ~ cast(char)(field.name[3].toLower) ~ field.name[4 .. $];
100     }
101     format ~= "(";
102     foreach (arg; field.parameters)
103     {
104         format ~= arg.symbol ~ ",";
105     }
106     format ~= ")";
107 
108     return format;
109 }
110 
111 string generateParameterFieldCall(ParameterField field)
112 {
113     return "this." ~ field.name ~ "=" ~ field.name;
114 }