diff options
33 files changed, 610 insertions, 314 deletions
diff --git a/GNUmakefile b/GNUmakefile index 39d0d3a..7aaa0f0 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -60,24 +60,25 @@ else endif endif -ToiletKit_OBJC_FILES = functions.m globals.m MLKArray.m \ - MLKBackquoteReader.m MLKBinding.m MLKCharacter.m \ - MLKCommaReader.m MLKCompiledClosure.m MLKCons.m \ - MLKDoubleFloat.m \ - MLKDispatchingMacroCharacterReader.m \ - MLKDynamicContext.m MLKEnvironment.m MLKFloat.m \ - MLKForeignProcedure.m MLKForm.m MLKInteger.m \ - MLKInterpretedClosure.m MLKInterpreter.m \ - MLKLexicalContext.m \ - MLKLexicalEnvironment.m MLKNumber.m MLKPackage.m \ - MLKParenReader.m MLKQuoteReader.m MLKRatio.m \ - MLKReader.m MLKReadtable.m MLKReaderError.m \ - MLKRoot.m MLKSemicolonReader.m \ - MLKSharpsignColonReader.m MLKSingleFloat.m \ - MLKStream.m MLKStringInputStream.m \ - MLKStringOutputStream.m MLKStringReader.m \ - MLKSymbol.m MLKThrowException.m \ - MLKValuesFunction.m NSObject-MLKPrinting.m \ +ToiletKit_OBJC_FILES = functions.m globals.m MLKArray.m \ + MLKBackquoteReader.m MLKBinaryStream.m \ + MLKBinaryStreamCharacterStream.m MLKBinding.m \ + MLKCharacter.m MLKCharacterStream.m \ + MLKCommaReader.m MLKCompiledClosure.m MLKCons.m \ + MLKDoubleFloat.m \ + MLKDispatchingMacroCharacterReader.m \ + MLKDynamicContext.m MLKEnvironment.m MLKFloat.m \ + MLKForeignProcedure.m MLKForm.m MLKInteger.m \ + MLKInterpretedClosure.m MLKInterpreter.m \ + MLKLexicalContext.m MLKLexicalEnvironment.m \ + MLKNumber.m MLKPackage.m MLKParenReader.m \ + MLKQuoteReader.m MLKRatio.m MLKReader.m \ + MLKReadtable.m MLKReaderError.m MLKRoot.m \ + MLKSemicolonReader.m MLKSharpsignColonReader.m \ + MLKSingleFloat.m MLKStreamStream.m \ + MLKStringInputStream.m MLKStringOutputStream.m \ + MLKStringReader.m MLKSymbol.m MLKThrowException.m \ + MLKValuesFunction.m NSObject-MLKPrinting.m \ NSString-MLKPrinting.m ToiletKit_OBJCFLAGS = -Wall ToiletKit_LDFLAGS = -lgmp -lffi -ldl diff --git a/MLKBackquoteReader.m b/MLKBackquoteReader.m index 23d1952..e18b762 100644 --- a/MLKBackquoteReader.m +++ b/MLKBackquoteReader.m @@ -23,7 +23,7 @@ #import "MLKReader.h" #import "MLKReadtable.h" #import "MLKPackage.h" -#import "MLKStream.h" +#import "MLKCharacterStream.h" #import "runtime-compatibility.h" #import "util.h" @@ -31,7 +31,7 @@ @implementation MLKBackquoteReader -(NSArray *) applyToArray:(NSArray *)arguments { - MLKStream *stream; + MLKCharacterStream *stream; MLKReadtable *readtable; MLKPackage *cl, *sys; unichar ch; diff --git a/MLKBinaryStream.h b/MLKBinaryStream.h new file mode 100644 index 0000000..9524db0 --- /dev/null +++ b/MLKBinaryStream.h @@ -0,0 +1,25 @@ +/* -*- mode: objc; coding: utf-8 -*- */ +/* Toilet Lisp, 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/NSObject.h> + +@interface MLKBinaryStream : NSObject +// To implement by subclasses: +-(uint8_t) readOctet; +-(void) writeOctet:(uint8_t)octet; +@end diff --git a/MLKBinaryStream.m b/MLKBinaryStream.m new file mode 100644 index 0000000..223634b --- /dev/null +++ b/MLKBinaryStream.m @@ -0,0 +1,35 @@ +/* -*- mode: objc; coding: utf-8 -*- */ +/* Toilet Lisp, 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 "MLKBinaryStream.h" + +#import <Foundation/NSException.h> + +@implementation MLKBinaryStream +-(uint8_t) readOctet +{ + [NSException raise:@"MLKNotImplementedError" format:@""]; + return 0; +} + +-(void) writeOctet:(uint8_t)octet +{ + [NSException raise:@"MLKNotImplementedError" format:@""]; + octet = 0; +} +@end diff --git a/MLKBinaryStreamCharacterStream.h b/MLKBinaryStreamCharacterStream.h new file mode 100644 index 0000000..fcf7a18 --- /dev/null +++ b/MLKBinaryStreamCharacterStream.h @@ -0,0 +1,39 @@ +/* -*- mode: objc; coding: utf-8 -*- */ +/* Toilet Lisp, 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 "MLKBinaryStream.h" +#import "MLKCharacterStream.h" + +#import <Foundation/NSStream.h> +#import <Foundation/NSString.h> + + +@interface MLKBinaryStreamCharacterStream : MLKCharacterStream +{ + MLKBinaryStream *_binaryStream; + NSStringEncoding _encoding; +} + +-(id) initWithBinaryStream:(MLKBinaryStream *)input; +-(id) initWithBinaryStream:(MLKBinaryStream *)input + encoding:(NSStringEncoding)encoding; + +-(unichar) readCharNoCache; + +-(void) writeChar:(unichar)ch; +@end diff --git a/MLKBinaryStreamCharacterStream.m b/MLKBinaryStreamCharacterStream.m new file mode 100644 index 0000000..6fc7119 --- /dev/null +++ b/MLKBinaryStreamCharacterStream.m @@ -0,0 +1,91 @@ +/* -*- mode: objc; coding: utf-8 -*- */ +/* Toilet Lisp, 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 "MLKBinaryStreamCharacterStream.h" +#import "runtime-compatibility.h" +#import "util.h" + +#import <Foundation/NSException.h> + +#include <unistd.h> +#include <stdlib.h> +#include <string.h> + + +@implementation MLKBinaryStreamCharacterStream +-(id) initWithBinaryStream:(MLKBinaryStream *)binaryStream +{ + return [self initWithBinaryStream:binaryStream + encoding:NSUTF8StringEncoding]; +} + +-(id) initWithBinaryStream:(MLKBinaryStream *)binaryStream + encoding:(NSStringEncoding)encoding +{ + self = [super init]; + LASSIGN (_binaryStream, binaryStream); + _encoding = encoding; + return self; +} + +-(unichar) readCharNoCache +{ + uint8_t *buffer; + size_t i; + unichar retval; + + buffer = NULL; + for (i = 0;; i++) + { + NSString *tmpstr; + + //NSLog (@"%@", _input); + + buffer = (uint8_t *) realloc (buffer, i+1); + buffer[i] = [_binaryStream readOctet]; + + tmpstr = [[NSString alloc] initWithBytes:buffer + length:(i+1) + encoding:_encoding]; + if ([tmpstr length] == 1) + { + retval = [tmpstr characterAtIndex:0]; + [tmpstr release]; + //free (buffer); + return retval; + } + else + { + [tmpstr release]; + } + } + + return -1; +} + +-(void) writeChar:(unichar)ch +{ + const void *cstring = [[NSString stringWithFormat:@"%C", ch] cStringUsingEncoding:_encoding]; + const char *c; + + for (c = cstring; *c; c++) + { + [_binaryStream writeOctet:*c]; + } +} +@end diff --git a/MLKCharacterStream.h b/MLKCharacterStream.h new file mode 100644 index 0000000..dd81942 --- /dev/null +++ b/MLKCharacterStream.h @@ -0,0 +1,42 @@ +/* -*- mode: objc; coding: utf-8 -*- */ +/* Toilet Lisp, 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/NSStream.h> +#import <Foundation/NSString.h> + + +@interface MLKCharacterStream : NSObject +{ + BOOL _charCached; + unichar _cachedChar; +} + +-(id) init; + +// To implement by subclasses: +-(unichar) readCharNoCache; +-(void) writeChar:(unichar)ch; + +-(unichar) readChar; +-(void) unreadChar:(unichar)ch; +-(unichar) peekChar; +-(BOOL) isEOF; + +//-(void) writeFormat:(NSString *)format, ...; +-(void) writeString:(NSString *)string; +@end diff --git a/MLKCharacterStream.m b/MLKCharacterStream.m new file mode 100644 index 0000000..d64ed3c --- /dev/null +++ b/MLKCharacterStream.m @@ -0,0 +1,111 @@ +/* -*- mode: objc; coding: utf-8 -*- */ +/* Toilet Lisp, 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 "MLKCharacterStream.h" +#import "runtime-compatibility.h" +#import "util.h" + +#import <Foundation/NSException.h> + +#include <unistd.h> +#include <stdlib.h> +#include <string.h> + + +@implementation MLKCharacterStream +-(id) init; +{ + self = [super init]; + _cachedChar = 0; + _charCached = NO; + return self; +} + +-(unichar) readChar +{ + if (_charCached) + { + char ch; + ch = _cachedChar; + _cachedChar = 0; + _charCached = NO; + return ch; + } + else + { + return [self readCharNoCache]; + } +} + +-(void) unreadChar:(unichar)ch +{ + if (_charCached) + [NSException raise:@"MLKInvalidOperationError" + format:@"Attempted to UNREAD-CHAR twice in a row."]; + + _charCached = YES; + _cachedChar = ch; +} + +-(unichar) peekChar +{ + unichar ch = [self readChar]; + [self unreadChar:ch]; + return ch; +} + +-(BOOL) isEOF +{ + BOOL eofp = NO; + + NS_DURING + { + [self peekChar]; + } + NS_HANDLER + { + if ([[localException name] isEqual:@"MLKStreamError"]) + eofp = YES; + else + [localException raise]; + } + NS_ENDHANDLER; + + return eofp; +} + +-(void) writeString:(NSString *)string +{ + int i; + + for (i = 0; i < [string length]; i++) + [self writeChar:[string characterAtIndex:i]]; +} + +-(void) writeChar:(unichar)ch +{ + [NSException raise:@"MLKNotImplementedError" format:@""]; + ch = 0; +} + +-(unichar) readCharNoCache +{ + [NSException raise:@"MLKNotImplementedError" format:@""]; + return 0; +} +@end diff --git a/MLKCommaReader.m b/MLKCommaReader.m index bceebfc..2b87a5f 100644 --- a/MLKCommaReader.m +++ b/MLKCommaReader.m @@ -23,7 +23,7 @@ #import "MLKReader.h" #import "MLKReadtable.h" #import "MLKPackage.h" -#import "MLKStream.h" +#import "MLKCharacterStream.h" #import "runtime-compatibility.h" #import "util.h" @@ -31,7 +31,7 @@ @implementation MLKCommaReader -(NSArray *) applyToArray:(NSArray *)arguments { - MLKStream *stream; + MLKCharacterStream *stream; MLKReadtable *readtable; MLKPackage *cl, *sys; MLKSymbol *marker; diff --git a/MLKDispatchingMacroCharacterReader.m b/MLKDispatchingMacroCharacterReader.m index 0286284..9ec0cad 100644 --- a/MLKDispatchingMacroCharacterReader.m +++ b/MLKDispatchingMacroCharacterReader.m @@ -23,7 +23,7 @@ #import "MLKReader.h" #import "MLKReadtable.h" #import "MLKPackage.h" -#import "MLKStream.h" +#import "MLKCharacterStream.h" #import "runtime-compatibility.h" #import "util.h" @@ -51,7 +51,7 @@ -(NSArray *) applyToArray:(NSArray *)arguments { - MLKStream *stream; + MLKCharacterStream *stream; MLKReadtable *readtable; MLKPackage *cl; unichar ch; diff --git a/MLKInterpreter.h b/MLKInterpreter.h index 67f7377..5d4c9a0 100644 --- a/MLKInterpreter.h +++ b/MLKInterpreter.h @@ -16,10 +16,10 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#import "MLKCharacterStream.h" #import "MLKForm.h" #import "MLKLexicalContext.h" #import "MLKLexicalEnvironment.h" -#import "MLKStream.h" #import <Foundation/NSArray.h> #import <Foundation/NSObject.h> @@ -44,7 +44,7 @@ enum MLKProcessingMode inLexicalContext:(MLKLexicalContext *)context withEnvironment:(MLKLexicalEnvironment *)lexenv; -+(BOOL) load:(MLKStream *)stream verbose:(BOOL)verbose print:(BOOL)print; ++(BOOL) load:(MLKCharacterStream *)stream verbose:(BOOL)verbose print:(BOOL)print; +(id) compile:(id)object inContext:(MLKLexicalContext *)context; diff --git a/MLKInterpreter.m b/MLKInterpreter.m index ce5d328..a808909 100644 --- a/MLKInterpreter.m +++ b/MLKInterpreter.m @@ -99,7 +99,7 @@ PRIMARY (NSArray *array) return [form interpretWithEnvironment:lexenv]; } -+(BOOL) load:(MLKStream *)stream verbose:(BOOL)verbose print:(BOOL)print ++(BOOL) load:(MLKCharacterStream *)stream verbose:(BOOL)verbose print:(BOOL)print { id eofValue = [[NSObject alloc] init]; int level = MLKIntWithInteger ([[MLKDynamicContext currentContext] diff --git a/MLKListenerController.h b/MLKListenerController.h index a5a7a4b..6e12a8f 100644 --- a/MLKListenerController.h +++ b/MLKListenerController.h @@ -16,26 +16,23 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#import "MLKStream.h" +#import "MLKCharacterStream.h" #import <Cocoa/Cocoa.h> -@interface MLKListenerController : NSObject +@interface MLKListenerController : MLKCharacterStream { IBOutlet id indicatorText; IBOutlet id inputField; IBOutlet id outputTextView; IBOutlet id statusText; IBOutlet id submitButton; - - MLKStream *lispStream; - NSOutputStream *ostream; } -- (id)init; -- (void)dealloc; ++ (void)initialize; -- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event; +- (void)writeChar:(unichar)ch; +- (void)writeString:(NSString *)string; - (IBAction)submit:(id)sender; @end diff --git a/MLKListenerController.m b/MLKListenerController.m index 696b08f..28e556b 100644 --- a/MLKListenerController.m +++ b/MLKListenerController.m @@ -22,27 +22,12 @@ #import "MLKPackage.h" #import "MLKReader.h" #import "util.h" +#import "special-symbols.h" @implementation MLKListenerController -- (id)init ++ (void)initialize { - self = [super init]; - - ostream = [[NSOutputStream alloc] initToMemory]; - lispStream = [[MLKStream alloc] initWithOutputStream:ostream]; - [ostream setDelegate:self]; - [ostream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; - [ostream open]; - - return self; -} - -- (void)dealloc -{ - [ostream close]; - LDESTROY (ostream); - LDESTROY (lispStream); - [super dealloc]; + ensure_symbols(); } - (IBAction)submit:(id)sender @@ -51,7 +36,8 @@ NSDictionary *attrs; NSString *input = [inputField stringValue]; MLKPackage *package; - + MLKDynamicContext *newctx; + [submitButton setEnabled:NO]; NS_DURING @@ -99,13 +85,33 @@ [statusText setStringValue:@"Compiling and executing."]; NS_DURING { + NSDictionary *vars = [NSDictionary dictionaryWithObjectsAndKeys: + self, QUERY_IO, + self, ERROR_OUTPUT, + self, STANDARD_OUTPUT, + self, TERMINAL_IO, + self, TRACE_OUTPUT, + self, DEBUG_IO, + nil]; + MLKDynamicContext *ctx = [MLKDynamicContext currentContext]; + newctx = [[MLKDynamicContext alloc] initWithParent:ctx + variables:vars + handlers:nil + restarts:nil + catchTags:nil + activeHandlerEnvironment:nil]; + [newctx pushContext]; + // ... } NS_HANDLER { // ... } - NS_ENDHANDLER + NS_ENDHANDLER; + + [MLKDynamicContext popContext]; + LDESTROY (newctx); [statusText setStringValue:@"Ready."]; [text beginEditing]; @@ -123,8 +129,20 @@ [submitButton setEnabled:YES]; } -- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event +- (void)writeChar:(unichar)ch +{ + [self writeString:[NSString stringWithFormat:@"%C", ch]]; +} + +- (void)writeString:(NSString *)string { - NSLog (@"Heya!"); + NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys: + [NSColor brownColor], + NSForegroundColorAttributeName, + nil]; + NSAttributedString *output = + LAUTORELEASE ([[NSAttributedString alloc] initWithString:string + attributes:attrs]); + [[outputTextView textStorage] appendAttributedString:output]; } @end diff --git a/MLKParenReader.m b/MLKParenReader.m index de40659..c47bfcb 100644 --- a/MLKParenReader.m +++ b/MLKParenReader.m @@ -24,14 +24,14 @@ #import "MLKReader.h" #import "MLKReadtable.h" #import "MLKPackage.h" -#import "MLKStream.h" +#import "MLKCharacterStream.h" #import "runtime-compatibility.h" #import "util.h" #import <Foundation/NSArray.h> -static unichar slurpWhitespaceAndPeek (MLKStream *stream, MLKReadtable *readtable) +static unichar slurpWhitespaceAndPeek (MLKCharacterStream *stream, MLKReadtable *readtable) { unichar ch; while ([readtable isWhitespaceCharacter:(ch = [stream readChar])]); @@ -43,7 +43,7 @@ static unichar slurpWhitespaceAndPeek (MLKStream *stream, MLKReadtable *readtabl @implementation MLKParenReader -(NSArray *) applyToArray:(NSArray *)arguments { - MLKStream *stream; + MLKCharacterStream *stream; unichar ch; MLKReadtable *readtable; MLKCons *cons, *tail; diff --git a/MLKQuoteReader.m b/MLKQuoteReader.m index 387c326..a814c09 100644 --- a/MLKQuoteReader.m +++ b/MLKQuoteReader.m @@ -23,7 +23,7 @@ #import "MLKReader.h" #import "MLKReadtable.h" #import "MLKPackage.h" -#import "MLKStream.h" +#import "MLKCharacterStream.h" #import "runtime-compatibility.h" #import "util.h" @@ -31,7 +31,7 @@ @implementation MLKQuoteReader -(NSArray *) applyToArray:(NSArray *)arguments { - MLKStream *stream; + MLKCharacterStream *stream; MLKReadtable *readtable; MLKPackage *cl; unichar ch; diff --git a/MLKReadEvalPrintLoop.m b/MLKReadEvalPrintLoop.m index de2f4f1..0e213b0 100644 --- a/MLKReadEvalPrintLoop.m +++ b/MLKReadEvalPrintLoop.m @@ -16,12 +16,14 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#import "MLKBinaryStreamCharacterStream.h" #import "MLKDynamicContext.h" #import "MLKInterpreter.h" #import "MLKLexicalEnvironment.h" #import "MLKPackage.h" #import "MLKReadEvalPrintLoop.h" #import "MLKReader.h" +#import "MLKStreamStream.h" #import "NSObject-MLKPrinting.h" #import "runtime-compatibility.h" #import "util.h" @@ -77,7 +79,8 @@ static const char *prompt (EditLine *e) { HistEvent event; NSInputStream *input; - MLKStream *stream; + MLKBinaryStream *filestream; + MLKCharacterStream *stream; BOOL success; NSAutoreleasePool *pool; @@ -103,7 +106,10 @@ static const char *prompt (EditLine *e) { { #endif input = [NSInputStream inputStreamWithFileAtPath:@"init.lisp"]; - stream = LAUTORELEASE ([[MLKStream alloc] initWithInputStream:input]); + filestream = LAUTORELEASE ([[MLKStreamStream alloc] + initWithInputStream:input]); + stream = LAUTORELEASE ([[MLKBinaryStreamCharacterStream alloc] + initWithBinaryStream:filestream]); [input open]; [MLKInterpreter load:stream verbose:YES print:YES]; diff --git a/MLKReader.h b/MLKReader.h index c2395c1..fcb4896 100644 --- a/MLKReader.h +++ b/MLKReader.h @@ -16,15 +16,15 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "MLKCharacterStream.h" #include "MLKReadtable.h" -#include "MLKStream.h" #include <Foundation/NSObject.h> #include <Foundation/NSString.h> @interface MLKReader : NSObject -+(id) readFromStream:(MLKStream *)stream ++(id) readFromStream:(MLKCharacterStream *)stream eofError:(BOOL)eofError eofValue:(id)eofValue recursive:(BOOL)recursive @@ -32,7 +32,7 @@ singleDotMarker:(id)dotMarker readingUninternedSymbol:(BOOL)readingUninternedSymbol; -+(id) readFromStream:(MLKStream *)stream ++(id) readFromStream:(MLKCharacterStream *)stream eofError:(BOOL)eofError eofValue:(id)eofValue recursive:(BOOL)recursive diff --git a/MLKReader.m b/MLKReader.m index 419441b..66826d9 100644 --- a/MLKReader.m +++ b/MLKReader.m @@ -24,7 +24,7 @@ #import "MLKEnvironment.h" #import "MLKPackage.h" #import "MLKFuncallable.h" -#import "MLKStream.h" +#import "MLKCharacterStream.h" #import "MLKFloat.h" #import "MLKInteger.h" #import "MLKRatio.h" @@ -40,7 +40,7 @@ @implementation MLKReader -+(id) readFromStream:(MLKStream *)stream ++(id) readFromStream:(MLKCharacterStream *)stream eofError:(BOOL)eofError eofValue:(id)eofValue recursive:(BOOL)recursive @@ -55,7 +55,7 @@ readingUninternedSymbol:NO]; } -+(id) readFromStream:(MLKStream *)stream ++(id) readFromStream:(MLKCharacterStream *)stream eofError:(BOOL)eofError eofValue:(id)eofValue recursive:(BOOL)recursive diff --git a/MLKReaderError.h b/MLKReaderError.h index 68963e6..ceef646 100644 --- a/MLKReaderError.h +++ b/MLKReaderError.h @@ -18,15 +18,15 @@ #import <Foundation/NSException.h> -@class MLKStream; +@class MLKCharacterStream; @interface MLKReaderError : NSException { - MLKStream *stream; + MLKCharacterStream *stream; } --(MLKReaderError *) initWithStream:(MLKStream *)aStream; +-(MLKReaderError *) initWithStream:(MLKCharacterStream *)aStream; -(void) dealloc; @end diff --git a/MLKReaderError.m b/MLKReaderError.m index 09ae86c..bcfbdf6 100644 --- a/MLKReaderError.m +++ b/MLKReaderError.m @@ -22,7 +22,7 @@ @implementation MLKReaderError --(MLKReaderError *) initWithStream:(MLKStream *)aStream +-(MLKReaderError *) initWithStream:(MLKCharacterStream *)aStream { self = [super init]; stream = aStream; @@ -16,6 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#import "MLKBinaryStreamCharacterStream.h" #import "MLKBinding.h" #import "MLKCharacter.h" #import "MLKCompiledClosure.h" @@ -27,7 +28,7 @@ #import "MLKNumber.h" #import "MLKPackage.h" #import "MLKRoot.h" -#import "MLKStream.h" +#import "MLKStreamStream.h" #import "MLKSymbol.h" #import "MLKInteger.h" #import "MLKSingleFloat.h" @@ -98,7 +99,10 @@ load (id _data, NSString *fileName, id _marker) BOOL success; int l, i; NSInputStream *input = [NSInputStream inputStreamWithFileAtPath:fileName]; - MLKStream *stream = LAUTORELEASE ([[MLKStream alloc] initWithInputStream:input]); + MLKBinaryStream *filestream = LAUTORELEASE ([[MLKStreamStream alloc] + initWithInputStream:input]); + MLKCharacterStream *stream = LAUTORELEASE ([[MLKBinaryStreamCharacterStream alloc] + initWithBinaryStream:filestream]); MLKDynamicContext *oldContext = [MLKDynamicContext currentContext]; int level = MLKIntWithInteger ([oldContext valueForSymbol:[sys intern:@"*LOAD-LEVEL*"]]); @@ -564,8 +568,10 @@ primitive_type_of (id _data, id object, id _marker) { return [sys intern:@"BINDING"]; } else if ([object isKindOfClass:[MLKPackage class]]) { return [cl intern:@"PACKAGE"]; } - else if ([object isKindOfClass:[MLKStream class]]) - { return [cl intern:@"STREAM"]; } + else if ([object isKindOfClass:[MLKBinaryStream class]]) + { return [cl intern:@"BINARY-STREAM"]; } + else if ([object isKindOfClass:[MLKCharacterStream class]]) + { return [cl intern:@"CHARACTER-STREAM"]; } else if ([object isKindOfClass:[NSException class]]) { return [sys intern:@"EXCEPTION"]; } else if ([object isKindOfClass:[NSArray class]]) diff --git a/MLKSemicolonReader.m b/MLKSemicolonReader.m index 3e4cd21..6922c1d 100644 --- a/MLKSemicolonReader.m +++ b/MLKSemicolonReader.m @@ -19,14 +19,14 @@ #import "MLKSemicolonReader.h" #import "MLKCons.h" -#import "MLKStream.h" +#import "MLKCharacterStream.h" #import "runtime-compatibility.h" @implementation MLKSemicolonReader -(NSArray *) applyToArray:(NSArray *)arguments { - MLKStream *stream; + MLKCharacterStream *stream; unichar nextChar; stream = [arguments objectAtIndex:0]; diff --git a/MLKSharpsignColonReader.m b/MLKSharpsignColonReader.m index bbd9621..8c650a7 100644 --- a/MLKSharpsignColonReader.m +++ b/MLKSharpsignColonReader.m @@ -19,7 +19,7 @@ #import "MLKSharpsignColonReader.h" #import "MLKReader.h" -#import "MLKStream.h" +#import "MLKCharacterStream.h" #import "runtime-compatibility.h" #import "util.h" @@ -27,7 +27,7 @@ @implementation MLKSharpsignColonReader -(NSArray *) applyToArray:(NSArray *)arguments { - MLKStream *stream; + MLKCharacterStream *stream; stream = [arguments objectAtIndex:0]; diff --git a/MLKStream.m b/MLKStream.m deleted file mode 100644 index 9d34edb..0000000 --- a/MLKStream.m +++ /dev/null @@ -1,201 +0,0 @@ -/* -*- mode: objc; coding: utf-8 -*- */ -/* Toilet Lisp, 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 "MLKStream.h" -#import "runtime-compatibility.h" -#import "util.h" - -#import <Foundation/NSException.h> - -#include <unistd.h> -#include <stdlib.h> -#include <string.h> - - -@implementation MLKStream --(id) init; -{ - return [self initWithInputStream:nil outputStream:nil]; -} - --(id) initWithInputStream:(NSInputStream *)input; -{ - return [self initWithInputStream:input outputStream:nil]; -} - --(id) initWithOutputStream:(NSOutputStream *)output; -{ - return [self initWithInputStream:nil outputStream:output]; -} - --(id) initWithInputStream:(NSInputStream *)input - outputStream:(NSOutputStream *)output -{ - return [self initWithInputStream:input - outputStream:output - encoding:NSUTF8StringEncoding]; -} - - --(id) initWithInputStream:(NSInputStream *)input - outputStream:(NSOutputStream *)output - encoding:(NSStringEncoding)encoding -{ - self = [super init]; - LASSIGN (_input, input); - LASSIGN (_output, output); - _encoding = encoding; - _cachedChar = 0; - _charCached = NO; - _closeInputWhenDone = NO; - _closeOutputWhenDone = NO; - return self; -} - --(unichar) readChar -{ - uint8_t *buffer; - size_t i; - unichar retval; - - if (_charCached) - { - char ch; - ch = _cachedChar; - _cachedChar = 0; - _charCached = NO; - return ch; - } - - if ([_input streamStatus] == NSStreamStatusNotOpen) - { - _closeInputWhenDone = YES; - [_input open]; - } - - buffer = NULL; - for (i = 0;; i++) - { - NSString *tmpstr; - ssize_t bytes_read; - - //NSLog (@"%@", _input); - - buffer = (uint8_t *) realloc (buffer, i+1); - bytes_read = [_input read:(buffer+i) maxLength:1]; - //NSLog (@"%d bytes read", bytes_read); - - if (bytes_read < 1) - { - free (buffer); - [NSException raise:@"MLKStreamError" - format:@"Tried to read beyond end of file."]; - } - - tmpstr = [[NSString alloc] initWithBytes:buffer - length:(i+1) - encoding:_encoding]; - if ([tmpstr length] == 1) - { - retval = [tmpstr characterAtIndex:0]; - [tmpstr release]; - //free (buffer); - return retval; - } - else - { - [tmpstr release]; - } - } - - return -1; -} - --(void) unreadChar:(unichar)ch -{ - if (_charCached) - [NSException raise:@"MLKInvalidOperationError" - format:@"Attempted to UNREAD-CHAR twice in a row."]; - - _charCached = YES; - _cachedChar = ch; -} - --(unichar) peekChar -{ - unichar ch = [self readChar]; - [self unreadChar:ch]; - return ch; -} - --(BOOL) isEOF -{ - BOOL eofp = NO; - - NS_DURING - { - [self peekChar]; - } - NS_HANDLER - { - if ([[localException name] isEqual:@"MLKStreamError"]) - eofp = YES; - else - [localException raise]; - } - NS_ENDHANDLER; - - return eofp; -} - --(void) writeChar:(unichar)ch -{ - const void *cstring = [[NSString stringWithFormat:@"%C", ch] cStringUsingEncoding:_encoding]; - [_output write:cstring maxLength:strlen(cstring)]; -} - -//-(void) writeFormat:(NSString *)format, ... -//{ -// NSString *string = ; -// [self writeString:string]; -//} - --(void) writeString:(NSString *)string -{ - unichar ch; - int i; - - for (i = 0; i < [string length]; i++) - [self writeChar:[string characterAtIndex:i]]; -} - --(void) dealloc -{ - if (_closeInputWhenDone) - { - [_input close]; - } - LRELEASE (_input); - if (_closeOutputWhenDone) - { - [_output close]; - } - LRELEASE (_output); - [super dealloc]; -} -@end diff --git a/MLKStream.h b/MLKStreamStream.h index a2536fd..3bd4f1b 100644 --- a/MLKStream.h +++ b/MLKStreamStream.h @@ -16,19 +16,18 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#import "MLKBinaryStream.h" + #import <Foundation/NSStream.h> #import <Foundation/NSString.h> - -@interface MLKStream : NSObject +@interface MLKStreamStream : MLKBinaryStream { NSInputStream *_input; NSOutputStream *_output; NSStringEncoding _encoding; - BOOL _charCached; BOOL _closeInputWhenDone; BOOL _closeOutputWhenDone; - unichar _cachedChar; } -(id) init; @@ -36,16 +35,7 @@ -(id) initWithOutputStream:(NSOutputStream *)output; -(id) initWithInputStream:(NSInputStream *)input outputStream:(NSOutputStream *)output; --(id) initWithInputStream:(NSInputStream *)input - outputStream:(NSOutputStream *)output - encoding:(NSStringEncoding)encoding; - --(unichar) readChar; --(void) unreadChar:(unichar)ch; --(unichar) peekChar; --(BOOL) isEOF; --(void) writeChar:(unichar)ch; -//-(void) writeFormat:(NSString *)format, ...; --(void) writeString:(NSString *)string; +-(uint8_t) readOctet; +-(void) writeOctet:(uint8_t)octet; @end diff --git a/MLKStreamStream.m b/MLKStreamStream.m new file mode 100644 index 0000000..7e19932 --- /dev/null +++ b/MLKStreamStream.m @@ -0,0 +1,104 @@ +/* -*- mode: objc; coding: utf-8 -*- */ +/* Toilet Lisp, 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 "MLKStreamStream.h" +#import "runtime-compatibility.h" +#import "util.h" + +#import <Foundation/NSException.h> + +#include <unistd.h> +#include <stdlib.h> +#include <string.h> + + +@implementation MLKStreamStream +-(id) init; +{ + return [self initWithInputStream:nil outputStream:nil]; +} + +-(id) initWithInputStream:(NSInputStream *)input; +{ + return [self initWithInputStream:input outputStream:nil]; +} + +-(id) initWithOutputStream:(NSOutputStream *)output; +{ + return [self initWithInputStream:nil outputStream:output]; +} + +-(id) initWithInputStream:(NSInputStream *)input + outputStream:(NSOutputStream *)output +{ + self = [super init]; + LASSIGN (_input, input); + LASSIGN (_output, output); + _closeInputWhenDone = NO; + _closeOutputWhenDone = NO; + return self; +} + +-(uint8_t) readOctet +{ + uint8_t octet; + size_t bytes_read; + + if ([_input streamStatus] == NSStreamStatusNotOpen) + { + _closeInputWhenDone = YES; + [_input open]; + } + + bytes_read = [_input read:&octet maxLength:1]; + + if (bytes_read < 1) + { + [NSException raise:@"MLKStreamError" + format:@"Tried to read beyond end of file."]; + } + + return octet; +} + +-(void) writeOctet:(uint8_t)octet +{ + if ([_output streamStatus] == NSStreamStatusNotOpen) + { + _closeOutputWhenDone = YES; + [_output open]; + } + + [_output write:&octet maxLength:1]; +} + +-(void) dealloc +{ + if (_closeInputWhenDone) + { + [_input close]; + } + LRELEASE (_input); + if (_closeOutputWhenDone) + { + [_output close]; + } + LRELEASE (_output); + [super dealloc]; +} +@end diff --git a/MLKStringInputStream.h b/MLKStringInputStream.h index e6c1f72..f41be7f 100644 --- a/MLKStringInputStream.h +++ b/MLKStringInputStream.h @@ -16,12 +16,12 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#import "MLKStream.h" +#import "MLKBinaryStreamCharacterStream.h" @class NSString; -@interface MLKStringInputStream : MLKStream +@interface MLKStringInputStream : MLKBinaryStreamCharacterStream -(MLKStringInputStream *) init; -(MLKStringInputStream *) initWithString:(NSString *)string; +(MLKStringInputStream *) streamWithString:(NSString *)string; diff --git a/MLKStringInputStream.m b/MLKStringInputStream.m index 30312d7..c8d7a38 100644 --- a/MLKStringInputStream.m +++ b/MLKStringInputStream.m @@ -16,6 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#import "MLKStreamStream.h" #import "MLKStringInputStream.h" #import "runtime-compatibility.h" #import "util.h" @@ -32,11 +33,13 @@ -(MLKStringInputStream *) initWithString:(NSString *)string { - self = (id) [super initWithInputStream: - [NSInputStream inputStreamWithData: - [string dataUsingEncoding: - NSUnicodeStringEncoding]] - outputStream:nil + MLKStreamStream *binstream = + LAUTORELEASE ([[MLKStreamStream alloc] + initWithInputStream: + [NSInputStream inputStreamWithData: + [string dataUsingEncoding: + NSUnicodeStringEncoding]]]); + self = (id) [super initWithBinaryStream:binstream encoding:NSUnicodeStringEncoding]; return self; } diff --git a/MLKStringOutputStream.h b/MLKStringOutputStream.h index f8e4ca5..75c3726 100644 --- a/MLKStringOutputStream.h +++ b/MLKStringOutputStream.h @@ -16,10 +16,15 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#import "MLKStream.h" +#import "MLKBinaryStreamCharacterStream.h" -@interface MLKStringOutputStream : MLKStream +@interface MLKStringOutputStream : MLKBinaryStreamCharacterStream +{ + NSOutputStream *_outputStream; +} + -(id) init; +-(void) dealloc; -(NSString *) string; @end diff --git a/MLKStringOutputStream.m b/MLKStringOutputStream.m index 00a60b0..ea08b89 100644 --- a/MLKStringOutputStream.m +++ b/MLKStringOutputStream.m @@ -17,6 +17,7 @@ */ #import "MLKStringOutputStream.h" +#import "MLKStreamStream.h" #import "runtime-compatibility.h" #import "util.h" @@ -28,16 +29,26 @@ @implementation MLKStringOutputStream -(id) init { - self = (id)[super initWithInputStream:nil - outputStream:LAUTORELEASE ([[NSOutputStream alloc] initToMemory]) - encoding:NSUnicodeStringEncoding]; + _outputStream = [[NSOutputStream alloc] initToMemory]; + + MLKStreamStream *binstream = + LAUTORELEASE ([[MLKStreamStream alloc] initWithOutputStream:_outputStream]); + + self = (id) [super initWithBinaryStream:binstream + encoding:NSUnicodeStringEncoding]; return self; } +-(void) dealloc +{ + LDESTROY (_outputStream); + [super dealloc]; +} + -(NSString *) string { - NSData *data = [_output propertyForKey:NSStreamDataWrittenToMemoryStreamKey]; + NSData *data = [_outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey]; return LAUTORELEASE ([[NSString alloc] initWithData:data - encoding:NSUnicodeStringEncoding]); + encoding:NSUnicodeStringEncoding]); } @end diff --git a/MLKStringReader.m b/MLKStringReader.m index 7c358d6..15d6232 100644 --- a/MLKStringReader.m +++ b/MLKStringReader.m @@ -19,12 +19,12 @@ #import "MLKStringReader.h" #import "MLKCharacter.h" +#import "MLKCharacterStream.h" #import "MLKCons.h" #import "MLKDynamicContext.h" #import "MLKReader.h" #import "MLKReadtable.h" #import "MLKPackage.h" -#import "MLKStream.h" #import "runtime-compatibility.h" #import <Foundation/NSString.h> @@ -33,7 +33,7 @@ @implementation MLKStringReader -(NSArray *) applyToArray:(NSArray *)arguments { - MLKStream *stream; + MLKCharacterStream *stream; unichar ch; MLKReadtable *readtable; unichar nextChar; diff --git a/special-symbols.h b/special-symbols.h index d0f93b0..752e1e9 100644 --- a/special-symbols.h +++ b/special-symbols.h @@ -61,6 +61,12 @@ static MLKSymbol *INLINE; static MLKSymbol *NOTINLINE; static MLKSymbol *SPECIAL; static MLKSymbol *LEXICAL; +static MLKSymbol *QUERY_IO; +static MLKSymbol *ERROR_OUTPUT; +static MLKSymbol *STANDARD_OUTPUT; +static MLKSymbol *TERMINAL_IO; +static MLKSymbol *TRACE_OUTPUT; +static MLKSymbol *DEBUG_IO; static void @@ -106,6 +112,13 @@ ensure_symbols () SPECIAL = [cl intern:@"INLINE"]; LEXICAL = [sys intern:@"NOTINLINE"]; + QUERY_IO = [cl intern:@"*QUERY-IO*"]; + ERROR_OUTPUT = [cl intern:@"*ERROR-OUTPUT*"]; + STANDARD_OUTPUT = [cl intern:@"*STANDARD-OUTPUT*"]; + TERMINAL_IO = [cl intern:@"*TERMINAL-IO*"]; + TRACE_OUTPUT = [cl intern:@"*TRACE-OUTPUT*"]; + DEBUG_IO = [cl intern:@"*DEBUG-IO*"]; + COMPILE_TOPLEVEL = [keyword intern:@"COMPILE-TOPLEVEL"]; COMPILE = [cl intern:@"COMPILE"]; LOAD_TOPLEVEL = [keyword intern:@"LOAD-TOPLEVEL"]; |