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<Variable> 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<Variable> collection) {
184
container.get_used_variables (collection);
185
start.get_used_variables (collection);
186
stop.get_used_variables (collection);