Directives.hh 7.03 KB
Newer Older
Houtan Bastani's avatar
Houtan Bastani committed
1
/*
2
 * Copyright (C) 2019-2020 Dynare Team
Houtan Bastani's avatar
Houtan Bastani committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * This file is part of Dynare.
 *
 * Dynare is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Dynare is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _DIRECTIVES_HH
#define _DIRECTIVES_HH

#include "Expressions.hh"

25 26
#include <filesystem>

Houtan Bastani's avatar
Houtan Bastani committed
27 28 29 30 31 32
namespace macro
{
  class Directive : public Node
  {
    // A Parent class just for clarity
  public:
33 34
    Directive(Environment &env_arg, Tokenizer::location location_arg) :
      Node(env_arg, move(location_arg)) { }
Houtan Bastani's avatar
Houtan Bastani committed
35
    // Directives can be interpreted
36
    virtual void interpret(ostream &output, vector<filesystem::path> &paths) = 0;
Houtan Bastani's avatar
Houtan Bastani committed
37 38
  };

39

Houtan Bastani's avatar
Houtan Bastani committed
40 41 42 43 44 45 46 47
  class TextNode : public Directive
  {
    // Class for text not interpreted by macroprocessor
    // Not a real directive node
    // Treated as such as the output is only to be interpreted
  private:
    const string text;
  public:
48
    TextNode(string text_arg, Environment &env_arg, Tokenizer::location location_arg) :
49
      Directive(env_arg, move(location_arg)), text{move(text_arg)} { }
50
    inline void interpret(ostream &output, vector<filesystem::path> &paths) override { output << text; }
Houtan Bastani's avatar
Houtan Bastani committed
51 52
  };

53

Houtan Bastani's avatar
Houtan Bastani committed
54 55 56 57 58 59 60 61
  class Eval : public Directive
  {
    // Class for @{} statements
    // Not a real directive node
    // Treated as such as the output is only to be interpreted
  private:
    const ExpressionPtr expr;
  public:
62
    Eval(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) :
63
      Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
64
    void interpret(ostream &output, vector<filesystem::path> &paths) override;
Houtan Bastani's avatar
Houtan Bastani committed
65 66
  };

67

Houtan Bastani's avatar
Houtan Bastani committed
68 69 70 71 72
  class Include : public Directive
  {
  private:
    const ExpressionPtr expr;
  public:
73
    Include(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) :
74
      Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
75
    void interpret(ostream &output, vector<filesystem::path> &paths) override;
Houtan Bastani's avatar
Houtan Bastani committed
76 77
  };

78

Houtan Bastani's avatar
Houtan Bastani committed
79 80 81 82 83
  class IncludePath : public Directive
  {
  private:
    const ExpressionPtr expr;
  public:
84
    IncludePath(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) :
85
      Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
86
    void interpret(ostream &output, vector<filesystem::path> &paths) override;
Houtan Bastani's avatar
Houtan Bastani committed
87 88
  };

89

Houtan Bastani's avatar
Houtan Bastani committed
90 91 92 93 94 95 96
  class Define : public Directive
  {
  private:
    const VariablePtr var;
    const FunctionPtr func;
    const ExpressionPtr value;
  public:
97 98 99
    Define(VariablePtr var_arg,
           ExpressionPtr value_arg,
           Environment &env_arg, Tokenizer::location location_arg) :
100
      Directive(env_arg, move(location_arg)), var{move(var_arg)}, value{move(value_arg)} { }
101 102 103
    Define(FunctionPtr func_arg,
           ExpressionPtr value_arg,
           Environment &env_arg, Tokenizer::location location_arg) :
104
      Directive(env_arg, move(location_arg)), func{move(func_arg)}, value{move(value_arg)} { }
105
    void interpret(ostream &output, vector<filesystem::path> &paths) override;
Houtan Bastani's avatar
Houtan Bastani committed
106 107
  };

108

Houtan Bastani's avatar
Houtan Bastani committed
109 110 111 112 113
  class Echo : public Directive
  {
  private:
    const ExpressionPtr expr;
  public:
114 115
    Echo(ExpressionPtr expr_arg,
         Environment &env_arg, Tokenizer::location location_arg) :
116
      Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
117
    void interpret(ostream &output, vector<filesystem::path> &paths) override;
Houtan Bastani's avatar
Houtan Bastani committed
118 119
  };

120

Houtan Bastani's avatar
Houtan Bastani committed
121 122 123 124 125
  class Error : public Directive
  {
  private:
    const ExpressionPtr expr;
  public:
126 127
    Error(ExpressionPtr expr_arg,
          Environment &env_arg, Tokenizer::location location_arg) :
128
      Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
129
    void interpret(ostream &output, vector<filesystem::path> &paths) override;
Houtan Bastani's avatar
Houtan Bastani committed
130 131
  };

132

Houtan Bastani's avatar
Houtan Bastani committed
133 134
  class EchoMacroVars : public Directive
  {
135
  private:
136
    const bool save;
137
    const vector<string> vars;
Houtan Bastani's avatar
Houtan Bastani committed
138
  public:
139
    EchoMacroVars(bool save_arg,
140
                  Environment &env_arg, Tokenizer::location location_arg) :
141
      Directive(env_arg, move(location_arg)), save{save_arg} { }
142 143
    EchoMacroVars(bool save_arg, vector<string> vars_arg,
                  Environment &env_arg, Tokenizer::location location_arg) :
144
      Directive(env_arg, move(location_arg)), save{save_arg}, vars{move(vars_arg)} { }
145
    void interpret(ostream &output, vector<filesystem::path> &paths) override;
Houtan Bastani's avatar
Houtan Bastani committed
146 147
  };

148

Houtan Bastani's avatar
Houtan Bastani committed
149 150 151 152 153
  class For : public Directive
  {
  private:
    const vector<VariablePtr> index_vec;
    const ExpressionPtr index_vals;
154
    const vector<DirectivePtr> statements;
Houtan Bastani's avatar
Houtan Bastani committed
155
  public:
156 157 158 159
    For(vector<VariablePtr> index_vec_arg,
        ExpressionPtr index_vals_arg,
        vector<DirectivePtr> statements_arg,
        Environment &env_arg, Tokenizer::location location_arg) :
Houtan Bastani's avatar
Houtan Bastani committed
160
      Directive(env_arg, move(location_arg)), index_vec{move(index_vec_arg)},
161
      index_vals{move(index_vals_arg)}, statements{move(statements_arg)} { }
162
    void interpret(ostream &output, vector<filesystem::path> &paths) override;
Houtan Bastani's avatar
Houtan Bastani committed
163 164
  };

165

Houtan Bastani's avatar
Houtan Bastani committed
166 167 168
  class If : public Directive
  {
  protected:
169 170 171 172 173 174 175 176
    /* Every if statement and the associated body to execute are stored in a
     * pair<ExpressionPtr, vector<DirectivePtr>>, where the ExpressionPtr is the condition
     * and vector<DirectivePtr> is the series of statements to execute if the condition evaluates
     * to true.
     * The `if` statement is the first element in the vector
     * If there exist any `elseif` statements, they follow
     * If there is an `else` statement it is the last element in the vector. Its condition is true.
     */
