Skip to content
Snippets Groups Projects
Select Git revision
  • ebe33e3d7e64fcb8e945c7a1d163b756f698a75a
  • master default protected
  • julia protected
  • 6.x protected
  • python-codegen
  • llvm-15
  • 5.x protected
  • 4.6 protected
  • uop
  • rework_pac
  • aux_vars_fix
  • julia-7.0.0
  • julia-6.4.0
  • julia-6.3.0
  • julia-6.2.0
15 results

Directives.hh

Blame
  • Directives.hh 6.57 KiB
    /*
     * Copyright © 2019-2023 Dynare Team
     *
     * 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 <https://www.gnu.org/licenses/>.
     */
    
    #ifndef DIRECTIVES_HH
    #define DIRECTIVES_HH
    
    #include "Expressions.hh"
    
    #include <filesystem>
    
    namespace macro
    {
    class Directive : public Node
    {
      // A Parent class just for clarity
    public:
      explicit Directive(Tokenizer::location location_arg) : Node(move(location_arg))
      {
      }
      // Directives can be interpreted
      virtual void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) = 0;
    };
    
    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:
      TextNode(string text_arg, Tokenizer::location location_arg) :
          Directive(move(location_arg)), text {move(text_arg)}
      {
      }
      void
      interpret(ostream& output, [[maybe_unused]] Environment& env,
                [[maybe_unused]] vector<filesystem::path>& paths) override
      {
        output << text;
      }
    };
    
    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:
      Eval(ExpressionPtr expr_arg, Tokenizer::location location_arg) :
          Directive(move(location_arg)), expr {move(expr_arg)}
      {
      }
      void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
    };
    
    class Include : public Directive
    {
    private:
      const ExpressionPtr expr;
    
    public:
      Include(ExpressionPtr expr_arg, Tokenizer::location location_arg) :
          Directive(move(location_arg)), expr {move(expr_arg)}
      {
      }
      void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
    };
    
    class IncludePath : public Directive
    {
    private:
      const ExpressionPtr expr;
    
    public:
      IncludePath(ExpressionPtr expr_arg, Tokenizer::location location_arg) :
          Directive(move(location_arg)), expr {move(expr_arg)}
      {
      }
      void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
    };
    
    class Define : public Directive
    {
    private:
      const VariablePtr var;
      const FunctionPtr func;
      const ExpressionPtr value;
    
    public:
      Define(VariablePtr var_arg, ExpressionPtr value_arg, Tokenizer::location location_arg) :
          Directive(move(location_arg)), var {move(var_arg)}, value {move(value_arg)}
      {
      }
      Define(FunctionPtr func_arg, ExpressionPtr value_arg, Tokenizer::location location_arg) :
          Directive(move(location_arg)), func {move(func_arg)}, value {move(value_arg)}
      {
      }
      void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
    };
    
    class Echo : public Directive
    {
    private:
      const ExpressionPtr expr;
    
    public:
      Echo(ExpressionPtr expr_arg, Tokenizer::location location_arg) :
          Directive(move(location_arg)), expr {move(expr_arg)}
      {
      }
      void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
    };
    
    class Error : public Directive
    {
    private:
      const ExpressionPtr expr;
    
    public:
      Error(ExpressionPtr expr_arg, Tokenizer::location location_arg) :
          Directive(move(location_arg)), expr {move(expr_arg)}
      {
      }
      void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
    };
    
    class EchoMacroVars : public Directive
    {
    private:
      const bool save;
      const vector<string> vars;
    
    public:
      EchoMacroVars(bool save_arg, Tokenizer::location location_arg) :
          Directive(move(location_arg)), save {save_arg}
      {
      }
      EchoMacroVars(bool save_arg, vector<string> vars_arg, Tokenizer::location location_arg) :
          Directive(move(location_arg)), save {save_arg}, vars {move(vars_arg)}
      {
      }
      void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
    };
    
    class For : public Directive
    {
    private:
      const vector<VariablePtr> index_vec;
      const ExpressionPtr index_vals;
      const vector<DirectivePtr> statements;
    
    public:
      For(vector<VariablePtr> index_vec_arg, ExpressionPtr index_vals_arg,
          vector<DirectivePtr> statements_arg, Tokenizer::location location_arg) :
          Directive(move(location_arg)),
          index_vec {move(index_vec_arg)},
          index_vals {move(index_vals_arg)},
          statements {move(statements_arg)}
      {
      }
      void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
    };
    
    class If : public Directive
    {
    protected:
      /* 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.
       */
      const vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body;
      const bool ifdef, ifndef;
    
    public:
      If(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
         Tokenizer::location location_arg, bool ifdef_arg = false, bool ifndef_arg = false) :
          Directive(move(location_arg)),
          expr_and_body {move(expr_and_body_arg)},
          ifdef {ifdef_arg},
          ifndef {ifndef_arg}
      {
      }
      void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
    
    protected:
      void interpretBody(const vector<DirectivePtr>& body, ostream& output, Environment& env,
                         vector<filesystem::path>& paths);
    };
    
    class Ifdef : public If
    {
    public:
      Ifdef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
            Tokenizer::location location_arg) :
          If(move(expr_and_body_arg), move(location_arg), true, false)
      {
      }
    };
    
    class Ifndef : public If
    {
    public:
      Ifndef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
             Tokenizer::location location_arg) :
          If(move(expr_and_body_arg), move(location_arg), false, true)
      {
      }
    };
    }
    #endif