1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 
3 /*
4  *  Main authors:
5  *     Guido Tack <guido.tack@monash.edu>
6  */
7 
8 /* This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
11 
12 #pragma once
13 
14 #include <minizinc/astexception.hh>
15 #include <minizinc/hash.hh>
16 #include <minizinc/model.hh>
17 
18 namespace MiniZinc {
19 
20 /// Scoped variable declarations
21 class Scopes {
22 protected:
23   typedef IdMap<VarDecl*> DeclMap;
24   enum ScopeType { ST_TOPLEVEL, ST_FUN, ST_INNER };
25   struct Scope {
26     /// Map from identifiers to declarations
27     DeclMap m;
28     /// Type of this scope
29     ScopeType st;
30     /// Constructor
ScopeMiniZinc::Scopes::Scope31     Scope(ScopeType st0) : st(st0) {}
32     /// Whether this scope is toplevel
toplevelMiniZinc::Scopes::Scope33     bool toplevel() const { return st == ST_TOPLEVEL; }
34   };
35   /// Stack of scopes
36   std::vector<Scope> _s;
37 
38 public:
39   /// Constructor
40   Scopes();
41 
42   /// Add a variable declaration
43   void add(EnvI& env, VarDecl* vd);
44 
45   /// Push a new toplevel scope
46   void pushToplevel();
47   /// Push a new function scope
48   void pushFun();
49   /// Push a new scope
50   void push();
51   /// Pop topmost scope
52   void pop();
53 
54   /// Return declaration for \a ident, or NULL if not found
55   VarDecl* find(Id* ident);
56 
57   /// Find declarations with identifiers similar to \a ident
58   VarDecl* findSimilar(Id* ident);
59 };
60 
61 /// Topological sorting of items
62 class TopoSorter {
63 public:
64   typedef std::vector<VarDecl*> Decls;
65   typedef std::unordered_map<VarDecl*, int> PosMap;
66 
67   /// List of all declarations
68   Decls decls;
69   /// Scoped declarations
70   Scopes scopes;
71   /// Map from declarations to positions
72   PosMap pos;
73   /// The model
74   Model* model;
75 
TopoSorter(Model * model0)76   TopoSorter(Model* model0) : model(model0) {}
77 
78   /// Add a variable declaration item
79   void add(EnvI& env, VarDeclI* vd, bool handleEnums, Model* enumItems);
80   /// Get variable declaration from identifier \a id
81   VarDecl* get(EnvI& env, const ASTString& id, const Location& loc);
82 
83   VarDecl* checkId(EnvI& env, const ASTString& id_v, const Location& loc);
84   VarDecl* checkId(EnvI& env, Id* ident, const Location& loc);
85   /// Run the topological sorting for expression \a e
86   void run(EnvI& env, Expression* e);
87 };
88 
89 /// Type check the model \a m
90 void typecheck(Env& env, Model* origModel, std::vector<TypeError>& typeErrors,
91                bool ignoreUndefinedParameters, bool allowMultiAssignment, bool isFlatZinc = false);
92 
93 /// Type check new assign item \a ai in model \a m
94 void typecheck(Env& env, Model* m, AssignI* ai);
95 
96 /// Output description of parameters and output variables to \a os
97 void output_model_interface(Env& env, Model* m, std::ostream& os,
98                             const std::vector<std::string>& skipDirs);
99 
100 /// Output information about variable types (enum types) to \a os
101 void output_model_variable_types(Env& env, Model* m, std::ostream& os,
102                                  const std::vector<std::string>& skipDirs);
103 
104 std::string create_enum_to_string_name(Id* ident, const std::string& prefix);
105 }  // namespace MiniZinc
106