/* -*- mode: objc; coding: utf-8 -*- */ /* Étoilisp/Mulklisp, a Common Lisp subset for the Étoilé runtime. * Copyright (C) 2008 Matthias Andreas Benkard. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #import "MLKCons.h" #import "MLKPackage.h" #import "MLKRoot.h" #import "MLKSymbol.h" #import "runtime-compatibility.h" #import #import #import #import #import #import static id nullify (id value) { if (value) return value; else return [NSNull null]; } static id denullify (id value) { if (value == [NSNull null]) return nil; else return value; } static NSMethodSignature *signature; static MLKPackage *sys; @implementation MLKRoot +(void) initialize { signature = RETAIN ([self methodSignatureForSelector:@selector(car:)]); sys = [MLKPackage findPackage:@"TOILET-SYSTEM"]; } +(NSArray *) dispatch:(MLKSymbol *)name withArguments:(NSArray *)args { NSInvocation *invocation; NSMutableString *methodName; NSArray *result; SEL selector; NS_DURING { if ([sys findSymbol:[name name]] != name) return nil; } NS_HANDLER { NS_VALUERETURN (nil, NSArray *); } NS_ENDHANDLER invocation = [NSInvocation invocationWithMethodSignature:signature]; methodName = [NSMutableString stringWithString:[[name name] lowercaseString]]; [methodName replaceOccurrencesOfString:@"-" withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, [methodName length])]; [methodName appendString:@":"]; selector = NSSelectorFromString (methodName); if (!selector || ![self respondsToSelector:selector]) return nil; [invocation setSelector:selector]; [invocation setTarget:self]; [invocation setArgument:&args atIndex:2]; [invocation invoke]; [invocation getReturnValue:&result]; return result; } +(NSArray *) car:(NSArray *)args { return [NSArray arrayWithObject:nullify([denullify([args objectAtIndex:0]) car])]; } +(NSArray *) cdr:(NSArray *)args { return [NSArray arrayWithObject:nullify([denullify([args objectAtIndex:0]) cdr])]; } +(NSArray *) set_car:(NSArray *)args { [[args objectAtIndex:0] setCar:denullify([args objectAtIndex:1])]; return [NSArray arrayWithObject:[args objectAtIndex:1]]; } +(NSArray *) set_cdr:(NSArray *)args { [[args objectAtIndex:0] setCdr:denullify([args objectAtIndex:1])]; return [NSArray arrayWithObject:[args objectAtIndex:1]]; } +(NSArray *) cons:(NSArray *)args { return [NSArray arrayWithObject: [MLKCons cons:denullify([args objectAtIndex:0]) with:denullify([args objectAtIndex:1])]]; } @end