1
1
mirror of https://github.com/kanaka/mal.git synced 2024-08-18 02:00:40 +03:00
mal/impls/objc/types.m
Joel Martin 8a19f60386 Move implementations into impls/ dir
- Reorder README to have implementation list after "learning tool"
  bullet.

- This also moves tests/ and libs/ into impls. It would be preferrable
  to have these directories at the top level.  However, this causes
  difficulties with the wasm implementations which need pre-open
  directories and have trouble with paths starting with "../../". So
  in lieu of that, symlink those directories to the top-level.

- Move the run_argv_test.sh script into the tests directory for
  general hygiene.
2020-02-10 23:50:16 -06:00

176 lines
3.5 KiB
Objective-C

#import "types.h"
@implementation MalTrue
@end
@implementation MalFalse
@end
// NSString subclassing based on:
// http://stackoverflow.com/a/21331422/471795
// Symbols
@interface MalSymbol ()
@property (nonatomic, strong) NSString *stringHolder;
@end
@implementation MalSymbol
- (instancetype)initWithCharactersNoCopy:(unichar *)characters length:(NSUInteger)length freeWhenDone:(BOOL)freeBuffer {
self = [super init];
if (self) {
self.stringHolder = [[NSString alloc] initWithCharactersNoCopy:characters length:length freeWhenDone:freeBuffer];
}
return self;
}
- (NSUInteger)length {
return self.stringHolder.length;
}
- (unichar)characterAtIndex:(NSUInteger)index {
return [self.stringHolder characterAtIndex:index];
}
@end
BOOL string_Q(id obj) {
if ([obj isKindOfClass:[NSString class]]) {
NSString * s = obj;
if (![s isKindOfClass:[MalSymbol class]]) {
return ![s hasPrefix:@"\u029e"];
}
}
return false;
}
// Lists
BOOL list_Q(id obj) {
return ([obj isKindOfClass:[NSArray class]] &&
![obj isKindOfClass:[MalVector class]]);
}
NSArray * _rest(NSArray * obj) {
return [obj subarrayWithRange:NSMakeRange(1, [obj count]-1)];
}
// Vectors
@implementation MalVector
@synthesize array = _array;
@synthesize count = _count;
- (id)initWithArray:(NSArray *)arr {
self = [self init];
if (self) {
_array = arr;
_count = [arr count];
}
return self;
}
- (id)init {
self = [super init];
if (self) {
_array = @[];
_count = 0;
}
return self;
}
+ (id)fromArray:(NSArray *)arr {
return [[MalVector alloc] initWithArray:arr];
}
- (id)objectAtIndex:(NSUInteger)index {
return _array[index];
}
- (id)copyWithZone:(NSZone *)zone {
return [[MalVector alloc] initWithArray:[_array copy]];
}
@end
// Hash Maps
NSDictionary * assoc_BANG(NSMutableDictionary * d, NSArray * kvs) {
for (int i=0; i < [kvs count]; i+=2) {
d[kvs[i]] = kvs[i+1];
}
return d;
}
NSDictionary * hash_map(NSArray *kvs) {
return assoc_BANG([NSMutableDictionary dictionary], kvs);
}
// Mal Functions
BOOL block_Q(id obj) {
id block = ^{};
Class blockClass = [block class];
while ([blockClass superclass] != [NSObject class]) {
blockClass = [blockClass superclass];
}
return [obj isKindOfClass:blockClass];
}
@implementation MalAtom
@synthesize val = _val;
- (id)init:(NSObject *)val {
self = [super init];
if (self) {
_val = val;
}
return self;
}
+ (id)fromObject:(NSObject *)val {
return [[MalAtom alloc] init:val];
}
@end
BOOL atom_Q(id obj) {
return [obj isKindOfClass:[MalAtom class]];
}
// General functions
BOOL sequential_Q(NSObject * obj) {
return [obj isKindOfClass:[NSArray class]];
}
BOOL equal_Q(NSObject * a, NSObject * b) {
//NSLog(@"= %@ (%@), %@ (%@)", a, [a class], b, [b class]);
if (!(([a class] == [b class]) ||
([a isKindOfClass:[NSArray class]] &&
[b isKindOfClass:[NSArray class]]) ||
([a isKindOfClass:[NSNumber class]] &&
[b isKindOfClass:[NSNumber class]]) ||
(string_Q(a) && string_Q(b)))) {
return false;
}
if ([a isKindOfClass:[MalTrue class]]) {
return true;
} else if ([a isKindOfClass:[MalFalse class]]) {
return true;
} else if ([a isKindOfClass:[NSNumber class]]) {
return [(NSNumber *)a intValue] == [(NSNumber *)b intValue];
} else {
return [a isEqual:b];
}
}