diff options
-rw-r--r-- | GNUmakefile | 6 | ||||
-rw-r--r-- | MLKCharacter.h | 32 | ||||
-rw-r--r-- | MLKEndOfFileError.h | 32 | ||||
-rw-r--r-- | MLKEndOfFileError.m | 35 | ||||
-rw-r--r-- | MLKPackage.h | 53 | ||||
-rw-r--r-- | MLKReader.h | 30 | ||||
-rw-r--r-- | MLKReader.m | 148 | ||||
-rw-r--r-- | MLKReaderError.h | 32 | ||||
-rw-r--r-- | MLKReaderError.m | 35 | ||||
-rw-r--r-- | MLKReadtable.h | 43 |
10 files changed, 443 insertions, 3 deletions
diff --git a/GNUmakefile b/GNUmakefile index b2de3a9..9eb3844 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -18,9 +18,9 @@ include $(GNUSTEP_MAKEFILES)/common.make TOOL_NAME = etoilisp -etoilisp_OBJC_FILES = MLKCons.m MLKDynamicContext.m MLKEnvironment.m \ - MLKLinkedList.m MLKLispValue.m MLKSymbol.m \ - MLKThrowException.m \ +etoilisp_OBJC_FILES = MLKCons.m MLKDynamicContext.m MLKEndOfFileError.m \ + MLKEnvironment.m MLKLinkedList.m MLKLispValue.m \ + MLKReader.m MLKSymbol.m MLKThrowException.m \ MLKUndefinedVariableException.m BUNDLE_NAME = Test diff --git a/MLKCharacter.h b/MLKCharacter.h new file mode 100644 index 0000000..664803a --- /dev/null +++ b/MLKCharacter.h @@ -0,0 +1,32 @@ +/* -*- 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 <http://www.gnu.org/licenses/>. + */ + +#import "MLKLispValue.h" + +#import <Foundation/NSString.h> + + +@interface MLKCharacter : MLKLispValue +{ + unichar unichar; +} + +-(MLKCharacter*) initWithUnichar:(unichar)anUnichar; + ++(MLKCharacter*) characterWithUnichar:(unichar)anUnichar; +@end diff --git a/MLKEndOfFileError.h b/MLKEndOfFileError.h new file mode 100644 index 0000000..cb066c1 --- /dev/null +++ b/MLKEndOfFileError.h @@ -0,0 +1,32 @@ +/* -*- 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 <http://www.gnu.org/licenses/>. + */ + +#import <Foundation/NSException.h> + +@class MLKStream; + + +@interface MLKEndOfFileError : NSException +{ + MLKStream *stream; +} + +-(MLKEndOfFileError *) initWithStream:(MLKStream *)aStream; + +-(void) dealloc; +@end diff --git a/MLKEndOfFileError.m b/MLKEndOfFileError.m new file mode 100644 index 0000000..237c2b2 --- /dev/null +++ b/MLKEndOfFileError.m @@ -0,0 +1,35 @@ +/* -*- 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 <http://www.gnu.org/licenses/>. + */ + +#import "MLKEndOfFileError.h" + + +@implementation MLKEndOfFileError +-(MLKEndOfFileError *) initWithStream:(MLKStream *)aStream +{ + self = [super init]; + stream = aStream; + return self; +} + +-(void) dealloc +{ + RELEASE (stream); + [super dealloc]; +} +@end diff --git a/MLKPackage.h b/MLKPackage.h new file mode 100644 index 0000000..25834f1 --- /dev/null +++ b/MLKPackage.h @@ -0,0 +1,53 @@ +/* -*- 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 <http://www.gnu.org/licenses/>. + */ + +#import "MLKLispValue.h" + +@class MLKSymbol, NSMutableDictionary, NSMutableSet, NSSet, NSString; + + +@interface MLKPackage : MLKLispValue +{ + NSMutableDictionary *symbols; + NSMutableSet *exported_symbols; + NSMutableSet *shadowed_symbols; + NSMutableSet *nicknames; + NSString *name; +} + +-(MLKPackage *) initWithName:(NSString *)name + nicknames:(NSSet *)nicknames; + +-(void) usePackage:(MLKPackage *)aPackage; +-(void) import:(MLKSymbol *)aSymbol; +-(void) shadow:(MLKPackage *)aPackage; +-(void) unintern:(MLKSymbol *)aSymbol; +-(MLKSymbol *) intern:(NSString*)symbolName; +-(MLKSymbol *) findSymbol:(NSString*)symbolName; + +-(NSString *) name; +-(NSSet *) nicknames; +-(NSSet *) exportedSymbols; +-(NSSet *) shadowedSymbols; +-(NSSet *) allSymbols; + +// [clUser cons: @"Mulk", [clUser __intern: @"NIL"]] ought to do the +// Right Thing. +-(void) forwardInvocation:(NSInvocation *)anInvocation; +-(BOOL) respondsToSelector:(SEL)selector; +@end diff --git a/MLKReader.h b/MLKReader.h new file mode 100644 index 0000000..9e62e9d --- /dev/null +++ b/MLKReader.h @@ -0,0 +1,30 @@ +/* -*- 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 <http://www.gnu.org/licenses/>. + */ + +#include <Foundation/NSObject.h> + +@class MLKStream; + + +@interface MLKReader : NSObject ++(id) readFromStream:(MLKStream *)stream + eofError:(BOOL)eofError + eofValue:(id)eofValue + recursive:(BOOL)recursive + preserveWhitespace:(BOOL)preserveWhitespace; +@end diff --git a/MLKReader.m b/MLKReader.m new file mode 100644 index 0000000..fba2ef2 --- /dev/null +++ b/MLKReader.m @@ -0,0 +1,148 @@ +/* -*- 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 <http://www.gnu.org/licenses/>. + */ + +#import "MLKReader.h" +#import "MLKCharacter.h" +#import "MLKReadtable.h" +#import "MLKEndOfFileError.h" +#import "MLKReaderError.h" +#import "MLKDynamicContext.h" +#import "MLKEnvironment.h" +#import "MLKPackage.h" + +#import <Foundation/NSArray.h> +#import <Foundation/NSString.h> + + +@implementation MLKReader ++(id) readFromStream:(MLKStream *)stream + eofError:(BOOL)eofError + eofValue:(id)eofValue + recursive:(BOOL)recursive + preserveWhitespace:(BOOL)preserveWhitespace +{ + unichar ch; + NSMutableString *token; + MLKReadtable *readtable; + BOOL escaped; + + readtable = [[[MLKDynamicContext currentContext] environment] + valueForBinding:[[MLKPackage commonLisp] + intern:@"*READTABLE*"]]; + + start: + if ([stream isEOF]) + { + if (eofError) + [[[MLKEndOfFileError alloc] initWithStream:stream] raise]; + else + return eofValue; + } + + ch = [stream readChar]; + if ([readtable isWhitespaceCharacter:ch]) + goto start; + + if ([readtable isMacroCharacter:ch]) + { + NSArray *returnValues; + MLKClosure *macrofun = [readtable macroFunctionForCharacter:ch]; + NSArray *args = [NSArray arrayWithObjects: + stream, + [MLKCharacter characterWithUnichar:ch], + nil]; + if ([args count] != 2) + { + args = [NSMutableArray arrayWithCapacity:2]; + [((NSMutableArray*)args) addObject:stream]; + [((NSMutableArray*)args) addObject:[MLKCharacter + characterWithUnichar:ch]]; + } + returnValues = [macrofun applyToArray:args]; + if ([returnValues count]) + return [returnValues objectAtIndex:0]; + else + goto start; + } + + escaped = NO; + + if ([readtable isSingleEscapeCharacter:ch]) + { + if ([stream isEOF]) + [[[MLKEndOfFileError alloc] initWithStream:stream] raise]; + + token = [NSMutableString stringWithCapacity:8]; + [token appendFormat:@"%C", [stream readChar]]; + } + + if ([readtable isMultipleEscapeCharacter:ch]) + { + token = [NSMutableString stringWithCapacity:8]; + escaped = YES; + } + + if ([readtable isConstituentCharacter:ch]) + { + token = [NSMutableString stringWithCapacity:8]; + [token appendFormat:@"%C", [stream readChar]]; + } + + while (![stream isEOF]) + { + ch = [stream readChar]; + if ([readtable isConstituentCharacter:ch] || + [readtable isNonTerminatingMacroCharacter:ch] || + (escaped && [readtable isWhitespaceCharacter:ch])) + { + if (escaped) + [token appendFormat:@"%C", ch]; + else + [token appendFormat:@"%C", [readtable charWithReadtableCase:ch]]; + } + else if ([readtable isSingleEscapeCharacter:ch]) + { + if ([stream isEOF]) + [[[MLKEndOfFileError alloc] initWithStream:stream] raise]; + + token = [NSMutableString stringWithCapacity:8]; + [token appendFormat:@"%C", [stream readChar]]; + } + else if ([readtable isMultipleEscapeCharacter:ch]) + escaped = !escaped; + else if ([readtable isTerminatingMacroCharacter:ch]) + { + [stream unreadChar]; + break; + } + else if ([readtable isWhitespaceCharacter:ch]) + { + if (preserveWhitespace) + [stream unreadChar]; + break; + } + else if ([readtable isInvalidCharacter:ch]) + { + [[[MLKReaderError alloc] initWithStream:stream] raise]; + } + } + + // FIXME: Check the token for invalid syntax. + return token; +} +@end diff --git a/MLKReaderError.h b/MLKReaderError.h new file mode 100644 index 0000000..7c48911 --- /dev/null +++ b/MLKReaderError.h @@ -0,0 +1,32 @@ +/* -*- 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 <http://www.gnu.org/licenses/>. + */ + +#import <Foundation/NSException.h> + +@class MLKStream; + + +@interface MLKReaderError : NSException +{ + MLKStream *stream; +} + +-(MLKReaderError *) initWithStream:(id)aStream; + +-(void) dealloc; +@end diff --git a/MLKReaderError.m b/MLKReaderError.m new file mode 100644 index 0000000..ce23176 --- /dev/null +++ b/MLKReaderError.m @@ -0,0 +1,35 @@ +/* -*- 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 <http://www.gnu.org/licenses/>. + */ + +#import "MLKEndOfFileError.h" + + +@implementation MLKReaderError +-(MLKReaderError *) initWithStream:(MLKStream *)aStream +{ + self = [super init]; + stream = aStream; + return self; +} + +-(void) dealloc +{ + RELEASE (stream); + [super dealloc]; +} +@end diff --git a/MLKReadtable.h b/MLKReadtable.h new file mode 100644 index 0000000..ed08d84 --- /dev/null +++ b/MLKReadtable.h @@ -0,0 +1,43 @@ +/* -*- 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 <http://www.gnu.org/licenses/>. + */ + +#import "MLKLispValue.h" + +@class NSMutableDictionary; + + +enum MLKReadtableCase +{ + MLKReadtableCase_UPCASE, + MLKReadtableCase_DOWNCASE, + MLKReadtableCase_INVERT, + MLKReadtableCase_PRESERVE +}; + + +@interface MLKReadtable : MLKLispValue +{ + NSMutableDictionary *_syntaxTable; + NSMutableDictionary *_readerMacros; + //MLKClosure *_caseConverter; + enum MLKReadtableCase _case; +} + +-(MLKReadtable *) init; +-(MLKReadtable *) copy; +@end |