-
Notifications
You must be signed in to change notification settings - Fork 4
/
type_conversion.h
129 lines (109 loc) · 3.64 KB
/
type_conversion.h
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#define T_ERROR -1
#define T_INT 0
#define T_CHAR 1
#define T_FLOAT 2
#define T_DOUBLE 3
#define T_STRING 4
#define T_BOOL 5
#define N_TYPES 6 // Number of types
struct T_tuple {
int type;
int warning;
};
struct T_table {
int add[N_TYPES][N_TYPES]; // row + col
int other[N_TYPES][N_TYPES]; //row -*/ col
// 0 = FALSE, 1 = TRUE, 2 = TRUE WITH WARNING
int implicit[N_TYPES][N_TYPES]; // row to col
int add_warnings[N_TYPES][N_TYPES];
int other_warnings[N_TYPES][N_TYPES];
};
struct T_table casting_table = {
.add={
{ T_INT, T_INT, T_FLOAT, T_DOUBLE, T_ERROR, T_INT },
{ T_INT, T_INT, T_FLOAT, T_DOUBLE, T_STRING, T_INT },
{ T_FLOAT, T_FLOAT, T_FLOAT, T_DOUBLE, T_ERROR, T_FLOAT },
{ T_DOUBLE, T_DOUBLE, T_DOUBLE, T_DOUBLE, T_ERROR, T_DOUBLE },
{ T_STRING, T_STRING, T_STRING, T_STRING, T_STRING, T_STRING },
{ T_INT, T_INT, T_FLOAT, T_DOUBLE, T_ERROR, T_INT }
},
.other={
{ T_INT, T_INT, T_FLOAT, T_DOUBLE, T_ERROR, T_INT },
{ T_INT, T_INT, T_FLOAT, T_DOUBLE, T_ERROR, T_INT },
{ T_FLOAT, T_FLOAT, T_FLOAT, T_DOUBLE, T_ERROR, T_FLOAT },
{ T_DOUBLE, T_DOUBLE, T_DOUBLE, T_DOUBLE, T_ERROR, T_DOUBLE },
{ T_ERROR, T_ERROR, T_ERROR, T_ERROR, T_ERROR, T_ERROR },
{ T_INT, T_INT, T_FLOAT, T_DOUBLE, T_ERROR, T_INT }
},
// 0 = FALSE, 1 = TRUE, 2 = TRUE WITH WARNING
.implicit={
{ 1, 1, 1, 1, 0, 1 },
{ 1, 1, 1, 1, 0, 1 },
{ 2, 2, 1, 1, 0, 2 },
{ 2, 2, 1, 1, 0, 2 },
{ 0, 0, 0, 0, 1, 1 },
{ 1, 1, 1, 1, 0, 1 }
},
.add_warnings={
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
{ 2, 2, 2, 2, 0, 2 },
{ 0, 0, 0, 0, 0, 0 }
},
.other_warnings={
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 }
}
};
struct T_tuple cast_type(char l_type_char, char r_type_char, char operator){
struct T_tuple ret;
int l_type = l_type_char-48;
int r_type = r_type_char-48;
switch (operator){
case '+':
ret.type = casting_table.add[l_type][r_type];
ret.warning = casting_table.add_warnings[l_type][r_type];
break;
case '0': ; // implicit
int aux = casting_table.implicit[l_type][r_type];
ret.type = aux == 0 ? T_ERROR : r_type;
ret.warning = aux == 2 ? 1 : 0;
break;
case '-':
case '*':
case '/':
ret.type = casting_table.other[l_type][r_type];
ret.warning = casting_table.other_warnings[l_type][r_type];
break;
default:
ret.type = T_ERROR;
ret.warning = 0;
break;
}
return ret;
}
char *type_to_str(char type_char){
int type = type_char-48;
switch (type){
case T_INT:
return "INT";
case T_CHAR:
return "CHAR";
case T_FLOAT:
return "FLOAT";
case T_DOUBLE:
return "DOUBLE";
case T_STRING:
return "STRING";
case T_BOOL:
return "BOOL";
default:
return "ERROR";
}
}