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 27using namespace std; 28 29class Evaluator; 30class Value; 31 32enum struct VarOrigin { 33 UNDEFINED, 34 DEFAULT, 35 ENVIRONMENT, 36 ENVIRONMENT_OVERRIDE, 37 FILE, 38 COMMAND_LINE, 39 OVERRIDE, 40 AUTOMATIC, 41}; 42 43const char* GetOriginStr(VarOrigin origin); 44 45class Var : public Evaluable { 46 public: 47 virtual ~Var(); 48 49 virtual const char* Flavor() const = 0; 50 virtual VarOrigin Origin() const = 0; 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 59 bool ReadOnly() const { return readonly_; } 60 void SetReadOnly() { readonly_ = true; } 61 62 protected: 63 Var(); 64 65 private: 66 bool readonly_; 67}; 68 69class SimpleVar : public Var { 70 public: 71 explicit SimpleVar(VarOrigin origin); 72 SimpleVar(const string& v, VarOrigin origin); 73 74 virtual const char* Flavor() const override { 75 return "simple"; 76 } 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 89 string* mutable_value() { return &v_; } 90 91 private: 92 string v_; 93 VarOrigin origin_; 94}; 95 96class RecursiveVar : public Var { 97 public: 98 RecursiveVar(Value* v, VarOrigin origin, StringPiece orig); 99 100 virtual const char* Flavor() const override { 101 return "recursive"; 102 } 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 121class UndefinedVar : public Var { 122 public: 123 UndefinedVar(); 124 125 virtual const char* Flavor() const override { 126 return "undefined"; 127 } 128 virtual VarOrigin Origin() const override { 129 return VarOrigin::UNDEFINED; 130 } 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 140extern UndefinedVar* kUndefined; 141 142class RuleVar : public Var { 143 public: 144 RuleVar(Var* v, AssignOp op) 145 : v_(v), op_(op) {} 146 virtual ~RuleVar() { 147 delete v_; 148 } 149 150 virtual const char* Flavor() const override { 151 return v_->Flavor(); 152 } 153 virtual VarOrigin Origin() const override { 154 return v_->Origin(); 155 } 156 virtual bool IsDefined() const override { 157 return v_->IsDefined(); 158 } 159 virtual void Eval(Evaluator* ev, string* s) const override { 160 v_->Eval(ev, s); 161 } 162 virtual void AppendVar(Evaluator* ev, Value* v) override { 163 v_->AppendVar(ev, v); 164 } 165 virtual StringPiece String() const override { 166 return v_->String(); 167 } 168 virtual string DebugString() const override { 169 return v_->DebugString(); 170 } 171 172 Var* v() const { return v_; } 173 AssignOp op() const { return op_; } 174 175 private: 176 Var* v_; 177 AssignOp op_; 178}; 179 180class 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 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 198class 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