1 #!/usr/bin/rdmd
2 /++
3   Author: Aziz Köksal
4   License: GPL3
5 +/
6 module TypeRules;
7 
8 import tango.io.Stdout;
9 
10 void main(char[][] args)
11 {
12   Stdout(
13     `<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
14 <html>
15 <head>
16   <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
17   <link href="" rel="stylesheet" type="text/css">
18   <style type="text/css">
19     .E { color: darkred; } /* Error */
20     .R { font-size: 0.8em; } /* Result */
21     .X { color: darkorange; }
22     .Y { color: darkblue; }
23   </style>
24 </head>
25 <body>
26 <p>The following tables show the type results of different expressions. Compiler used: `
27   );
28 
29   Stdout.format("{} {}.{,:d3}.</p>\n", __VENDOR__, __VERSION__/1000, __VERSION__%1000);
30 
31   Stdout.format("<table>\n<tr><th colspan=\"{}\">Unary Expressions</th></tr>\n", unaryExpressions.length);
32   Stdout("<tr><td><!--typecol--></td>");
33   foreach (unaryExpression; unaryExpressions)
34     Stdout.format("<td>{}</td>", {
35       if (unaryExpression[0] == 'x')
36         return `<span class="X">x</span>` ~ xml_escape(unaryExpression[1..$]);
37       else
38         return xml_escape(unaryExpression[0..$-1]) ~ `<span class="X">x</span>`;
39     }());
40   Stdout("</tr>\n");
41   foreach (i, basicType; basicTypes)
42   {
43     Stdout.format("<tr>\n"`<td class="X">{}</td>`, basicType);
44     foreach (expResults; unaryExpsResults)
45     {
46       auto result =  expResults[i];
47       Stdout.format(`<td class="R">{}</td>`, result[0] == 'E' ? `<span class="E">Error</span>`[] : result);
48     }
49     Stdout("\n<tr>\n");
50   }
51   Stdout("</table>\n");
52 
53   foreach (i, expResults; binaryExpsResults)
54   {
55     const(char)[] binaryExpression = binaryExpressions[i];
56     binaryExpression = `<span class="X">x</span> ` ~
57                        xml_escape(binaryExpression[1..$-1]) ~
58                        ` <span class="Y">y</span>`;
59     Stdout.format("<table>\n<tr><th colspan=\"{}\">{}</th></tr>\n", basicTypes.length, binaryExpression);
60     Stdout.format("<tr><td><!--typecol--></td>");
61     foreach (basicType; basicTypes)
62       Stdout.format(`<td class="Y">{}</td>`, basicType);
63     Stdout("\n<tr>\n");
64     foreach (j, results; expResults)
65     {
66       Stdout.format("<tr>\n"`<td class="X">{}</td>`, basicTypes[j]);
67       foreach (result; results)
68         Stdout.format(`<td class="R">{}</td>`, result[0] == 'E' ? `<span class="E">Error</span>`[] : result);
69       Stdout("\n<tr>\n");
70     }
71     Stdout("</table>\n");
72   }
73 
74   Stdout(
75     "\n</body>"
76     "\n</html>"
77   );
78 }
79 
80 /// Escapes the characters '<', '>' and '&' with named character entities.
81 /// Taken from module cmd.Highlight;
82 const(char)[] xml_escape(const(char)[] text)
83 {
84   char[] result;
85   foreach (c; text)
86     switch (c)
87     {
88       case '<': result ~= "&lt;";  break;
89       case '>': result ~= "&gt;";  break;
90       case '&': result ~= "&amp;"; break;
91       default:  result ~= c;
92     }
93   if (result.length != text.length)
94     return result;
95   // Nothing escaped. Return original text.
96   delete result;
97   return text;
98 }
99 
100 char char_; wchar wchar_; dchar dchar_; bool bool_;
101 byte byte_; ubyte ubyte_; short short_; ushort ushort_;
102 int int_; uint uint_; long long_; ulong ulong_;
103 /+cent cent_;   ucent ucent_;+/
104 float float_; double double_; real real_;
105 ifloat ifloat_; idouble idouble_; ireal ireal_;
106 cfloat cfloat_; cdouble cdouble_; creal creal_;
107 
108 enum string[] basicTypes = [
109   "char"[],   "wchar",   "dchar", "bool",
110   "byte",   "ubyte",   "short", "ushort",
111   "int",    "uint",    "long",  "ulong",
112   /+"cent",   "ucent",+/
113   "float",  "double",  "real",
114   "ifloat", "idouble", "ireal",
115   "cfloat", "cdouble", "creal"/+, "void"+/
116 ];
117 
118 enum string[] unaryExpressions = [
119   "!x",
120   "&x",
121   "~x",
122   "+x",
123   "-x",
124   "++x",
125   "--x",
126   "x++",
127   "x--",
128 ];
129 
130 enum string[] binaryExpressions = [
131   "x!<>=y",
132   "x!<>y",
133   "x!<=y",
134   "x!<y",
135   "x!>=y",
136   "x!>y",
137   "x<>=y",
138   "x<>y",
139 
140   "x=y", "x==y", "x!=y",
141   "x<=y", "x<y",
142   "x>=y", "x>y",
143   "x<<=y", "x<<y",
144   "x>>=y","x>>y",
145   "x>>>=y", "x>>>y",
146   "x|=y", "x||y", "x|y",
147   "x&=y", "x&&y", "x&y",
148   "x+=y", "x+y",
149   "x-=y", "x-y",
150   "x/=y", "x/y",
151   "x*=y", "x*y",
152   "x%=y", "x%y",
153   "x^=y", "x^y",
154   "x~=y",
155   "x~y",
156   "x,y"
157 ];
158 
159 template ExpressionType(alias x, alias y, string expression)
160 {
161   static if (is(typeof(mixin(expression)) ResultType))
162     immutable result = ResultType.stringof;
163   else
164     immutable result = "Error";
165 }
166 alias EType = ExpressionType;
167 
168 char[] genBinaryExpArray(string expression)
169 {
170   char[] result = "[\n".dup;
171   foreach (t1; basicTypes)
172   {
173     result ~= "[\n".dup;
174     foreach (t2; basicTypes)
175       result ~= `EType!(`~t1~`_, `~t2~`_, "`~expression~`").result,`"\n";
176     result[result.length-2] = ']'; // Overwrite last comma.
177     result[result.length-1] = ','; // Overwrite last \n.
178   }
179   result[result.length-1] = ']'; // Overwrite last comma.
180   return result;
181 }
182 // pragma(msg, mixin(genBinaryExpArray("x%y")).stringof);
183 
184 char[] genBinaryExpsArray()
185 {
186   char[] result = "[\n".dup;
187   foreach (expression; binaryExpressions)
188     result ~= genBinaryExpArray(expression) ~ ",\n";
189   result[result.length-2] = ']';
190   return result;
191 }
192 
193 // pragma(msg, mixin(genBinaryExpsArray()).stringof);
194 
195 char[] genUnaryExpArray(string expression)
196 {
197   char[] result = "[\n".dup;
198   foreach (t1; basicTypes)
199     result ~= `EType!(`~t1~`_, int_, "`~expression~`").result,`"\n";
200   result[result.length-2] = ']'; // Overwrite last comma.
201   return result;
202 }
203 
204 char[] genUnaryExpsArray()
205 {
206   char[] result = "[\n".dup;
207   foreach (expression; unaryExpressions)
208     result ~= genUnaryExpArray(expression) ~ ",\n";
209   result[result.length-2] = ']';
210   return result;
211 }
212 
213 // pragma(msg, mixin(genUnaryExpsArray()).stringof);
214 
215 auto unaryExpsResults = mixin(genUnaryExpsArray());
216 auto binaryExpsResults = mixin(genBinaryExpsArray());