DISABLE FDs (REMOVE ME).
[jackhill/mal.git] / objc / env.m
1 #import <Foundation/Foundation.h>
2
3 #import "types.h"
4 //#import "env.h"
5
6 @implementation Env
7
8 @synthesize data = _data;
9 @synthesize outer = _outer;
10
11 - (id)initWithBindings:(Env *)outer binds:(NSArray *)binds exprs:(NSArray *)exprs {
12 self = [super init];
13 if (self) {
14 _outer = outer;
15 _data = [NSMutableDictionary dictionary];
16
17 for (int i=0; i < [binds count]; i++) {
18 if ([(NSString *)binds[i] isEqualTo:@"&"]) {
19 if ([exprs count] > i) {
20 NSRange r = NSMakeRange(i, [exprs count] - i);
21 _data[binds[i+1]] = [exprs subarrayWithRange:r];
22 } else {
23 _data[binds[i+1]] = @[];
24 }
25 break;
26 } else {
27 _data[binds[i]] = exprs[i];
28 }
29 }
30 }
31 return self;
32 }
33
34 - (id)initWithOuter:(Env *)outer {
35 return [self initWithBindings:outer binds:@[] exprs:@[]];
36 }
37
38 - (id)init {
39 return [self initWithBindings:nil binds:@[] exprs:@[]];
40 }
41
42 + (id)fromOuter:(Env *)outer {
43 return [[Env alloc] initWithOuter:outer];
44 }
45
46 + (id)fromBindings:(Env *)outer binds:(NSArray *)binds exprs:(NSArray *)exprs {
47 return [[Env alloc] initWithBindings:outer binds:binds exprs:exprs];
48 }
49
50 - (NSObject *) set:(MalSymbol *)key val:(NSObject *)val {
51 _data[key] = val;
52 return val;
53 }
54
55 - (Env *) find:(MalSymbol *)key {
56 if (_data[key]) {
57 return self;
58 } else if (_outer) {
59 Env * e = _outer;
60 return [e find:key];
61 } else {
62 return nil;
63 }
64 }
65
66 - (NSObject *) get:(MalSymbol *)key {
67 Env * e = [self find:key];
68 if (e) {
69 return e.data[key];
70 } else {
71 @throw [NSString stringWithFormat:@"'%@' not found", key];
72 }
73 }
74
75 @end