1 // {{{ MIT License
2 
3 // Copyright 2017 Roland Kaminski
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to
7 // deal in the Software without restriction, including without limitation the
8 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 // sell copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 // IN THE SOFTWARE.
22 
23 // }}}
24 
25 #ifndef _GRINGO_LOCATABLE_HH
26 #define _GRINGO_LOCATABLE_HH
27 
28 #include <gringo/symbol.hh>
29 #include <gringo/utility.hh>
30 
31 namespace Gringo {
32 
33 // {{{ declaration of Location
34 
35 struct Location {
36     Location(String beginFilename, unsigned beginLine, unsigned beginColumn, String endFilename, unsigned endLine, unsigned endColumn);
37     //Location(Location const &loc);
38     //Location(Location &&loc);
39 
40     String beginFilename;
41     String endFilename;
42     unsigned beginLine;
43     unsigned endLine;
44     unsigned beginColumn;
45     unsigned endColumn;
46 
47     Location operator+(Location const &other) const;
48     bool operator<(Location const &other) const;
49     bool operator==(Location const &other) const;
50 };
51 
52 std::ostream &operator<<(std::ostream &out, Location const &loc);
53 
54 // }}}
55 // {{{ declaration of Locatable
56 
57 class Locatable {
58 public:
59     virtual Location const &loc() const = 0;
60     virtual void loc(Location const &loc) = 0;
~Locatable()61     virtual ~Locatable() { }
62 };
63 
64 // }}}
65 // {{{ declaration of LocatableClass
66 
67 template <class T>
68 class LocatableClass : public T {
69 public:
70     template <typename... Args>
71     LocatableClass(Location const &loc, Args&&... args);
72     virtual void loc(Location const &loc) final;
73     virtual Location const &loc() const final;
74     virtual ~LocatableClass();
75 private:
76     Location loc_;
77 };
78 
79 // }}}
80 // {{{ declaration of make_locatable<T,Args...>
81 
82 template <class T, class... Args>
83 std::unique_ptr<T> make_locatable(Location const &loc, Args&&... args);
84 
85 // }}}
86 
87 // {{{ defintion of Location
88 
Location(String beginFilename,unsigned beginLine,unsigned beginColumn,String endFilename,unsigned endLine,unsigned endColumn)89 inline Location::Location(String beginFilename, unsigned beginLine, unsigned beginColumn, String endFilename, unsigned endLine, unsigned endColumn)
90     : beginFilename(beginFilename)
91     , endFilename(endFilename)
92     , beginLine(beginLine)
93     , endLine(endLine)
94     , beginColumn(beginColumn)
95     , endColumn(endColumn) { }
96 
operator +(Location const & other) const97 inline Location Location::operator+(Location const &other) const {
98     return Location(beginFilename, beginLine, beginColumn, other.endFilename, other.endLine, other.endColumn);
99 }
100 
operator <(Location const & x) const101 inline bool Location::operator<(Location const &x) const {
102     if (beginFilename != x.beginFilename) { return beginFilename < x.beginFilename; }
103     if (endFilename != x.endFilename) { return endFilename < x.endFilename; }
104     if (beginLine != x.beginLine) { return beginLine < x.beginLine; }
105     if (endLine != x.endLine) { return endLine < x.endLine; }
106     if (beginColumn != x.beginColumn) { return beginColumn < x.beginColumn; }
107     return endColumn < x.endColumn;
108 }
109 
operator ==(Location const & x) const110 inline bool Location::operator==(Location const &x) const {
111     return beginFilename == x.beginFilename &&
112            endFilename == x.endFilename &&
113            beginLine == x.beginLine &&
114            endLine == x.endLine &&
115            beginColumn == x.beginColumn &&
116            endColumn == x.endColumn;
117 }
118 
operator <<(std::ostream & out,Location const & loc)119 inline std::ostream &operator<<(std::ostream &out, Location const &loc) {
120     out << loc.beginFilename << ":" << loc.beginLine << ":" << loc.beginColumn;
121     if (loc.beginFilename != loc.endFilename) {
122         out << "-" << loc.endFilename << ":" << loc.endLine << ":" << loc.endColumn;
123     }
124     else if(loc.beginLine != loc.endLine) {
125         out << "-" << loc.endLine << ":" << loc.endColumn;
126     }
127     else if (loc.beginColumn != loc.endColumn) {
128         out << "-" << loc.endColumn;
129     }
130     return out;
131 }
132 
133 // }}}
134 // {{{ defintion of LocatableClass<T>
135 
136 template <class T>
137 template <typename... Args>
LocatableClass(Location const & loc,Args &&...args)138 LocatableClass<T>::LocatableClass(Location const &loc, Args&&... args)
139     : T(std::forward<Args>(args)...)
140     , loc_(loc) { }
141 
142 template <class T>
loc() const143 Location const &LocatableClass<T>::loc() const {
144     return loc_;
145 }
146 
147 template <class T>
loc(Location const & loc)148 void LocatableClass<T>::loc(Location const &loc) {
149     loc_ = loc;
150 }
151 
152 template <class T>
~LocatableClass()153 LocatableClass<T>::~LocatableClass() { }
154 
155 // }}}
156 // {{{ defintion of make_locatable<T, Args>
157 
158 template <class T, class... Args>
make_locatable(Location const & loc,Args &&...args)159 std::unique_ptr<T> make_locatable(Location const &loc, Args&&... args) {
160     return gringo_make_unique<LocatableClass<T>>(loc, std::forward<Args>(args)...);
161 }
162 
163 // }}}
164 
165 } // namespace Gringo
166 
167 #endif // _GRINGO_LOCATABLE_HH
168