#import "SchemeTypes.h" @implementation SCMType static int allocatedAfterGC = 0; static NSMutableSet *scmobjects = nil; static NSMutableSet *scmmarkables = nil; static int currentMark = -1; static int totalAllocated = 0; + (int)allocatedAfterGC { return allocatedAfterGC; } + (int)totalAllocated { return totalAllocated; } + (int)nextMark { currentMark++; return currentMark; } + addToMarkables:(id)item { NSValue *entry = [NSValue valueWithBytes:&item objCType:@encode(id)]; if(scmmarkables==nil){ scmmarkables = [NSMutableSet setWithCapacity:1]; [scmmarkables retain]; } [scmmarkables addObject:entry]; return self; } + removeFromMarkables:(id)item { NSValue *entry = [NSValue valueWithBytes:&item objCType:@encode(id)]; if(scmmarkables==nil){ scmmarkables = [NSMutableSet setWithCapacity:1]; [scmmarkables retain]; } [scmmarkables removeObject:entry]; return self; } + currentMarkForMarkables { NSEnumerator *enumerator; NSValue *curval; id markable; if(scmmarkables==nil){ scmmarkables = [NSMutableSet setWithCapacity:1]; } enumerator = [scmmarkables objectEnumerator]; while((curval = (NSValue *)[enumerator nextObject])!=nil){ [curval getValue:&markable]; if(MARKABLE(markable)){ [markable setMarkToCurrent]; } } return self; } + runGC { NSMutableSet *nextobjects = [NSMutableSet setWithCapacity:1]; NSEnumerator *enumerator = [scmobjects objectEnumerator]; // NSValue *curval; SCMType *current; while((current = (SCMType *)[enumerator nextObject])!=nil){ // [curval getValue:¤t]; if([current mark]!=currentMark){ [current free]; } else{ [nextobjects addObject:current]; // curval]; } } [scmobjects release]; scmobjects = nextobjects; [scmobjects retain]; allocatedAfterGC = totalAllocated = [scmobjects count]; } + alloc { id inst = [super alloc]; /* NSValue *entry = [NSValue valueWithBytes:&inst objCType:@encode(id)]; */ if(scmobjects==nil){ scmobjects = [NSMutableSet setWithCapacity:1]; [scmobjects retain]; } [scmobjects addObject:inst]; // entry]; totalAllocated++; return [inst setMark:-1]; } - (int)mark { return mark; } - setMark:(int)newMark { mark = newMark; return self; } - setMarkToCurrent { mark = currentMark; return self; } - (void)free { int count = [self retainCount]; while(count>2){ // count>1 (leave one release for the set) count--; [self release]; } [super release]; } @end @implementation Pair + (int)length:(Pair *)list { return (list==(Pair *)[NSNull null] ? 0 : 1+[self length:[list cdr]]); } + newCar:(id)carval Cdr:(id)cdrval { return [[super alloc] initCar:carval Cdr:cdrval]; } - initCar:(id)carval Cdr:(id)cdrval { car = carval; [car retain]; cdr = cdrval; [cdr retain]; return self; } - car { return car; } - cdr { return cdr; } - setcar:(id)carval { car = carval; [car retain]; return self; } - setcdr:(id)cdrval { cdr = cdrval; [cdr retain]; return self; } - setMarkToCurrent { if(mark==currentMark){ return; } mark = currentMark; if(MARKABLE(car)){ [car setMarkToCurrent]; } if(MARKABLE(cdr)){ [cdr setMarkToCurrent]; } return self; } @end @implementation Vector + newFromList:(Pair *)list { return [[super alloc] initWithList:list]; } + newWithItem:(id)item count:(int)cval { return [[super alloc] initWithItem:item count:cval]; } - initWithList:(Pair *)list { Pair *current = list; int index = 0, length = [Pair length:list]; count = length; data = NSZoneMalloc([self zone], length*sizeof(id)); while(isPair(current)){ data[index] = [current car]; [data[index++] retain]; current = [current cdr]; } return self; } - initWithItem:(id)item count:(int)cval { count = cval; data = NSZoneMalloc([self zone], cval*sizeof(id)); while(cval--){ data[cval] = item; [item retain]; } return self; } - (id *)entries { return data; } - (unsigned)count { return count; } - setMarkToCurrent { int index; if(mark==currentMark){ return; } mark = currentMark; for(index=0; indexcapacity){ while(length+otherLength>capacity){ capacity *= 2; } data = (id *)NSZoneRealloc(NSDefaultMallocZone(), data, capacity*sizeof(id)); } unsigned int pos; for(pos=0; pos