1 /* valasliceexpression.vala
3 * Copyright (C) 2009 Robin Sonefors
4 * Copyright (C) 2009-2010 Jürg Billeter
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * Robin Sonefors <ozamosi@flukkost.nu>
22 * Jürg Billeter <j@bitron.ch>
28 * Represents an array slice expression e.g "a[1:5]".
30 public class Vala
.SliceExpression
: Expression
{
31 public Expression container
{
37 _container
.parent_node
= this
;
41 public Expression start
{
47 _start
.parent_node
= this
;
51 public Expression stop
{
57 _stop
.parent_node
= this
;
61 Expression _container
;
65 public SliceExpression (Expression container
, Expression start
, Expression stop
, SourceReference? source_reference
= null) {
66 this
.container
= container
;
69 this
.source_reference
= source_reference
;
72 public override void accept (CodeVisitor visitor
) {
73 visitor
.visit_slice_expression (this
);
75 visitor
.visit_expression (this
);
78 public override void accept_children (CodeVisitor visitor
) {
79 container
.accept (visitor
);
81 start
.accept (visitor
);
82 stop
.accept (visitor
);
85 public override void replace_expression (Expression old_node
, Expression new_node
) {
86 if (container
== old_node
) {
89 if (start
== old_node
) {
92 if (stop
== old_node
) {
97 public override bool is_pure () {
101 public override bool check (CodeContext context
) {
108 if (!container
.check (context
)) {
113 if (!start
.check (context
)) {
118 if (!stop
.check (context
)) {
123 if (container
.value_type
== null) {
125 Report
.error (container
.source_reference
, "Invalid container expression");
131 Report
.error (container
.source_reference
, "Slice expressions cannot be used as lvalue");
135 if (container
.value_type is ArrayType
) {
136 value_type
= container
.value_type
.copy ();
137 value_type
.value_owned
= false;
139 /* check if the index is of type integer */
140 if (!(start
.value_type is IntegerType
|| start
.value_type is EnumValueType
)) {
142 Report
.error (start
.source_reference
, "Expression of integer type expected");
144 if (!(stop
.value_type is IntegerType
|| stop
.value_type is EnumValueType
)) {
146 Report
.error (stop
.source_reference
, "Expression of integer type expected");
149 var slice_method
= container
.value_type
.get_member ("slice") as Method
;
150 if (slice_method
!= null) {
151 var slice_call
= new
MethodCall (new
MemberAccess (container
, "slice"));
152 slice_call
.add_argument (start
);
153 slice_call
.add_argument (stop
);
154 slice_call
.target_type
= this
.target_type
;
155 parent_node
.replace_expression (this
, slice_call
);
156 return slice_call
.check (context
);
160 Report
.error (source_reference
, "The expression `%s' does not denote an array".printf (container
.value_type
.to_string ()));
166 public override void emit (CodeGenerator codegen
) {
167 container
.emit (codegen
);
169 start
.emit (codegen
);
172 codegen
.visit_slice_expression (this
);
174 codegen
.visit_expression (this
);
177 public override void get_defined_variables (Collection
<LocalVariable
> collection
) {
178 container
.get_defined_variables (collection
);
179 start
.get_defined_variables (collection
);
180 stop
.get_defined_variables (collection
);
183 public override void get_used_variables (Collection
<LocalVariable
> collection
) {
184 container
.get_used_variables (collection
);
185 start
.get_used_variables (collection
);
186 stop
.get_used_variables (collection
);