diff options
Diffstat (limited to '')
-rw-r--r-- | src/lexer.cpp | 68 | ||||
-rw-r--r-- | src/lexer.h | 14 | ||||
-rw-r--r-- | src/parser.cpp | 22 | ||||
-rw-r--r-- | src/token.cpp | 2 | ||||
-rw-r--r-- | src/token.h | 1 |
5 files changed, 95 insertions, 12 deletions
diff --git a/src/lexer.cpp b/src/lexer.cpp index 2521b40..97ceb1b 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp | |||
@@ -10,7 +10,8 @@ Lexer::Lexer( Bu::Stream &rIn ) : | |||
10 | iScale( 0 ), | 10 | iScale( 0 ), |
11 | iRadix( 10 ), | 11 | iRadix( 10 ), |
12 | numRangeTop('9'), | 12 | numRangeTop('9'), |
13 | ascRangeTop('a'-1) | 13 | ascRangeTop('a'-1), |
14 | eMode( modeNormal ) | ||
14 | { | 15 | { |
15 | } | 16 | } |
16 | 17 | ||
@@ -20,6 +21,21 @@ Lexer::~Lexer() | |||
20 | 21 | ||
21 | Token Lexer::nextToken() | 22 | Token Lexer::nextToken() |
22 | { | 23 | { |
24 | switch( eMode ) | ||
25 | { | ||
26 | case modeNormal: | ||
27 | return nextTokenNormal(); | ||
28 | |||
29 | case modeCommand: | ||
30 | return nextTokenCommand(); | ||
31 | |||
32 | default: | ||
33 | throw Bu::ExceptionBase("Invalid mode."); | ||
34 | } | ||
35 | } | ||
36 | |||
37 | Token Lexer::nextTokenNormal() | ||
38 | { | ||
23 | for(;;) | 39 | for(;;) |
24 | { | 40 | { |
25 | if( iBufPos >= sBuf.getSize() ) | 41 | if( iBufPos >= sBuf.getSize() ) |
@@ -151,6 +167,56 @@ Token Lexer::nextToken() | |||
151 | } | 167 | } |
152 | } | 168 | } |
153 | 169 | ||
170 | Token Lexer::nextTokenCommand() | ||
171 | { | ||
172 | for(;;) | ||
173 | { | ||
174 | if( iBufPos >= sBuf.getSize() ) | ||
175 | { | ||
176 | iBufPos = -1; | ||
177 | return Token( Token::tEndOfLine ); | ||
178 | } | ||
179 | |||
180 | if( iBufPos < 0 ) | ||
181 | { | ||
182 | if( rIn.isEos() ) | ||
183 | return Token( Token::tEndOfInput ); | ||
184 | |||
185 | sBuf = rIn.readLine(); | ||
186 | if( sBuf.getSize() == 0 ) | ||
187 | { | ||
188 | iBufPos = -1; | ||
189 | continue; | ||
190 | } | ||
191 | iBufPos = 0; | ||
192 | } | ||
193 | |||
194 | //Bu::println("Testing char '%1' at %2").arg( sBuf[iBufPos] ).arg( iBufPos ); | ||
195 | switch( sBuf[iBufPos] ) | ||
196 | { | ||
197 | case ' ': | ||
198 | case '\t': | ||
199 | iBufPos++; | ||
200 | break; | ||
201 | |||
202 | default: | ||
203 | { | ||
204 | Bu::String *sTmp = new Bu::String(); | ||
205 | for( ; iBufPos < sBuf.getSize() ; iBufPos++ ) | ||
206 | { | ||
207 | if( sBuf[iBufPos] == ' ' || | ||
208 | sBuf[iBufPos] == '\t' ) | ||
209 | break; | ||
210 | |||
211 | sTmp->append( sBuf[iBufPos] ); | ||
212 | } | ||
213 | return Token( Token::tString, sTmp ); | ||
214 | } | ||
215 | break; | ||
216 | } | ||
217 | } | ||
218 | } | ||
219 | |||
154 | void Lexer::setRadix( int i ) | 220 | void Lexer::setRadix( int i ) |
155 | { | 221 | { |
156 | iRadix = i; | 222 | iRadix = i; |
diff --git a/src/lexer.h b/src/lexer.h index 4e6d73d..57b2865 100644 --- a/src/lexer.h +++ b/src/lexer.h | |||
@@ -11,6 +11,15 @@ public: | |||
11 | Lexer( Bu::Stream &rIn ); | 11 | Lexer( Bu::Stream &rIn ); |
12 | virtual ~Lexer(); | 12 | virtual ~Lexer(); |
13 | 13 | ||
14 | enum Mode | ||
15 | { | ||
16 | modeNormal, | ||
17 | modeCommand, | ||
18 | }; | ||
19 | |||
20 | void setMode( Mode e ) { eMode = e; } | ||
21 | Mode getMode() const { return eMode; } | ||
22 | |||
14 | Token nextToken(); | 23 | Token nextToken(); |
15 | 24 | ||
16 | int getScale() const { return iScale; } | 25 | int getScale() const { return iScale; } |
@@ -20,6 +29,10 @@ public: | |||
20 | void setRadix( int i ); | 29 | void setRadix( int i ); |
21 | 30 | ||
22 | private: | 31 | private: |
32 | Token nextTokenNormal(); | ||
33 | Token nextTokenCommand(); | ||
34 | |||
35 | private: | ||
23 | Bu::Stream &rIn; | 36 | Bu::Stream &rIn; |
24 | Bu::String sBuf; | 37 | Bu::String sBuf; |
25 | int iBufPos; | 38 | int iBufPos; |
@@ -27,6 +40,7 @@ private: | |||
27 | int iRadix; | 40 | int iRadix; |
28 | char numRangeTop; | 41 | char numRangeTop; |
29 | char ascRangeTop; | 42 | char ascRangeTop; |
43 | Mode eMode; | ||
30 | }; | 44 | }; |
31 | 45 | ||
32 | #endif | 46 | #endif |
diff --git a/src/parser.cpp b/src/parser.cpp index 804e595..57144c2 100644 --- a/src/parser.cpp +++ b/src/parser.cpp | |||
@@ -31,9 +31,11 @@ void Parser::parse() | |||
31 | Bu::println( rOut, "%1").arg( deref( tsTerminal.peek() ) ); | 31 | Bu::println( rOut, "%1").arg( deref( tsTerminal.peek() ) ); |
32 | } | 32 | } |
33 | tsTerminal.clear(); | 33 | tsTerminal.clear(); |
34 | lex.setMode( Lexer::modeNormal ); | ||
34 | break; | 35 | break; |
35 | 36 | ||
36 | case Token::tCommand: | 37 | case Token::tCommand: |
38 | lex.setMode( Lexer::modeCommand ); | ||
37 | if( *t.sVal == "exit" || *t.sVal == "quit" ) | 39 | if( *t.sVal == "exit" || *t.sVal == "quit" ) |
38 | return; | 40 | return; |
39 | else if( *t.sVal == "scale" ) | 41 | else if( *t.sVal == "scale" ) |
@@ -44,9 +46,9 @@ void Parser::parse() | |||
44 | Bu::println( rOut, "Current scale: %1"). | 46 | Bu::println( rOut, "Current scale: %1"). |
45 | arg( lex.getScale() ); | 47 | arg( lex.getScale() ); |
46 | } | 48 | } |
47 | else if( t2.eType == Token::tNumber ) | 49 | else if( t2.eType == Token::tString ) |
48 | { | 50 | { |
49 | int32_t i = t2.nVal->toInt32(); | 51 | int32_t i = strtol( t2.sVal->getStr(), 0, 10 ); |
50 | lex.setScale( i ); | 52 | lex.setScale( i ); |
51 | if( i < 0 ) | 53 | if( i < 0 ) |
52 | { | 54 | { |
@@ -77,9 +79,9 @@ void Parser::parse() | |||
77 | Bu::println( rOut, "Current radix: %1"). | 79 | Bu::println( rOut, "Current radix: %1"). |
78 | arg( lex.getRadix() ); | 80 | arg( lex.getRadix() ); |
79 | } | 81 | } |
80 | else if( t2.eType == Token::tNumber ) | 82 | else if( t2.eType == Token::tString ) |
81 | { | 83 | { |
82 | int32_t i = t2.nVal->toInt32(); | 84 | int32_t i = strtol( t2.sVal->getStr(), 0, 10 ); |
83 | if( i < 2 || i > 36 ) | 85 | if( i < 2 || i > 36 ) |
84 | Bu::println( rOut, "ERROR: Radix must be between " | 86 | Bu::println( rOut, "ERROR: Radix must be between " |
85 | "2 and 36 inclusive"); | 87 | "2 and 36 inclusive"); |
@@ -127,13 +129,9 @@ void Parser::parse() | |||
127 | "When using a radix greater than 10 all extended digits are lowercase letters\n" | 129 | "When using a radix greater than 10 all extended digits are lowercase letters\n" |
128 | "starting with 'a'. Upper case is not currently supported.\n" | 130 | "starting with 'a'. Upper case is not currently supported.\n" |
129 | "\n" | 131 | "\n" |
130 | "All numbers are interpreted in the current radix, this means that you need to\n" | 132 | "All numeric command parameters (i.e. \\scale, \\radix) are in base 10 no\n" |
131 | "set the radix using the current radix, even though the current value is aways\n" | 133 | "matter what radix is currently set. These are also displayed in base 10\n" |
132 | "displayed in decimal. That is, to go to base 8 and back to base 10 you would:\n" | 134 | "at all times.\n" |
133 | " \\radix 8\n" | ||
134 | " Radix changed to: 8\n" | ||
135 | " \\radix 12\n" | ||
136 | " Radix changed to: 10\n" | ||
137 | "\n" | 135 | "\n" |
138 | "Changing the radix always clears all variables.\n" | 136 | "Changing the radix always clears all variables.\n" |
139 | ); | 137 | ); |
@@ -144,6 +142,7 @@ void Parser::parse() | |||
144 | Bu::println( rOut, "ERROR: Unknown command '%1'"). | 142 | Bu::println( rOut, "ERROR: Unknown command '%1'"). |
145 | arg( *t.sVal ); | 143 | arg( *t.sVal ); |
146 | } | 144 | } |
145 | lex.setMode( Lexer::modeNormal ); | ||
147 | break; | 146 | break; |
148 | 147 | ||
149 | case Token::tNumber: | 148 | case Token::tNumber: |
@@ -292,6 +291,7 @@ void Parser::unwind() | |||
292 | case Token::tNumber: | 291 | case Token::tNumber: |
293 | case Token::tVariable: | 292 | case Token::tVariable: |
294 | case Token::tCommand: | 293 | case Token::tCommand: |
294 | case Token::tString: | ||
295 | case Token::tEndOfLine: | 295 | case Token::tEndOfLine: |
296 | case Token::tEndOfInput: | 296 | case Token::tEndOfInput: |
297 | // These should never show up at all | 297 | // These should never show up at all |
diff --git a/src/token.cpp b/src/token.cpp index 5b0e6fe..a03c821 100644 --- a/src/token.cpp +++ b/src/token.cpp | |||
@@ -40,6 +40,7 @@ Token::~Token() | |||
40 | 40 | ||
41 | case tVariable: | 41 | case tVariable: |
42 | case tCommand: | 42 | case tCommand: |
43 | case tString: | ||
43 | delete sVal; | 44 | delete sVal; |
44 | break; | 45 | break; |
45 | 46 | ||
@@ -63,6 +64,7 @@ Bu::Formatter &operator<<( Bu::Formatter &f, Token::Type eType ) | |||
63 | case Token::tOpenParen: return f << "("; | 64 | case Token::tOpenParen: return f << "("; |
64 | case Token::tCloseParen: return f << ")"; | 65 | case Token::tCloseParen: return f << ")"; |
65 | case Token::tEquals: return f << "="; | 66 | case Token::tEquals: return f << "="; |
67 | case Token::tString: return f << "str"; | ||
66 | case Token::tEndOfLine: return f << "eol"; | 68 | case Token::tEndOfLine: return f << "eol"; |
67 | case Token::tEndOfInput: return f << "eoi"; | 69 | case Token::tEndOfInput: return f << "eoi"; |
68 | 70 | ||
diff --git a/src/token.h b/src/token.h index 1cc6516..92a7bcc 100644 --- a/src/token.h +++ b/src/token.h | |||
@@ -24,6 +24,7 @@ public: | |||
24 | tOpenParen, | 24 | tOpenParen, |
25 | tCloseParen, | 25 | tCloseParen, |
26 | tEquals, | 26 | tEquals, |
27 | tString, | ||
27 | 28 | ||
28 | tEndOfLine, | 29 | tEndOfLine, |
29 | 30 | ||