summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MLKFloat.h36
-rw-r--r--MLKInteger.h35
-rw-r--r--MLKRatio.h34
-rw-r--r--MLKReader.m156
-rw-r--r--MLKReadtable.h1
5 files changed, 261 insertions, 1 deletions
diff --git a/MLKFloat.h b/MLKFloat.h
new file mode 100644
index 0000000..fdb1212
--- /dev/null
+++ b/MLKFloat.h
@@ -0,0 +1,36 @@
+/* -*- 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 NSString;
+
+
+@interface MLKFloat : MLKLispValue
+{
+}
+
++(MLKFloat *) floatWithExponentMarker:(unichar)exponentMarker
+ integerPart:(NSString *)intPart
+ negative:(BOOL)negative
+ fractionalPart:(NSString *)fractPart
+ exponent:(NSString *)exponent
+ exponentNegative:(BOOL)exponentNegative;
+
+-(void) dealloc;
+@end
diff --git a/MLKInteger.h b/MLKInteger.h
new file mode 100644
index 0000000..38d319e
--- /dev/null
+++ b/MLKInteger.h
@@ -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 "MLKLispValue.h"
+
+@class NSString;
+
+
+@interface MLKInteger : MLKLispValue
+{
+}
+
++(MLKInteger *) integerWithString:(NSString *)string
+ negative:(BOOL)negative
+ base:(unsigned int)base;
+
+-(int) intValue;
+
+-(void) dealloc;
+@end
diff --git a/MLKRatio.h b/MLKRatio.h
new file mode 100644
index 0000000..c67d7dd
--- /dev/null
+++ b/MLKRatio.h
@@ -0,0 +1,34 @@
+/* -*- 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 NSString, MLKInteger;
+
+
+@interface MLKRatio : MLKLispValue
+{
+ MLKInteger *numerator;
+ MLKInteger *denominator;
+}
+
++(MLKRatio *) ratioWithNumeratorString:(NSString *)numerString
+ denominatorString:(NSString *)denomString;
+
+-(void) dealloc;
+@end
diff --git a/MLKReader.m b/MLKReader.m
index 9a9b956..5663efb 100644
--- a/MLKReader.m
+++ b/MLKReader.m
@@ -26,8 +26,12 @@
#import "MLKPackage.h"
#import "MLKClosure.h"
#import "MLKStream.h"
+#import "MLKFloat.h"
+#import "MLKInteger.h"
+#import "MLKRatio.h"
#import <Foundation/NSArray.h>
+#import <Foundation/NSRange.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSString.h>
@@ -206,7 +210,157 @@
{
if ([self isPotentialNumber:token readtable:readtable])
{
- // ???
+ unsigned long i, firstNum, secondNum, exponent, exponentMarkerPos;
+ unichar sign, exponentSign;
+ unichar firstSeparator, exponentMarker;
+ BOOL negative;
+ MLKInteger *base;
+
+ base = [[MLKDynamicContext currentContext]
+ valueForBinding:[[MLKPackage findPackage:@"COMMON-LISP"]
+ intern:@"*READ-BASE*"]];
+
+ // Read the sign (if present).
+ if ([readtable isSign:[token characterAtIndex:0]])
+ {
+ sign = [token characterAtIndex:0];
+ i = 1;
+ firstNum = 1;
+ }
+ else
+ {
+ i = 0;
+ firstNum = 0;
+ }
+
+ negative = (firstNum > 0 && sign == '-');
+
+ while ((i < [token length])
+ && [readtable isDecimalDigit:[token characterAtIndex:i]])
+ i++;
+
+ if (i == [token length])
+ {
+ return [MLKInteger integerWithString:
+ [token substringWithRange:
+ NSMakeRange (firstNum, [token length] - firstNum)]
+ negative:negative
+ base:10];
+ }
+
+ firstSeparator = [token characterAtIndex:i];
+
+ if (!([readtable isDecimalPoint:firstSeparator]
+ || [readtable isExponentMarker:[token characterAtIndex:i]]))
+ goto digits;
+
+ i++;
+ secondNum = i;
+
+ if (i == [token length] && [readtable isDecimalPoint:firstSeparator])
+ {
+ return [MLKInteger integerWithString:
+ [token substringWithRange:
+ NSMakeRange (firstNum, [token length] - firstNum - 1)]
+ negative:negative
+ base:10];
+ }
+ else
+ {
+ // We're dealing with a floating point number. Bah. I hate
+ // floating point numbers.
+ if ([readtable isExponentMarker:firstSeparator])
+ {
+ exponentMarkerPos = i;
+ if ([readtable isSign:[token characterAtIndex:i]])
+ {
+ exponentSign = [token characterAtIndex:i];
+ i++;
+ }
+ else
+ exponentSign = '+';
+
+ exponent = i;
+
+ while ((i < [token length])
+ && [readtable isDecimalDigit:[token characterAtIndex:i]])
+ i++;
+
+ return [MLKFloat floatWithExponentMarker:firstSeparator
+ integerPart:[token substringWithRange:NSMakeRange(firstNum, exponentMarkerPos - firstNum - 1)]
+ negative:negative
+ fractionalPart:@""
+ exponent:[token substringFromIndex:exponent]
+ exponentNegative:(exponentSign == '-')];
+ }
+ else
+ {
+ while ((i < [token length])
+ && [readtable isDecimalDigit:[token characterAtIndex:i]])
+ i++;
+
+ if (i == [token length])
+ {
+ return [MLKFloat floatWithExponentMarker:firstSeparator
+ integerPart:[token substringWithRange:NSMakeRange (firstNum, secondNum - firstNum - 1)]
+ negative:negative
+ fractionalPart:[token substringFromIndex:secondNum]
+ exponent:@""
+ exponentNegative:NO];
+ }
+
+ // Assume token[i] is an exponent marker.
+ exponentMarkerPos = i;
+ exponentMarker = [token characterAtIndex:i];
+ i++;
+
+ if ([readtable isSign:[token characterAtIndex:i]])
+ {
+ exponentSign = [token characterAtIndex:i];
+ i++;
+ }
+ else
+ exponentSign = '+';
+
+ exponent = i;
+
+ while ((i < [token length])
+ && [readtable isDecimalDigit:[token characterAtIndex:i]])
+ i++;
+
+ return [MLKFloat floatWithExponentMarker:exponentMarker
+ integerPart:[token substringWithRange:NSMakeRange (firstNum, secondNum - firstNum - 1)]
+ negative:negative
+ fractionalPart:[token substringWithRange:NSMakeRange (secondNum, exponentMarkerPos - secondNum)]
+ exponent:[token substringFromIndex:exponent]
+ exponentNegative:(exponentSign == '-')];
+ }
+ }
+
+ digits:
+ i = firstNum;
+ while ((i < [token length])
+ && [readtable isDigit:[token characterAtIndex:0]])
+ i++;
+
+ if (i == [token length])
+ {
+ return [MLKInteger integerWithString:
+ [token substringWithRange:
+ NSMakeRange (firstNum, [token length] - firstNum)]
+ negative:negative
+ base:[base intValue]];
+ }
+
+ // Assume token[i] is a slash.
+ i++;
+ secondNum = i;
+
+ return [MLKRatio ratioWithNumeratorString:
+ [token substringWithRange:
+ NSMakeRange (firstNum,
+ secondNum - firstNum - 1)]
+ denominatorString:[token substringFromIndex:secondNum]];
}
else
{
diff --git a/MLKReadtable.h b/MLKReadtable.h
index faf98c6..c8421cb 100644
--- a/MLKReadtable.h
+++ b/MLKReadtable.h
@@ -69,6 +69,7 @@ enum MLKReadtableCase
-(BOOL) isDot:(unichar)ch;
// Read-base-dependent digit properties.
+-(BOOL) isDecimalDigit:(unichar)ch;
-(BOOL) isDigit:(unichar)ch;
-(int) digitWeight:(unichar)ch;