blob: e2eddc7efc75e8af480200be4251c1a48062824c [file] [log] [blame]
Shinichiro Hamaji1d545aa2015-06-23 15:29:13 +09001// 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
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090015#ifndef VAR_H_
16#define VAR_H_
17
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090018#include <string>
19#include <unordered_map>
Shinichiro Hamaji5163e042015-07-14 03:51:44 +090020#include <unordered_set>
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090021
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +090022#include "ast.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090023#include "string_piece.h"
Shinichiro Hamajie7992752015-06-29 18:38:35 +090024#include "symtab.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090025#include "value.h"
26
27using namespace std;
28
29class Evaluator;
30class Value;
31
Shinichiro Hamajif62e9a72015-06-26 04:18:21 +090032enum 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
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090045class Var : public Evaluable {
46 public:
47 virtual ~Var();
48
49 virtual const char* Flavor() const = 0;
Shinichiro Hamajif62e9a72015-06-26 04:18:21 +090050 virtual VarOrigin Origin() const = 0;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090051 virtual bool IsDefined() const { return true; }
52
Shinichiro Hamaji4c469b32015-06-15 19:53:36 +090053 virtual void AppendVar(Evaluator* ev, Value* v);
54
Shinichiro Hamaji81699be2015-06-22 18:07:38 +090055 virtual StringPiece String() const = 0;
56
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090057 virtual string DebugString() const = 0;
58
59 protected:
60 Var();
61};
62
63class SimpleVar : public Var {
64 public:
Shinichiro Hamaji5081c712015-08-14 16:49:20 +090065 SimpleVar(const string& v, VarOrigin origin);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090066
67 virtual const char* Flavor() const {
68 return "simple";
69 }
Shinichiro Hamajif62e9a72015-06-26 04:18:21 +090070 virtual VarOrigin Origin() const {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090071 return origin_;
72 }
73
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090074 virtual void Eval(Evaluator* ev, string* s) const override;
75
Shinichiro Hamaji4c469b32015-06-15 19:53:36 +090076 virtual void AppendVar(Evaluator* ev, Value* v);
77
Shinichiro Hamaji81699be2015-06-22 18:07:38 +090078 virtual StringPiece String() const override;
79
Shinichiro Hamajicf0cd682015-06-18 16:18:13 +090080 virtual string DebugString() const override;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090081
82 private:
Shinichiro Hamaji5081c712015-08-14 16:49:20 +090083 string v_;
Shinichiro Hamajif62e9a72015-06-26 04:18:21 +090084 VarOrigin origin_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090085};
86
87class RecursiveVar : public Var {
88 public:
Shinichiro Hamajif62e9a72015-06-26 04:18:21 +090089 RecursiveVar(Value* v, VarOrigin origin, StringPiece orig);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090090
91 virtual const char* Flavor() const {
92 return "recursive";
93 }
Shinichiro Hamajif62e9a72015-06-26 04:18:21 +090094 virtual VarOrigin Origin() const {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090095 return origin_;
96 }
97
98 virtual void Eval(Evaluator* ev, string* s) const override;
99
Shinichiro Hamaji4c469b32015-06-15 19:53:36 +0900100 virtual void AppendVar(Evaluator* ev, Value* v);
101
Shinichiro Hamaji81699be2015-06-22 18:07:38 +0900102 virtual StringPiece String() const override;
103
Shinichiro Hamajicf0cd682015-06-18 16:18:13 +0900104 virtual string DebugString() const override;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900105
106 private:
107 Value* v_;
Shinichiro Hamajif62e9a72015-06-26 04:18:21 +0900108 VarOrigin origin_;
Shinichiro Hamaji81699be2015-06-22 18:07:38 +0900109 StringPiece orig_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900110};
111
112class UndefinedVar : public Var {
113 public:
114 UndefinedVar();
115
116 virtual const char* Flavor() const {
117 return "undefined";
118 }
Shinichiro Hamajif62e9a72015-06-26 04:18:21 +0900119 virtual VarOrigin Origin() const {
120 return VarOrigin::UNDEFINED;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900121 }
122 virtual bool IsDefined() const { return false; }
123
124 virtual void Eval(Evaluator* ev, string* s) const override;
125
Shinichiro Hamaji81699be2015-06-22 18:07:38 +0900126 virtual StringPiece String() const override;
127
Shinichiro Hamajicf0cd682015-06-18 16:18:13 +0900128 virtual string DebugString() const override;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900129};
130
131extern UndefinedVar* kUndefined;
132
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900133class RuleVar : public Var {
134 public:
135 RuleVar(Var* v, AssignOp op)
136 : v_(v), op_(op) {}
137 virtual ~RuleVar() {
138 delete v_;
139 }
140
141 virtual const char* Flavor() const {
142 return v_->Flavor();
143 }
Shinichiro Hamajif62e9a72015-06-26 04:18:21 +0900144 virtual VarOrigin Origin() const {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900145 return v_->Origin();
146 }
147 virtual bool IsDefined() const {
148 return v_->IsDefined();
149 }
150 virtual void Eval(Evaluator* ev, string* s) const {
151 v_->Eval(ev, s);
152 }
153 virtual void AppendVar(Evaluator* ev, Value* v) {
154 v_->AppendVar(ev, v);
155 }
156 virtual StringPiece String() const override {
157 return v_->String();
158 }
159 virtual string DebugString() const override {
160 return v_->DebugString();
161 }
162
163 Var* v() const { return v_; }
164 AssignOp op() const { return op_; }
165
166 private:
167 Var* v_;
168 AssignOp op_;
169};
170
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900171class Vars : public unordered_map<Symbol, Var*> {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900172 public:
173 ~Vars();
174
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900175 Var* Lookup(Symbol name) const;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900176
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900177 void Assign(Symbol name, Var* v);
Shinichiro Hamaji5163e042015-07-14 03:51:44 +0900178
179 static const unordered_set<Symbol>& used_env_vars() {
180 return used_env_vars_;
181 }
182
183 private:
184 static unordered_set<Symbol> used_env_vars_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900185};
186
Shinichiro Hamajicf0cd682015-06-18 16:18:13 +0900187class ScopedVar {
188 public:
189 // Does not take ownerships of arguments.
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900190 ScopedVar(Vars* vars, Symbol name, Var* var);
Shinichiro Hamajicf0cd682015-06-18 16:18:13 +0900191 ~ScopedVar();
192
193 private:
194 Vars* vars_;
195 Var* orig_;
196 Vars::iterator iter_;
197};
198
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900199#endif // VAR_H_