~ubuntu-branches/ubuntu/raring/vala-0.20/raring-proposed

« back to all changes in this revision

Viewing changes to vala/valasliceexpression.vala

  • Committer: Package Import Robot
  • Author(s): Sebastien Bacher
  • Date: 2013-04-05 13:45:05 UTC
  • Revision ID: package-import@ubuntu.com-20130405134505-yyk3rec9904i7p8o
Tags: upstream-0.20.1
Import upstream version 0.20.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* valasliceexpression.vala
 
2
 *
 
3
 * Copyright (C) 2009 Robin Sonefors
 
4
 * Copyright (C) 2009-2010 Jürg Billeter
 
5
 *
 
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.
 
10
 
 
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.
 
15
 
 
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
 
19
 *
 
20
 * Author:
 
21
 *      Robin Sonefors <ozamosi@flukkost.nu>
 
22
 *      Jürg Billeter <j@bitron.ch>
 
23
 */
 
24
 
 
25
using GLib;
 
26
 
 
27
/**
 
28
 * Represents an array slice expression e.g "a[1:5]".
 
29
 */
 
30
public class Vala.SliceExpression : Expression {
 
31
        public Expression container {
 
32
                get {
 
33
                        return _container;
 
34
                }
 
35
                set {
 
36
                        _container = value;
 
37
                        _container.parent_node = this;
 
38
                }
 
39
        }
 
40
 
 
41
        public Expression start {
 
42
                get {
 
43
                        return _start;
 
44
                }
 
45
                private set {
 
46
                        _start = value;
 
47
                        _start.parent_node = this;
 
48
                }
 
49
        }
 
50
 
 
51
        public Expression stop {
 
52
                get {
 
53
                        return _stop;
 
54
                }
 
55
                private set {
 
56
                        _stop = value;
 
57
                        _stop.parent_node = this;
 
58
                }
 
59
        }
 
60
 
 
61
        Expression _container;
 
62
        Expression _start;
 
63
        Expression _stop;
 
64
 
 
65
        public SliceExpression (Expression container, Expression start, Expression stop, SourceReference? source_reference = null) {
 
66
                this.container = container;
 
67
                this.start = start;
 
68
                this.stop = stop;
 
69
                this.source_reference = source_reference;
 
70
        }
 
71
 
 
72
        public override void accept (CodeVisitor visitor) {
 
73
                visitor.visit_slice_expression (this);
 
74
 
 
75
                visitor.visit_expression (this);
 
76
        }
 
77
 
 
78
        public override void accept_children (CodeVisitor visitor) {
 
79
                container.accept (visitor);
 
80
 
 
81
                start.accept (visitor);
 
82
                stop.accept (visitor);
 
83
        }
 
84
 
 
85
        public override void replace_expression (Expression old_node, Expression new_node) {
 
86
                if (container == old_node) {
 
87
                        container = new_node;
 
88
                }
 
89
                if (start == old_node) {
 
90
                        start = new_node;
 
91
                }
 
92
                if (stop == old_node) {
 
93
                        stop = new_node;
 
94
                }
 
95
        }
 
96
 
 
97
        public override bool is_pure () {
 
98
                return false;
 
99
        }
 
100
 
 
101
        public override bool check (CodeContext context) {
 
102
                if (checked) {
 
103
                        return !error;
 
104
                }
 
105
 
 
106
                checked = true;
 
107
 
 
108
                if (!container.check (context)) {
 
109
                        error = true;
 
110
                        return false;
 
111
                }
 
112
 
 
113
                if (!start.check (context)) {
 
114
                        error = true;
 
115
                        return false;
 
116
                }
 
117
 
 
118
                if (!stop.check (context)) {
 
119
                        error = true;
 
120
                        return false;
 
121
                }
 
122
 
 
123
                if (container.value_type == null) {
 
124
                        error = true;
 
125
                        Report.error (container.source_reference, "Invalid container expression");
 
126
                        return false;
 
127
                }
 
128
 
 
129
                if (lvalue) {
 
130
                        error = true;
 
131
                        Report.error (container.source_reference, "Slice expressions cannot be used as lvalue");
 
132
                        return false;
 
133
                }
 
134
 
 
135
                if (container.value_type is ArrayType) {
 
136
                        value_type = container.value_type.copy ();
 
137
                        value_type.value_owned = false;
 
138
 
 
139
                        /* check if the index is of type integer */
 
140
                        if (!(start.value_type is IntegerType || start.value_type is EnumValueType)) {
 
141
                                error = true;
 
142
                                Report.error (start.source_reference, "Expression of integer type expected");
 
143
                        }
 
144
                        if (!(stop.value_type is IntegerType || stop.value_type is EnumValueType)) {
 
145
                                error = true;
 
146
                                Report.error (stop.source_reference, "Expression of integer type expected");
 
147
                        }
 
148
                } else {
 
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);
 
157
                        }
 
158
 
 
159
                        error = true;
 
160
                        Report.error (source_reference, "The expression `%s' does not denote an array".printf (container.value_type.to_string ()));
 
161
                }
 
162
 
 
163
                return !error;
 
164
        }
 
165
 
 
166
        public override void emit (CodeGenerator codegen) {
 
167
                container.emit (codegen);
 
168
 
 
169
                start.emit (codegen);
 
170
                stop.emit (codegen);
 
171
 
 
172
                codegen.visit_slice_expression (this);
 
173
 
 
174
                codegen.visit_expression (this);
 
175
        }
 
176
 
 
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);
 
181
        }
 
182
 
 
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);
 
187
        }
 
188
}