Skip to content
Newer
Older
100644 361 lines (248 sloc) 10.4 KB
ee99867 @ccgus oh geeze
authored Mar 4, 2009
1 //
2 // JSTPreprocessor.m
3 // jstalk
4 //
5 // Created by August Mueller on 2/14/09.
6 // Copyright 2009 Flying Meat Inc. All rights reserved.
7 //
8
9 #import "JSTPreprocessor.h"
10 #import "TDTokenizer.h"
11 #import "TDToken.h"
12 #import "TDWhitespaceState.h"
13 #import "TDCommentState.h"
14
15 @implementation JSTPreprocessor
16
23db0b8 @ccgus Added support for experimental python-like multiline strings:
authored Aug 4, 2010
17 + (NSString*)processMultilineStrings:(NSString*)sourceString {
18
19 NSString *tok = @"\"\"\"";
20
21 NSScanner *scanner = [NSScanner scannerWithString:sourceString];
22 NSMutableString *ret = [NSMutableString string];
23
24 while (![scanner isAtEnd]) {
25
26 NSString *into;
27 NSString *quot;
28
29 if ([scanner scanUpToString:tok intoString:&into]) {
30 [ret appendString:into];
31 }
32
33
34 if ([scanner scanString:tok intoString:nil]) {
35 if ([scanner scanString:tok intoString: nil]) {
36 continue;
37 }
38 else if ([scanner scanUpToString:tok intoString:&quot] && [scanner scanString:tok intoString: nil]) {
39
40 quot = [quot stringByReplacingOccurrencesOfString:@"\r\n" withString:@"\n"];
41 quot = [quot stringByReplacingOccurrencesOfString:@"\r" withString:@"\n"];
42
43 [ret appendString:@"\""];
44
45 NSArray *lines = [quot componentsSeparatedByString:@"\n"];
46 int i = 0;
47 while (i < [lines count] - 1) {
48 NSString *line = [lines objectAtIndex:i];
49 line = [line stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
50 [ret appendFormat:@"%@\\n", line];
51 i++;
52 }
53
54 NSString *line = [lines objectAtIndex:i];
55 line = [line stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
56 [ret appendFormat:@"%@\"", line];
57 }
58 }
59 }
60
61 return ret;
62 }
63
c07386b @ccgus Added a new method "include" which includes and evals the named file
authored Jul 24, 2010
64 + (NSString*)preprocessForObjCStrings:(NSString*)sourceString {
ee99867 @ccgus oh geeze
authored Mar 5, 2009
65
66 NSMutableString *buffer = [NSMutableString string];
67 TDTokenizer *tokenizer = [TDTokenizer tokenizerWithString:sourceString];
68
69 tokenizer.whitespaceState.reportsWhitespaceTokens = YES;
e4b1c1e @ccgus [FIX] (<- look, just like wolf!) Some preprocessing bugs fixed.
authored Mar 15, 2009
70 tokenizer.commentState.reportsCommentTokens = NO;
ee99867 @ccgus oh geeze
authored Mar 5, 2009
71
72 TDToken *eof = [TDToken EOFToken];
73 TDToken *tok = 0x00;
74 TDToken *nextToken = 0x00;
75
76 while ((tok = [tokenizer nextToken]) != eof) {
77
78 if (tok.isSymbol && [[tok stringValue] isEqualToString:@"@"]) {
79
80 // woo, it's special objc stuff.
81
82 nextToken = [tokenizer nextToken];
83 if (nextToken.quotedString) {
84 [buffer appendFormat:@"[NSString stringWithString:%@]", [nextToken stringValue]];
85 }
86 else {
87 [buffer appendString:[tok stringValue]];
88 [buffer appendString:[nextToken stringValue]];
89 }
90 }
91 else {
92 [buffer appendString:[tok stringValue]];
93 }
94 }
95
96 return buffer;
97 }
98
c07386b @ccgus Added a new method "include" which includes and evals the named file
authored Jul 25, 2010
99 + (BOOL)isOpenSymbol:(NSString*)tag {
2789c34 @ccgus playing with a new parser strategy.
authored Jun 28, 2009
100 return [tag isEqualToString:@"["] || [tag isEqualToString:@"("];
101 }
102
c07386b @ccgus Added a new method "include" which includes and evals the named file
authored Jul 25, 2010
103 + (BOOL)isCloseSymbol:(NSString*)tag {
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
104 return [tag isEqualToString:@"]"] || [tag isEqualToString:@")"];
105 }
106
c07386b @ccgus Added a new method "include" which includes and evals the named file
authored Jul 25, 2010
107 + (NSString*)preprocessForObjCMessagesToJS:(NSString*)sourceString {
ee99867 @ccgus oh geeze
authored Mar 5, 2009
108
109 NSMutableString *buffer = [NSMutableString string];
110 TDTokenizer *tokenizer = [TDTokenizer tokenizerWithString:sourceString];
111
112 tokenizer.whitespaceState.reportsWhitespaceTokens = YES;
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
113 tokenizer.commentState.reportsCommentTokens = YES;
ee99867 @ccgus oh geeze
authored Mar 5, 2009
114
115 TDToken *eof = [TDToken EOFToken];
116 TDToken *tok = nil;
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
117
118 JSTPSymbolGroup *currentGroup = 0x00;
ee99867 @ccgus oh geeze
authored Mar 5, 2009
119
120 while ((tok = [tokenizer nextToken]) != eof) {
121
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
122 //debug(@"tok: '%@' %d", [tok description], tok.word);
123
124 if ([tok isSymbol] && [self isOpenSymbol:[tok stringValue]]) {
ee99867 @ccgus oh geeze
authored Mar 5, 2009
125
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
126 JSTPSymbolGroup *nextGroup = [[[JSTPSymbolGroup alloc] init] autorelease];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
127
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
128 nextGroup.parent = currentGroup;
129 currentGroup = nextGroup;
130
ee99867 @ccgus oh geeze
authored Mar 5, 2009
131 }
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
132 else if (tok.isSymbol && [self isCloseSymbol:tok.stringValue]) {
ee99867 @ccgus oh geeze
authored Mar 5, 2009
133
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
134 if (currentGroup.parent) {
135 [currentGroup.parent addSymbol:currentGroup];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
136 }
a84aff8 @ccgus Just oooone more tiny fix.
authored Sep 23, 2010
137 else if ([currentGroup description]) {
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
138 [buffer appendString:[currentGroup description]];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
139 }
140
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
141 currentGroup = currentGroup.parent;
ee99867 @ccgus oh geeze
authored Mar 5, 2009
142
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
143 continue;
ee99867 @ccgus oh geeze
authored Mar 5, 2009
144 }
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
145
146 if (currentGroup) {
147 [currentGroup addSymbol:tok];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
148 }
149 else {
150 [buffer appendString:[tok stringValue]];
151 }
152 }
153
154 return buffer;
155 }
156
c07386b @ccgus Added a new method "include" which includes and evals the named file
authored Jul 25, 2010
157 + (NSString*)preprocessCode:(NSString*)sourceString {
ee99867 @ccgus oh geeze
authored Mar 5, 2009
158
23db0b8 @ccgus Added support for experimental python-like multiline strings:
authored Aug 4, 2010
159 sourceString = [self processMultilineStrings:sourceString];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
160 sourceString = [self preprocessForObjCStrings:sourceString];
161 sourceString = [self preprocessForObjCMessagesToJS:sourceString];
162
163 return sourceString;
164 }
165
166 @end
167
168
169
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
170 @implementation JSTPSymbolGroup
ee99867 @ccgus oh geeze
authored Mar 5, 2009
171 @synthesize args=_args;
172 @synthesize parent=_parent;
173
c07386b @ccgus Added a new method "include" which includes and evals the named file
authored Jul 25, 2010
174 - (id)init {
ee99867 @ccgus oh geeze
authored Mar 5, 2009
175 self = [super init];
176 if (self != nil) {
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
177 _args = [[NSMutableArray array] retain];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
178 }
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
179
ee99867 @ccgus oh geeze
authored Mar 5, 2009
180 return self;
181 }
182
183
184 - (void)dealloc {
185 [_args release];
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
186 [_parent release];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
187 [super dealloc];
188 }
189
c07386b @ccgus Added a new method "include" which includes and evals the named file
authored Jul 25, 2010
190 - (void)addSymbol:(id)aSymbol {
ee99867 @ccgus oh geeze
authored Mar 5, 2009
191
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
192 if (!_openSymbol && [aSymbol isKindOfClass:[TDToken class]]) {
193 _openSymbol = [[aSymbol stringValue] characterAtIndex:0];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
194 }
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
195 else {
196 [_args addObject:aSymbol];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
197 }
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
198 }
199
781aade @ccgus Made a change to the preprocessor to support inline functions, which …
authored Sep 28, 2010
200 - (int)nonWhitespaceCountInArray:(NSArray*)ar {
201
202 int count = 0;
203
204 for (id f in ar) {
205
206 f = [[f description] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
207
208 if ([f length]) {
209 count++;
210 }
211 }
212
213 return count;
214
215 }
216
c07386b @ccgus Added a new method "include" which includes and evals the named file
authored Jul 25, 2010
217 - (NSString*)description {
ee99867 @ccgus oh geeze
authored Mar 5, 2009
218
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
219 NSUInteger argsCount = [_args count];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
220
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
221 if (_openSymbol == '(') {
222 return [NSString stringWithFormat:@"(%@)", [_args componentsJoinedByString:@""]];
e4b1c1e @ccgus [FIX] (<- look, just like wolf!) Some preprocessing bugs fixed.
authored Mar 16, 2009
223 }
224
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
225 if (_openSymbol != '[') {
226 return [NSString stringWithFormat:@"Bad JSTPSymbolGroup! %@", _args];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
227 }
228
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
229 BOOL firstArgIsWord = [_args count] && ([[_args objectAtIndex:0] isKindOfClass:[TDToken class]] && [[_args objectAtIndex:0] isWord]);
230 BOOL firstArgIsSymbolGroup = [_args count] && [[_args objectAtIndex:0] isKindOfClass:[JSTPSymbolGroup class]];
e4b1c1e @ccgus [FIX] (<- look, just like wolf!) Some preprocessing bugs fixed.
authored Mar 16, 2009
231
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
232 // objc messages start with a word. So, if it isn't- then let's just fling things back the way they were.
233 if (!firstArgIsWord && !firstArgIsSymbolGroup) {
234 return [NSString stringWithFormat:@"[%@]", [_args componentsJoinedByString:@""]];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
235 }
236
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
237
238 NSMutableString *selector = [NSMutableString string];
239 NSMutableArray *currentArgs = [NSMutableArray array];
240 NSMutableArray *methodArgs = [NSMutableArray array];
241 NSString *target = [_args objectAtIndex:0];
242 NSString *lastWord = 0x00;
243 BOOL hadSymbolAsArg = NO;
244 NSUInteger idx = 1;
245
246 while (idx < argsCount) {
ee99867 @ccgus oh geeze
authored Mar 5, 2009
247
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
248 id currentPassedArg = [_args objectAtIndex:idx++];
249
250 TDToken *currentToken = [currentPassedArg isKindOfClass:[TDToken class]] ? currentPassedArg : 0x00;
ee99867 @ccgus oh geeze
authored Mar 5, 2009
251
781aade @ccgus Made a change to the preprocessor to support inline functions, which …
authored Sep 28, 2010
252 NSString *value = currentToken ? [currentToken stringValue] : [currentPassedArg description];
253
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
254 if ([currentToken isWhitespace]) {
781aade @ccgus Made a change to the preprocessor to support inline functions, which …
authored Sep 28, 2010
255
256 //if ([value isEqualToString:@" "]) {
257 [currentArgs addObject:value];
258 //}
259
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
260 continue;
261 }
ee99867 @ccgus oh geeze
authored Mar 5, 2009
262
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
263 if (!hadSymbolAsArg && [currentToken isSymbol]) {
264 hadSymbolAsArg = YES;
ee99867 @ccgus oh geeze
authored Mar 5, 2009
265 }
266
781aade @ccgus Made a change to the preprocessor to support inline functions, which …
authored Sep 28, 2010
267
ee99867 @ccgus oh geeze
authored Mar 5, 2009
268
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
269 if ([@":" isEqualToString:value]) {
270
271 [currentArgs removeLastObject];
272
273 if ([currentArgs count]) {
274 [methodArgs addObject:[currentArgs componentsJoinedByString:@" "]];
275 [currentArgs removeAllObjects];
276 }
277
278 [selector appendString:lastWord];
279 [selector appendString:value];
280 }
281 else {
282 [currentArgs addObject:[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
283 }
284
285 lastWord = value;
ee99867 @ccgus oh geeze
authored Mar 5, 2009
286 }
287
e4b1c1e @ccgus [FIX] (<- look, just like wolf!) Some preprocessing bugs fixed.
authored Mar 16, 2009
288
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
289 if ([currentArgs count]) {
290 [methodArgs addObject:[currentArgs componentsJoinedByString:@""]];
291 }
e4b1c1e @ccgus [FIX] (<- look, just like wolf!) Some preprocessing bugs fixed.
authored Mar 16, 2009
292
ee99867 @ccgus oh geeze
authored Mar 5, 2009
293
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
294 if (![selector length] && !hadSymbolAsArg && ([methodArgs count] == 1)) {
295 [selector appendString:[methodArgs lastObject]];
296 [methodArgs removeAllObjects];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
297 }
298
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
299 if (![selector length] && [methodArgs count] == 1) {
300 return [NSString stringWithFormat:@"[%@%@]", target, [methodArgs lastObject]];
e4b1c1e @ccgus [FIX] (<- look, just like wolf!) Some preprocessing bugs fixed.
authored Mar 16, 2009
301 }
302
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
303 if (![methodArgs count] && ![selector length]) {
304 return [NSString stringWithFormat:@"[%@]", target];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
305 }
306
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
307 if (![selector length] && lastWord) {
308 [selector appendString:lastWord];
309 [methodArgs removeLastObject];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
310 }
311
312
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
313 BOOL useMsgSend = NO;
ee99867 @ccgus oh geeze
authored Mar 5, 2009
314
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
315 if (useMsgSend) {
698bb6e @ccgus Little formatting updates, and a bit of experimentation.
authored Sep 14, 2010
316 NSMutableString *ret = [NSMutableString stringWithString:@"jsobjc_msgSend"];
317
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
318 if ([methodArgs count]) {
4916b19 @ccgus Fixed a bunch of string formatting errors (thanks to clang 3.1 pointi…
authored May 14, 2012
319 [ret appendFormat:@"%d", (int)[methodArgs count]];
698bb6e @ccgus Little formatting updates, and a bit of experimentation.
authored Sep 15, 2010
320 }
321
322 [ret appendFormat:@"(%@, \"%@\"", target, selector];
323
324 for (NSString *arg in methodArgs) {
325 [ret appendFormat:@", %@", arg];
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
326 }
327
698bb6e @ccgus Little formatting updates, and a bit of experimentation.
authored Sep 15, 2010
328 [ret appendString:@")"];
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
329
330 return ret;
331 }
ee99867 @ccgus oh geeze
authored Mar 5, 2009
332
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
333 [selector replaceOccurrencesOfString:@":" withString:@"_" options:0 range:NSMakeRange(0, [selector length])];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
334
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
335 NSMutableString *ret = [NSMutableString stringWithFormat:@"%@.%@(", target, selector];
ee99867 @ccgus oh geeze
authored Mar 5, 2009
336
781aade @ccgus Made a change to the preprocessor to support inline functions, which …
authored Sep 28, 2010
337 if ([self nonWhitespaceCountInArray:methodArgs]) {
338
339 for (int i = 0; i < [methodArgs count]; i++) {
340
341 NSString *arg = [methodArgs objectAtIndex:i];
342 NSString *s = [arg description];
343 NSString *t = [s stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
344
345 [ret appendString:s];
346
347 if ([t length] && i < [methodArgs count] - 1) {
348 [ret appendString:@","];
349 }
350 }
ee99867 @ccgus oh geeze
authored Mar 5, 2009
351 }
352
353 [ret appendString:@")"];
354
355 return ret;
2789c34 @ccgus playing with a new parser strategy.
authored Jun 29, 2009
356
ee99867 @ccgus oh geeze
authored Mar 5, 2009
357 }
358
359 @end
360
Something went wrong with that request. Please try again.