]> pd.if.org Git - lice/blob - conv.c
autocommit for files dated 2014-11-17 20:15:26
[lice] / conv.c
1 /*
2  * The complicated C rule set for type conversion. This is a full research
3  * oriented approach, run against the standard, and the tons of trial and
4  * error.
5  *
6  * A little bit about what is involed in type conversion:
7  *  - Arithmetic type rules
8  *  - Implicit conversion
9  *  - Explicit conversion
10  *
11  * 1. Arithmetic type rules:
12  *      The C standard defines a set of rules about arithmetic type
13  *      conversion, known as the conversion rank rules, which
14  *      essentially dictate which sides of an expression need to be
15  *      converted.
16  *
17  *      First rule:
18  *      If the left hand side of an expression isn't an arithmetic type
19  *      or the right hand side of an expression isn't an arithmetic type
20  *      no conversion takes place.
21  *
22  *      Second rule:
23  *      If the conversion rank of the left hand side expression type
24  *      is less than the conversion rank of the right hand side
25  *      expression type, then the left hand side of that expressions type
26  *      gets converted to the right hands type.
27  *
28  *      Third rule:
29  *      If the conversion rank of the left hand expression type doesn't
30  *      compare equal to the right hands type, then the right hand side of
31  *      that expressions type gets converted to the left hands type.
32  *
33  *      Last rule:
34  *      If none of the above applies, then nothing is subjected to conversion,
35  *      and doesn't need to be converted, unless the following:
36  *
37  *          The binary expression in which each operand is associated with happens
38  *          to be of a relational one in which case the type is converted to
39  *          integer type.
40  *
41  *          The expression happens to be of array type, in which case the array
42  *          decays to a pointer of it's base type.
43  *
44  *  2. Implicit conversion
45  *      Implicit type conversion takes place in two senarios, 1, when
46  *      conversion ranking is involved (promoted types), or when the
47  *      subject of a shift operation where the larger types is always
48  *      assumed to satisfy the shift operation.
49  *
50  *  3. Explicit conversion
51  *      The type which is assumed in explicit conversion (casting) is
52  *      the type in which the operand is converted to, unless the conversion
53  *      isn't legal (vector -> scalar for instance)
54  */
55 #include "ast.h"
56 #include "lice.h"
57
58 bool conv_capable(data_type_t *type) {
59     return ast_type_isinteger(type) || ast_type_isfloating(type);
60 }
61
62 int conv_rank(data_type_t *type) {
63     if (!conv_capable(type))
64         goto error;
65
66     switch (type->type) {
67         case TYPE_BOOL:    return 0;
68         case TYPE_CHAR:    return 1;
69         case TYPE_SHORT:   return 2;
70         case TYPE_INT:     return 3;
71         case TYPE_LONG:    return 4;
72         case TYPE_LLONG:   return 5;
73         case TYPE_FLOAT:   return 6;
74         case TYPE_DOUBLE:  return 7;
75         case TYPE_LDOUBLE: return 8;
76         default:
77             goto error;
78     }
79
80 error:
81     compile_ice("conv_rank");
82 }
83
84 data_type_t *conv_senority(data_type_t *lhs, data_type_t *rhs) {
85     return conv_rank(lhs) < conv_rank(rhs) ? rhs : lhs;
86 }
87
88 ast_t *conv_usual(int operation, ast_t *left, ast_t *right) {
89     if (!conv_capable(left->ctype) || !conv_capable(right->ctype)) {
90         data_type_t *result;
91         switch (operation) {
92             case AST_TYPE_LEQUAL:
93             case AST_TYPE_GEQUAL:
94             case AST_TYPE_EQUAL:
95             case AST_TYPE_NEQUAL:
96             case '<':
97             case '>':
98                 result = ast_data_table[AST_DATA_INT];
99                 break;
100             default:
101                 result = ast_array_convert(left->ctype);
102                 break;
103         }
104
105         return ast_new_binary(result, operation, left, right);
106     }
107
108     int lrank = conv_rank(left->ctype);
109     int rrank = conv_rank(right->ctype);
110
111     if (lrank < rrank)
112         left  = ast_type_convert(right->ctype, left);
113     else if (lrank != rrank)
114         right = ast_type_convert(left->ctype, right);
115
116     data_type_t *result = ast_result_type(operation, left->ctype);
117     return ast_new_binary(result, operation, left, right);
118 }