summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <matthias@benkard.de>2008-06-14 23:29:25 +0200
committerMatthias Andreas Benkard <matthias@benkard.de>2008-06-14 23:29:25 +0200
commit93bd600a7b1bc4062c29f1c8e961c29317312efb (patch)
treeb3966d04bd263f7092e1512b8ed5ccb19a548daa
parent932d3df11b56b88a97ef497ca7c891547275d05a (diff)
Add class MLKReadtable.
-rw-r--r--GNUmakefile4
-rw-r--r--MLKReadtable.h8
-rw-r--r--MLKReadtable.m136
3 files changed, 144 insertions, 4 deletions
diff --git a/GNUmakefile b/GNUmakefile
index b9ddad3..4b614b0 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -21,8 +21,8 @@ TOOL_NAME = etoilisp
etoilisp_OBJC_FILES = MLKCharacter.m MLKCons.m MLKDynamicContext.m \
MLKEndOfFileError.m MLKEnvironment.m MLKError.m \
MLKLinkedList.m MLKLispValue.m MLKPackage.m \
- MLKReader.m MLKReaderError.m MLKStream.m \
- MLKSymbol.m MLKThrowException.m \
+ MLKReader.m MLKReadtable.m MLKReaderError.m \
+ MLKStream.m MLKSymbol.m MLKThrowException.m \
MLKUndefinedVariableException.m
BUNDLE_NAME = Test
diff --git a/MLKReadtable.h b/MLKReadtable.h
index 1f4bf97..2ea4cc7 100644
--- a/MLKReadtable.h
+++ b/MLKReadtable.h
@@ -18,6 +18,9 @@
#import "MLKLispValue.h"
+#import <Foundation/NSObject.h>
+#import <Foundation/NSString.h>
+
@class MLKClosure, NSMutableDictionary;
@@ -30,7 +33,7 @@ enum MLKReadtableCase
};
-@interface MLKReadtable : MLKLispValue
+@interface MLKReadtable : MLKLispValue <NSCopying>
{
NSMutableDictionary *_syntaxTable;
NSMutableDictionary *_readerMacros;
@@ -39,7 +42,8 @@ enum MLKReadtableCase
}
-(MLKReadtable *) init;
--(MLKReadtable *) copy;
+
+-(MLKReadtable *) copyWithZone:(NSZone *)zone;
-(BOOL) isWhitespaceCharacter:(unichar)ch;
-(BOOL) isMacroCharacter:(unichar)ch;
diff --git a/MLKReadtable.m b/MLKReadtable.m
new file mode 100644
index 0000000..41d6a9c
--- /dev/null
+++ b/MLKReadtable.m
@@ -0,0 +1,136 @@
+/* -*- 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 "MLKReadtable.h"
+
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSValue.h>
+
+
+#define CONSTITUENT 0
+#define WHITESPACE 1
+#define TERMINATING_MACRO 2
+#define NONTERMINATING_MACRO 3
+#define SINGLE_ESCAPE 4
+#define MULTI_ESCAPE 5
+
+
+@implementation MLKReadtable
+-(MLKReadtable *) init
+{
+ self = [super init];
+ _syntaxTable = [[NSMutableDictionary alloc] init];
+ _readerMacros = [[NSMutableDictionary alloc] init];
+ _case = MLKReadtableCase_UPCASE;
+ return self;
+}
+
+-(MLKReadtable *) copyWithZone:(NSZone *)zone
+{
+ MLKReadtable *copy = [MLKReadtable allocWithZone:zone];
+ copy->_syntaxTable = [_syntaxTable mutableCopyWithZone:zone];
+ copy->_readerMacros = [_readerMacros mutableCopyWithZone:zone];
+ copy->_case = _case;
+ return copy;
+}
+
+-(BOOL) isWhitespaceCharacter:(unichar)ch
+{
+ return ([[_syntaxTable objectForKey:[NSNumber numberWithLong:ch]]
+ isEqual:[NSNumber numberWithShort:WHITESPACE]]);
+}
+
+-(BOOL) isMacroCharacter:(unichar)ch;
+{
+ return ([self isNonTerminatingMacroCharacter:ch] ||
+ [self isTerminatingMacroCharacter:ch]);
+}
+
+-(BOOL) isNonTerminatingMacroCharacter:(unichar)ch;
+{
+ return ([[_syntaxTable objectForKey:[NSNumber numberWithLong:ch]]
+ isEqual:[NSNumber numberWithShort:NONTERMINATING_MACRO]]);
+}
+
+-(BOOL) isTerminatingMacroCharacter:(unichar)ch;
+{
+ return ([[_syntaxTable objectForKey:[NSNumber numberWithLong:ch]]
+ isEqual:[NSNumber numberWithShort:TERMINATING_MACRO]]);
+}
+
+-(BOOL) isSingleEscapeCharacter:(unichar)ch;
+{
+ return ([[_syntaxTable objectForKey:[NSNumber numberWithLong:ch]]
+ isEqual:[NSNumber numberWithShort:SINGLE_ESCAPE]]);
+}
+
+-(BOOL) isMultipleEscapeCharacter:(unichar)ch;
+{
+ return ([[_syntaxTable objectForKey:[NSNumber numberWithLong:ch]]
+ isEqual:[NSNumber numberWithShort:MULTI_ESCAPE]]);
+}
+
+-(BOOL) isConstituentCharacter:(unichar)ch;
+{
+ return ([[_syntaxTable objectForKey:[NSNumber numberWithLong:ch]]
+ isEqual:[NSNumber numberWithShort:CONSTITUENT]]);
+}
+
+-(BOOL) isInvalidCharacter:(unichar)ch;
+{
+ return ([_syntaxTable objectForKey:[NSNumber numberWithLong:ch]] == nil);
+}
+
+-(BOOL) characterHasCase:(unichar)ch
+{
+ return (![[[NSString stringWithFormat:@"%C", ch] uppercaseString]
+ isEqual:[[NSString stringWithFormat:@"%C", ch] lowercaseString]]);
+}
+
+-(MLKClosure *) macroFunctionForCharacter:(unichar)ch;
+{
+ return [_readerMacros objectForKey:[NSNumber numberWithLong:ch]];
+}
+
+-(unichar) charWithReadtableCase:(unichar)ch
+{
+ switch (_case)
+ {
+ case MLKReadtableCase_PRESERVE:
+ return ch;
+ case MLKReadtableCase_UPCASE:
+ return [[[NSString stringWithFormat:@"%C", ch] uppercaseString]
+ characterAtIndex:0];
+ case MLKReadtableCase_DOWNCASE:
+ return [[[NSString stringWithFormat:@"%C", ch] lowercaseString]
+ characterAtIndex:0];
+ case MLKReadtableCase_INVERT:
+ {
+ unichar upCh;
+ upCh = [[[NSString stringWithFormat:@"%C", ch] uppercaseString]
+ characterAtIndex:0];
+ if (ch == upCh)
+ return [[[NSString stringWithFormat:@"%C", ch] lowercaseString]
+ characterAtIndex:0];
+ else
+ return upCh;
+ }
+ }
+ return 0;
+}
+@end