1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING.  If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if ! defined (octave_pt_loop_h)
27 #define octave_pt_loop_h 1
28 
29 #include "octave-config.h"
30 
31 class octave_value;
32 
33 #include "pt-cmd.h"
34 #include "pt-walk.h"
35 #include "pt-jit.h"
36 
37 namespace octave
38 {
39   class jit_info;
40   class tree_argument_list;
41   class tree_expression;
42   class tree_statement_list;
43 
44   // While.
45 
46   class tree_while_command : public tree_command
47   {
48   public:
49 
50     tree_while_command (int l = -1, int c = -1)
tree_command(l,c)51       : tree_command (l, c), m_expr (nullptr), m_list (nullptr),
52         m_lead_comm (nullptr), m_trail_comm (nullptr)
53 #if defined (HAVE_LLVM)
54       , m_compiled (nullptr)
55 #endif
56     { }
57 
58     tree_while_command (tree_expression *e,
59                         comment_list *lc = nullptr,
60                         comment_list *tc = nullptr,
61                         int l = -1, int c = -1)
tree_command(l,c)62       : tree_command (l, c), m_expr (e), m_list (nullptr),
63         m_lead_comm (lc), m_trail_comm (tc)
64 #if defined (HAVE_LLVM)
65       , m_compiled (nullptr)
66 #endif
67     { }
68 
69     tree_while_command (tree_expression *e, tree_statement_list *lst,
70                         comment_list *lc = nullptr,
71                         comment_list *tc = nullptr,
72                         int l = -1, int c = -1)
tree_command(l,c)73       : tree_command (l, c), m_expr (e), m_list (lst), m_lead_comm (lc),
74         m_trail_comm (tc)
75 #if defined (HAVE_LLVM)
76       , m_compiled (nullptr)
77 #endif
78     { }
79 
80     // No copying!
81 
82     tree_while_command (const tree_while_command&) = delete;
83 
84     tree_while_command& operator = (const tree_while_command&) = delete;
85 
86     ~tree_while_command (void);
87 
condition(void)88     tree_expression * condition (void) { return m_expr; }
89 
body(void)90     tree_statement_list * body (void) { return m_list; }
91 
leading_comment(void)92     comment_list * leading_comment (void) { return m_lead_comm; }
93 
trailing_comment(void)94     comment_list * trailing_comment (void) { return m_trail_comm; }
95 
accept(tree_walker & tw)96     void accept (tree_walker& tw)
97     {
98       tw.visit_while_command (*this);
99     }
100 
101 #if defined (HAVE_LLVM)
102     // some functions use by tree_jit
get_info(void)103     jit_info * get_info (void) const { return m_compiled; }
104 
stash_info(jit_info * jinfo)105     void stash_info (jit_info *jinfo) { m_compiled = jinfo; }
106 #endif
107 
108   protected:
109 
110     // Expression to test.
111     tree_expression *m_expr;
112 
113     // List of commands to execute.
114     tree_statement_list *m_list;
115 
116     // Comment preceding WHILE token.
117     comment_list *m_lead_comm;
118 
119     // Comment preceding ENDWHILE token.
120     comment_list *m_trail_comm;
121 
122   private:
123 
124 #if defined (HAVE_LLVM)
125     // compiled version of the loop
126     jit_info *m_compiled;
127 #endif
128   };
129 
130   // Do-Until.
131 
132   class tree_do_until_command : public tree_while_command
133   {
134   public:
135 
136     tree_do_until_command (int l = -1, int c = -1)
tree_while_command(l,c)137       : tree_while_command (l, c)
138     { }
139 
140     tree_do_until_command (tree_expression *e,
141                            comment_list *lc = nullptr,
142                            comment_list *tc = nullptr,
143                            int l = -1, int c = -1)
tree_while_command(e,lc,tc,l,c)144       : tree_while_command (e, lc, tc, l, c)
145     { }
146 
147     tree_do_until_command (tree_expression *e, tree_statement_list *lst,
148                            comment_list *lc = nullptr,
149                            comment_list *tc = nullptr,
150                            int l = -1, int c = -1)
tree_while_command(e,lst,lc,tc,l,c)151       : tree_while_command (e, lst, lc, tc, l, c)
152     { }
153 
154     // No copying!
155 
156     tree_do_until_command (const tree_do_until_command&) = delete;
157 
158     tree_do_until_command& operator = (const tree_do_until_command&) = delete;
159 
160     ~tree_do_until_command (void) = default;
161 
accept(tree_walker & tw)162     void accept (tree_walker& tw)
163     {
164       tw.visit_do_until_command (*this);
165     }
166   };
167 
168   // For.
169 
170   class tree_simple_for_command : public tree_command
171   {
172   public:
173 
174     tree_simple_for_command (int l = -1, int c = -1)
tree_command(l,c)175       : tree_command (l, c), m_parallel (false), m_lhs (nullptr),
176         m_expr (nullptr), m_maxproc (nullptr), m_list (nullptr),
177         m_lead_comm (nullptr), m_trail_comm (nullptr)
178 #if defined (HAVE_LLVM)
179       , m_compiled (nullptr)
180 #endif
181     { }
182 
183     tree_simple_for_command (bool parallel_arg, tree_expression *le,
184                              tree_expression *re,
185                              tree_expression *maxproc_arg,
186                              tree_statement_list *lst,
187                              comment_list *lc = nullptr,
188                              comment_list *tc = nullptr,
189                              int l = -1, int c = -1)
tree_command(l,c)190       : tree_command (l, c), m_parallel (parallel_arg), m_lhs (le),
191         m_expr (re), m_maxproc (maxproc_arg), m_list (lst),
192         m_lead_comm (lc), m_trail_comm (tc)
193 #if defined (HAVE_LLVM)
194       , m_compiled (0)
195 #endif
196     { }
197 
198     // No copying!
199 
200     tree_simple_for_command (const tree_simple_for_command&) = delete;
201 
202     tree_simple_for_command& operator = (const tree_simple_for_command&) = delete;
203 
204     ~tree_simple_for_command (void);
205 
in_parallel(void)206     bool in_parallel (void) { return m_parallel; }
207 
left_hand_side(void)208     tree_expression * left_hand_side (void) { return m_lhs; }
209 
control_expr(void)210     tree_expression * control_expr (void) { return m_expr; }
211 
maxproc_expr(void)212     tree_expression * maxproc_expr (void) { return m_maxproc; }
213 
body(void)214     tree_statement_list * body (void) { return m_list; }
215 
leading_comment(void)216     comment_list * leading_comment (void) { return m_lead_comm; }
217 
trailing_comment(void)218     comment_list * trailing_comment (void) { return m_trail_comm; }
219 
accept(tree_walker & tw)220     void accept (tree_walker& tw)
221     {
222       tw.visit_simple_for_command (*this);
223     }
224 
225 #if defined (HAVE_LLVM)
226     // some functions use by tree_jit
get_info(void)227     jit_info * get_info (void) const
228     {
229       return m_compiled;
230     }
231 
stash_info(jit_info * jinfo)232     void stash_info (jit_info *jinfo)
233     {
234       m_compiled = jinfo;
235     }
236 #endif
237 
238   private:
239     // TRUE means operate in parallel (subject to the value of the
240     // maxproc expression).
241     bool m_parallel;
242 
243     // Expression to modify.
244     tree_expression *m_lhs;
245 
246     // Expression to evaluate.
247     tree_expression *m_expr;
248 
249     // Expression to tell how many processors should be used (only valid
250     // if parallel is TRUE).
251     tree_expression *m_maxproc;
252 
253     // List of commands to execute.
254     tree_statement_list *m_list;
255 
256     // Comment preceding FOR token.
257     comment_list *m_lead_comm;
258 
259     // Comment preceding ENDFOR token.
260     comment_list *m_trail_comm;
261 
262 #if defined (HAVE_LLVM)
263     // compiled version of the loop
264     jit_info *m_compiled;
265 #endif
266   };
267 
268   class tree_complex_for_command : public tree_command
269   {
270   public:
271 
272     tree_complex_for_command (int l = -1, int c = -1)
tree_command(l,c)273       : tree_command (l, c), m_lhs (nullptr), m_expr (nullptr),
274         m_list (nullptr), m_lead_comm (nullptr), m_trail_comm (nullptr)
275     { }
276 
277     tree_complex_for_command (tree_argument_list *le, tree_expression *re,
278                               tree_statement_list *lst,
279                               comment_list *lc = nullptr,
280                               comment_list *tc = nullptr,
281                               int l = -1, int c = -1)
tree_command(l,c)282       : tree_command (l, c), m_lhs (le), m_expr (re), m_list (lst),
283         m_lead_comm (lc), m_trail_comm (tc)
284     { }
285 
286     // No copying!
287 
288     tree_complex_for_command (const tree_complex_for_command&) = delete;
289 
290     tree_complex_for_command& operator = (const tree_complex_for_command&) = delete;
291 
292     ~tree_complex_for_command (void);
293 
left_hand_side(void)294     tree_argument_list * left_hand_side (void) { return m_lhs; }
295 
control_expr(void)296     tree_expression * control_expr (void) { return m_expr; }
297 
body(void)298     tree_statement_list * body (void) { return m_list; }
299 
leading_comment(void)300     comment_list * leading_comment (void) { return m_lead_comm; }
301 
trailing_comment(void)302     comment_list * trailing_comment (void) { return m_trail_comm; }
303 
accept(tree_walker & tw)304     void accept (tree_walker& tw)
305     {
306       tw.visit_complex_for_command (*this);
307     }
308 
309   private:
310 
311     // Expression to modify.
312     tree_argument_list *m_lhs;
313 
314     // Expression to evaluate.
315     tree_expression *m_expr;
316 
317     // List of commands to execute.
318     tree_statement_list *m_list;
319 
320     // Comment preceding FOR token.
321     comment_list *m_lead_comm;
322 
323     // Comment preceding ENDFOR token.
324     comment_list *m_trail_comm;
325   };
326 }
327 
328 #endif
329