amath  1.8.5
Simple command line calculator
operators.cpp
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2014-2018 Carsten Sonne Larsen <cs@innolan.net>
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  * Project homepage:
26  * https://amath.innolan.net
27  *
28  */
29 
30 #include "amathc.h"
31 #include "operators.h"
32 #include "lib/numb.h"
33 #include "lib/charbuf.h"
34 
35 // -----------------------------------------------------
36 // -------------------- UnaryNode ----------------------
37 // -----------------------------------------------------
38 
40  ExpressionNode(), expression(expression)
41 {
42 }
43 
45 {
46  if (expression != nullptr)
47  {
48  delete expression;
49  }
50 }
51 
52 ReductionType UnaryNode::GetReductionType()
53 {
54  return unaryreduc;
55 }
56 
58 {
59  return 7;
60 }
61 
63 {
64  static char* ret = (char*)"-";
65  return ret;
66 }
67 
69 {
70  const char* expText = expression->GetText();
71  const char* nodeText = GetNodeText();
72 
74  output->EnsureSize(StrLen(expText) + StrLen(nodeText) + 2 + 1);
75 
77  {
78  output->Append(nodeText);
80  output->Append(expText);
82  }
83  else
84  {
85  output->Append(nodeText);
86  output->Append(expText);
87  }
88 
89  return output->GetString();
90 }
91 
93 {
95  return result;
96 }
97 
99 {
100  if (iterator == nullptr)
101  {
103  return iterator;
104  }
105 
106  return nullptr;
107 }
108 
110 {
111  if (expression == nullptr)
112  {
113  expression = static_cast<ExpressionNode*>(node);
114  node->SetParent(this);
115  }
116 }
117 
119 {
120  if (expression == node)
121  {
122  expression = nullptr;
123  }
124 }
125 
127 {
128  if (expression == n)
129  {
130  delete expression;
131  expression = static_cast<ExpressionNode*>(x);
132  }
133 }
134 
135 // -----------------------------------------------------
136 // ------------------- AbsoluteNode --------------------
137 // -----------------------------------------------------
138 
140  ExpressionNode(), expression(expression)
141 {
142 }
143 
145 {
146  if (expression != nullptr)
147  {
148  delete expression;
149  }
150 }
151 
153 {
154  const char* expText = expression->GetText();
155  const char* nodeText = GetNodeText();
156 
158  output->EnsureSize(StrLen(expText) + StrLen(nodeText) * 2 + 1);
159  output->Append(nodeText);
160  output->Append(expText);
161  output->Append(nodeText);
162 
163  return output->GetString();
164 }
165 
167 {
168  return 8;
169 }
170 
172 {
174  return result;
175 }
176 
178 {
179  static char* ret = (char*)"|";
180  return ret;
181 }
182 
184 {
185  if (iterator == nullptr)
186  {
188  return iterator;
189  }
190 
191  return nullptr;
192 }
193 
195 {
196  if (expression == nullptr)
197  {
198  expression = static_cast<ExpressionNode*>(node);
199  node->SetParent(this);
200  }
201 }
202 
204 {
205  if (expression == node)
206  {
207  expression = nullptr;
208  }
209 }
210 
212 {
213  if (expression == n)
214  {
215  delete expression;
216  expression = static_cast<ExpressionNode*>(x);
217  }
218 }
219 
220 // -----------------------------------------------------
221 // ------------------- FactorialNode -------------------
222 // -----------------------------------------------------
223 
225  ExpressionNode(), expression(expression)
226 {
227 }
228 
230 {
231  if (expression != nullptr)
232  {
233  delete expression;
234  }
235 }
236 
238 {
239  const char* expText = expression->GetText();
240  const char* nodeText = GetNodeText();
241 
243  output->EnsureSize(StrLen(expText) + StrLen(nodeText) + 1);
244  output->Append(expText);
245  output->Append(nodeText);
246 
247  return output->GetString();
248 }
249 
251 {
252  return 9;
253 }
254 
256 {
258  return result;
259 }
260 
262 {
263  static char* ret = (char*)"!";
264  return ret;
265 }
266 
268 {
269  if (iterator == nullptr)
270  {
272  return iterator;
273  }
274 
275  return nullptr;
276 }
277 
279 {
280  if (expression == nullptr)
281  {
282  expression = static_cast<ExpressionNode*>(node);
283  node->SetParent(this);
284  }
285 }
286 
288 {
289  if (expression == node)
290  {
291  expression = nullptr;
292  }
293 }
294 
296 {
297  if (expression == n)
298  {
299  delete expression;
300  expression = static_cast<ExpressionNode*>(x);
301  }
302 }
303 
304 // -----------------------------------------------------
305 // ----------------- NumericOperator -------------------
306 // -----------------------------------------------------
307 
309  ExpressionNode(), left(left), right(right)
310 {
311 }
312 
314 {
315  if (left != nullptr)
316  {
317  delete left;
318  }
319 
320  if (right != nullptr)
321  {
322  delete right;
323  }
324 }
325 
327 {
328  const char* leftText = left->GetText();
329  const char* nodeText = GetNodeText();
330  const char* rightText = right->GetText();
331 
333  output->EnsureSize(StrLen(leftText) + 2 + StrLen(nodeText) + StrLen(rightText) + 2 + 1);
334 
336  {
337  output->Append("(");
338  output->Append(leftText);
339  output->Append(")");
340  }
341  else
342  {
343  output->Append(leftText);
344  }
345 
346  output->Append(nodeText);
347 
349  {
350  output->Append("(");
351  output->Append(rightText);
352  output->Append(")");
353  }
354  else
355  {
356  output->Append(rightText);
357  }
358 
359  return output->GetString();
360 }
361 
363 {
364  if (iterator == nullptr)
365  {
366  iterator = left;
367  return left;
368  }
369 
370  if (iterator == left)
371  {
372  iterator = right;
373  return right;
374  }
375 
376  return nullptr;
377 }
378 
380 {
381  if (left == nullptr)
382  {
383  left = static_cast<ExpressionNode*>(node);
384  node->SetParent(this);
385  }
386  else if (right == nullptr)
387  {
388  right = static_cast<ExpressionNode*>(node);
389  node->SetParent(this);
390  }
391 }
392 
394 {
395  if (left == node)
396  {
397  left = nullptr;
398  }
399  else if (right == node)
400  {
401  right = nullptr;
402  }
403 }
404 
406 {
407  if (left == n)
408  {
409  if (iterator == left)
410  {
411  iterator = static_cast<ExpressionNode*>(x);
412  }
413  delete left;
414  left = static_cast<ExpressionNode*>(x);
415  }
416  else if (right == n)
417  {
418  if (iterator == right)
419  {
420  iterator = static_cast<ExpressionNode*>(x);
421  }
422  delete right;
423  right = static_cast<ExpressionNode*>(x);
424  }
425 }
426 
427 // -----------------------------------------------------
428 // ------------------- AdditionNode --------------------
429 // -----------------------------------------------------
430 
432  NumericOperator(left, right)
433 {
434 }
435 
437 {
438  return compladdreduc;
439 }
440 
442 {
443  return 2;
444 }
445 
447 {
449  return result;
450 }
451 
453 {
454  static char* ret = (char*)"+";
455  return ret;
456 }
457 
458 // -----------------------------------------------------
459 // ----------------- SubtractionNode -------------------
460 // -----------------------------------------------------
461 
463  NumericOperator(left, right)
464 {
465 }
466 
468 {
469  return complsubreduc;
470 }
471 
473 {
474  return 2;
475 }
476 
478 {
480  return result;
481 }
482 
484 {
485  static char* ret = (char*)"-";
486  return ret;
487 }
488 
489 // -----------------------------------------------------
490 // ----------------- MultiplicationNode ----------------
491 // -----------------------------------------------------
492 
494  NumericOperator(left, right)
495 {
496 }
497 
499 {
500  return 3;
501 }
502 
504 {
506  return result;
507 }
508 
510 {
511  static char* ret = (char*)"*";
512  return ret;
513 }
514 
515 // -----------------------------------------------------
516 // ------------------- DivisionNode --------------------
517 // -----------------------------------------------------
518 
520  NumericOperator(left, right)
521 {
522 }
523 
525 {
526  return 3;
527 }
528 
530 {
532  return result;
533 }
534 
536 {
537  static char* ret = (char*)"/";
538  return ret;
539 }
540 
541 // -----------------------------------------------------
542 // -------------------- PowerNode ----------------------
543 // -----------------------------------------------------
544 
546  NumericOperator(left, right)
547 {
548 }
549 
551 {
552  return 4;
553 }
554 
556 {
557  Number* exponent = right->Evaluate();
559  return result;
560 }
561 
563 {
564  static char* ret = (char*)"^";
565  return ret;
566 }
567 
568 // -----------------------------------------------------
569 // ------------------ AssignmentNode -------------------
570 // -----------------------------------------------------
571 
573  NumericOperator(variable, expression),
574  variable(variable), expression(expression)
575 {
576 }
577 
579 {
580  return 6;
581 }
582 
584 {
585  // NOTICE: Assignment does not generate a value itself.
587  return variable->Evaluate();
588 }
589 
591 {
592  return true;
593 }
594 
596 {
597  static char* ret = (char*)"=";
598  return ret;
599 }
DivisionNode(ExpressionNode *left, ExpressionNode *right)
Definition: operators.cpp:519
int GetPrecedence()
Definition: operators.cpp:441
Number * Evaluate()
Definition: operators.cpp:583
AbsoluteNode(ExpressionNode *expression)
Definition: operators.cpp:139
Number * Evaluate()
Definition: operators.cpp:255
ExpressionNode * expression
Definition: operators.h:61
virtual Number * Absolute()=0
void Detach(SyntaxNode *node)
Definition: operators.cpp:287
void Empty()
Definition: charbuf.cpp:218
char * GetNodeText()
Definition: operators.cpp:62
virtual Number * Factorial()=0
char * GetNodeText()
Definition: operators.cpp:595
void Attach(SyntaxNode *node)
Definition: operators.cpp:278
virtual Number * Mul(Number *other)=0
NumericOperator(ExpressionNode *left, ExpressionNode *right)
Definition: operators.cpp:308
char * GetString() const
Definition: charbuf.cpp:306
char * GetNodeText()
Definition: operators.cpp:452
SyntaxNode * GetNext()
Definition: operators.cpp:362
ReductionType GetReductionType()
Definition: operators.cpp:467
Base class for all nodes in a syntax tree.
Definition: nodes.h:65
ExpressionNode()
Definition: nodes.cpp:89
char * GetText()
Definition: operators.cpp:326
int GetPrecedence()
Definition: operators.cpp:166
void Detach(SyntaxNode *node)
Definition: operators.cpp:203
ExpressionNode * expression
Definition: operators.h:103
virtual Number * Raise(Number *exponent)=0
PowerNode(ExpressionNode *left, ExpressionNode *right)
Definition: operators.cpp:545
void Detach(SyntaxNode *node)
Definition: operators.cpp:118
void Replace(SyntaxNode *n, SyntaxNode *x)
Definition: operators.cpp:126
virtual char * GetNodeText()=0
MultiplicationNode(ExpressionNode *left, ExpressionNode *right)
Definition: operators.cpp:493
void Append(const char *source)
Definition: charbuf.cpp:262
char * GetNodeText()
Definition: operators.cpp:483
Definition: numb.h:66
void Replace(SyntaxNode *n, SyntaxNode *x)
Definition: operators.cpp:295
virtual Number * Unary()=0
char * GetNodeText()
Definition: operators.cpp:177
int GetPrecedence()
Definition: operators.cpp:57
void Attach(SyntaxNode *node)
Definition: operators.cpp:379
AssignmentNode(VariableNode *variable, ExpressionNode *expression)
Definition: operators.cpp:572
void Attach(SyntaxNode *node)
Definition: operators.cpp:109
void AssignValue(Number *value) const
Definition: values.cpp:309
char * GetText()
Definition: operators.cpp:237
Number * Evaluate()
Definition: operators.cpp:503
char * GetNodeText()
Definition: operators.cpp:509
SyntaxNode * GetNext()
Definition: operators.cpp:267
ExpressionNode * left
Definition: operators.h:119
AdditionNode(ExpressionNode *left, ExpressionNode *right)
Definition: operators.cpp:431
void SetParent(SyntaxNode *node)
Definition: nodes.cpp:75
UnaryNode(ExpressionNode *expression)
Definition: operators.cpp:39
char * GetNodeText()
Definition: operators.cpp:562
virtual Number * Evaluate()=0
int GetPrecedence()
Definition: operators.cpp:524
SyntaxNode * GetNext()
Definition: operators.cpp:183
ExpressionNode * right
Definition: operators.h:120
Number * Evaluate()
Definition: operators.cpp:171
Number * Evaluate()
Definition: operators.cpp:555
void Attach(SyntaxNode *node)
Definition: operators.cpp:194
ReductionType GetReductionType()
Definition: operators.cpp:436
Number * result
Definition: nodes.h:116
Number * Evaluate()
Definition: operators.cpp:529
char * GetNodeText()
Definition: operators.cpp:261
virtual Number * Sub(Number *other)=0
Number * Evaluate()
Definition: operators.cpp:477
ExpressionNode * expression
Definition: operators.h:193
int GetPrecedence()
Definition: operators.cpp:550
int GetPrecedence()
Definition: operators.cpp:250
VariableNode * variable
Definition: operators.h:192
virtual int GetPrecedence()=0
virtual Number * Add(Number *other)=0
Use of a variable in a syntax tree.
Definition: values.h:110
char * GetNodeText()
Definition: operators.cpp:535
Number * Evaluate()
Definition: values.cpp:303
int StrLen(const char *string)
Get the length of a null terminated string.
Definition: strlen.c:34
virtual char * GetText()=0
virtual Number * Div(Number *other)=0
void Detach(SyntaxNode *node)
Definition: operators.cpp:393
ReductionType GetReductionType()
Definition: operators.cpp:52
int GetPrecedence()
Definition: operators.cpp:578
void Replace(SyntaxNode *n, SyntaxNode *x)
Definition: operators.cpp:211
CharBuffer * output
Definition: nodes.h:85
void Replace(SyntaxNode *n, SyntaxNode *x)
Definition: operators.cpp:405
char * GetText()
Definition: operators.cpp:152
SubtractionNode(ExpressionNode *left, ExpressionNode *right)
Definition: operators.cpp:462
ExpressionNode * expression
Definition: operators.h:82
SyntaxNode * GetNext()
Definition: operators.cpp:98
Base class for all nodes related to mathematical expressions.
Definition: nodes.h:99
char * GetText()
Definition: operators.cpp:68
SyntaxNode * iterator
Definition: nodes.h:87
FactorialNode(ExpressionNode *expression)
Definition: operators.cpp:224
void EnsureSize(unsigned int size)
Ensure a memory block of specified size is allocated.
Definition: charbuf.cpp:114
Number * Evaluate()
Definition: operators.cpp:92
Number * Evaluate()
Definition: operators.cpp:446