177
    const vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body;
178
    const bool ifdef, ifndef;
Houtan Bastani's avatar
Houtan Bastani committed
179
  public:
180
    If(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
181 182 183 184
       Environment &env_arg, Tokenizer::location location_arg,
       bool ifdef_arg = false, bool ifndef_arg = false) :
      Directive(env_arg, move(location_arg)), expr_and_body{move(expr_and_body_arg)},
      ifdef{ifdef_arg}, ifndef{ifndef_arg} { }
185
    void interpret(ostream &output, vector<filesystem::path> &paths) override;
Houtan Bastani's avatar
Houtan Bastani committed
186
  protected:
187 188
    void interpretBody(const vector<DirectivePtr> &body, ostream &output,
                       vector<filesystem::path> &paths);
Houtan Bastani's avatar
Houtan Bastani committed
189 190 191 192 193
  };

  class Ifdef : public If
  {
  public:
194
    Ifdef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
195
          Environment &env_arg, Tokenizer::location location_arg) :
196
      If(move(expr_and_body_arg), env_arg, move(location_arg), true, false) { }
Houtan Bastani's avatar
Houtan Bastani committed
197 198
  };

199

Houtan Bastani's avatar
Houtan Bastani committed
200 201 202
  class Ifndef : public If
  {
  public:
203
    Ifndef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
204
           Environment &env_arg, Tokenizer::location location_arg) :
205
      If(move(expr_and_body_arg), env_arg, move(location_arg), false, true) { }
Houtan Bastani's avatar
Houtan Bastani committed
206 207 208
  };
}
#endif