Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 123 lines (98 sloc) 2.389 kB
7aa6b9d The remaining "core" files OBJJified (with probable errors)
Ross Boucher authored
1
2 @import "TDTokenizerState.j"
3
4 @implementation TDNumberState : TDTokenizerState
5 {
6 BOOL allowsTrailingDot;
7 BOOL gotADigit;
8 BOOL negative;
9 int c;
10 float floatValue;
11 }
12
13 - (TDToken)nextTokenFromReader:(TDReader)r startingWith:(int)cin tokenizer:(TDTokenizer)t
14 {
15 [self reset];
16
17 negative = NO;
18
19 var originalCin = cin;
20
21 if ('-' == cin) {
22 negative = YES;
23 cin = [r read];
24 [self append:'-'];
25 } else if ('+' == cin) {
26 cin = [r read];
27 [self append:'+'];
28 }
29
30 [self reset:cin];
31
32 if ('.' == c) {
33 [self parseRightSideFromReader:r];
34 } else {
35 [self parseLeftSideFromReader:r];
36 [self parseRightSideFromReader:r];
37 }
38
39 // erroneous ., +, or -
40 if (!gotADigit) {
41 if (negative && -1 != c) { // ??
42 [r unread];
43 }
44 return [t.symbolState nextTokenFromReader:r startingWith:originalCin tokenizer:t];
45 }
46
47 if (-1 != c) {
48 [r unread];
49 }
50
51 if (negative) {
52 floatValue = -floatValue;
53 }
54
55 return [TDToken tokenWithTokenType:TDTokenTypeNumber stringValue:[self bufferedString] floatValue:[self value]];
56 }
57
58 - (float)value
59 {
60 return floatValue;
61 }
62
63 - (float)absorbDigitsFromReader:(TDReader)r isFraction:(BOOL)isFraction
64 {
65 var divideBy = 1.0,
66 v = 0.0;
67
68 while (1) {
69 if (isdigit(c)) {
70 [self append:c];
71 gotADigit = YES;
72 v = v * 10.0 + (c - '0');
73 c = [r read];
74 if (isFraction) {
75 divideBy *= 10.0;
76 }
77 } else {
78 break;
79 }
80 }
81
82 if (isFraction) {
83 v = v / divideBy;
84 }
85
86 return v;
87 }
88
89 - (void)parseLeftSideFromReader:(TDReader)r
90 {
91 floatValue = [self absorbDigitsFromReader:r isFraction:NO];
92 }
93
94
95 - (void)parseRightSideFromReader:(TDReader)r
96 {
97 if ('.' == c)
98 {
99 var n = [r read],
100 nextIsDigit = isdigit(n);
101
102 if (-1 != n)
103 [r unread];
104
105 if (nextIsDigit || allowsTrailingDot) {
106 [self append:'.'];
107 if (nextIsDigit) {
108 c = [r read];
109 floatValue += [self absorbDigitsFromReader:r isFraction:YES];
110 }
111 }
112 }
113 }
114
115 - (void)reset:(int)cin
116 {
117 gotADigit = NO;
118 floatValue = 0.0;
119 c = cin;
120 }
121
122 @end
Something went wrong with that request. Please try again.