1 #pragma once 2 3 #include <stack> 4 #include <string> 5 #include <memory> 6 7 #include <pdal/Dimension.hpp> 8 #include <pdal/PointLayout.hpp> 9 #include <pdal/PointRef.hpp> 10 #include <pdal/util/Utils.hpp> 11 12 namespace pdal 13 { 14 namespace expr 15 { 16 17 enum class NodeType 18 { 19 And, 20 Or, 21 Add, 22 Subtract, 23 Multiply, 24 Divide, 25 Not, 26 Equal, 27 NotEqual, 28 Greater, 29 GreaterEqual, 30 Less, 31 LessEqual, 32 Negative, 33 Value, 34 Identifier, 35 None 36 }; 37 38 struct Result 39 { Resultpdal::expr::Result40 Result(double d) 41 { m_dval = d; m_bval = false; } 42 Resultpdal::expr::Result43 Result(bool b) 44 { m_bval = b; m_dval = 0; } 45 46 enum class Type 47 { 48 Bool, 49 Val 50 }; 51 52 double m_dval; 53 bool m_bval; 54 Type m_type; 55 }; 56 57 class Node 58 { 59 protected: 60 Node(NodeType type); 61 62 public: 63 virtual ~Node(); 64 NodeType type() const; 65 66 virtual std::string print() const = 0; 67 virtual Utils::StatusWithReason prepare(PointLayoutPtr l) = 0; 68 virtual Result eval(PointRef& p) const = 0; 69 virtual bool isBool() const = 0; isValue() const70 virtual bool isValue() const 71 { return !isBool(); } 72 73 private: 74 NodeType m_type; 75 76 protected: 77 size_t m_pos; 78 size_t m_level; 79 }; 80 using NodePtr = std::unique_ptr<Node>; 81 82 class LogicalNode : public Node 83 { 84 public: LogicalNode(NodeType type)85 LogicalNode(NodeType type) : Node(type) 86 {} 87 isBool() const88 virtual bool isBool() const 89 { return true; } 90 }; 91 92 class ValueNode : public Node 93 { 94 public: ValueNode(NodeType type)95 ValueNode(NodeType type) : Node(type) 96 {} 97 isBool() const98 virtual bool isBool() const 99 { return false; } 100 }; 101 102 class BinMathNode : public ValueNode 103 { 104 public: 105 BinMathNode(NodeType type, NodePtr left, NodePtr right); 106 107 virtual std::string print() const; 108 virtual Utils::StatusWithReason prepare(PointLayoutPtr l); 109 virtual Result eval(PointRef& p) const; 110 111 private: 112 NodePtr m_left; 113 NodePtr m_right; 114 }; 115 116 class UnMathNode : public ValueNode 117 { 118 public: 119 UnMathNode(NodeType type, NodePtr sub); 120 121 virtual std::string print() const; 122 virtual Utils::StatusWithReason prepare(PointLayoutPtr l); 123 virtual Result eval(PointRef& p) const; 124 125 private: 126 NodePtr m_sub; 127 }; 128 129 class NotNode : public LogicalNode 130 { 131 public: 132 NotNode(NodeType type, NodePtr sub); 133 134 virtual std::string print() const; 135 virtual Utils::StatusWithReason prepare(PointLayoutPtr l); 136 virtual Result eval(PointRef& p) const; 137 138 private: 139 NodePtr m_sub; 140 }; 141 142 class BoolNode : public LogicalNode 143 { 144 public: 145 BoolNode(NodeType type, NodePtr left, NodePtr right); 146 147 virtual std::string print() const; 148 virtual Utils::StatusWithReason prepare(PointLayoutPtr l); 149 virtual Result eval(PointRef& p) const; 150 151 private: 152 NodePtr m_left; 153 NodePtr m_right; 154 }; 155 156 class CompareNode : public LogicalNode 157 { 158 public: 159 CompareNode(NodeType type, NodePtr left, NodePtr right); 160 161 virtual std::string print() const; 162 virtual Utils::StatusWithReason prepare(PointLayoutPtr l); 163 virtual Result eval(PointRef& p) const; 164 165 private: 166 NodePtr m_left; 167 NodePtr m_right; 168 }; 169 170 class ConstValueNode : public ValueNode 171 { 172 public: 173 ConstValueNode(double d); 174 175 virtual std::string print() const; 176 virtual Utils::StatusWithReason prepare(PointLayoutPtr l); 177 virtual Result eval(PointRef&) const; 178 179 double value() const; 180 181 private: 182 double m_val; 183 }; 184 185 class ConstLogicalNode : public LogicalNode 186 { 187 public: 188 ConstLogicalNode(bool b); 189 190 virtual std::string print() const; 191 virtual Utils::StatusWithReason prepare(PointLayoutPtr l); 192 virtual Result eval(PointRef&) const; 193 194 bool value() const; 195 196 private: 197 bool m_val; 198 }; 199 200 class VarNode : public ValueNode 201 { 202 public: 203 VarNode(const std::string& s); 204 205 virtual std::string print() const; 206 virtual Utils::StatusWithReason prepare(PointLayoutPtr l); 207 virtual Result eval(PointRef& p) const; 208 Dimension::Id eval() const; 209 210 private: 211 std::string m_name; 212 Dimension::Id m_id; 213 }; 214 215 class Expression 216 { 217 public: 218 Expression(); 219 virtual ~Expression(); 220 Expression(const Expression& expr); 221 Expression(Expression&& expr) noexcept; 222 Expression& operator=(Expression&& expr); 223 Expression& operator=(const Expression& expr); 224 225 void clear(); 226 bool valid() const; 227 std::string error() const; 228 NodePtr popNode(); 229 void pushNode(NodePtr node); 230 Node *topNode(); 231 const Node *topNode() const; 232 virtual std::string print() const; 233 virtual Utils::StatusWithReason prepare(PointLayoutPtr layout) = 0; 234 235 private: 236 std::string m_error; 237 std::stack<NodePtr> m_nodes; 238 239 friend std::ostream& operator<<(std::ostream& out, const Expression& expr); 240 }; 241 242 } // namespace expr 243 } // namespace pdal 244