GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
pt-binop.cc
Go to the documentation of this file.
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 (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include "error.h"
31 #include "interpreter.h"
32 #include "ov.h"
33 #include "profiler.h"
34 #include "pt-binop.h"
35 #include "pt-eval.h"
36 #include "variables.h"
37 
38 namespace octave
39 {
40  // Binary expressions.
41 
42  void
44  {
45  warning_with_id ("Octave:possible-matlab-short-circuit-operator",
46  "Matlab-style short-circuit operation performed for operator %s",
47  op);
48 
50  }
51 
52  std::string
54  {
56  }
57 
60  {
62  = new tree_binary_expression (m_lhs ? m_lhs->dup (scope) : nullptr,
63  m_rhs ? m_rhs->dup (scope) : nullptr,
64  line (), column (), m_etype);
65 
66  new_be->copy_base (*this);
67 
68  return new_be;
69  }
70 
73  {
74  octave_value val;
75 
77  {
78  if (m_lhs)
79  {
80  octave_value a = m_lhs->evaluate (tw);
81 
82  if (a.ndims () == 2 && a.rows () == 1 && a.columns () == 1)
83  {
84  bool result = false;
85 
86  bool a_true = a.is_true ();
87 
88  if (a_true)
89  {
91  {
93  return octave_value (true);
94  }
95  }
96  else
97  {
99  {
101  return octave_value (false);
102  }
103  }
104 
105  if (m_rhs)
106  {
107  octave_value b = m_rhs->evaluate (tw);
108 
109  result = b.is_true ();
110  }
111 
112  return octave_value (result);
113  }
114  }
115  }
116 
117  if (m_lhs)
118  {
119  octave_value a = m_lhs->evaluate (tw);
120 
121  if (a.is_defined () && m_rhs)
122  {
123  octave_value b = m_rhs->evaluate (tw);
124 
125  if (b.is_defined ())
126  {
128  block (tw.get_profiler (), *this);
129 
130  // Note: The profiler does not catch the braindead
131  // short-circuit evaluation code above, but that should be
132  // ok. The evaluation of operands and the operator itself
133  // is entangled and it's not clear where to start/stop
134  // timing the operator to make it reasonable.
135 
136  interpreter& interp = tw.get_interpreter ();
137 
138  type_info& ti = interp.get_type_info ();
139 
140  val = ::do_binary_op (ti, m_etype, a, b);
141  }
142  }
143  }
144 
145  return val;
146  }
147 
148  // Boolean expressions.
149 
150  std::string
152  {
153  std::string retval = "<unknown>";
154 
155  switch (m_etype)
156  {
157  case bool_and:
158  retval = "&&";
159  break;
160 
161  case bool_or:
162  retval = "||";
163  break;
164 
165  default:
166  break;
167  }
168 
169  return retval;
170  }
171 
174  {
176  = new tree_boolean_expression (m_lhs ? m_lhs->dup (scope) : nullptr,
177  m_rhs ? m_rhs->dup (scope) : nullptr,
178  line (), column (), m_etype);
179 
180  new_be->copy_base (*this);
181 
182  return new_be;
183  }
184 
187  {
188  octave_value val;
189 
190  bool result = false;
191 
192  // This evaluation is not caught by the profiler, since we can't find
193  // a reasonable place where to time. Note that we don't want to
194  // include evaluation of LHS or RHS into the timing, but this is
195  // entangled together with short-circuit evaluation here.
196 
197  if (m_lhs)
198  {
199  octave_value a = m_lhs->evaluate (tw);
200 
201  bool a_true = a.is_true ();
202 
203  if (a_true)
204  {
206  return octave_value (true);
207  }
208  else
209  {
211  return octave_value (false);
212  }
213 
214  if (m_rhs)
215  {
216  octave_value b = m_rhs->evaluate (tw);
217 
218  result = b.is_true ();
219  }
220 
221  val = octave_value (result);
222  }
223 
224  return val;
225  }
226 }
type_info & get_type_info(void)
Definition: interpreter.h:253
void matlab_style_short_circuit_warning(const char *op)
Definition: pt-binop.cc:43
octave_value evaluate(tree_evaluator &, int nargout=1)
Definition: pt-binop.cc:72
tree_expression * m_rhs
Definition: pt-binop.h:126
tree_expression * m_lhs
Definition: pt-binop.h:125
octave_value::binary_op m_etype
Definition: pt-binop.h:131
tree_binary_expression(int l=-1, int c=-1, octave_value::binary_op t=octave_value::unknown_binary_op)
Definition: pt-binop.h:50
tree_expression * dup(symbol_scope &scope) const
Definition: pt-binop.cc:59
std::string oper(void) const
Definition: pt-binop.cc:53
bool is_eligible_for_braindead_shortcircuit(void) const
Definition: pt-binop.h:99
std::string oper(void) const
Definition: pt-binop.cc:151
tree_expression * dup(symbol_scope &scope) const
Definition: pt-binop.cc:173
tree_boolean_expression(int l=-1, int c=-1, type t=unknown)
Definition: pt-binop.h:155
octave_value evaluate(tree_evaluator &, int nargout=1)
Definition: pt-binop.cc:186
interpreter & get_interpreter(void)
Definition: pt-eval.h:370
profiler & get_profiler(void)
Definition: pt-eval.h:374
virtual void copy_base(const tree_expression &e)
Definition: pt-exp.h:131
virtual tree_expression * dup(symbol_scope &scope) const =0
virtual octave_value evaluate(tree_evaluator &tw, int nargout=1)=0
virtual int column(void) const
Definition: pt.h:62
static std::string binary_op_as_string(binary_op)
Definition: ov.cc:178
bool is_true(void) const
Definition: ov.h:711
octave_idx_type rows(void) const
Definition: ov.h:504
bool is_defined(void) const
Definition: ov.h:551
octave_idx_type columns(void) const
Definition: ov.h:506
int ndims(void) const
Definition: ov.h:510
@ op_el_or
Definition: ov.h:114
@ op_el_and
Definition: ov.h:113
void warning_with_id(const char *id, const char *fmt,...)
Definition: error.cc:1065
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
OCTINTERP_API octave_value do_binary_op(octave::type_info &ti, octave_value::binary_op op, const octave_value &a, const octave_value &b)