]> git.saurik.com Git - cycript.git/blob - Decode.cpp
Parse scope and symbol colon operators, from Ruby.
[cycript.git] / Decode.cpp
1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2015 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 CYTypedIdentifier *Primitive<bool>::Decode(CYPool &pool) const {
31 return $ CYTypedIdentifier($ CYTypeVariable("bool"));
32 }
33
34 template <>
35 CYTypedIdentifier *Primitive<char>::Decode(CYPool &pool) const {
36 return $ CYTypedIdentifier($ CYTypeCharacter(CYTypeNeutral));
37 }
38
39 template <>
40 CYTypedIdentifier *Primitive<double>::Decode(CYPool &pool) const {
41 return $ CYTypedIdentifier($ CYTypeVariable("double"));
42 }
43
44 template <>
45 CYTypedIdentifier *Primitive<float>::Decode(CYPool &pool) const {
46 return $ CYTypedIdentifier($ CYTypeVariable("float"));
47 }
48
49 template <>
50 CYTypedIdentifier *Primitive<signed char>::Decode(CYPool &pool) const {
51 return $ CYTypedIdentifier($ CYTypeCharacter(CYTypeSigned));
52 }
53
54 template <>
55 CYTypedIdentifier *Primitive<signed int>::Decode(CYPool &pool) const {
56 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 1));
57 }
58
59 template <>
60 CYTypedIdentifier *Primitive<signed long int>::Decode(CYPool &pool) const {
61 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 2));
62 }
63
64 template <>
65 CYTypedIdentifier *Primitive<signed long long int>::Decode(CYPool &pool) const {
66 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 3));
67 }
68
69 template <>
70 CYTypedIdentifier *Primitive<signed short int>::Decode(CYPool &pool) const {
71 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 0));
72 }
73
74 template <>
75 CYTypedIdentifier *Primitive<unsigned char>::Decode(CYPool &pool) const {
76 return $ CYTypedIdentifier($ CYTypeCharacter(CYTypeUnsigned));
77 }
78
79 template <>
80 CYTypedIdentifier *Primitive<unsigned int>::Decode(CYPool &pool) const {
81 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 1));
82 }
83
84 template <>
85 CYTypedIdentifier *Primitive<unsigned long int>::Decode(CYPool &pool) const {
86 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 2));
87 }
88
89 template <>
90 CYTypedIdentifier *Primitive<unsigned long long int>::Decode(CYPool &pool) const {
91 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 3));
92 }
93
94 template <>
95 CYTypedIdentifier *Primitive<unsigned short int>::Decode(CYPool &pool) const {
96 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 0));
97 }
98
99 CYTypedIdentifier *Void::Decode(CYPool &pool) const {
100 return $ CYTypedIdentifier($ CYTypeVoid());
101 }
102
103 CYTypedIdentifier *Unknown::Decode(CYPool &pool) const {
104 return $ CYTypedIdentifier($ CYTypeError());
105 }
106
107 CYTypedIdentifier *String::Decode(CYPool &pool) const {
108 return $ CYTypedIdentifier($ CYTypeCharacter(CYTypeNeutral), $ CYTypePointerTo());
109 }
110
111 CYTypedIdentifier *Meta::Decode(CYPool &pool) const {
112 return $ CYTypedIdentifier($ CYTypeVariable("Class"));
113 }
114
115 CYTypedIdentifier *Selector::Decode(CYPool &pool) const {
116 return $ CYTypedIdentifier($ CYTypeVariable("SEL"));
117 }
118
119 CYTypedIdentifier *Bits::Decode(CYPool &pool) const {
120 _assert(false);
121 }
122
123 CYTypedIdentifier *Pointer::Decode(CYPool &pool) const {
124 return CYDecodeType(pool, &type)->Modify($ CYTypePointerTo());
125 }
126
127 CYTypedIdentifier *Array::Decode(CYPool &pool) const {
128 return CYDecodeType(pool, &type)->Modify($ CYTypeArrayOf($D(size)));
129 }
130
131 CYTypedIdentifier *Object::Decode(CYPool &pool) const {
132 if (name == NULL)
133 return $ CYTypedIdentifier($ CYTypeVariable("id"));
134 else
135 return $ CYTypedIdentifier($ CYTypeVariable(name), $ CYTypePointerTo());
136 }
137
138 CYTypedIdentifier *Aggregate::Decode(CYPool &pool) const {
139 _assert(!overlap);
140
141 CYTypeStructField *fields(NULL);
142 for (size_t i(signature.count); i != 0; --i) {
143 sig::Element &element(signature.elements[i - 1]);
144 CYTypedIdentifier *typed(CYDecodeType(pool, element.type));
145 if (element.name != NULL)
146 typed->identifier_ = $I(element.name);
147 fields = $ CYTypeStructField(typed, fields);
148 }
149 CYIdentifier *identifier(name == NULL ? NULL : $I(name));
150 return $ CYTypedIdentifier($ CYTypeStruct(identifier, $ CYStructTail(fields)));
151 }
152
153 CYTypedIdentifier *Callable::Decode(CYPool &pool) const {
154 _assert(signature.count != 0);
155 CYTypedParameter *parameters(NULL);
156 for (size_t i(signature.count - 1); i != 0; --i)
157 parameters = $ CYTypedParameter(CYDecodeType(pool, signature.elements[i].type), parameters);
158 return Modify(pool, CYDecodeType(pool, signature.elements[0].type), parameters);
159 }
160
161 CYTypedIdentifier *Function::Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const {
162 return result->Modify($ CYTypeFunctionWith(variadic, parameters));
163 }
164
165 CYTypedIdentifier *Block::Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const {
166 return result->Modify($ CYTypeBlockWith(parameters));
167 }
168
169 CYTypedIdentifier *Block::Decode(CYPool &pool) const {
170 if (signature.count == 0)
171 return $ CYTypedIdentifier($ CYTypeVariable("NSBlock"), $ CYTypePointerTo());
172 return Callable::Decode(pool);
173 }
174
175 }
176
177 CYTypedIdentifier *CYDecodeType(CYPool &pool, struct sig::Type *type) {
178 CYTypedIdentifier *typed(type->Decode(pool));
179 if ((type->flags & JOC_TYPE_CONST) != 0) {
180 if (dynamic_cast<sig::String *>(type) != NULL)
181 typed->modifier_ = $ CYTypeConstant(typed->modifier_);
182 else
183 typed = typed->Modify($ CYTypeConstant());
184 }
185 return typed;
186 }