summaryrefslogtreecommitdiff
path: root/MLKReader.m
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <matthias@benkard.de>2008-06-15 16:31:15 +0200
committerMatthias Andreas Benkard <matthias@benkard.de>2008-06-15 16:31:15 +0200
commitc2efa347a8e5f1d83427c34defa953e594a2bb12 (patch)
tree95aae957b63f4b7e9db4095a3a608a3b077aaece /MLKReader.m
parent915e7a81737866a5bf8e9b39fea20716ad18bce7 (diff)
MLKReader: Read numbers.
Diffstat (limited to 'MLKReader.m')
-rw-r--r--MLKReader.m156
1 files changed, 155 insertions, 1 deletions
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
{