Home | History | Annotate | Download | only in kati
      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;
     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 
     68   virtual const char* Flavor() const override {
     69     return "simple";
     70   }
     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 
     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 
     94   virtual const char* Flavor() const override {
     95     return "recursive";
     96   }
     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 
    119   virtual const char* Flavor() const override {
    120     return "undefined";
    121   }
    122   virtual VarOrigin Origin() const override {
    123     return VarOrigin::UNDEFINED;
    124   }
    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:
    138   RuleVar(Var* v, AssignOp op)
    139       : v_(v), op_(op) {}
    140   virtual ~RuleVar() {
    141     delete v_;
    142   }
    143 
    144   virtual const char* Flavor() const override {
    145     return v_->Flavor();
    146   }
    147   virtual VarOrigin Origin() const override {
    148     return v_->Origin();
    149   }
    150   virtual bool IsDefined() const override {
    151     return v_->IsDefined();
    152   }
    153   virtual void Eval(Evaluator* ev, string* s) const override {
    154     v_->Eval(ev, s);
    155   }
    156   virtual void AppendVar(Evaluator* ev, Value* v) override {
    157     v_->AppendVar(ev, v);
    158   }
    159   virtual StringPiece String() const override {
    160     return v_->String();
    161   }
    162   virtual string DebugString() const override {
    163     return v_->DebugString();
    164   }
    165 
    166   Var* v() const { return v_; }
    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 
    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