summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lexer.cpp68
-rw-r--r--src/lexer.h14
-rw-r--r--src/parser.cpp22
-rw-r--r--src/token.cpp2
-rw-r--r--src/token.h1
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
21Token Lexer::nextToken() 22Token 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
37Token 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
170Token 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
154void Lexer::setRadix( int i ) 220void 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
22private: 31private:
32 Token nextTokenNormal();
33 Token nextTokenCommand();
34
35private:
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