1 #pragma once 2 3 #include <string> 4 #include <vector> 5 #include "value.h" 6 #include "memory.h" 7 #include "boost-utils.h" 8 #include "Assignment.h" 9 10 class Expression : public ASTNode 11 { 12 public: Expression(const Location & loc)13 Expression(const Location &loc) : ASTNode(loc) {} ~Expression()14 ~Expression() {} 15 virtual bool isLiteral() const; 16 virtual Value evaluate(const std::shared_ptr<Context>& context) const = 0; 17 Value checkUndef(Value&& val, const std::shared_ptr<Context>& context) const; 18 }; 19 20 class UnaryOp : public Expression 21 { 22 public: 23 enum class Op { 24 Not, 25 Negate 26 }; 27 bool isLiteral() const override; 28 UnaryOp(Op op, Expression *expr, const Location &loc); 29 Value evaluate(const std::shared_ptr<Context>& context) const override; 30 void print(std::ostream &stream, const std::string &indent) const override; 31 32 private: 33 const char *opString() const; 34 35 Op op; 36 shared_ptr<Expression> expr; 37 }; 38 39 class BinaryOp : public Expression 40 { 41 public: 42 enum class Op { 43 LogicalAnd, 44 LogicalOr, 45 Exponent, 46 Multiply, 47 Divide, 48 Modulo, 49 Plus, 50 Minus, 51 Less, 52 LessEqual, 53 Greater, 54 GreaterEqual, 55 Equal, 56 NotEqual 57 }; 58 59 BinaryOp(Expression *left, Op op, Expression *right, const Location &loc); 60 Value evaluate(const std::shared_ptr<Context>& context) const override; 61 void print(std::ostream &stream, const std::string &indent) const override; 62 63 private: 64 const char *opString() const; 65 66 Op op; 67 shared_ptr<Expression> left; 68 shared_ptr<Expression> right; 69 }; 70 71 class TernaryOp : public Expression 72 { 73 public: 74 TernaryOp(Expression *cond, Expression *ifexpr, Expression *elseexpr, const Location &loc); 75 const shared_ptr<Expression>& evaluateStep(const std::shared_ptr<Context>& context) const; 76 Value evaluate(const std::shared_ptr<Context>& context) const override; 77 void print(std::ostream &stream, const std::string &indent) const override; 78 private: 79 shared_ptr<Expression> cond; 80 shared_ptr<Expression> ifexpr; 81 shared_ptr<Expression> elseexpr; 82 }; 83 84 class ArrayLookup : public Expression 85 { 86 public: 87 ArrayLookup(Expression *array, Expression *index, const Location &loc); 88 Value evaluate(const std::shared_ptr<Context>& context) const override; 89 void print(std::ostream &stream, const std::string &indent) const override; 90 private: 91 shared_ptr<Expression> array; 92 shared_ptr<Expression> index; 93 }; 94 95 class Literal : public Expression 96 { 97 public: 98 Literal(Value val, const Location &loc = Location::NONE); 99 Value evaluate(const std::shared_ptr<Context>& context) const override; 100 void print(std::ostream &stream, const std::string &indent) const override; isLiteral()101 bool isLiteral() const override { return true;} 102 private: 103 const Value value; 104 }; 105 106 class Range : public Expression 107 { 108 public: 109 Range(Expression *begin, Expression *end, const Location &loc); 110 Range(Expression *begin, Expression *step, Expression *end, const Location &loc); 111 Value evaluate(const std::shared_ptr<Context>& context) const override; 112 void print(std::ostream &stream, const std::string &indent) const override; 113 bool isLiteral() const override; 114 private: 115 shared_ptr<Expression> begin; 116 shared_ptr<Expression> step; 117 shared_ptr<Expression> end; 118 }; 119 120 class Vector : public Expression 121 { 122 public: 123 Vector(const Location &loc); 124 Value evaluate(const std::shared_ptr<Context>& context) const override; 125 void print(std::ostream &stream, const std::string &indent) const override; 126 void emplace_back(Expression *expr); 127 bool isLiteral() const override; 128 private: 129 std::vector<shared_ptr<Expression>> children; 130 mutable boost::tribool literal_flag; // cache if already computed 131 }; 132 133 class Lookup : public Expression 134 { 135 public: 136 Lookup(const std::string &name, const Location &loc); 137 Value evaluate(const std::shared_ptr<Context>& context) const override; 138 const Value& evaluateSilently(const std::shared_ptr<Context>& context) const; 139 void print(std::ostream &stream, const std::string &indent) const override; get_name()140 const std::string& get_name() const { return name; } 141 private: 142 std::string name; 143 }; 144 145 class MemberLookup : public Expression 146 { 147 public: 148 MemberLookup(Expression *expr, const std::string &member, const Location &loc); 149 Value evaluate(const std::shared_ptr<Context>& context) const override; 150 void print(std::ostream &stream, const std::string &indent) const override; 151 private: 152 shared_ptr<Expression> expr; 153 std::string member; 154 }; 155 156 class FunctionCall : public Expression 157 { 158 public: 159 FunctionCall(Expression *expr, const AssignmentList &arglist, const Location &loc); 160 void prepareTailCallContext(const std::shared_ptr<Context> context, std::shared_ptr<Context> tailCallContext, const AssignmentList &definition_arguments); 161 Value evaluate(const std::shared_ptr<Context>& context) const override; 162 void print(std::ostream &stream, const std::string &indent) const override; get_name()163 const std::string& get_name() const { return name; } 164 static Expression * create(const std::string &funcname, const AssignmentList &arglist, Expression *expr, const Location &loc); 165 shared_ptr<class FunctionDefinition> getFunctionDefinition(const Value& v) const; 166 public: 167 bool isLookup; 168 std::string name; 169 shared_ptr<Expression> expr; 170 AssignmentList arguments; 171 AssignmentMap resolvedArguments; 172 std::vector<std::pair<std::string, Value>> defaultArguments; // Only the ones not mentioned in 'resolvedArguments' 173 }; 174 175 class FunctionDefinition : public Expression 176 { 177 public: 178 FunctionDefinition(Expression *expr, const AssignmentList &definition_arguments, const Location &loc); 179 Value evaluate(const std::shared_ptr<Context>& context) const override; 180 void print(std::ostream &stream, const std::string &indent) const override; 181 public: 182 shared_ptr<Context> ctx; 183 AssignmentList definition_arguments; 184 shared_ptr<Expression> expr; 185 }; 186 187 class Assert : public Expression 188 { 189 public: 190 Assert(const AssignmentList &args, Expression *expr, const Location &loc); 191 const shared_ptr<Expression>& evaluateStep(const std::shared_ptr<Context>& context) const; 192 Value evaluate(const std::shared_ptr<Context>& context) const override; 193 void print(std::ostream &stream, const std::string &indent) const override; 194 private: 195 AssignmentList arguments; 196 shared_ptr<Expression> expr; 197 }; 198 199 class Echo : public Expression 200 { 201 public: 202 Echo(const AssignmentList &args, Expression *expr, const Location &loc); 203 const shared_ptr<Expression>& evaluateStep(const std::shared_ptr<Context>& context) const; 204 Value evaluate(const std::shared_ptr<Context>& context) const override; 205 void print(std::ostream &stream, const std::string &indent) const override; 206 private: 207 AssignmentList arguments; 208 shared_ptr<Expression> expr; 209 }; 210 211 class Let : public Expression 212 { 213 public: 214 Let(const AssignmentList &args, Expression *expr, const Location &loc); 215 const shared_ptr<Expression>& evaluateStep(const std::shared_ptr<Context>& context) const; 216 Value evaluate(const std::shared_ptr<Context>& context) const override; 217 void print(std::ostream &stream, const std::string &indent) const override; 218 private: 219 AssignmentList arguments; 220 shared_ptr<Expression> expr; 221 }; 222 223 class ListComprehension : public Expression 224 { 225 public: 226 ListComprehension(const Location &loc); 227 ~ListComprehension() = default; 228 }; 229 230 class LcIf : public ListComprehension 231 { 232 public: 233 LcIf(Expression *cond, Expression *ifexpr, Expression *elseexpr, const Location &loc); 234 Value evaluate(const std::shared_ptr<Context>& context) const override; 235 void print(std::ostream &stream, const std::string &indent) const override; 236 private: 237 shared_ptr<Expression> cond; 238 shared_ptr<Expression> ifexpr; 239 shared_ptr<Expression> elseexpr; 240 }; 241 242 class LcFor : public ListComprehension 243 { 244 public: 245 LcFor(const AssignmentList &args, Expression *expr, const Location &loc); 246 Value evaluate(const std::shared_ptr<Context>& context) const override; 247 void print(std::ostream &stream, const std::string &indent) const override; 248 private: 249 AssignmentList arguments; 250 shared_ptr<Expression> expr; 251 }; 252 253 class LcForC : public ListComprehension 254 { 255 public: 256 LcForC(const AssignmentList &args, const AssignmentList &incrargs, Expression *cond, Expression *expr, const Location &loc); 257 Value evaluate(const std::shared_ptr<Context>& context) const override; 258 void print(std::ostream &stream, const std::string &indent) const override; 259 private: 260 AssignmentList arguments; 261 AssignmentList incr_arguments; 262 shared_ptr<Expression> cond; 263 shared_ptr<Expression> expr; 264 }; 265 266 class LcEach : public ListComprehension 267 { 268 public: 269 LcEach(Expression *expr, const Location &loc); 270 Value evaluate(const std::shared_ptr<Context>& context) const override; 271 void print(std::ostream &stream, const std::string &indent) const override; 272 private: 273 Value evalRecur(Value &&v, const std::shared_ptr<Context>& context) const; 274 shared_ptr<Expression> expr; 275 }; 276 277 class LcLet : public ListComprehension 278 { 279 public: 280 LcLet(const AssignmentList &args, Expression *expr, const Location &loc); 281 Value evaluate(const std::shared_ptr<Context>& context) const override; 282 void print(std::ostream &stream, const std::string &indent) const override; 283 private: 284 AssignmentList arguments; 285 shared_ptr<Expression> expr; 286 }; 287 288 void evaluate_assert(const std::shared_ptr<Context>& context, const std::shared_ptr<class EvalContext> evalctx); 289 290 Value evaluate_function(const std::string& name, 291 const std::shared_ptr<Expression>& expr, const AssignmentList& definition_arguments, 292 const std::shared_ptr<Context>& ctx, const std::shared_ptr<EvalContext>& evalctx, 293 const Location& loc); 294