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 
59  protected:
60   Var();
61 };
62 
63 class SimpleVar : public Var {
64  public:
65   explicit SimpleVar(VarOrigin origin);
66   SimpleVar(const string& v, VarOrigin origin);
67 
Flavor()68   virtual const char* Flavor() const override {
69     return "simple";
70   }
Origin()71   virtual VarOrigin Origin() const override {
72     return origin_;
73   }
74 
75   virtual void Eval(Evaluator* ev, string* s) const override;
76 
77   virtual void AppendVar(Evaluator* ev, Value* v) override;
78 
79   virtual StringPiece String() const override;
80 
81   virtual string DebugString() const override;
82 
mutable_value()83   string* mutable_value() { return &v_; }
84 
85  private:
86   string v_;
87   VarOrigin origin_;
88 };
89 
90 class RecursiveVar : public Var {
91  public:
92   RecursiveVar(Value* v, VarOrigin origin, StringPiece orig);
93 
Flavor()94   virtual const char* Flavor() const override {
95     return "recursive";
96   }
Origin()97   virtual VarOrigin Origin() const override {
98     return origin_;
99   }
100 
101   virtual void Eval(Evaluator* ev, string* s) const override;
102 
103   virtual void AppendVar(Evaluator* ev, Value* v) override;
104 
105   virtual StringPiece String() const override;
106 
107   virtual string DebugString() const override;
108 
109  private:
110   Value* v_;
111   VarOrigin origin_;
112   StringPiece orig_;
113 };
114 
115 class UndefinedVar : public Var {
116  public:
117   UndefinedVar();
118 
Flavor()119   virtual const char* Flavor() const override {
120     return "undefined";
121   }
Origin()122   virtual VarOrigin Origin() const override {
123     return VarOrigin::UNDEFINED;
124   }
IsDefined()125   virtual bool IsDefined() const override { return false; }
126 
127   virtual void Eval(Evaluator* ev, string* s) const override;
128 
129   virtual StringPiece String() const override;
130 
131   virtual string DebugString() const override;
132 };
133 
134 extern UndefinedVar* kUndefined;
135 
136 class RuleVar : public Var {
137  public:
RuleVar(Var * v,AssignOp op)138   RuleVar(Var* v, AssignOp op)
139       : v_(v), op_(op) {}
~RuleVar()140   virtual ~RuleVar() {
141     delete v_;
142   }
143 
Flavor()144   virtual const char* Flavor() const override {
145     return v_->Flavor();
146   }
Origin()147   virtual VarOrigin Origin() const override {
148     return v_->Origin();
149   }
IsDefined()150   virtual bool IsDefined() const override {
151     return v_->IsDefined();
152   }
Eval(Evaluator * ev,string * s)153   virtual void Eval(Evaluator* ev, string* s) const override {
154     v_->Eval(ev, s);
155   }
AppendVar(Evaluator * ev,Value * v)156   virtual void AppendVar(Evaluator* ev, Value* v) override {
157     v_->AppendVar(ev, v);
158   }
String()159   virtual StringPiece String() const override {
160     return v_->String();
161   }
DebugString()162   virtual string DebugString() const override {
163     return v_->DebugString();
164   }
165 
v()166   Var* v() const { return v_; }
op()167   AssignOp op() const { return op_; }
168 
169  private:
170   Var* v_;
171   AssignOp op_;
172 };
173 
174 class Vars : public unordered_map<Symbol, Var*> {
175  public:
176   ~Vars();
177 
178   Var* Lookup(Symbol name) const;
179 
180   void Assign(Symbol name, Var* v);
181 
182   static void add_used_env_vars(Symbol v);
183 
used_env_vars()184   static const unordered_set<Symbol>& used_env_vars() {
185     return used_env_vars_;
186   }
187 
188  private:
189   static unordered_set<Symbol> used_env_vars_;
190 };
191 
192 class ScopedVar {
193  public:
194   // Does not take ownerships of arguments.
195   ScopedVar(Vars* vars, Symbol name, Var* var);
196   ~ScopedVar();
197 
198  private:
199   Vars* vars_;
200   Var* orig_;
201   Vars::iterator iter_;
202 };
203 
204 #endif  // VAR_H_
205