From 3a5710bf7cb85da4ba6a327d6149db46e6bed82e Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Thu, 28 Aug 2008 16:26:07 +0200 Subject: Eliminate MLKStream, introduce MLKBinaryStream and MLKCharacterStream. --- GNUmakefile | 37 +++---- MLKBackquoteReader.m | 4 +- MLKBinaryStream.h | 25 +++++ MLKBinaryStream.m | 35 ++++++ MLKBinaryStreamCharacterStream.h | 39 +++++++ MLKBinaryStreamCharacterStream.m | 91 ++++++++++++++++ MLKCharacterStream.h | 42 ++++++++ MLKCharacterStream.m | 111 +++++++++++++++++++ MLKCommaReader.m | 4 +- MLKDispatchingMacroCharacterReader.m | 4 +- MLKInterpreter.h | 4 +- MLKInterpreter.m | 2 +- MLKListenerController.h | 13 +-- MLKListenerController.m | 62 +++++++---- MLKParenReader.m | 6 +- MLKQuoteReader.m | 4 +- MLKReadEvalPrintLoop.m | 10 +- MLKReader.h | 6 +- MLKReader.m | 6 +- MLKReaderError.h | 6 +- MLKReaderError.m | 2 +- MLKRoot.m | 14 ++- MLKSemicolonReader.m | 4 +- MLKSharpsignColonReader.m | 4 +- MLKStream.h | 51 --------- MLKStream.m | 201 ----------------------------------- MLKStreamStream.h | 41 +++++++ MLKStreamStream.m | 104 ++++++++++++++++++ MLKStringInputStream.h | 4 +- MLKStringInputStream.m | 13 ++- MLKStringOutputStream.h | 9 +- MLKStringOutputStream.m | 21 +++- MLKStringReader.m | 4 +- special-symbols.h | 13 +++ 34 files changed, 646 insertions(+), 350 deletions(-) create mode 100644 MLKBinaryStream.h create mode 100644 MLKBinaryStream.m create mode 100644 MLKBinaryStreamCharacterStream.h create mode 100644 MLKBinaryStreamCharacterStream.m create mode 100644 MLKCharacterStream.h create mode 100644 MLKCharacterStream.m delete mode 100644 MLKStream.h delete mode 100644 MLKStream.m create mode 100644 MLKStreamStream.h create mode 100644 MLKStreamStream.m 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 . + */ + +#import + +@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 . + */ + +#import "MLKBinaryStream.h" + +#import + +@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 . + */ + +#import "MLKBinaryStream.h" +#import "MLKCharacterStream.h" + +#import +#import + + +@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 . + */ + +#import "MLKBinaryStreamCharacterStream.h" +#import "runtime-compatibility.h" +#import "util.h" + +#import + +#include +#include +#include + + +@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 . + */ + +#import +#import + + +@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 . + */ + +#import "MLKCharacterStream.h" +#import "runtime-compatibility.h" +#import "util.h" + +#import + +#include +#include +#include + + +@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 . */ +#import "MLKCharacterStream.h" #import "MLKForm.h" #import "MLKLexicalContext.h" #import "MLKLexicalEnvironment.h" -#import "MLKStream.h" #import #import @@ -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 . */ -#import "MLKStream.h" +#import "MLKCharacterStream.h" #import -@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 -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 . */ +#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 . */ +#include "MLKCharacterStream.h" #include "MLKReadtable.h" -#include "MLKStream.h" #include #include @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 -@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; diff --git a/MLKRoot.m b/MLKRoot.m index 1efd024..2184d6a 100644 --- a/MLKRoot.m +++ b/MLKRoot.m @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#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.h b/MLKStream.h deleted file mode 100644 index a2536fd..0000000 --- a/MLKStream.h +++ /dev/null @@ -1,51 +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 . - */ - -#import -#import - - -@interface MLKStream : NSObject -{ - NSInputStream *_input; - NSOutputStream *_output; - NSStringEncoding _encoding; - BOOL _charCached; - BOOL _closeInputWhenDone; - BOOL _closeOutputWhenDone; - unichar _cachedChar; -} - --(id) init; --(id) initWithInputStream:(NSInputStream *)input; --(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; -@end 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 . - */ - -#import "MLKStream.h" -#import "runtime-compatibility.h" -#import "util.h" - -#import - -#include -#include -#include - - -@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/MLKStreamStream.h b/MLKStreamStream.h new file mode 100644 index 0000000..3bd4f1b --- /dev/null +++ b/MLKStreamStream.h @@ -0,0 +1,41 @@ +/* -*- 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 . + */ + +#import "MLKBinaryStream.h" + +#import +#import + +@interface MLKStreamStream : MLKBinaryStream +{ + NSInputStream *_input; + NSOutputStream *_output; + NSStringEncoding _encoding; + BOOL _closeInputWhenDone; + BOOL _closeOutputWhenDone; +} + +-(id) init; +-(id) initWithInputStream:(NSInputStream *)input; +-(id) initWithOutputStream:(NSOutputStream *)output; +-(id) initWithInputStream:(NSInputStream *)input + outputStream:(NSOutputStream *)output; + +-(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 . + */ + +#import "MLKStreamStream.h" +#import "runtime-compatibility.h" +#import "util.h" + +#import + +#include +#include +#include + + +@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 . */ -#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 . */ +#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 . */ -#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 @@ -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"]; -- cgit v1.2.3