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