• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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