]> git.saurik.com Git - cycript.git/blob - Decode.cpp
libcycript.cy needs to be set as symlink, for zip.
[cycript.git] / Decode.cpp
1 /* Cycript - The Truly Universal Scripting Language
2 * Copyright (C) 2009-2016 Jay Freeman (saurik)
3 */
4
5 /* GNU Affero General Public License, Version 3 {{{ */
6 /*
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20 /* }}} */
21
22 #include <sstream>
23
24 #include "Decode.hpp"
25 #include "Replace.hpp"
26
27 namespace sig {
28
29 template <>
30 CYType *Primitive<bool>::Decode(CYPool &pool) const {
31 return $ CYType($ CYTypeVariable("bool"));
32 }
33
34 template <>
35 CYType *Primitive<char>::Decode(CYPool &pool) const {
36 return $ CYType($ CYTypeCharacter(CYTypeNeutral));
37 }
38
39 template <>
40 CYType *Primitive<double>::Decode(CYPool &pool) const {
41 return $ CYType($ CYTypeFloating(1));
42 }
43
44 template <>
45 CYType *Primitive<float>::Decode(CYPool &pool) const {
46 return $ CYType($ CYTypeFloating(0));
47 }
48
49 template <>
50 CYType *Primitive<long double>::Decode(CYPool &pool) const {
51 return $ CYType($ CYTypeFloating(2));
52 }
53
54 template <>
55 CYType *Primitive<signed char>::Decode(CYPool &pool) const {
56 return $ CYType($ CYTypeCharacter(CYTypeSigned));
57 }
58
59 template <>
60 CYType *Primitive<signed int>::Decode(CYPool &pool) const {
61 return $ CYType($ CYTypeIntegral(CYTypeSigned, 1));
62 }
63
64 #ifdef __SIZEOF_INT128__
65 template <>
66 CYType *Primitive<signed __int128>::Decode(CYPool &pool) const {
67 return $ CYType($ CYTypeInt128(CYTypeSigned));
68 }
69 #endif
70
71 template <>
72 CYType *Primitive<signed long int>::Decode(CYPool &pool) const {
73 return $ CYType($ CYTypeIntegral(CYTypeSigned, 2));
74 }
75
76 template <>
77 CYType *Primitive<signed long long int>::Decode(CYPool &pool) const {
78 return $ CYType($ CYTypeIntegral(CYTypeSigned, 3));
79 }
80
81 template <>
82 CYType *Primitive<signed short int>::Decode(CYPool &pool) const {
83 return $ CYType($ CYTypeIntegral(CYTypeSigned, 0));
84 }
85
86 template <>
87 CYType *Primitive<unsigned char>::Decode(CYPool &pool) const {
88 return $ CYType($ CYTypeCharacter(CYTypeUnsigned));
89 }
90
91 template <>
92 CYType *Primitive<unsigned int>::Decode(CYPool &pool) const {
93 return $ CYType($ CYTypeIntegral(CYTypeUnsigned, 1));
94 }
95
96 #ifdef __SIZEOF_INT128__
97 template <>
98 CYType *Primitive<unsigned __int128>::Decode(CYPool &pool) const {
99 return $ CYType($ CYTypeInt128(CYTypeUnsigned));
100 }
101 #endif
102
103 template <>
104 CYType *Primitive<unsigned long int>::Decode(CYPool &pool) const {
105 return $ CYType($ CYTypeIntegral(CYTypeUnsigned, 2));
106 }
107
108 template <>
109 CYType *Primitive<unsigned long long int>::Decode(CYPool &pool) const {
110 return $ CYType($ CYTypeIntegral(CYTypeUnsigned, 3));
111 }
112
113 template <>
114 CYType *Primitive<unsigned short int>::Decode(CYPool &pool) const {
115 return $ CYType($ CYTypeIntegral(CYTypeUnsigned, 0));
116 }
117
118 CYType *Void::Decode(CYPool &pool) const {
119 return $ CYType($ CYTypeVoid());
120 }
121
122 CYType *Unknown::Decode(CYPool &pool) const {
123 return $ CYType($ CYTypeError());
124 }
125
126 CYType *String::Decode(CYPool &pool) const {
127 return $ CYType($ CYTypeCharacter(CYTypeNeutral), $ CYTypePointerTo());
128 }
129
130 #ifdef CY_OBJECTIVEC
131 CYType *Meta::Decode(CYPool &pool) const {
132 return $ CYType($ CYTypeVariable("Class"));
133 }
134
135 CYType *Selector::Decode(CYPool &pool) const {
136 return $ CYType($ CYTypeVariable("SEL"));
137 }
138 #endif
139
140 CYType *Bits::Decode(CYPool &pool) const {
141 _assert(false);
142 }
143
144 CYType *Pointer::Decode(CYPool &pool) const {
145 return CYDecodeType(pool, &type)->Modify($ CYTypePointerTo());
146 }
147
148 CYType *Array::Decode(CYPool &pool) const {
149 return CYDecodeType(pool, &type)->Modify($ CYTypeArrayOf($D(size)));
150 }
151
152 #ifdef CY_OBJECTIVEC
153 CYType *Object::Decode(CYPool &pool) const {
154 if (name == NULL)
155 return $ CYType($ CYTypeVariable("id"));
156 else
157 return $ CYType($ CYTypeVariable(name), $ CYTypePointerTo());
158 }
159 #endif
160
161 CYType *Enum::Decode(CYPool &pool) const {
162 CYEnumConstant *values(NULL);
163 for (size_t i(count); i != 0; --i)
164 values = $ CYEnumConstant($I(pool.strdup(constants[i - 1].name)), $D(constants[i - 1].value), values);
165 CYIdentifier *identifier(name == NULL ? NULL : $I(name));
166 CYType *typed(type.Decode(pool));
167 _assert(typed->modifier_ == NULL);
168 return $ CYType($ CYTypeEnum(identifier, typed->specifier_, values));
169 }
170
171 CYType *Aggregate::Decode(CYPool &pool) const {
172 _assert(!overlap);
173
174 if (signature.count == _not(size_t)) {
175 _assert(name != NULL);
176 return $ CYType($ CYTypeReference(CYTypeReferenceStruct, $I($pool.strdup(name))));
177 }
178
179 CYTypeStructField *fields(NULL);
180 for (size_t i(signature.count); i != 0; --i) {
181 sig::Element &element(signature.elements[i - 1]);
182 fields = $ CYTypeStructField(CYDecodeType(pool, element.type), element.name == NULL ? NULL : $I(element.name), fields);
183 }
184 CYIdentifier *identifier(name == NULL ? NULL : $I(name));
185 return $ CYType($ CYTypeStruct(identifier, $ CYStructTail(fields)));
186 }
187
188 CYType *Callable::Decode(CYPool &pool) const {
189 _assert(signature.count != 0);
190 CYTypedParameter *parameters(NULL);
191 for (size_t i(signature.count - 1); i != 0; --i)
192 parameters = $ CYTypedParameter(CYDecodeType(pool, signature.elements[i].type), NULL, parameters);
193 return Modify(pool, CYDecodeType(pool, signature.elements[0].type), parameters);
194 }
195
196 CYType *Function::Modify(CYPool &pool, CYType *result, CYTypedParameter *parameters) const {
197 return result->Modify($ CYTypeFunctionWith(variadic, parameters));
198 }
199
200 #ifdef CY_OBJECTIVEC
201 CYType *Block::Modify(CYPool &pool, CYType *result, CYTypedParameter *parameters) const {
202 return result->Modify($ CYTypeBlockWith(parameters));
203 }
204
205 CYType *Block::Decode(CYPool &pool) const {
206 if (signature.count == 0)
207 return $ CYType($ CYTypeVariable("NSBlock"), $ CYTypePointerTo());
208 return Callable::Decode(pool);
209 }
210 #endif
211
212 }
213
214 CYType *CYDecodeType(CYPool &pool, struct sig::Type *type) {
215 CYType *typed(type->Decode(pool));
216 if ((type->flags & JOC_TYPE_CONST) != 0) {
217 if (dynamic_cast<sig::String *>(type) != NULL)
218 typed->modifier_ = $ CYTypeConstant(typed->modifier_);
219 else
220 typed = typed->Modify($ CYTypeConstant());
221 }
222 return typed;
223 }