GNU Octave 7.1.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-2022 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
38namespace 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 = 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:291
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
virtual void copy_base(const tree_expression &e)
Definition: pt-exp.h:133
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
virtual int line(void) const
Definition: pt.h:60
static OCTINTERP_API std::string binary_op_as_string(binary_op)
Definition: ov.cc:184
bool is_true(void) const
Definition: ov.h:803
octave_idx_type rows(void) const
Definition: ov.h:590
bool is_defined(void) const
Definition: ov.h:637
octave_idx_type columns(void) const
Definition: ov.h:592
int ndims(void) const
Definition: ov.h:596
@ op_el_or
Definition: ov.h:108
@ op_el_and
Definition: ov.h:107
interpreter & get_interpreter(void)
Definition: pt-eval.h:414
profiler & get_profiler(void)
Definition: pt-eval.h:418
void warning_with_id(const char *id, const char *fmt,...)
Definition: error.cc:1070
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
OCTINTERP_API octave_value binary_op(type_info &ti, octave_value::binary_op op, const octave_value &a, const octave_value &b)