diff options
author | Mike Buland <mike@xagasoft.com> | 2013-04-22 13:05:22 -0600 |
---|---|---|
committer | Mike Buland <mike@xagasoft.com> | 2013-04-22 13:05:22 -0600 |
commit | 2909f50d008920568f0e50da760b266388ccc124 (patch) | |
tree | 6789c162a2b950c2006c944e9d21e6ed9bda7069 /src/lexer.cpp | |
parent | d7ccd9c4d8e5a5bb4f12b36b3e4ad3105c5a9317 (diff) | |
download | clic-2909f50d008920568f0e50da760b266388ccc124.tar.gz clic-2909f50d008920568f0e50da760b266388ccc124.tar.bz2 clic-2909f50d008920568f0e50da760b266388ccc124.tar.xz clic-2909f50d008920568f0e50da760b266388ccc124.zip |
There is now a parser & calculator interface.
Diffstat (limited to 'src/lexer.cpp')
-rw-r--r-- | src/lexer.cpp | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/src/lexer.cpp b/src/lexer.cpp new file mode 100644 index 0000000..834d3bc --- /dev/null +++ b/src/lexer.cpp | |||
@@ -0,0 +1,163 @@ | |||
1 | #include "lexer.h" | ||
2 | #include "token.h" | ||
3 | #include "number.h" | ||
4 | |||
5 | #include <bu/sio.h> | ||
6 | |||
7 | Lexer::Lexer( Bu::Stream &rIn ) : | ||
8 | rIn( rIn ), | ||
9 | iBufPos( 0 ), | ||
10 | iScale( 0 ), | ||
11 | iRadix( 10 ), | ||
12 | numRangeTop('9'), | ||
13 | ascRangeTop(0) | ||
14 | { | ||
15 | } | ||
16 | |||
17 | Lexer::~Lexer() | ||
18 | { | ||
19 | } | ||
20 | |||
21 | Token Lexer::nextToken() | ||
22 | { | ||
23 | for(;;) | ||
24 | { | ||
25 | if( iBufPos >= sBuf.getSize() ) | ||
26 | { | ||
27 | iBufPos = -1; | ||
28 | return Token( Token::tEndOfLine ); | ||
29 | } | ||
30 | |||
31 | if( iBufPos < 0 ) | ||
32 | { | ||
33 | if( rIn.isEos() ) | ||
34 | return Token( Token::tEndOfInput ); | ||
35 | |||
36 | sBuf = rIn.readLine(); | ||
37 | if( sBuf.getSize() == 0 ) | ||
38 | { | ||
39 | iBufPos = -1; | ||
40 | continue; | ||
41 | } | ||
42 | iBufPos = 0; | ||
43 | } | ||
44 | |||
45 | //Bu::println("Testing char '%1' at %2").arg( sBuf[iBufPos] ).arg( iBufPos ); | ||
46 | switch( sBuf[iBufPos] ) | ||
47 | { | ||
48 | case ' ': | ||
49 | case '\t': | ||
50 | iBufPos++; | ||
51 | break; | ||
52 | |||
53 | case '\\': | ||
54 | { | ||
55 | Bu::String *sTmp = new Bu::String(); | ||
56 | for( iBufPos++; iBufPos < sBuf.getSize() && | ||
57 | sBuf[iBufPos] != ' ' && sBuf[iBufPos] != '\t'; | ||
58 | iBufPos++ ) | ||
59 | { | ||
60 | sTmp->append( sBuf[iBufPos] ); | ||
61 | } | ||
62 | return Token( Token::tCommand, sTmp ); | ||
63 | } | ||
64 | break; | ||
65 | |||
66 | case '+': | ||
67 | iBufPos++; | ||
68 | return Token( Token::tPlus ); | ||
69 | |||
70 | case '-': | ||
71 | iBufPos++; | ||
72 | return Token( Token::tMinus ); | ||
73 | |||
74 | case '*': | ||
75 | iBufPos++; | ||
76 | return Token( Token::tMultiply ); | ||
77 | |||
78 | case '/': | ||
79 | iBufPos++; | ||
80 | return Token( Token::tDivide ); | ||
81 | |||
82 | case '(': | ||
83 | iBufPos++; | ||
84 | return Token( Token::tOpenParen ); | ||
85 | |||
86 | case ')': | ||
87 | iBufPos++; | ||
88 | return Token( Token::tCloseParen ); | ||
89 | |||
90 | default: | ||
91 | { | ||
92 | Bu::String *sTmp = new Bu::String(); | ||
93 | if( (sBuf[iBufPos] >= '0' && | ||
94 | sBuf[iBufPos] <= numRangeTop) || | ||
95 | (sBuf[iBufPos] >= 'a' && | ||
96 | sBuf[iBufPos] <= ascRangeTop) || | ||
97 | sBuf[iBufPos] == '.' ) | ||
98 | { | ||
99 | for( ; iBufPos < sBuf.getSize() ; iBufPos++ ) | ||
100 | { | ||
101 | if( (sBuf[iBufPos] >= '0' && | ||
102 | sBuf[iBufPos] <= numRangeTop) || | ||
103 | (sBuf[iBufPos] >= 'a' && | ||
104 | sBuf[iBufPos] <= ascRangeTop) || | ||
105 | sBuf[iBufPos] == '.' ) | ||
106 | { | ||
107 | sTmp->append( sBuf[iBufPos] ); | ||
108 | } | ||
109 | else | ||
110 | { | ||
111 | break; | ||
112 | } | ||
113 | } | ||
114 | Number *n = new Number( *sTmp, iScale, iRadix ); | ||
115 | delete sTmp; | ||
116 | return Token( Token::tNumber, n ); | ||
117 | } | ||
118 | else if( (sBuf[iBufPos]>=(ascRangeTop+1) && sBuf[iBufPos]<='z') || | ||
119 | (sBuf[iBufPos]>='A' && sBuf[iBufPos]<='Z') || | ||
120 | sBuf[iBufPos] == '_' ) | ||
121 | { | ||
122 | for( ; iBufPos < sBuf.getSize(); iBufPos++ ) | ||
123 | { | ||
124 | if( (sBuf[iBufPos]>='a' && sBuf[iBufPos]<='z') || | ||
125 | (sBuf[iBufPos]>='A' && sBuf[iBufPos]<='Z') || | ||
126 | (sBuf[iBufPos]>='0' && sBuf[iBufPos]<='9') || | ||
127 | sBuf[iBufPos] == '_' ) | ||
128 | { | ||
129 | sTmp->append( sBuf[iBufPos] ); | ||
130 | } | ||
131 | else | ||
132 | { | ||
133 | break; | ||
134 | } | ||
135 | } | ||
136 | return Token( Token::tString, sTmp ); | ||
137 | } | ||
138 | else | ||
139 | { | ||
140 | sBuf.clear(); | ||
141 | Bu::println("Invalid character discovered!"); | ||
142 | } | ||
143 | } | ||
144 | break; | ||
145 | } | ||
146 | } | ||
147 | } | ||
148 | |||
149 | void Lexer::setRadix( int i ) | ||
150 | { | ||
151 | iRadix = i; | ||
152 | if( iRadix <= 10 ) | ||
153 | { | ||
154 | numRangeTop = '0'+iRadix-1; | ||
155 | ascRangeTop = 0; | ||
156 | } | ||
157 | else | ||
158 | { | ||
159 | numRangeTop = '9'; | ||
160 | ascRangeTop = 'a'+iRadix-11; | ||
161 | } | ||
162 | } | ||
163 | |||