amath  1.8.5
Simple command line calculator
values.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 "mathr.h"
31 #include "amath.h"
32 #include "amathc.h"
33 #include "nodes.h"
34 #include "values.h"
35 #include "lib/numb.h"
36 #include "lib/real.h"
37 #include "lib/cplex.h"
38 #include "lib/charbuf.h"
39 #include "loc/text.h"
40 #include "system/program.h"
41 
42 // -----------------------------------------------------
43 // --------------------- Variable ----------------------
44 // -----------------------------------------------------
45 
46 Variable::Variable(const char* name)
47 {
48  AllocAndCopy(&this->name, name);
49  value = nullptr;
50  Next = nullptr;
51  chainDelete = true;
52 }
53 
55 {
56  delete [] name;
57 
58  if (value != nullptr)
59  {
60  delete value;
61  }
62 
63  if (chainDelete && Next != nullptr)
64  {
65  delete Next;
66  }
67 }
68 
69 char* Variable::GetName() const
70 {
71  return name;
72 }
73 
75 {
76  return value->Clone();;
77 }
78 
80 {
81  if (this->value != nullptr)
82  {
83  delete this->value;
84  }
85 
86  this->value = value->Clone();
87 }
88 
89 // -----------------------------------------------------
90 // ------------------- VariableList --------------------
91 // -----------------------------------------------------
92 
94 {
95  first = nullptr;
96  buf = new CharBuffer();
97 }
98 
100 {
101  if (first != nullptr)
102  {
103  delete first;
104  }
105 
106  delete buf;
107 }
108 
110 {
111  if (first != nullptr)
112  {
113  delete first;
114  first = nullptr;
115  }
116 
118 }
119 
120 bool VariableList::Delete(const char* name)
121 {
122  Variable* var = GetVariable(name);
123 
124  if (var == nullptr)
125  {
126  return false;
127  }
128 
129  if (var == first)
130  {
131  first = var->Next;
132  var->chainDelete = false;
133  delete var;
134  return true;
135  }
136 
137  Variable* current = first->Next;
138  Variable* last = first;
139 
140  while (current != var)
141  {
142  current = current->Next;
143  last = last->Next;
144  }
145 
146  last->Next = var->Next;
147 
148  // Only delete this variable. Not the whole chain.
149  var->chainDelete = false;
150  delete var;
151 
152  return true;
153 }
154 
156 {
157  return first;
158 }
159 
160 Variable* VariableList::GetVariable(const char* name) const
161 {
162  Variable* current = first;
163 
164  while (current != nullptr && !StrIsEqual(current->GetName(), name))
165  {
166  current = current->Next;
167  }
168 
169  return current;
170 }
171 
173 {
174  if (first == nullptr)
175  {
176  first = new Variable(name);
177  return first;
178  }
179 
180  Variable* current = first;
181  Variable* last = nullptr;
182 
183  while (current != nullptr)
184  {
185  if (StrIsEqual(name, current->GetName()))
186  {
187  return current;
188  }
189 
190  last = current;
191  current = current->Next;
192  }
193 
194  current = new Variable(name);
195  last->Next = current;
196 
197  return current;
198 }
199 
201 {
202  // Temporary variables are always inserted at the beginning of the list.
203  Variable* oldFirst = first;
204  first = variable;
205  variable->Next = oldFirst;
206 
207  return variable;
208 }
209 
211 {
212  // Temporary variables are not owned by the variable list. Do not free memory.
213  Variable* newFirst = first->Next;
214  first->Next = nullptr;
215  first = newFirst;
216 }
217 
218 char* VariableList::List() const
219 {
220  return ListContent(false);
221 }
222 
224 {
225  return ListContent(true);
226 }
227 
228 char* VariableList::ListContent(bool cmdFormat) const
229 {
230  buf->Empty();
231 
232  if (GetFirstVariable() == nullptr)
233  {
234  return static_cast<char*>(cmdFormat ? nullptr : HELPVARSNDEF);
235  }
236 
237  int len = 0;
238  Variable* current = GetFirstVariable();
239 
240  while (current != nullptr)
241  {
242  len += StrLen(current->GetName());
243  len += 3;
244  len += 32; // Max length of value
245  len += cmdFormat ? 2 : 1;
246  current = current->Next;
247  }
248 
249  current = GetFirstVariable();
250 
252 
253  while (current != nullptr)
254  {
256  buf->Append(" = ");
257 
258  Number* num = current->GetValue();
259  const char* val = Program->Output->GetText(num);
260  buf->Append(val);
261  delete num;
262 
263  if (cmdFormat)
264  {
265  buf->Append(';');
266  }
267 
269  current = current->Next;
270  }
271 
272  return buf->GetString();
273 }
274 
275 // -----------------------------------------------------
276 // -------------- ListVariablesStatement ---------------
277 // -----------------------------------------------------
278 
281 {
282 }
283 
285 {
286  return Program->Variables->List();
287 }
288 
289 // -----------------------------------------------------
290 // ------------------- VariableNode --------------------
291 // -----------------------------------------------------
292 
294  ExpressionNode(), variable(variable)
295 {
296 }
297 
299 {
300  return 0;
301 }
302 
304 {
306  return result;
307 }
308 
309 void VariableNode::AssignValue(Number* value) const
310 {
312 }
313 
315 {
316  return variable->GetName();
317 }
318 
320 {
321  return variable->GetName();
322 }
323 
325 {
326  return nullptr;
327 }
328 
330 {
331 }
332 
334 {
335 }
336 
338 {
339 }
340 
341 // -----------------------------------------------------
342 // ----------------- InsVariableNode -------------------
343 // -----------------------------------------------------
344 
346  VariableNode(nullptr)
347 {
348 }
349 
351 {
352  return Program->GetLastResult();
353 }
354 
356 {
357  static char* ret = (char*)"ins";
358  return ret;
359 }
360 
362 {
363  static char* ret = (char*)"ins";
364  return ret;
365 }
366 
367 // -----------------------------------------------------
368 // ----------------- NumericValueNode ------------------
369 // -----------------------------------------------------
370 
373 {
374 }
375 
377  ExpressionNode(value)
378 {
379 }
380 
382 {
383  return valuereduc;
384 }
385 
387 {
388  return !leftBottom ?
391 }
392 
394 {
395  return result;
396 }
397 
399 {
400  return GetNodeText();
401 }
402 
404 {
405  const char* val = Program->Input->GetText(result);
407  return output->GetString();
408 }
409 
411 {
412  return nullptr;
413 }
414 
416 {
417 }
418 
420 {
421 }
422 
424 {
425 }
426 
428 {
429  delete result;
430  result = value;
431 }
432 
433 // -----------------------------------------------------
434 // ----------------- EulersNumberNode ------------------
435 // -----------------------------------------------------
436 
439 {
440 }
441 
443 {
444  return nonereduc;
445 }
446 
448 {
449  static char* ret = (char*)"e";
450  return ret;
451 }
452 
453 // -----------------------------------------------------
454 // ---------------------- PiNode -----------------------
455 // -----------------------------------------------------
456 
459 {
460 }
461 
462 ReductionType PiNode::GetReductionType()
463 {
464  return nonereduc;
465 }
466 
468 {
469  static char* ret = (char*)"pi";
470  return ret;
471 }
472 
473 // -----------------------------------------------------
474 // ------------------- ComplexiNode --------------------
475 // -----------------------------------------------------
476 
479 {
480 }
481 
483 {
484  return nonereduc;
485 }
486 
488 {
489  static char* ret = (char*)"i";
490  return ret;
491 }
PiNode()
Definition: values.cpp:457
void Append(const char c)
Definition: charbuf.cpp:245
virtual int GetPrecedence()=0
Use of the square root of -2 in a syntax tree.
Definition: values.h:202
void Attach(SyntaxNode *node)
Definition: values.cpp:415
#define NEWLINE
Definition: amath.h:222
virtual ReductionType GetReductionType()
Definition: values.cpp:381
#define EULERS
Definition: mathr.h:50
bool chainDelete
Definition: values.h:91
void Empty()
Definition: charbuf.cpp:218
ReductionType GetReductionType()
Definition: values.cpp:482
CharBuffer * buf
Definition: values.h:68
Number * GetValue() const
Definition: values.cpp:74
char * GetString() const
Definition: charbuf.cpp:306
A user defined variable.
Definition: values.h:76
void Detach(SyntaxNode *node)
Definition: values.cpp:333
~Variable()
Definition: values.cpp:54
Base class for all statements in a syntax tree.
Definition: node.h:40
char * GetText()
Definition: values.cpp:398
Variable * variable
Definition: values.h:127
Base class for all nodes in a syntax tree.
Definition: nodes.h:65
NumericValueNode(Number *value)
Definition: values.cpp:376
ExpressionNode()
Definition: nodes.cpp:89
char * GetNodeText()
Definition: values.cpp:319
void Replace(SyntaxNode *n, SyntaxNode *x)
Definition: values.cpp:337
Variable(const char *name)
Definition: values.cpp:46
void AssignValue(Number *value)
Definition: values.cpp:79
void ClearBuffer()
Release memory in buffer.
Definition: charbuf.cpp:65
Use of PI in a syntax tree.
Definition: values.h:188
Variable * InsertTemporaryVariable(Variable *variable)
Definition: values.cpp:200
char * GetText()
Definition: values.cpp:314
void Append(const char *source)
Definition: charbuf.cpp:262
bool leftBottom
Definition: nodes.h:88
Definition: numb.h:66
Variable * GetVariable(const char *name) const
Definition: values.cpp:160
virtual Number * Clone()=0
A list of user defined variables.
Definition: values.h:49
virtual const char * GetText(Number *number)=0
char * ListDefinitions() const
Definition: values.cpp:223
CharBuffer()
Initialize without allocating memory.
Definition: charbuf.cpp:38
bool StrIsEqual(const char *s1, const char *s2)
Compare two null terminated strings to each other.
Definition: strcmp.c:50
ExpressionNode(Number *value)
Definition: nodes.cpp:95
void AssignValue(Number *value) const
Definition: values.cpp:309
Number * value
Definition: values.h:90
void Detach(SyntaxNode *node)
Definition: values.cpp:419
VariableNode(Variable *variable)
Definition: values.cpp:293
char * GetName() const
Definition: values.cpp:69
ReductionType GetReductionType()
Definition: values.cpp:442
char * GetNodeText()
Definition: values.cpp:467
Variable * CreateVariable(const char *name)
Definition: values.cpp:172
char * GetNodeText()
Definition: values.cpp:403
char * GetNodeText()
Definition: values.cpp:447
void Clear()
Definition: values.cpp:109
Represent a real number with 15 significant digits.
Definition: real.h:45
Variable * GetFirstVariable() const
Definition: values.cpp:155
int GetPrecedence()
Definition: values.cpp:386
char * GetNodeText()
Definition: values.cpp:361
RealNumber()
Definition: real.cpp:37
void Attach(SyntaxNode *node)
Definition: values.cpp:329
#define PI
Definition: mathr.h:49
#define HELPVARSNDEF
Definition: text.h:91
void ReplaceWith(Number *value)
Definition: values.cpp:427
Number * Evaluate()
Definition: values.cpp:393
Statement to list all user defined variables.
Definition: values.h:99
StatementNode()
Definition: node.cpp:34
Represent a complex number with 2 components of 15 significant digits.
Definition: cplex.h:46
SyntaxNode * GetNext()
Definition: values.cpp:410
Number * result
Definition: nodes.h:116
int GetPrecedence()
Definition: values.cpp:298
class VariableList * Variables
Definition: program.h:77
Use of a variable in a syntax tree.
Definition: values.h:110
Use of a numeric value in a syntax tree.
Definition: values.h:150
char * name
Definition: values.h:89
Number * Evaluate()
Definition: values.cpp:303
int StrLen(const char *string)
Get the length of a null terminated string.
Definition: strlen.c:34
Number * Evaluate()
Definition: values.cpp:350
RealNumber(double x)
Definition: real.cpp:42
ComplexNumber(double real, double imag)
Definition: cplex.cpp:46
SyntaxNode * GetNext()
Definition: values.cpp:324
struct Number * GetLastResult() const
Definition: program.cpp:122
~VariableList()
Definition: values.cpp:99
virtual int GetDefaultPrecedence()=0
void RemoveTemporaryVariable()
Definition: values.cpp:210
Variable * first
Definition: values.h:69
char * List() const
Definition: values.cpp:218
CharBuffer * output
Definition: nodes.h:85
char * GetText()
Definition: values.cpp:355
void ClearAndCopy(const char *source)
Release memory, allocate and copy source.
Definition: charbuf.cpp:81
void Replace(SyntaxNode *n, SyntaxNode *x)
Definition: values.cpp:423
char * GetNodeText()
Definition: values.cpp:487
Base class for all nodes related to mathematical expressions.
Definition: nodes.h:99
unsigned int AllocAndCopy(char **destination, const char *source)
Allocate memory and copy a string into the array.
Definition: alloccpy.c:40
char * ListContent(bool cmdFormat) const
Definition: values.cpp:228
class NumeralSystem * Input
Definition: program.h:75
Encapsulate an character array which can be used as a string.
Definition: charbuf.h:44
void EnsureSize(unsigned int size)
Ensure a memory block of specified size is allocated.
Definition: charbuf.cpp:114
ReductionType GetReductionType()
Definition: values.cpp:462
friend bool VariableList::Delete(const char *name)
VariableList()
Definition: values.cpp:93
Variable * Next
Definition: values.h:86
Use of Euler&#39;s number in a syntax tree.
Definition: values.h:174
class NumeralSystem * Output
Definition: program.h:76
Use of last result in a syntax tree.
Definition: values.h:135