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_assign_h)
27 #define octave_pt_assign_h 1
28 
29 #include "octave-config.h"
30 
31 #include <iosfwd>
32 #include <string>
33 
34 class octave_value;
35 class octave_value_list;
36 
37 #include "ov.h"
38 #include "pt-exp.h"
39 #include "pt-walk.h"
40 
41 namespace octave
42 {
43   class symbol_scope;
44   class octave_lvalue;
45   class tree_argument_list;
46 
47   // Simple assignment expressions.
48 
49   class tree_simple_assignment : public tree_expression
50   {
51   public:
52 
53     tree_simple_assignment (bool plhs = false, int l = -1, int c = -1,
54                             octave_value::assign_op t = octave_value::op_asn_eq)
tree_expression(l,c)55       : tree_expression (l, c), m_lhs (nullptr), m_rhs (nullptr),
56         m_preserve (plhs), m_ans_assign (), m_etype (t)
57     { }
58 
59     tree_simple_assignment (tree_expression *le, tree_expression *re,
60                             bool plhs = false, int l = -1, int c = -1,
61                             octave_value::assign_op t = octave_value::op_asn_eq);
62 
63     // No copying!
64 
65     tree_simple_assignment (const tree_simple_assignment&) = delete;
66 
67     tree_simple_assignment& operator = (const tree_simple_assignment&) = delete;
68 
69     ~tree_simple_assignment (void);
70 
rvalue_ok(void)71     bool rvalue_ok (void) const { return true; }
72 
is_assignment_expression(void)73     bool is_assignment_expression (void) const { return true; }
74 
75     std::string oper (void) const;
76 
left_hand_side(void)77     tree_expression * left_hand_side (void) { return m_lhs; }
78 
right_hand_side(void)79     tree_expression * right_hand_side (void) { return m_rhs; }
80 
81     tree_expression * dup (symbol_scope& scope) const;
82 
83     octave_value evaluate (tree_evaluator& tw, int nargout = 1);
84 
85     octave_value_list evaluate_n (tree_evaluator& tw, int nargout = 1)
86     {
87       return ovl (evaluate (tw, nargout));
88     }
89 
accept(tree_walker & tw)90     void accept (tree_walker& tw)
91     {
92       tw.visit_simple_assignment (*this);
93     }
94 
op_type(void)95     octave_value::assign_op op_type (void) const { return m_etype; }
96 
97   private:
98 
99     void do_assign (octave_lvalue& ult, const octave_value_list& args,
100                     const octave_value& rhs_val);
101 
102     void do_assign (octave_lvalue& ult, const octave_value& rhs_val);
103 
104     // The left hand side of the assignment.
105     tree_expression *m_lhs;
106 
107     // The right hand side of the assignment.
108     tree_expression *m_rhs;
109 
110     // True if we should not delete the lhs.
111     bool m_preserve;
112 
113     // True if this is an assignment to the automatic variable ans.
114     bool m_ans_assign;
115 
116     // The type of the expression.
117     octave_value::assign_op m_etype;
118   };
119 
120   // Multi-valued assignment expressions.
121 
122   class tree_multi_assignment : public tree_expression
123   {
124   public:
125 
126     tree_multi_assignment (bool plhs = false, int l = -1, int c = -1)
tree_expression(l,c)127       : tree_expression (l, c), m_lhs (nullptr), m_rhs (nullptr),
128         m_preserve (plhs)
129     { }
130 
131     tree_multi_assignment (tree_argument_list *lst, tree_expression *r,
132                            bool plhs = false, int l = -1, int c = -1);
133 
134     // No copying!
135 
136     tree_multi_assignment (const tree_multi_assignment&) = delete;
137 
138     tree_multi_assignment& operator = (const tree_multi_assignment&) = delete;
139 
140     ~tree_multi_assignment (void);
141 
is_assignment_expression(void)142     bool is_assignment_expression (void) const { return true; }
143 
rvalue_ok(void)144     bool rvalue_ok (void) const { return true; }
145 
146     std::string oper (void) const;
147 
left_hand_side(void)148     tree_argument_list * left_hand_side (void) { return m_lhs; }
149 
right_hand_side(void)150     tree_expression * right_hand_side (void) { return m_rhs; }
151 
152     tree_expression * dup (symbol_scope& scope) const;
153 
154     octave_value evaluate (tree_evaluator& tw, int nargout = 1)
155     {
156       octave_value_list retval = evaluate_n (tw, nargout);
157 
158       return retval.length () > 0 ? retval(0) : octave_value ();
159     }
160 
161     octave_value_list evaluate_n (tree_evaluator& tw, int nargout = 1);
162 
accept(tree_walker & tw)163     void accept (tree_walker& tw)
164     {
165       tw.visit_multi_assignment (*this);
166     }
167 
op_type(void)168     octave_value::assign_op op_type (void) const
169     {
170       return octave_value::op_asn_eq;
171     }
172 
173   private:
174 
175     // The left hand side of the assignment.
176     tree_argument_list *m_lhs;
177 
178     // The right hand side of the assignment.
179     tree_expression *m_rhs;
180 
181     // True if we should not delete the lhs.
182     bool m_preserve;
183   };
184 }
185 
186 #endif
187