Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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.