Skip to content

Commit 5b0932b

Browse files
committed
Working
1 parent 66e9d1e commit 5b0932b

File tree

9 files changed

+360
-15
lines changed

9 files changed

+360
-15
lines changed

JawaScriptExecutive-iOS/JawaArray.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ -(NSMutableString*) toJSON:(NSMutableString*)ret {
3939
}
4040

4141
-(void)append:(JawaObjectRef*)element {
42-
[self.elements addObject:element];
42+
// Need weak references stored in NSArray.
43+
NSValue* weakRef = [NSValue valueWithNonretainedObject:element];
44+
[self.elements addObject:weakRef];
4345
}
4446

4547
-(JawaObjectRef*)at:(int)index {

JawaScriptExecutive-iOS/JawaExecutor.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,17 @@
1212
@class JawaObjectRef;
1313

1414
@interface JawaExecutor : NSObject
15+
@property (weak) NSMutableDictionary* env;
16+
@property NSMutableDictionary* global;
17+
@property NSMutableArray* activations;
1518
@property NSMutableArray* currentActivation;
19+
@property NSMutableDictionary* currentIterationScope;
20+
@property BOOL isFromCallExpression;
1621

22+
-(id)init;
1723
-(JawaObjectRef*)evaluate:(NSDictionary*)tree;
24+
-(void)execute:(NSDictionary*)ast;
25+
-(NSMutableDictionary*) invoke:(NSString*)funcName with:(NSMutableDictionary*)asInput;
1826
-(JawaObjectRef*)dispatchBuiltin:(NSString*)funcName;
1927
@end
2028

@@ -37,7 +45,7 @@ typedef NS_ENUM(NSInteger, ASTType) {
3745
AND_EXPRESSION,
3846
EQUALITY_EXPRESSION,
3947
RELATIONAL_EXPRESSION,
40-
IN_EXPRESSINO,
48+
IN_EXPRESSION,
4149

4250
SHIFT_EXPRESSION,
4351
ADDITIVE_EXPRESSION,
@@ -70,16 +78,21 @@ typedef NS_ENUM(NSInteger, ASTType) {
7078
OBJECT_PROPERTY,
7179
};
7280

81+
#define PR_statements @"0"
82+
#define PR_elements @"7"
83+
#define PR_varName @"26"
84+
#define PR_initialization @"27"
85+
#define PR_declarations @"33"
86+
7387
typedef NS_ENUM(NSInteger, PropType) {
74-
PR_statements = 0,
7588
PR_valueType,
7689
PR_arguments,
7790
PR_id,
7891
PR_key,
7992

8093
PR_expr,
8194
PR_properties,
82-
PR_elements,
95+
8396
PR_literal,
8497
PR_constructor,
8598

@@ -102,15 +115,15 @@ typedef NS_ENUM(NSInteger, PropType) {
102115
PR_body,
103116

104117
PR_test,
105-
PR_varName,
106-
PR_initialization,
118+
119+
107120
PR_iterable,
108121
PR_iterator,
109122

110123
PR_init,
111124
PR_update,
112125
PR_argument,
113-
PR_declarations,
126+
114127
};
115128

116129
#endif /* JawaExecutor_h */

JawaScriptExecutive-iOS/JawaExecutor.m

Lines changed: 212 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,221 @@
77
//
88

99
#import <Foundation/Foundation.h>
10+
#import <UIKit/UIKit.h>
1011
#import "JawaExecutor.h"
12+
#import "JawaArray.h"
13+
#import "JawaFunc.h"
14+
#import "utility.h"
1115

16+
@implementation JawaExecutor
1217

18+
-(id)init {
19+
self = [super init];
20+
if (self) {
21+
_global = [[NSMutableDictionary alloc]init];
22+
_activations = [[NSMutableArray alloc]init];
23+
_currentActivation = [[NSMutableArray alloc]init];
24+
[_currentActivation addObject:_global];
25+
_currentIterationScope = nil;
26+
_isFromCallExpression = false;
27+
// TODO: Add externalCallback
28+
}
29+
return self;
30+
}
31+
32+
-(JawaObjectRef*)dispatchBuiltin:(NSString *)funcName {
33+
return nil;
34+
}
35+
36+
-(void)execute:(NSDictionary*)ast {
37+
[self evaluate:ast];
38+
}
39+
40+
-(NSMutableDictionary*)invoke:(NSString *)funcName with:(NSMutableDictionary*)asInput {
41+
self.env = asInput;
42+
JawaObjectRef* func = [self.global objectForKey:funcName];
43+
JawaFunc* resolvedFunction = (JawaFunc*)func.object;
44+
NSMutableDictionary* scope = [[NSMutableDictionary alloc]init];
45+
NSMutableArray* activation = [[NSMutableArray alloc]init];
46+
[activation addObject:scope];
47+
bool oldIsFromCallExpression = self.isFromCallExpression;
48+
self.isFromCallExpression = true;
49+
[self.activations addObject:activation];
50+
self.currentActivation = activation;
51+
JawaObjectRef *ret = [resolvedFunction apply];
52+
[self.activations removeLastObject];
53+
self.currentActivation = [self.activations lastObject];
54+
self.isFromCallExpression = oldIsFromCallExpression;
55+
56+
NSMutableDictionary* retJSON = [[NSMutableDictionary alloc]init];
57+
if (ret == nil || ret.object == nil)
58+
[retJSON setObject:@"null" forKey:@"retType"];
59+
else if ([ret.object isMemberOfClass:[JawaArray class]]) {
60+
[retJSON setObject:@"array" forKey:@"retType"];
61+
NSString* json = [((JawaArray*)ret.object) toJSON:nil];
62+
[retJSON setObject:jsonToArray(json) forKey:@"retValue"];
63+
} else if ([ret.object isKindOfClass:[JawaObject class]]) {
64+
[retJSON setObject:@"object" forKey:@"retType"];
65+
NSString* json = [((JawaObject*)ret.object) toJSON:nil];
66+
[retJSON setObject:jsonToDictionary(json) forKey:@"retValue"];
67+
} else if ([ret.object isMemberOfClass:[NSMutableString class]]) {
68+
[retJSON setObject:@"string" forKey:@"retType"];
69+
[retJSON setObject:[ret.object copy] forKey:@"retValue"];
70+
} else if ([ret.object isMemberOfClass:[NSDecimalNumber class]]) {
71+
[retJSON setObject:@"number" forKey:@"retType"];
72+
[retJSON setObject:[ret.object copy] forKey:@"retValue"];
73+
} else if ([ret.object isMemberOfClass:[NSNumber class]]) {
74+
[retJSON setObject:@"boolean" forKey:@"retType"];
75+
NSNumber *n = (NSNumber*)ret.object;
76+
[retJSON
77+
setObject:n.boolValue ? @"true" : @"false"
78+
forKey:@"retValue"];
79+
}
80+
81+
return retJSON;
82+
}
83+
84+
-(JawaObjectRef*)evalArrayExpression:(NSDictionary*)ast {
85+
NSArray* elements = [ast objectForKey:PR_elements];
86+
JawaArray* ret = [[JawaArray alloc]initIn:self];
87+
for (NSDictionary* element in elements) {
88+
[ret append:[self evaluate:element]];
89+
}
90+
return [JawaObjectRef RefWithJawaArray:ret];
91+
}
1392

14-
int main(int argc, char *argv[]) {
15-
return 0;
93+
-(void)declare:(NSString*)name with:(JawaObjectRef*)value {
94+
NSDictionary* currentScope = [self.currentActivation lastObject];
95+
if ([currentScope objectForKey:name] != nil)
96+
[NSException raise:@"JawaScript Runtime Error" format:@"Variable redeclaration (%@) in the current scope.", name];
97+
if (value == nil)
98+
[currentScope setValue:[JawaObjectRef RefIn:self] forKey:name];
99+
else
100+
[currentScope setValue:value forKey:name];
16101
}
17102

18-
// Test
103+
-(JawaObjectRef*)declareVar:(NSDictionary*)ast {
104+
printf("Running VARIABLE_DECLARATION\n");
105+
NSString* name = (NSString*)[ast objectForKey:PR_varName];
106+
NSDictionary* init = (NSDictionary*)[ast objectForKey:PR_initialization];
107+
if (init == nil)
108+
[self declare:name with:nil];
109+
else {
110+
JawaObjectRef* value = [self evaluate:init];
111+
[self declare:name with:value];
112+
}
113+
return nil;
114+
}
115+
116+
-(JawaObjectRef*)execVarStatement:(NSDictionary*)ast {
117+
printf("Running VAR_STATEMENT\n");
118+
NSArray* declarations = (NSArray*)[ast objectForKey:PR_declarations];
119+
for (NSDictionary* declaration in declarations) {
120+
[self evaluate:declaration];
121+
}
122+
return nil;
123+
}
124+
125+
-(JawaObjectRef*)evalScriptBody:(NSDictionary*)ast {
126+
printf("Running SCRIPT_BODY\n");
127+
NSArray* statements = (NSArray*)[ast objectForKey:PR_statements];
128+
for (NSDictionary* statement in statements) {
129+
[self evaluate:statement];
130+
}
131+
return nil;
132+
}
133+
134+
-(JawaObjectRef*)evaluate:(NSDictionary *)tree {
135+
if (tree == nil)
136+
return nil;
137+
int astType = ((NSNumber*)[tree objectForKey:@"t"]).intValue;
138+
switch (astType) {
139+
case SCRIPT_BODY:
140+
return [self evalScriptBody:tree];
141+
case FUNCTION_DECLARATION:
142+
break;
143+
case BLOCK_STATEMENT:
144+
break;
145+
case EMPTY_STATEMENT:
146+
break;
147+
case SEQUENCE_EXPRESSION:
148+
break;
149+
case ASSIGNMENT_EXPRESSION:
150+
break;
151+
case CONDITIONAL_EXPRESSION:
152+
break;
153+
case LOGICAL_OR_EXPRESSION:
154+
break;
155+
case LOGICAL_AND_EXPRESSION:
156+
break;
157+
case INCLUSIVE_OR_EXPRESSION:
158+
break;
159+
case EXCLUSIVE_OR_EXPRESSION:
160+
break;
161+
case AND_EXPRESSION:
162+
break;
163+
case EQUALITY_EXPRESSION:
164+
break;
165+
case RELATIONAL_EXPRESSION:
166+
break;
167+
case IN_EXPRESSION:
168+
break;
169+
case SHIFT_EXPRESSION:
170+
break;
171+
case ADDITIVE_EXPRESSION:
172+
break;
173+
case MULTIPLICATIVE_EXPRESSION:
174+
break;
175+
case UNARY_EXPRESSION:
176+
break;
177+
case POSTFIX_EXPRESSION:
178+
break;
179+
case STATIC_MEMBER_EXPRESSION:
180+
break;
181+
case CALL_EXPRESSION:
182+
break;
183+
case COMPUTED_MEMBER_EXPRESSION:
184+
break;
185+
case ARRAY_EXPRESSION:
186+
return [self evalArrayExpression:tree];
187+
case OBJECT_EXPRESSION:
188+
break;
189+
case IDENTIFIER:
190+
break;
191+
case IF_STATEMENT:
192+
break;
193+
case RETURN_STATEMENT:
194+
break;
195+
case VAR_STATEMENT:
196+
return [self execVarStatement:tree];
197+
case WHILE_STATEMENT:
198+
break;
199+
case CONTINUE_STATEMENT:
200+
break;
201+
case BREAK_STATEMENT:
202+
break;
203+
case DO_WHILE_STATEMENT:
204+
break;
205+
case FOR_STATEMENT:
206+
break;
207+
case VARIABLE_DECLARATION:
208+
return [self declareVar:tree];
209+
case LITERAL:
210+
break;
211+
default:
212+
break;
213+
}
214+
[NSException raise:@"Not implemented" format:@"%d not implemented", astType];
215+
return nil;
216+
}
217+
218+
-(void)placeReturn:(JawaObjectRef*)retValue {
219+
NSMutableDictionary* topScope = [self.currentActivation objectAtIndex:0];
220+
[topScope setObject:retValue forKey:@"return"];
221+
}
222+
223+
224+
225+
@end
226+
227+

JawaScriptExecutive-iOS/test.m

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// test.m
3+
// JawaScriptExecutive-iOS
4+
//
5+
// Created by Ben on 2016/1/30.
6+
//
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
#import "JawaExecutor.h"
11+
12+
BOOL test1() {
13+
JawaExecutor* ex = [[JawaExecutor alloc]init];
14+
NSError *error;
15+
NSString *parsed = @"{\"t\":0,\"0\":[{\"t\":37,\"33\":[{\"t\":34,\"26\":\"arr\",\"27\":{\"t\":27,\"7\":[{\"t\":25,\"8\":\"NUMERIC_LITERAL,5.0\"},{\"t\":25,\"8\":\"NUMERIC_LITERAL,1.0\"},{\"t\":25,\"8\":\"NUMERIC_LITERAL,6.0\"},{\"t\":25,\"8\":\"NUMERIC_LITERAL,2.0\"},{\"t\":25,\"8\":\"NUMERIC_LITERAL,9.0\"}]}}]},{\"t\":1,\"3\":\"insertion_sort\",\"23\":[\"arr\"],\"24\":{\"t\":2,\"0\":[{\"t\":33,\"24\":{\"t\":2,\"0\":[{\"t\":37,\"33\":[{\"t\":34,\"26\":\"min\",\"27\":{\"t\":22,\"10\":{\"t\":24,\"3\":\"arr\"},\"11\":{\"t\":24,\"3\":\"i\"}}}]},{\"t\":37,\"33\":[{\"t\":34,\"26\":\"minp\",\"27\":{\"t\":24,\"3\":\"i\"}}]},{\"t\":33,\"24\":{\"t\":2,\"0\":[{\"t\":35,\"18\":{\"t\":2,\"0\":[{\"t\":5,\"14\":\"PUNCTUATOR,=\",\"20\":{\"t\":24,\"3\":\"min\"},\"21\":{\"t\":22,\"10\":{\"t\":24,\"3\":\"arr\"},\"11\":{\"t\":24,\"3\":\"j\"}}},{\"t\":5,\"14\":\"PUNCTUATOR,=\",\"20\":{\"t\":24,\"3\":\"minp\"},\"21\":{\"t\":24,\"3\":\"j\"}}]},\"25\":{\"t\":13,\"15\":[{\"t\":5,\"v\":\"<\"}],\"16\":[{\"t\":22,\"10\":{\"t\":24,\"3\":\"arr\"},\"11\":{\"t\":24,\"3\":\"j\"}},{\"t\":24,\"3\":\"min\"}]}}]},\"25\":{\"t\":13,\"15\":[{\"t\":5,\"v\":\"<\"}],\"16\":[{\"t\":24,\"3\":\"j\"},{\"t\":20,\"10\":{\"t\":24,\"3\":\"arr\"},\"11\":{\"t\":24,\"3\":\"length\"}}]},\"30\":[{\"t\":34,\"26\":\"j\",\"27\":{\"t\":16,\"15\":[{\"t\":5,\"v\":\"+\"}],\"16\":[{\"t\":24,\"3\":\"i\"},{\"t\":25,\"8\":\"NUMERIC_LITERAL,1.0\"}]}}],\"31\":{\"t\":19,\"13\":{\"t\":24,\"3\":\"j\"},\"14\":\"PUNCTUATOR,++\"}},{\"t\":5,\"14\":\"PUNCTUATOR,=\",\"20\":{\"t\":22,\"10\":{\"t\":24,\"3\":\"arr\"},\"11\":{\"t\":24,\"3\":\"minp\"}},\"21\":{\"t\":22,\"10\":{\"t\":24,\"3\":\"arr\"},\"11\":{\"t\":24,\"3\":\"i\"}}},{\"t\":5,\"14\":\"PUNCTUATOR,=\",\"20\":{\"t\":22,\"10\":{\"t\":24,\"3\":\"arr\"},\"11\":{\"t\":24,\"3\":\"i\"}},\"21\":{\"t\":24,\"3\":\"min\"}}]},\"25\":{\"t\":13,\"15\":[{\"t\":5,\"v\":\"<\"}],\"16\":[{\"t\":24,\"3\":\"i\"},{\"t\":20,\"10\":{\"t\":24,\"3\":\"arr\"},\"11\":{\"t\":24,\"3\":\"length\"}}]},\"30\":[{\"t\":34,\"26\":\"i\",\"27\":{\"t\":25,\"8\":\"NUMERIC_LITERAL,0.0\"}}],\"31\":{\"t\":19,\"13\":{\"t\":24,\"3\":\"i\"},\"14\":\"PUNCTUATOR,++\"}}]}},{\"t\":1,\"3\":\"test\",\"23\":[],\"24\":{\"t\":2,\"0\":[{\"t\":37,\"33\":[{\"t\":34,\"26\":\"ret\",\"27\":{\"t\":25,\"8\":\"STRING_LITERAL,\"}}]},{\"t\":21,\"2\":{\"t\":26,\"2\":[{\"t\":24,\"3\":\"arr\"}]},\"12\":{\"t\":24,\"3\":\"insertion_sort\"}},{\"t\":33,\"24\":{\"t\":5,\"14\":\"PUNCTUATOR,+=\",\"20\":{\"t\":24,\"3\":\"ret\"},\"21\":{\"t\":16,\"15\":[{\"t\":5,\"v\":\"+\"}],\"16\":[{\"t\":25,\"8\":\"STRING_LITERAL, \"},{\"t\":22,\"10\":{\"t\":24,\"3\":\"arr\"},\"11\":{\"t\":24,\"3\":\"i\"}}]}},\"25\":{\"t\":13,\"15\":[{\"t\":5,\"v\":\"<\"}],\"16\":[{\"t\":24,\"3\":\"i\"},{\"t\":20,\"10\":{\"t\":24,\"3\":\"arr\"},\"11\":{\"t\":24,\"3\":\"length\"}}]},\"30\":[{\"t\":34,\"26\":\"i\",\"27\":{\"t\":25,\"8\":\"NUMERIC_LITERAL,0.0\"}}],\"31\":{\"t\":19,\"13\":{\"t\":24,\"3\":\"i\"},\"14\":\"PUNCTUATOR,++\"}},{\"t\":36,\"32\":{\"t\":24,\"3\":\"ret\"}}]}}]}";
16+
17+
NSData *data = [parsed dataUsingEncoding:NSUTF8StringEncoding];
18+
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
19+
NSString *answer = @"{\"retType\":\"array\",\"retValue\":[30,40,49,57,59,63,73,90,103,129,131,139,151,161,167,180,182,203,209,224,251,253,255,265,297,301,320,328,329,333,341,348,352,414,440,452,454,456,457,458,461,462,475,478,494,506,515,516,520,527,543,557,567,575,577,582,598,600,607,629,639,646,660,675,682,712,722,723,739,744,746,756,757,779,785,792,814,820,832,852,865,881,896,898,903,905,906,907,920,923,928,931,943,945,949,956,961,969,980,993]}";
20+
21+
[ex execute:json];
22+
NSString *actual = [[ex invoke:@"test" with:nil] description];
23+
if (![actual isEqualToString:answer]) {
24+
printf("Test 1 failed!");
25+
printf("Expected : %s", [answer UTF8String]);
26+
printf("Actual : %s", [actual UTF8String]);
27+
return false;
28+
}
29+
return true;
30+
}
31+
32+
int main(int argc, char *argv[]) {
33+
@autoreleasepool {
34+
if (!test1()) return -1;
35+
}
36+
return 0;
37+
}
38+
39+
// Test

JawaScriptExecutive-iOS/utility.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// utility.h
3+
// JawaScriptExecutive-iOS
4+
//
5+
// Created by Chi-Wei (Jack) Wang on 2016/1/28.
6+
//
7+
//
8+
9+
#ifndef utility_h
10+
#define utility_h
11+
12+
extern NSMutableArray* jsonToArray(NSString* str);
13+
extern NSMutableDictionary* jsonToDictionary(NSString* str);
14+
15+
#endif /* utility_h */

JawaScriptExecutive-iOS/utility.m

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//
2+
// utility.m
3+
// JawaScriptExecutive-iOS
4+
//
5+
// Created by Chi-Wei (Jack) Wang on 2016/1/28.
6+
//
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
#import "utility.h"
11+
12+
NSMutableArray* jsonToArray(NSString* str) {
13+
NSError *error;
14+
NSMutableArray * array = [NSJSONSerialization
15+
JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding]
16+
options:kNilOptions
17+
error:&error];
18+
return array;
19+
}
20+
21+
NSMutableDictionary* jsonToDictionary(NSString* str) {
22+
NSError *error;
23+
NSMutableDictionary * dict = [NSJSONSerialization
24+
JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding]
25+
options:kNilOptions
26+
error:&error];
27+
return dict;
28+
}

0 commit comments

Comments
 (0)