diff --git a/scan-build/index.html b/scan-build/index.html index 7d7e6699..61326006 100644 --- a/scan-build/index.html +++ b/scan-build/index.html @@ -58,24 +58,22 @@ function ToggleDisplay(CheckButton, ClassName) {

amath - scan-build results

- + - +
User:cs@innolan.net
User:carsten@kingster
Working Directory:/home/carsten/amath
Command Line:make
Clang Version:clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Date:Wed Jan 11 20:50:46 2017
Date:Sat Jan 28 22:08:32 2017

Bug Summary

- + - -
Bug TypeQuantityDisplay?
All Bugs19
All Bugs18
Dead store
Dead assignment3
Dead increment1
Logic error
Assigned value is garbage or undefined6
Result of operation is garbage or undefined8
Memory Error
Memory leak1

Reports

@@ -91,62 +89,59 @@ function ToggleDisplay(CheckButton, ClassName) { -Logic errorAssigned value is garbage or undefinedlib/real/kremp2.c__kernel_rem_pio234727View Report - +Logic errorAssigned value is garbage or undefinedreal/kremp2.c__kernel_rem_pio234625View Report + -Logic errorAssigned value is garbage or undefinedlib/real/kremp2.c__kernel_rem_pio234625View Report - +Logic errorAssigned value is garbage or undefinedreal/kremp2.c__kernel_rem_pio234727View Report + -Logic errorAssigned value is garbage or undefinedlib/real/kremp2.c__kernel_rem_pio227133View Report - +Logic errorAssigned value is garbage or undefinedreal/kremp2.c__kernel_rem_pio227133View Report + -Logic errorAssigned value is garbage or undefinedlib/real/kremp2.c__kernel_rem_pio235041View Report - +Logic errorAssigned value is garbage or undefinedreal/kremp2.c__kernel_rem_pio235144View Report + -Logic errorAssigned value is garbage or undefinedlib/real/kremp2.c__kernel_rem_pio235144View Report - +Logic errorAssigned value is garbage or undefinedreal/kremp2.c__kernel_rem_pio235041View Report + -Logic errorAssigned value is garbage or undefinedlib/dconv/dragon4.cppBigInt_ShiftLeft70224View Report - +Logic errorAssigned value is garbage or undefineddconv/dragon4.cppBigInt_ShiftLeft70224View Report + -Dead storeDead assignmentlib/real/expm1.cexpm11671View Report - +Dead storeDead assignmentreal/expm1.cexpm11661View Report + -Dead storeDead assignmentlib/real/expm1.cexpm11661View Report - +Dead storeDead assignmentreal/expm1.cexpm11671View Report + -Dead storeDead assignmentlib/real/pow.cpow1481View Report - +Dead storeDead assignmentreal/pow.cpow1481View Report + -Dead storeDead incrementlib/dconv/dprint.cppFormatScientific3851View Report - +Dead storeDead incrementdconv/dprint.cppFormatScientific3851View Report + -Memory ErrorMemory leakapp/main/parser.cppParse616View Report - +Logic errorResult of operation is garbage or undefinedreal/kremp2.c__kernel_rem_pio230720View Report + -Logic errorResult of operation is garbage or undefinedlib/dconv/dragon4.cppBigInt_DivideWithRemainder_MaxQuotient963138View Report - +Logic errorResult of operation is garbage or undefineddconv/dragon4.cppBigInt_DivideWithRemainder_MaxQuotient963138View Report + -Logic errorResult of operation is garbage or undefinedlib/dconv/dragon4.cppBigInt_DivideWithRemainder_MaxQuotient966039View Report - +Logic errorResult of operation is garbage or undefinedreal/remp2.crempio220215View Report + -Logic errorResult of operation is garbage or undefinedlib/real/remp2.crempio220215View Report - +Logic errorResult of operation is garbage or undefinedreal/kremp2.c__kernel_rem_pio228933View Report + -Logic errorResult of operation is garbage or undefinedlib/real/kremp2.c__kernel_rem_pio230720View Report - +Logic errorResult of operation is garbage or undefineddconv/dragon4.cppBigInt_DivideWithRemainder_MaxQuotient966039View Report + -Logic errorResult of operation is garbage or undefinedlib/dconv/dragon4.cppBigInt_Multiply1040342View Report - +Logic errorResult of operation is garbage or undefineddconv/dragon4.cppBigInt_Multiply1040342View Report + -Logic errorResult of operation is garbage or undefinedlib/real/kremp2.c__kernel_rem_pio222223View Report - +Logic errorResult of operation is garbage or undefinedreal/kremp2.c__kernel_rem_pio222223View Report + -Logic errorResult of operation is garbage or undefinedlib/real/kremp2.c__kernel_rem_pio232923View Report - - -Logic errorResult of operation is garbage or undefinedlib/real/kremp2.c__kernel_rem_pio228933View Report - +Logic errorResult of operation is garbage or undefinedreal/kremp2.c__kernel_rem_pio232923View Report + diff --git a/scan-build/report-0d2bf1.html b/scan-build/report-020199.html similarity index 99% rename from scan-build/report-0d2bf1.html rename to scan-build/report-020199.html index fb7500df..ed7dfb1d 100644 --- a/scan-build/report-0d2bf1.html +++ b/scan-build/report-020199.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/real/kremp2.c
File:real/kremp2.c
Location:line 289, column 21
Description:The left operand of '==' is a garbage value
diff --git a/scan-build/report-2088b3.html b/scan-build/report-262893.html similarity index 99% rename from scan-build/report-2088b3.html rename to scan-build/report-262893.html index 9f7da514..ab0222f8 100644 --- a/scan-build/report-2088b3.html +++ b/scan-build/report-262893.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/dconv/dragon4.cpp
File:dconv/dragon4.cpp
Location:line 631, column 51
Description:The left operand of '-' is a garbage value
diff --git a/scan-build/report-4c2709.html b/scan-build/report-273e84.html similarity index 99% rename from scan-build/report-4c2709.html rename to scan-build/report-273e84.html index 0215f3a5..1bcb9eff 100644 --- a/scan-build/report-4c2709.html +++ b/scan-build/report-273e84.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/real/expm1.c
File:real/expm1.c
Location:line 167, column 10
Description:Value stored to 'y' is never read
diff --git a/scan-build/report-a0ecbd.html b/scan-build/report-27428e.html similarity index 99% rename from scan-build/report-a0ecbd.html rename to scan-build/report-27428e.html index 7fd9786b..f2ce057a 100644 --- a/scan-build/report-a0ecbd.html +++ b/scan-build/report-27428e.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/real/kremp2.c
File:real/kremp2.c
Location:line 350, column 18
Description:Assigned value is garbage or undefined
diff --git a/scan-build/report-d01db6.html b/scan-build/report-27e74a.html similarity index 99% rename from scan-build/report-d01db6.html rename to scan-build/report-27e74a.html index ce66a602..bf4fe79b 100644 --- a/scan-build/report-d01db6.html +++ b/scan-build/report-27e74a.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/dconv/dragon4.cpp
File:dconv/dragon4.cpp
Location:line 403, column 38
Description:The left operand of '*' is a garbage value
diff --git a/scan-build/report-db6763.html b/scan-build/report-3a56cc.html similarity index 99% rename from scan-build/report-db6763.html rename to scan-build/report-3a56cc.html index bbde79bd..d6e84256 100644 --- a/scan-build/report-db6763.html +++ b/scan-build/report-3a56cc.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/real/pow.c
File:real/pow.c
Location:line 148, column 5
Description:Value stored to 'i1' is never read
diff --git a/scan-build/report-87283b.html b/scan-build/report-40d42f.html similarity index 99% rename from scan-build/report-87283b.html rename to scan-build/report-40d42f.html index 9b3d339d..af497936 100644 --- a/scan-build/report-87283b.html +++ b/scan-build/report-40d42f.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/dconv/dprint.cpp
File:dconv/dprint.cpp
Location:line 385, column 9
Description:Value stored to 'bufferSize' is never read
diff --git a/scan-build/report-e9ab87.html b/scan-build/report-4b20f3.html similarity index 99% rename from scan-build/report-e9ab87.html rename to scan-build/report-4b20f3.html index d6341404..2f89ec68 100644 --- a/scan-build/report-e9ab87.html +++ b/scan-build/report-4b20f3.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/real/kremp2.c
File:real/kremp2.c
Location:line 307, column 18
Description:The right operand of '*' is a garbage value
diff --git a/scan-build/report-7ef7cd.html b/scan-build/report-4fd7ba.html similarity index 99% rename from scan-build/report-7ef7cd.html rename to scan-build/report-4fd7ba.html index ae2ea24a..461e7c84 100644 --- a/scan-build/report-7ef7cd.html +++ b/scan-build/report-4fd7ba.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/real/kremp2.c
File:real/kremp2.c
Location:line 329, column 19
Description:The left operand of '-' is a garbage value
diff --git a/scan-build/report-9786f8.html b/scan-build/report-762445.html similarity index 99% rename from scan-build/report-9786f8.html rename to scan-build/report-762445.html index 80d6f662..a96efeee 100644 --- a/scan-build/report-9786f8.html +++ b/scan-build/report-762445.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/real/kremp2.c
File:real/kremp2.c
Location:line 222, column 24
Description:The left operand of '+' is a garbage value
diff --git a/scan-build/report-d645c4.html b/scan-build/report-831a75.html similarity index 99% rename from scan-build/report-d645c4.html rename to scan-build/report-831a75.html index 26b205e6..1049a72a 100644 --- a/scan-build/report-d645c4.html +++ b/scan-build/report-831a75.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/real/kremp2.c
File:real/kremp2.c
Location:line 346, column 18
Description:Assigned value is garbage or undefined
diff --git a/scan-build/report-1eae93.html b/scan-build/report-a2ee02.html similarity index 99% rename from scan-build/report-1eae93.html rename to scan-build/report-a2ee02.html index 0ff32a7d..1523f60b 100644 --- a/scan-build/report-1eae93.html +++ b/scan-build/report-a2ee02.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/dconv/dragon4.cpp
File:dconv/dragon4.cpp
Location:line 702, column 22
Description:Assigned value is garbage or undefined
diff --git a/scan-build/report-c9a3b1.html b/scan-build/report-b77ae8.html similarity index 99% rename from scan-build/report-c9a3b1.html rename to scan-build/report-b77ae8.html index be330968..9fc43178 100644 --- a/scan-build/report-c9a3b1.html +++ b/scan-build/report-b77ae8.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/dconv/dragon4.cpp
File:dconv/dragon4.cpp
Location:line 660, column 51
Description:The left operand of '-' is a garbage value
diff --git a/scan-build/report-d9685e.html b/scan-build/report-cc9ed8.html similarity index 99% rename from scan-build/report-d9685e.html rename to scan-build/report-cc9ed8.html index 87d5adbc..5979d5bb 100644 --- a/scan-build/report-d9685e.html +++ b/scan-build/report-cc9ed8.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/real/kremp2.c
File:real/kremp2.c
Location:line 351, column 18
Description:Assigned value is garbage or undefined
diff --git a/scan-build/report-d82713.html b/scan-build/report-d82713.html deleted file mode 100644 index ebce910e..00000000 --- a/scan-build/report-d82713.html +++ /dev/null @@ -1,750 +0,0 @@ - - - -app/main/parser.cpp - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:app/main/parser.cpp
Location:line 61, column 9
Description:Potential leak of memory pointed to by 'result'
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/*
2 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 */
26
27#include "clib.h"
28#include "lib/numb.h"
29#include "lib/real.h"
30#include "lib/cplex.h"
31#include "main/parser.h"
32#include "main/values.h"
33#include "main/operators.h"
34#include "main/functions.h"
35#include "main/statements.h"
36#include "localize/text.h"
37#include "system/program.h"
38
39Parser::Parser(const char *input)
40{
41 lexer = new Lexer(input);
42}
43
44Parser::~Parser()
45{
46 delete lexer;
47}
48
49SyntaxNode* Parser::Parse()
50{
51 lexer->Tokenize();
52 token = NOMEM0;
53
54 StatementBlockNode *block = NOMEM0;
55 SyntaxNode *result;
56 Token *current;
57
58 do {
5
Loop condition is true. Execution continues on line 59
59 result = TryParseStatement();
60
61 GetToken();
6
Potential leak of memory pointed to by 'result'
62 if (token->symbol == symdelimiter || (token->symbol == symend && block != NOMEM0)) {
63 if (block == NOMEM0) {
64 block = new StatementBlockNode();
65 }
66
67 if (result != NOMEM0) {
68 block->Add(result);
69 }
70
71 while (token->symbol == symdelimiter) {
72 GetToken();
73 }
74 } else if (token->symbol != symend) {
1
Taking true branch
75 if (result != NOMEM0) {
2
Taking true branch
76 delete result;
77 }
78
79 result = new ErrorNode(lexer->GetInput(), token->GetPos());
3
Memory is allocated
80 if (block != NOMEM0) {
4
Taking false branch
81 block->Add(result);
82 }
83
84 GetToken();
85 }
86
87 current = token;
88 PutToken();
89 } while (current->symbol != symend);
90
91 return block != NOMEM0 ? block :
92 result != NOMEM0 ? result : new EmptyStatement();;
93}
94
95SyntaxNode* Parser::TryParseStatement()
96{
97 GetToken();
98 if(token->symbol == symend || token->symbol == symdelimiter) {
99 PutToken();
100 return NOMEM0;
101 }
102 PutToken();
103
104 errorNode = NOMEM0;
105 syntaxError = -1;
106 SyntaxNode *result = ParseStatement();
107
108 if (errorNode == NOMEM0 && syntaxError != -1) {
109 errorNode = new ErrorNode(lexer->GetInput(), syntaxError);
110 }
111
112 if (errorNode != NOMEM0) {
113 delete result;
114 result = errorNode;
115 }
116
117 return result;
118}
119
120// -----------------------------------------------------
121// -------------- Recursive-descent logic --------------
122// -----------------------------------------------------
123
124SyntaxNode* Parser::ParseStatement()
125{
126 SyntaxNode* res = NOMEM0;
127
128 GetToken();
129 switch (token->symbol) {
130 case symhelp:
131 res = ParseHelpStatement();
132 break;
133 case symdelete:
134 res = ParseDeleteStatement();
135 break;
136 case symdef:
137 res = ParseFunctionDef();
138 break;
139 case symlist:
140 res = ParseListStatement();
141 break;
142 case symshow:
143 case symload:
144 case symsave:
145 case symexecute:
146 res = ParseFileStatement();
147 break;
148 case syminput:
149 case symoutput:
150 res = ParseNumeralStatement();
151 break;
152 case symprompt:
153 res = ParsePromptStatement();
154 break;
155 case symprefs:
156 res = ParsePrefsStatement();
157 break;
158 case symdigits:
159 res = ParseDigistStatement();
160 break;
161 case symdraw:
162 case symplot:
163 res = ParseDrawStatement();
164 break;
165 case symversion:
166 res = new VersionStatement();
167 break;
168 case symexit:
169 res = new ExitStatement();
170 break;
171 case symclear:
172 res = new ClearStatement();
173 break;
174 case symmem:
175 res = new MemoryStatement();
176 break;
177 case symvariable:
178 res = new ListVariablesStatement();
179 break;
180 case symfunction:
181 res = new ListFunctionsStatement();
182 break;
183 case symeval:
184 res = new EvalStatement(ParseExpression());
185 break;
186 default:
187 PutToken();
188 res = ParseDefault();
189 }
190
191 return res;
192}
193
194SyntaxNode* Parser::ParseDefault()
195{
196 Token *temp = token;
197
198 // Peek tokens
199 bool funcdef = Expect(symident);
200 funcdef = funcdef && Expect(symlparen);
201 funcdef = funcdef && Expect(symident);
202 funcdef = funcdef && Expect(symrparen);
203 funcdef = funcdef && Expect(symassign);
204
205 // Restart parsing
206 syntaxError = -1;
207 errorNode = NOMEM0;
208 token = temp;
209
210 if (funcdef) {
211 return ParseFunctionDef();
212 } else {
213 return ParseEvaluation();
214 }
215}
216
217SyntaxNode* Parser::ParseEvaluation()
218{
219 ExpressionNode *exp = ParseExpression();
220 if (exp == NOMEM0) {
221 return NOMEM0;
222 }
223
224 StatementNode *sta = new EvalStatement(exp);
225 if (exp->IsSilent()) {
226 sta = new SilentStatement(sta);
227 }
228
229 return sta;
230}
231
232ExpressionNode* Parser::ParseExpression ()
233{
234 return ParseAddSubstract();
235}
236
237ExpressionNode* Parser::ParseAddSubstract ()
238{
239 ExpressionNode* node = ParseFactor ();
240
241 GetToken();
242 while (token->symbol == symplus || token->symbol == symminus) {
243 if (token->symbol == symplus) {
244 node = new AdditionNode (node, ParseFactor ());
245 } else if (token->symbol == symminus) {
246 node = new SubtractionNode (node, ParseFactor ());
247 }
248
249 GetToken();
250 }
251
252 PutToken();
253 return node;
254}
255
256ExpressionNode* Parser::ParseFactor ()
257{
258 ExpressionNode* node = ParsePower ();
259
260 GetToken();
261 while (token->symbol == symtimes || token->symbol == symslash) {
262 if (token->symbol == symtimes) {
263 node = new MultiplicationNode (node, ParsePower ());
264 } else if (token->symbol == symslash) {
265 node = new DivisionNode (node, ParsePower ());
266 }
267
268 GetToken();
269 }
270
271 PutToken();
272 return node;
273}
274
275ExpressionNode* Parser::ParsePower()
276{
277 ExpressionNode* node = ParseUnary ();
278
279 GetToken();
280 while (token->symbol == sympower) {
281 node = new PowerNode (node, ParseUnary ());
282 GetToken ();
283 }
284
285 PutToken();
286 return node;
287}
288
289ExpressionNode* Parser::ParseUnary()
290{
291 ExpressionNode* node;
292
293 GetToken();
294 if (token->symbol == symminus) {
295 node = new UnaryNode(ParseAtomic ());
296 } else {
297 PutToken();
298 node = ParseAtomic();
299 }
300
301 return node;
302}
303
304ExpressionNode* Parser::ParseAtomic ()
305{
306 ExpressionNode* node;
307
308 GetToken();
309 if (token->symbol == symlparen) {
310 node = ParseExpression();
311 Expect(symrparen);
312 } else if (token->symbol == symabsolute) {
313 node = new AbsoluteNode(ParseExpression());
314 Expect(symabsolute);
315 } else if (token->symbol == symident) {
316 node = ParseIdent();
317 } else if (token->symbol == sympi) {
318 node = new PiNode();
319 } else if (token->symbol == syme) {
320 node = new EulersNumberNode();
321 } else if (token->symbol == symi) {
322 node = new ComplexiNode();
323 } else if (token->symbol == symins) {
324 node = new InsVariableNode();
325 } else if (token->symbol == symnumber) {
326 node = ParseNumber();
327 } else {
328 node = new NumericValueNode();
329 syntaxError = token->GetPos();
330 }
331
332 return node;
333}
334
335ExpressionNode* Parser::ParseIdent()
336{
337 ExpressionNode *node;
338 Token *identToken = token;
339
340 GetToken();
341 if (token->symbol == symlparen) {
342 ExpressionNode* parameter = ParseExpression();
343 Expect(symrparen);
344 node = Program->Functions->GetFunctionCall(identToken->GetText(), parameter);
345
346 if (node == NOMEM0) {
347 errorNode = new ErrorNode(
348 lexer->GetInput(),
349 HELPFUNNDEFProgram->Language->GetText(12),
350 identToken->GetText(),
351 identToken->GetPos());
352
353 delete parameter;
354 node = new NumericValueNode();
355 }
356 } else if (token->symbol == symassign) {
357 Variable* var = Program->Variables->CreateVariable(identToken->GetText());
358 node = new AssignmentNode(new VariableNode(var), ParseExpression());
359 } else {
360 PutToken();
361 Variable* var = Program->Variables->GetVariable(token->GetText());
362
363 if (var == NOMEM0) {
364 errorNode = new ErrorNode(
365 lexer->GetInput(),
366 HELPVARNDEFProgram->Language->GetText(11),
367 identToken->GetText(),
368 identToken->GetPos());
369
370 node = new NumericValueNode();
371 } else {
372 node = new VariableNode(var);
373 }
374 }
375
376 return node;
377}
378
379ExpressionNode* Parser::ParseNumber()
380{
381 const char *a = token->GetText();
382 Number *number = NOMEM0;
383
384 GetToken();
385 if (token->symbol == symi) {
386 Number *imag = Program->Input->Parse(a);
387 number = new ComplexNumber(0.0, imag->GetRealValue());
388 delete imag;
389 } else {
390 PutToken();
391 number = Program->Input->Parse(a);
392 }
393
394 return new NumericValueNode (number);
395}
396
397// -----------------------------------------------------
398// ------------------- Token logic ---------------------
399// -----------------------------------------------------
400
401void Parser::GetToken ()
402{
403 token = (token == NOMEM0 ? lexer->GetFirstToken() : token->GetNextToken());
404}
405
406void Parser::PutToken()
407{
408 token = token->GetLastToken();
409}
410
411bool Parser::Expect(Symbol symbol)
412{
413 GetToken();
414 if (token->symbol != symbol) {
415 syntaxError = token->GetPos();
416 return false;
417 } else {
418 return true;
419 }
420}
421
422// -----------------------------------------------------
423// ----------------- Statement logic -------------------
424// -----------------------------------------------------
425
426SyntaxNode* Parser::ParseFunctionDef()
427{
428 Expect(symident);
429 Token* funcToken = token;
430 Expect(symlparen);
431 Expect(symident);
432 Token* funcVariable = token;
433 Expect(symrparen);
434 Expect(symassign);
435
436 if (Program->Functions->IsSystemFunction(funcToken->GetText())) {
437 errorNode = new ErrorNode(
438 lexer->GetInput(),
439 HELPFUNRDEFProgram->Language->GetText(13),
440 funcToken->GetText(),
441 funcToken->GetPos());
442
443 return NOMEM0;
444 }
445
446 UserFunction* function = Program->Functions->GetFunctionDef(funcToken->GetText());
447 Variable* variable = function->CreateVariable(funcVariable->GetText());
448 Program->Variables->InsertTemporaryVariable(variable);
449 function->SetExpression(ParseExpression());
450 Program->Variables->RemoveTemporaryVariable();
451
452 // TODO: Move logic to FunctionDefinitionNode
453 return new FunctionDefinitionNode();
454}
455
456SyntaxNode* Parser::ParseHelpStatement()
457{
458 GetToken();
459
460 if (token->symbol == symdelimiter || token->symbol == symend) {
461 PutToken();
462 return new HelpStatement();
463 } else if (token->symbol == symident) {
464 return new HelpStatement(token->GetText());
465 } else {
466 return new HelpStatement(token->symbol);
467 }
468}
469
470SyntaxNode* Parser::ParseDeleteStatement()
471{
472 GetToken();
473 if (token->symbol == symvariable || token->symbol == symfunction) {
474 return new DeleteStatement(token->symbol);
475 } else if (token->symbol != symident) {
476 syntaxError = token->GetPos();
477 return NOMEM0;
478 }
479
480 Token *identToken = token;
481
482 GetToken();
483 if (token->symbol == symlparen) {
484 Expect(symident);
485 Token *parameter = token;
486 Expect(symrparen);
487 return new DeleteStatement(identToken->GetText(), parameter->GetText());
488 } else {
489 PutToken();
490 return new DeleteStatement(token->GetText());
491 }
492}
493
494SyntaxNode* Parser::ParseListStatement()
495{
496 GetToken();
497 if (token->symbol == symqident)
498 return new ListStatement(token->GetText());
499 else if (token->symbol == symend || symdelimiter) {
500 PutToken();
501 return new ListStatement();
502 } else {
503 syntaxError = token->GetPos();
504 return NOMEM0;
505 }
506}
507
508SyntaxNode* Parser::ParseFileStatement()
509{
510 Token *statement = token;
511
512 Expect(symqident);
513 Token *identToken = token;
514
515 if (statement->symbol == symload) {
516 return new LoadStatement(identToken->GetText());
517 } else if (statement->symbol == symsave) {
518 return new SaveStatement(identToken->GetText());
519 } else if (statement->symbol == symexecute) {
520 return new ExecuteStatement(identToken->GetText());
521 } else if (statement->symbol == symshow) {
522 return new ShowStatement(identToken->GetText());
523 } else {
524 return new ErrorNode(
525 lexer->GetInput(),
526 HELPUERRORProgram->Language->GetText(10), EMPTYSTRING"",
527 statement->GetPos());
528 }
529}
530
531SyntaxNode* Parser::ParseNumeralStatement()
532{
533 Token *statement = token;
534 unsigned int base;
535
536 GetToken();
537 switch (token->symbol) {
538 case symend:
539 case symdelimiter:
540 PutToken();
541 return (statement->symbol == syminput) ?
542 (SyntaxNode*)new InputStatement() :
543 (SyntaxNode*)new OutputStatement();
544 case symbin:
545 base = 2;
546 break;
547 case symoct:
548 base = 8;
549 break;
550 case symdec:
551 base = 10;
552 break;
553 case symhex:
554 base = 16;
555 break;
556 default:
557 base = 0;
558 }
559
560 if (base == 0 && token->symbol != symnumber) {
561 syntaxError = token->GetPos();
562 return NOMEM0;
563 }
564
565 if (base == 0) {
566 NumeralSystem *nsys = new DecimalSystem(0);
567 Number *number = nsys->Parse(token->GetText());
568 base = number->GetIntegerValue();
569 delete number;
570 delete nsys;
571
572 if (base < 2 || base > 32) {
573 errorNode = new ErrorNode(
574 lexer->GetInput(),
575 HELPPNUMERAProgram->Language->GetText(14),
576 token->GetText(),
577 token->GetPos());
578
579 return NOMEM0;
580 }
581 }
582
583 return (statement->symbol == syminput) ?
584 (SyntaxNode*)new InputStatement(base) :
585 (SyntaxNode*)new OutputStatement(base);
586}
587
588SyntaxNode* Parser::ParseDigistStatement()
589{
590 GetToken();
591 if (token->symbol == symdelimiter || token->symbol == symend) {
592 PutToken();
593 return new DigitsStatement();
594 } else if (token->symbol != symnumber) {
595 syntaxError = token->GetPos();
596 return NOMEM0;
597 }
598
599 NumeralSystem *nsys = new DecimalSystem(0);
600 Number *number = nsys->Parse(token->GetText());
601 int digits = number->GetIntegerValue();
602 delete number;
603 delete nsys;
604
605 if (digits < 0 || digits > 15) {
606 errorNode = new ErrorNode(
607 lexer->GetInput(),
608 HELPPDIGITSProgram->Language->GetText(15),
609 token->GetText(),
610 token->GetPos());
611
612 return NOMEM0;
613 }
614
615 return new DigitsStatement(digits);
616}
617
618SyntaxNode* Parser::ParsePromptStatement()
619{
620 GetToken();
621 if (token->symbol == symqident) {
622 return new PromptStatement(token->GetText());
623 }
624
625 PutToken();
626 return NOMEM0;
627}
628
629SyntaxNode* Parser::ParsePrefsStatement()
630{
631 GetToken();
632 if (token->symbol == symload || token->symbol == symsave) {
633 return new PrefsStatement(token->symbol);
634 }
635
636 PutToken();
637 return new PrefsStatement();;
638}
639
640SyntaxNode* Parser::ParseDrawStatement()
641{
642 Token *statement = token;
643
644 Expect(symident);
645 Token *identToken = token;
646 Expect(symlparen);
647 Expect(symident);
648 Token *paramToken = token;
649 Expect(symrparen);
650
651 if (statement->symbol == symplot) {
652 return new PlotStatement(identToken->GetText(), paramToken->GetText());
653 } else {
654 return new DrawStatement(identToken->GetText(), paramToken->GetText());
655 }
656}
diff --git a/scan-build/report-0fbb45.html b/scan-build/report-e79f68.html similarity index 99% rename from scan-build/report-0fbb45.html rename to scan-build/report-e79f68.html index 34d24685..c38344c0 100644 --- a/scan-build/report-0fbb45.html +++ b/scan-build/report-e79f68.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/real/expm1.c
File:real/expm1.c
Location:line 166, column 16
Description:Value stored to 'y' is never read
diff --git a/scan-build/report-d27033.html b/scan-build/report-e85ac2.html similarity index 99% rename from scan-build/report-d27033.html rename to scan-build/report-e85ac2.html index 1ac7f522..ebaab250 100644 --- a/scan-build/report-d27033.html +++ b/scan-build/report-e85ac2.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/real/remp2.c
File:real/remp2.c
Location:line 202, column 19
Description:The left operand of '==' is a garbage value
diff --git a/scan-build/report-e39bf1.html b/scan-build/report-f61e62.html similarity index 99% rename from scan-build/report-e39bf1.html rename to scan-build/report-f61e62.html index 008ecac6..9a304e77 100644 --- a/scan-build/report-e39bf1.html +++ b/scan-build/report-f61e62.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/real/kremp2.c
File:real/kremp2.c
Location:line 347, column 18
Description:Assigned value is garbage or undefined
diff --git a/scan-build/report-75dc7f.html b/scan-build/report-fcf014.html similarity index 99% rename from scan-build/report-75dc7f.html rename to scan-build/report-fcf014.html index 23dd37d2..262651a9 100644 --- a/scan-build/report-75dc7f.html +++ b/scan-build/report-fcf014.html @@ -78,7 +78,7 @@

Bug Summary

- +
File:lib/real/kremp2.c
File:real/kremp2.c
Location:line 271, column 36
Description:Assigned value is garbage or undefined