AbaKus – a complex calculator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

220 lines
5.4 KiB

  1. #ifndef ABAKUS_NODE_H
  2. #define ABAKUS_NODE_H
  3. /*
  4. * node.h - part of abakus
  5. * Copyright (C) 2004, 2005 Michael Pyne <michael.pyne@kdemail.net>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include <tqstring.h>
  22. #include "numerictypes.h"
  23. class Node;
  24. class Function;
  25. template <class T> class SharedPtr;
  26. typedef SharedPtr<Node> NodePtr;
  27. /**
  28. * A class that operates on a Node. Called recursively on a node and all
  29. * of its children.
  30. */
  31. class NodeFunctor
  32. {
  33. public:
  34. virtual void operator()(const Node *node) = 0;
  35. virtual ~NodeFunctor() { }
  36. };
  37. class Node
  38. {
  39. public:
  40. virtual ~Node() { }
  41. virtual Abakus::number_t value() const = 0;
  42. // Deletes a node only if it isn't a function, since those are
  43. // typically read-only.
  44. virtual void deleteNode(Node *node);
  45. // Calls functor() on all subchildren and this.
  46. virtual void applyMap(NodeFunctor &fn) const = 0;
  47. // Returns an infix representation of the expression.
  48. virtual TQString infixString() const = 0;
  49. // Returns the derivative of the node.
  50. virtual Abakus::number_t derivative() const = 0;
  51. };
  52. class BaseFunction : public Node
  53. {
  54. public:
  55. BaseFunction(const char *name);
  56. virtual TQString name() const { return m_name; }
  57. virtual const Function *function() const;
  58. private:
  59. TQString m_name;
  60. const Function *m_function;
  61. };
  62. class UnaryFunction : public BaseFunction
  63. {
  64. public:
  65. UnaryFunction(const char *name, Node *operand);
  66. virtual ~UnaryFunction();
  67. virtual Node *operand() const { return m_node; }
  68. virtual void setOperand(Node *operand);
  69. virtual void applyMap(NodeFunctor &fn) const;
  70. virtual TQString infixString() const;
  71. private:
  72. Node *m_node;
  73. };
  74. // Calculates the approximate derivative of its operand.
  75. class DerivativeFunction : public Node
  76. {
  77. public:
  78. DerivativeFunction(Node *operand, Node *where) :
  79. m_operand(operand), m_where(where) { }
  80. ~DerivativeFunction();
  81. virtual Abakus::number_t value() const;
  82. virtual void applyMap(NodeFunctor &fn) const;
  83. // Returns an infix representation of the expression.
  84. virtual TQString infixString() const;
  85. virtual Abakus::number_t derivative() const;
  86. private:
  87. Node *m_operand;
  88. Node *m_where;
  89. };
  90. class UserDefinedFunction : public UnaryFunction
  91. {
  92. public:
  93. UserDefinedFunction(const char *name, Node *operand) : UnaryFunction(name, operand) { };
  94. virtual Abakus::number_t value() const { return operand()->value(); }
  95. virtual Abakus::number_t derivative() const { return operand()->derivative(); }
  96. };
  97. class BuiltinFunction : public UnaryFunction
  98. {
  99. public:
  100. BuiltinFunction(const char *name, Node *operand);
  101. virtual Abakus::number_t value() const;
  102. virtual Abakus::number_t derivative() const;
  103. };
  104. class UnaryOperator : public Node
  105. {
  106. public:
  107. typedef enum { Negation } Type;
  108. UnaryOperator(Type type, Node *operand);
  109. virtual ~UnaryOperator();
  110. virtual void applyMap(NodeFunctor &fn) const;
  111. virtual TQString infixString() const;
  112. virtual Abakus::number_t value() const;
  113. virtual Abakus::number_t derivative() const;
  114. virtual Type type() const { return m_type; }
  115. virtual Node *operand() const { return m_node; }
  116. private:
  117. Type m_type;
  118. Node *m_node;
  119. };
  120. class BinaryOperator : public Node
  121. {
  122. public:
  123. typedef enum { Addition, Subtraction, Multiplication, Division, Exponentiation } Type;
  124. BinaryOperator(Type type, Node *left, Node *right);
  125. virtual ~BinaryOperator();
  126. virtual void applyMap(NodeFunctor &fn) const;
  127. virtual TQString infixString() const;
  128. virtual Abakus::number_t value() const;
  129. virtual Abakus::number_t derivative() const;
  130. virtual Type type() const { return m_type; }
  131. virtual Node *leftNode() const { return m_left; }
  132. virtual Node *rightNode() const { return m_right; }
  133. private:
  134. bool isSimpleNode(Node *node) const;
  135. Type m_type;
  136. Node *m_left, *m_right;
  137. };
  138. class Identifier : public Node
  139. {
  140. public:
  141. Identifier(const char *name);
  142. virtual void applyMap(NodeFunctor &fn) const;
  143. virtual TQString infixString() const { return name(); }
  144. virtual Abakus::number_t value() const;
  145. virtual Abakus::number_t derivative() const
  146. {
  147. if(name() == "x")
  148. return "1";
  149. else
  150. return "0";
  151. }
  152. virtual TQString name() const { return m_name; }
  153. private:
  154. TQString m_name;
  155. };
  156. class NumericValue : public Node
  157. {
  158. public:
  159. NumericValue(const Abakus::number_t value) : m_value(value) { }
  160. virtual void applyMap(NodeFunctor &fn) const { fn(this); }
  161. virtual TQString infixString() const;
  162. virtual Abakus::number_t value() const { return m_value; }
  163. virtual Abakus::number_t derivative() const { return "0"; }
  164. private:
  165. Abakus::number_t m_value;
  166. };
  167. #endif
  168. // vim: set et sw=4 ts=8: