Mercurial > projects > dang
comparison sema/Operation.d @ 107:189c049cbfcc new_gen
Cleanup of codegen, better support for operators a few bugfixes
author | Anders Halager <halager@gmail.com> |
---|---|
date | Sun, 25 May 2008 14:40:14 +0200 |
parents | |
children | ed815b31479b |
comparison
equal
deleted
inserted
replaced
103:09b4d74cb3f5 | 107:189c049cbfcc |
---|---|
1 module sema.Operation; | |
2 | |
3 /// Operators | |
4 public enum Operator | |
5 { | |
6 Add, Sub, Mul, Div, Rem, | |
7 Shl, LShr, AShr, | |
8 And, Or, Xor, | |
9 | |
10 Eq, Ne, | |
11 Lt, Le, | |
12 Gt, Ge, | |
13 } | |
14 | |
15 /** | |
16 Enum for the basic builtin operations. | |
17 | |
18 S for signed, U for unsigned and F for floating point. | |
19 **/ | |
20 public enum BuiltinOperation | |
21 { | |
22 Add, Sub, Mul, SDiv, UDiv, FDiv, SRem, URem, FRem, | |
23 | |
24 Shl, LShr, AShr, | |
25 And, Or, Xor, | |
26 | |
27 Eq, Ne, | |
28 SLt, ULt, FLt, SLe, ULe, FLe, | |
29 SGt, UGt, FGt, SGe, UGe, FGe, | |
30 | |
31 None | |
32 } | |
33 | |
34 /** | |
35 Returns true if the operation has an unsigned variant. | |
36 | |
37 Will only be true for the S version, so SDiv gives true, UDiv or FDiv dont. | |
38 **/ | |
39 private bool hasUnsignedVariant(BuiltinOperation op) | |
40 { | |
41 alias BuiltinOperation O; | |
42 return op is O.SDiv | |
43 || op is O.SRem | |
44 || op is O.SLt | |
45 || op is O.SLe | |
46 || op is O.SGt | |
47 || op is O.SGe; | |
48 } | |
49 | |
50 /// Same as hasUnsignedVariant, but for float variants | |
51 private bool hasFloatVariant(BuiltinOperation op) | |
52 { | |
53 alias BuiltinOperation O; | |
54 return op is O.SDiv | |
55 || op is O.SRem | |
56 || op is O.SLt | |
57 || op is O.SLe | |
58 || op is O.SGt | |
59 || op is O.SGe; | |
60 } | |
61 | |
62 private BuiltinOperation OpToBI(Operator op) | |
63 { | |
64 // This is dependent on the definition of Operator | |
65 // Maps from an Operator to the first appropiate BuiltinOperation | |
66 static const BuiltinOperation[] map = | |
67 [ | |
68 BuiltinOperation.Add, | |
69 BuiltinOperation.Sub, | |
70 BuiltinOperation.Mul, | |
71 BuiltinOperation.SDiv, | |
72 BuiltinOperation.SRem, | |
73 | |
74 BuiltinOperation.Shl, | |
75 BuiltinOperation.LShr, | |
76 BuiltinOperation.AShr, | |
77 BuiltinOperation.And, | |
78 BuiltinOperation.Or, | |
79 BuiltinOperation.Xor, | |
80 | |
81 BuiltinOperation.Eq, | |
82 BuiltinOperation.Ne, | |
83 BuiltinOperation.SLt, | |
84 BuiltinOperation.SLe, | |
85 BuiltinOperation.SGt, | |
86 BuiltinOperation.SGe, | |
87 | |
88 ]; | |
89 if (op >= Operator.Add && op <= Operator.Ge) | |
90 return map[op]; | |
91 | |
92 return BuiltinOperation.None; | |
93 } | |
94 | |
95 /** | |
96 Represents an operation on to values of (potentionally) different types. | |
97 | |
98 Can be either some built-in thing (addition of floats, int etc) or a user | |
99 defined operation (a method in a struct/class). | |
100 **/ | |
101 struct Operation | |
102 { | |
103 /// Returns true if the operation is legal | |
104 bool isPossible() { return is_valid; } | |
105 | |
106 /// True for <, <=, ==, !=, >, >= | |
107 bool isComparison() { return false; } | |
108 | |
109 /// Built in operations like adding ints or floats | |
110 bool isBuiltin() { return is_bi; } | |
111 | |
112 /// Get the builtin operation - only valid if isBuiltin() returns true | |
113 BuiltinOperation builtinOp() { return bi_op; }; | |
114 | |
115 /// Create builtin operation | |
116 static Operation builtin(Operator op, bool unsigned, bool fp) | |
117 { | |
118 assert(!(unsigned && fp), "Can't be both unsigned and a float"); | |
119 Operation res; | |
120 res.is_valid = true; | |
121 res.is_bi = true; | |
122 res.bi_op = OpToBI(op); | |
123 | |
124 if (unsigned && hasUnsignedVariant(res.bi_op)) | |
125 res.bi_op += 1; | |
126 if (fp && hasFloatVariant(res.bi_op)) | |
127 res.bi_op += 2; | |
128 return res; | |
129 } | |
130 | |
131 private: | |
132 bool is_valid = false; | |
133 bool is_bi; | |
134 BuiltinOperation bi_op; | |
135 } | |
136 |