summaryrefslogtreecommitdiff
path: root/src/formula.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/formula.cpp')
-rw-r--r--src/formula.cpp157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/formula.cpp b/src/formula.cpp
new file mode 100644
index 0000000..7cc1804
--- /dev/null
+++ b/src/formula.cpp
@@ -0,0 +1,157 @@
1#include "formula.h"
2
3subExceptionDef( ParseException );
4
5Formula::Formula()
6{
7}
8
9Formula::~Formula()
10{
11}
12
13double Formula::run( const char *sFormula )
14{
15 sBuf.write( sFormula, strlen( sFormula ) );
16 sBuf.setPos( 0 );
17
18 nState = 0;
19 for(;;)
20 {
21 tLook = nextToken();
22 if( tLook.nSym == symEOS )
23 break;
24 state();
25 }
26 printf("\n");
27 return 0.0;
28}
29
30void Formula::state()
31{
32 switch( nState )
33 {
34 case 0: // initial expr
35 switch( tLook.nSym )
36 {
37 case symNumber:
38 push();
39 nState = 1;
40 break;
41 }
42 break;
43
44 case 1: // binary operator
45 switch( tLook.nSym )
46 {
47 case symAdd:
48 case symSubtract:
49 push();
50 nState = 2;
51 break;
52
53 case symMultiply:
54 case symDivide:
55 push();
56 nState = 3;
57 break;
58 }
59 break;
60
61 case 2: // add/subtract
62 break;
63 }
64}
65
66void Formula::push()
67{
68 printToken( tLook );
69 sToken.push( tLook );
70}
71
72Formula::Token Formula::nextToken()
73{
74 char cbuf;
75 for(;;)
76 {
77 if( sBuf.isEOS() )
78 return Token( symEOS );
79
80 sBuf.read( &cbuf, 1 );
81 switch( cbuf )
82 {
83 case '+':
84 return Token( symAdd );
85
86 case '-':
87 return Token( symSubtract );
88
89 case '*':
90 return Token( symMultiply );
91
92 case '/':
93 return Token( symDivide );
94
95 case '(':
96 return Token( symOpenParen );
97
98 case ')':
99 return Token( symCloseParen );
100
101 case ' ':
102 case '\t':
103 case '\n':
104 case '\r':
105 break;
106
107 default:
108 if( cbuf == '.' || (cbuf >= '0' && cbuf <= '9') )
109 {
110 char num[50];
111 int nPos = 0;
112 bool bDot = false;
113
114 for(;;)
115 {
116 num[nPos++] = cbuf;
117 if( cbuf == '.' )
118 {
119 if( bDot == false )
120 bDot = true;
121 else
122 throw ParseException(
123 "Numbers cannot have more than one "
124 ". in them."
125 );
126 }
127 sBuf.read( &cbuf, 1 );
128 if( (cbuf != '.' && (cbuf < '0' || cbuf > '9')) ||
129 sBuf.isEOS() )
130 {
131 if( !sBuf.isEOS() ) sBuf.seek( -1 );
132 num[nPos] = '\0';
133 return Token( symNumber, strtod( num, NULL ) );
134 }
135 }
136 }
137 break;
138 }
139 }
140}
141
142void Formula::printToken( Token &tok )
143{
144 switch( tok.nSym )
145 {
146 case symEOS: printf("[EOS] "); break;
147 case symAdd: printf("+ "); break;
148 case symSubtract: printf("- "); break;
149 case symMultiply: printf("* "); break;
150 case symDivide: printf("/ "); break;
151 case symOpenParen: printf("( "); break;
152 case symCloseParen: printf(") "); break;
153 case symNumber: printf("%f ", tok.val.num ); break;
154 default: printf("??? "); break;
155 }
156}
157