1 // Copyright 2015 Google Inc. All rights reserved 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef VAR_H_ 16 #define VAR_H_ 17 18 #include <string> 19 #include <unordered_map> 20 #include <unordered_set> 21 22 #include "expr.h" 23 #include "stmt.h" 24 #include "string_piece.h" 25 #include "symtab.h" 26 27 using namespace std; 28 29 class Evaluator; 30 class Value; 31 32 enum struct VarOrigin { 33 UNDEFINED, 34 DEFAULT, 35 ENVIRONMENT, 36 ENVIRONMENT_OVERRIDE, 37 FILE, 38 COMMAND_LINE, 39 OVERRIDE, 40 AUTOMATIC, 41 }; 42 43 const char* GetOriginStr(VarOrigin origin); 44 45 class Var : public Evaluable { 46 public: 47 virtual ~Var(); 48 49 virtual const char* Flavor() const = 0; 50 virtual VarOrigin Origin() const = 0; IsDefined()51 virtual bool IsDefined() const { return true; } 52 53 virtual void AppendVar(Evaluator* ev, Value* v); 54 55 virtual StringPiece String() const = 0; 56 57 virtual string DebugString() const = 0; 58 ReadOnly()59 bool ReadOnly() const { return readonly_; } SetReadOnly()60 void SetReadOnly() { readonly_ = true; } 61 62 protected: 63 Var(); 64 65 private: 66 bool readonly_; 67 }; 68 69 class SimpleVar : public Var { 70 public: 71 explicit SimpleVar(VarOrigin origin); 72 SimpleVar(const string& v, VarOrigin origin); 73 Flavor()74 virtual const char* Flavor() const override { 75 return "simple"; 76 } Origin()77 virtual VarOrigin Origin() const override { 78 return origin_; 79 } 80 81 virtual void Eval(Evaluator* ev, string* s) const override; 82 83 virtual void AppendVar(Evaluator* ev, Value* v) override; 84 85 virtual StringPiece String() const override; 86 87 virtual string DebugString() const override; 88 mutable_value()89 string* mutable_value() { return &v_; } 90 91 private: 92 string v_; 93 VarOrigin origin_; 94 }; 95 96 class RecursiveVar : public Var { 97 public: 98 RecursiveVar(Value* v, VarOrigin origin, StringPiece orig); 99 Flavor()100 virtual const char* Flavor() const override { 101 return "recursive"; 102 } Origin()103 virtual VarOrigin Origin() const override { 104 return origin_; 105 } 106 107 virtual void Eval(Evaluator* ev, string* s) const override; 108 109 virtual void AppendVar(Evaluator* ev, Value* v) override; 110 111 virtual StringPiece String() const override; 112 113 virtual string DebugString() const override; 114 115 private: 116 Value* v_; 117 VarOrigin origin_; 118 StringPiece orig_; 119 }; 120 121 class UndefinedVar : public Var { 122 public: 123 UndefinedVar(); 124 Flavor()125 virtual const char* Flavor() const override { 126 return "undefined"; 127 } Origin()128 virtual VarOrigin Origin() const override { 129 return VarOrigin::UNDEFINED; 130 } IsDefined()131 virtual bool IsDefined() const override { return false; } 132 133 virtual void Eval(Evaluator* ev, string* s) const override; 134 135 virtual StringPiece String() const override; 136 137 virtual string DebugString() const override; 138 }; 139 140 extern UndefinedVar* kUndefined; 141 142 class RuleVar : public Var { 143 public: RuleVar(Var * v,AssignOp op)144 RuleVar(Var* v, AssignOp op) 145 : v_(v), op_(op) {} ~RuleVar()146 virtual ~RuleVar() { 147 delete v_; 148 } 149 Flavor()150 virtual const char* Flavor() const override { 151 return v_->Flavor(); 152 } Origin()153 virtual VarOrigin Origin() const override { 154 return v_->Origin(); 155 } IsDefined()156 virtual bool IsDefined() const override { 157 return v_->IsDefined(); 158 } Eval(Evaluator * ev,string * s)159 virtual void Eval(Evaluator* ev, string* s) const override { 160 v_->Eval(ev, s); 161 } AppendVar(Evaluator * ev,Value * v)162 virtual void AppendVar(Evaluator* ev, Value* v) override { 163 v_->AppendVar(ev, v); 164 } String()165 virtual StringPiece String() const override { 166 return v_->String(); 167 } DebugString()168 virtual string DebugString() const override { 169 return v_->DebugString(); 170 } 171 v()172 Var* v() const { return v_; } op()173 AssignOp op() const { return op_; } 174 175 private: 176 Var* v_; 177 AssignOp op_; 178 }; 179 180 class Vars : public unordered_map<Symbol, Var*> { 181 public: 182 ~Vars(); 183 184 Var* Lookup(Symbol name) const; 185 186 void Assign(Symbol name, Var* v, bool* readonly); 187 188 static void add_used_env_vars(Symbol v); 189 used_env_vars()190 static const unordered_set<Symbol>& used_env_vars() { 191 return used_env_vars_; 192 } 193 194 private: 195 static unordered_set<Symbol> used_env_vars_; 196 }; 197 198 class ScopedVar { 199 public: 200 // Does not take ownerships of arguments. 201 ScopedVar(Vars* vars, Symbol name, Var* var); 202 ~ScopedVar(); 203 204 private: 205 Vars* vars_; 206 Var* orig_; 207 Vars::iterator iter_; 208 }; 209 210 #endif // VAR_H_ 211