1 /* valadovavaluemodule.vala
3 * Copyright (C) 2009-2010 Jürg Billeter
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Jürg Billeter <j@bitron.ch>
23 internal class Vala
.DovaValueModule
: DovaObjectModule
{
24 public DovaValueModule (CCodeGenerator codegen
, CCodeModule? next
) {
28 public override void generate_class_declaration (Class cl
, CCodeDeclarationSpace decl_space
) {
29 if (cl
.base_class
== null ||
30 cl
.base_class
.get_full_name () != "Dova.Value") {
31 base.generate_class_declaration (cl
, decl_space
);
35 if (decl_space
.add_symbol_declaration (cl
, cl
.get_cname ())) {
39 var type_fun
= new
CCodeFunction ("%s_type_get".printf (cl
.get_lower_case_cname ()), "DovaType *");
40 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
41 type_fun
.modifiers
= CCodeModifiers
.STATIC
;
43 decl_space
.add_type_member_declaration (type_fun
);
45 var type_init_fun
= new
CCodeFunction ("%s_type_init".printf (cl
.get_lower_case_cname ()));
46 type_init_fun
.add_parameter (new
CCodeFormalParameter ("type", "DovaType *"));
47 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
48 type_init_fun
.modifiers
= CCodeModifiers
.STATIC
;
50 decl_space
.add_type_member_declaration (type_init_fun
);
52 var instance_struct
= new
CCodeStruct ("_%s".printf (cl
.get_cname ()));
54 foreach (Field f
in cl
.get_fields ()) {
55 if (f
.binding
== MemberBinding
.INSTANCE
) {
56 generate_type_declaration (f
.field_type
, decl_space
);
58 string field_ctype
= f
.field_type
.get_cname ();
60 field_ctype
= "volatile " + field_ctype
;
63 string cname
= f
.get_cname ();
64 var array_type
= f
.field_type as ArrayType
;
65 if (array_type
!= null && array_type
.inline_allocated
) {
69 instance_struct
.add_field (field_ctype
, cname
);
73 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct _%s".printf (cl
.get_cname ()), new
CCodeVariableDeclarator (cl
.get_cname ())));
74 decl_space
.add_type_definition (instance_struct
);
76 if (cl
.get_full_name () == "string") {
77 generate_method_declaration ((Method
) cl
.scope
.lookup ("ref"), decl_space
);
78 generate_method_declaration ((Method
) cl
.scope
.lookup ("unref"), decl_space
);
81 add_value_assert (cl
, decl_space
);
84 public override void visit_class (Class cl
) {
85 if (cl
.base_class
== null ||
86 cl
.base_class
.get_full_name () != "Dova.Value") {
87 base.visit_class (cl
);
91 var old_symbol
= current_symbol
;
94 generate_class_declaration (cl
, source_declarations
);
96 if (!cl
.is_internal_symbol ()) {
97 generate_class_declaration (cl
, header_declarations
);
99 generate_class_declaration (cl
, internal_header_declarations
);
102 var cdecl
= new
CCodeDeclaration ("DovaType *");
103 cdecl
.add_declarator (new
CCodeVariableDeclarator ("%s_type".printf (cl
.get_lower_case_cname ()), new
CCodeConstant ("NULL")));
104 cdecl
.modifiers
= CCodeModifiers
.STATIC
;
105 source_declarations
.add_type_member_declaration (cdecl
);
107 var type_fun
= new
CCodeFunction ("%s_type_get".printf (cl
.get_lower_case_cname ()), "DovaType *");
108 type_fun
.block
= new
CCodeBlock ();
110 var type_init_block
= new
CCodeBlock ();
112 generate_method_declaration ((Method
) object_class
.scope
.lookup ("alloc"), source_declarations
);
113 generate_property_accessor_declaration (((Property
) type_class
.scope
.lookup ("base_type")).set_accessor
, source_declarations
);
114 generate_property_accessor_declaration (((Property
) type_class
.scope
.lookup ("type_size")).get_accessor
, source_declarations
);
115 generate_property_accessor_declaration (((Property
) type_class
.scope
.lookup ("type_size")).set_accessor
, source_declarations
);
116 generate_property_accessor_declaration (((Property
) type_class
.scope
.lookup ("value_size")).set_accessor
, source_declarations
);
118 generate_class_declaration ((Class
) context
.root
.scope
.lookup ("Dova").scope
.lookup ("Value"), source_declarations
);
120 var base_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_value_type_get"));
122 var base_type_size
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_get_type_size"));
123 base_type_size
.add_argument (base_type
);
125 var calloc_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("calloc"));
126 calloc_call
.add_argument (new
CCodeConstant ("1"));
127 calloc_call
.add_argument (base_type_size
);
129 type_init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ())), calloc_call
)));
131 generate_class_declaration ((Class
) object_class
, source_declarations
);
133 type_init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ())), "DovaObject *"), "type"), new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_type_get")))));
135 var set_base_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_base_type"));
136 set_base_type
.add_argument (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ())));
137 set_base_type
.add_argument (base_type
);
138 type_init_block
.add_statement (new
CCodeExpressionStatement (set_base_type
));
140 var set_size
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_type_size"));
141 set_size
.add_argument (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ())));
142 set_size
.add_argument (base_type_size
);
143 type_init_block
.add_statement (new
CCodeExpressionStatement (set_size
));
145 var type_init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_type_init".printf (cl
.get_lower_case_cname ())));
146 type_init_call
.add_argument (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ())));
147 type_init_block
.add_statement (new
CCodeExpressionStatement (type_init_call
));
149 type_fun
.block
.add_statement (new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ()))), type_init_block
));
151 type_fun
.block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ()))));
153 source_type_member_definition
.append (type_fun
);
155 var type_init_fun
= new
CCodeFunction ("%s_type_init".printf (cl
.get_lower_case_cname ()));
156 type_init_fun
.add_parameter (new
CCodeFormalParameter ("type", "DovaType *"));
157 type_init_fun
.block
= new
CCodeBlock ();
159 type_init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_value_type_init"));
160 type_init_call
.add_argument (new
CCodeIdentifier ("type"));
161 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (type_init_call
));
163 declare_set_value_copy_function (source_declarations
);
165 var value_copy_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_value_copy"));
166 value_copy_call
.add_argument (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ())));
167 value_copy_call
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("string_copy"), "void (*)(void *, int32_t, void *, int32_t)"));
168 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (value_copy_call
));
170 var function
= new
CCodeFunction ("string_copy", "void");
171 function
.modifiers
= CCodeModifiers
.STATIC
;
172 function
.add_parameter (new
CCodeFormalParameter ("dest", "string **"));
173 function
.add_parameter (new
CCodeFormalParameter ("dest_index", "int32_t"));
174 function
.add_parameter (new
CCodeFormalParameter ("src", "string **"));
175 function
.add_parameter (new
CCodeFormalParameter ("src_index", "int32_t"));
177 function
.block
= new
CCodeBlock ();
178 var cfrag
= new
CCodeFragment ();
179 function
.block
.add_statement (cfrag
);
181 var dest
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("dest"), new
CCodeIdentifier ("dest_index"));
182 var src
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("src"), new
CCodeIdentifier ("src_index"));
184 var unref_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("string_unref"));
185 unref_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, dest
));
186 var unref_block
= new
CCodeBlock ();
187 unref_block
.add_statement (new
CCodeExpressionStatement (unref_call
));
188 unref_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, dest
), new
CCodeConstant ("NULL"))));
189 function
.block
.add_statement (new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, dest
), unref_block
));
191 var ref_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("string_ref"));
192 ref_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, src
));
193 var ref_block
= new
CCodeBlock ();
194 ref_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, dest
), ref_call
)));
195 function
.block
.add_statement (new
CCodeIfStatement (new
CCodeIdentifier ("src"), ref_block
));
197 source_type_member_definition
.append (function
);
199 if (cl
.scope
.lookup ("equals") is Method
) {
200 var value_equals_fun
= new
CCodeFunction ("%s_value_equals".printf (cl
.get_lower_case_cname ()), "bool");
201 value_equals_fun
.modifiers
= CCodeModifiers
.STATIC
;
202 value_equals_fun
.add_parameter (new
CCodeFormalParameter ("value", cl
.get_cname () + "**"));
203 value_equals_fun
.add_parameter (new
CCodeFormalParameter ("value_index", "int32_t"));
204 value_equals_fun
.add_parameter (new
CCodeFormalParameter ("other", cl
.get_cname () + "**"));
205 value_equals_fun
.add_parameter (new
CCodeFormalParameter ("other_index", "int32_t"));
206 value_equals_fun
.block
= new
CCodeBlock ();
207 var val
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("value"), new
CCodeIdentifier ("value_index"));
208 var other
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("other"), new
CCodeIdentifier ("other_index"));
209 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_equals".printf (cl
.get_lower_case_cname ())));
210 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, val
));
211 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, other
));
212 value_equals_fun
.block
.add_statement (new
CCodeReturnStatement (ccall
));
213 source_type_member_definition
.append (value_equals_fun
);
215 declare_set_value_equals_function (source_declarations
);
217 var value_equals_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_value_equals"));
218 value_equals_call
.add_argument (new
CCodeIdentifier ("type"));
219 value_equals_call
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("%s_value_equals".printf (cl
.get_lower_case_cname ())), "bool (*)(void *, int32_t, void *, int32_t)"));
220 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (value_equals_call
));
223 if (cl
.scope
.lookup ("hash") is Method
) {
224 var value_hash_fun
= new
CCodeFunction ("%s_value_hash".printf (cl
.get_lower_case_cname ()), "int32_t");
225 value_hash_fun
.modifiers
= CCodeModifiers
.STATIC
;
226 value_hash_fun
.add_parameter (new
CCodeFormalParameter ("value", cl
.get_cname () + "**"));
227 value_hash_fun
.add_parameter (new
CCodeFormalParameter ("value_index", "int32_t"));
228 value_hash_fun
.block
= new
CCodeBlock ();
229 var val
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("value"), new
CCodeIdentifier ("value_index"));
230 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_hash".printf (cl
.get_lower_case_cname ())));
231 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, val
));
232 value_hash_fun
.block
.add_statement (new
CCodeReturnStatement (ccall
));
233 source_type_member_definition
.append (value_hash_fun
);
235 declare_set_value_hash_function (source_declarations
);
237 var value_hash_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_value_hash"));
238 value_hash_call
.add_argument (new
CCodeIdentifier ("type"));
239 value_hash_call
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("%s_value_hash".printf (cl
.get_lower_case_cname ())), "int32_t (*)(void *, int32_t)"));
240 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (value_hash_call
));
243 source_type_member_definition
.append (type_init_fun
);
245 cl
.accept_children (codegen
);
247 current_symbol
= old_symbol
;
250 public override void visit_creation_method (CreationMethod m
) {
251 if (current_type_symbol is Class
&&
252 (current_class
.base_class
== null ||
253 current_class
.base_class
.get_full_name () != "Dova.Value")) {
254 base.visit_creation_method (m
);
261 public override void generate_struct_declaration (Struct st
, CCodeDeclarationSpace decl_space
) {
262 base.generate_struct_declaration (st
, decl_space
);
264 if (decl_space
.add_symbol_declaration (st
, st
.get_copy_function ())) {
268 decl_space
.add_include ("stdint.h");
270 generate_class_declaration (type_class
, decl_space
);
272 var type_fun
= new
CCodeFunction ("%s_type_get".printf (st
.get_lower_case_cname ()), "DovaType *");
273 if (st
.access
== SymbolAccessibility
.PRIVATE
) {
274 type_fun
.modifiers
= CCodeModifiers
.STATIC
;
276 decl_space
.add_type_member_declaration (type_fun
);
278 var type_init_fun
= new
CCodeFunction ("%s_type_init".printf (st
.get_lower_case_cname ()));
279 type_init_fun
.add_parameter (new
CCodeFormalParameter ("type", "DovaType *"));
280 if (st
.access
== SymbolAccessibility
.PRIVATE
) {
281 type_init_fun
.modifiers
= CCodeModifiers
.STATIC
;
283 decl_space
.add_type_member_declaration (type_init_fun
);
285 var function
= new
CCodeFunction (st
.get_copy_function (), "void");
286 if (st
.access
== SymbolAccessibility
.PRIVATE
) {
287 function
.modifiers
= CCodeModifiers
.STATIC
;
290 function
.add_parameter (new
CCodeFormalParameter ("dest", st
.get_cname () + "*"));
291 function
.add_parameter (new
CCodeFormalParameter ("dest_index", "int32_t"));
292 function
.add_parameter (new
CCodeFormalParameter ("src", st
.get_cname () + "*"));
293 function
.add_parameter (new
CCodeFormalParameter ("src_index", "int32_t"));
295 decl_space
.add_type_member_declaration (function
);
297 add_value_assert (st
, decl_space
);
300 void add_value_assert (TypeSymbol sym
, CCodeDeclarationSpace decl_space
) {
301 string cname
= sym
.get_cname ();
307 var compare_method
= sym
.scope
.lookup ("compare") as Method
;
308 if (compare_method
!= null) {
309 assert_body
= "do { %s __v1 = (v1); %s __v2 = (v2); if (%s (__v1, __v2) cmp 0); else dova_assert_compare (string_create_from_cstring (#v1 \" \" #cmp \" \" #v2), %s_to_string (v1), string_create_from_cstring (#cmp), %s_to_string (v2)); } while (0)".printf (cname
, cname
, compare_method
.get_cname (), sym
.get_lower_case_cname (), sym
.get_lower_case_cname ());
311 assert_body
= "do { %s __v1 = (v1); %s __v2 = (v2); if (__v1 cmp __v2); else dova_assert_compare (string_create_from_cstring (#v1 \" \" #cmp \" \" #v2), %s_to_string (v1), string_create_from_cstring (#cmp), %s_to_string (v2)); } while (0)".printf (cname
, cname
, sym
.get_lower_case_cname (), sym
.get_lower_case_cname ());
313 var assert_macro
= new
CCodeMacroReplacement ("%s_assert(v1, cmp, v2)".printf (sym
.get_lower_case_cname ()), assert_body
);
314 decl_space
.add_type_member_declaration (assert_macro
);
317 public override void visit_struct (Struct st
) {
318 base.visit_struct (st
);
320 source_declarations
.add_include ("stddef.h");
322 source_declarations
.add_include ("stdlib.h");
324 var cdecl
= new
CCodeDeclaration ("DovaType *");
325 cdecl
.add_declarator (new
CCodeVariableDeclarator ("%s_type".printf (st
.get_lower_case_cname ()), new
CCodeConstant ("NULL")));
326 cdecl
.modifiers
= CCodeModifiers
.STATIC
;
327 source_declarations
.add_type_member_declaration (cdecl
);
329 var type_fun
= new
CCodeFunction ("%s_type_get".printf (st
.get_lower_case_cname ()), "DovaType *");
330 type_fun
.block
= new
CCodeBlock ();
332 var type_init_block
= new
CCodeBlock ();
334 generate_method_declaration ((Method
) object_class
.scope
.lookup ("alloc"), source_declarations
);
335 generate_property_accessor_declaration (((Property
) type_class
.scope
.lookup ("base_type")).get_accessor
, source_declarations
);
336 generate_property_accessor_declaration (((Property
) type_class
.scope
.lookup ("base_type")).set_accessor
, source_declarations
);
337 generate_property_accessor_declaration (((Property
) type_class
.scope
.lookup ("object_size")).get_accessor
, source_declarations
);
338 generate_property_accessor_declaration (((Property
) type_class
.scope
.lookup ("object_size")).set_accessor
, source_declarations
);
339 generate_property_accessor_declaration (((Property
) type_class
.scope
.lookup ("type_size")).get_accessor
, source_declarations
);
340 generate_property_accessor_declaration (((Property
) type_class
.scope
.lookup ("type_size")).set_accessor
, source_declarations
);
341 generate_property_accessor_declaration (((Property
) type_class
.scope
.lookup ("value_size")).set_accessor
, source_declarations
);
343 generate_class_declaration ((Class
) context
.root
.scope
.lookup ("Dova").scope
.lookup ("Value"), source_declarations
);
345 var base_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_value_type_get"));
347 var base_type_size
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_get_type_size"));
348 base_type_size
.add_argument (base_type
);
350 var calloc_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("calloc"));
351 calloc_call
.add_argument (new
CCodeConstant ("1"));
352 calloc_call
.add_argument (base_type_size
);
354 type_init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("%s_type".printf (st
.get_lower_case_cname ())), calloc_call
)));
356 generate_class_declaration ((Class
) object_class
, source_declarations
);
358 type_init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("%s_type".printf (st
.get_lower_case_cname ())), "DovaObject *"), "type"), new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_type_get")))));
360 var set_base_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_base_type"));
361 set_base_type
.add_argument (new
CCodeIdentifier ("%s_type".printf (st
.get_lower_case_cname ())));
362 set_base_type
.add_argument (base_type
);
363 type_init_block
.add_statement (new
CCodeExpressionStatement (set_base_type
));
365 var base_size
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_get_object_size"));
366 base_size
.add_argument (base_type
);
368 var sizeof_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("sizeof"));
369 sizeof_call
.add_argument (new
CCodeIdentifier (st
.get_cname ()));
370 var set_size
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_object_size"));
371 set_size
.add_argument (new
CCodeIdentifier ("%s_type".printf (st
.get_lower_case_cname ())));
372 set_size
.add_argument (new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, base_size
, sizeof_call
));
373 type_init_block
.add_statement (new
CCodeExpressionStatement (set_size
));
375 set_size
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_value_size"));
376 set_size
.add_argument (new
CCodeIdentifier ("%s_type".printf (st
.get_lower_case_cname ())));
377 set_size
.add_argument (sizeof_call
);
378 type_init_block
.add_statement (new
CCodeExpressionStatement (set_size
));
380 set_size
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_type_size"));
381 set_size
.add_argument (new
CCodeIdentifier ("%s_type".printf (st
.get_lower_case_cname ())));
382 set_size
.add_argument (base_type_size
);
383 type_init_block
.add_statement (new
CCodeExpressionStatement (set_size
));
385 var type_init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_type_init".printf (st
.get_lower_case_cname ())));
386 type_init_call
.add_argument (new
CCodeIdentifier ("%s_type".printf (st
.get_lower_case_cname ())));
387 type_init_block
.add_statement (new
CCodeExpressionStatement (type_init_call
));
389 type_fun
.block
.add_statement (new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("%s_type".printf (st
.get_lower_case_cname ()))), type_init_block
));
391 type_fun
.block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("%s_type".printf (st
.get_lower_case_cname ()))));
393 source_type_member_definition
.append (type_fun
);
395 var type_init_fun
= new
CCodeFunction ("%s_type_init".printf (st
.get_lower_case_cname ()));
396 type_init_fun
.add_parameter (new
CCodeFormalParameter ("type", "DovaType *"));
397 type_init_fun
.block
= new
CCodeBlock ();
399 type_init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_value_type_init"));
400 type_init_call
.add_argument (new
CCodeIdentifier ("type"));
401 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (type_init_call
));
403 declare_set_value_copy_function (source_declarations
);
405 var value_copy_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_value_copy"));
406 value_copy_call
.add_argument (new
CCodeIdentifier ("type"));
407 value_copy_call
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("%s_copy".printf (st
.get_lower_case_cname ())), "void (*)(void *, int32_t, void *, int32_t)"));
408 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (value_copy_call
));
410 if (st
.scope
.lookup ("equals") is Method
) {
411 var value_equals_fun
= new
CCodeFunction ("%s_value_equals".printf (st
.get_lower_case_cname ()), "bool");
412 value_equals_fun
.modifiers
= CCodeModifiers
.STATIC
;
413 value_equals_fun
.add_parameter (new
CCodeFormalParameter ("value", st
.get_cname () + "*"));
414 value_equals_fun
.add_parameter (new
CCodeFormalParameter ("value_index", "int32_t"));
415 value_equals_fun
.add_parameter (new
CCodeFormalParameter ("other", st
.get_cname () + "*"));
416 value_equals_fun
.add_parameter (new
CCodeFormalParameter ("other_index", "int32_t"));
417 value_equals_fun
.block
= new
CCodeBlock ();
418 var val
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("value"), new
CCodeIdentifier ("value_index"));
419 var other
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("other"), new
CCodeIdentifier ("other_index"));
420 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_equals".printf (st
.get_lower_case_cname ())));
421 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, val
));
422 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, other
));
423 value_equals_fun
.block
.add_statement (new
CCodeReturnStatement (ccall
));
424 source_type_member_definition
.append (value_equals_fun
);
426 declare_set_value_equals_function (source_declarations
);
428 var value_equals_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_value_equals"));
429 value_equals_call
.add_argument (new
CCodeIdentifier ("type"));
430 value_equals_call
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("%s_value_equals".printf (st
.get_lower_case_cname ())), "bool (*)(void *, int32_t, void *, int32_t)"));
431 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (value_equals_call
));
434 if (st
.scope
.lookup ("hash") is Method
) {
435 var value_hash_fun
= new
CCodeFunction ("%s_value_hash".printf (st
.get_lower_case_cname ()), "int32_t");
436 value_hash_fun
.modifiers
= CCodeModifiers
.STATIC
;
437 value_hash_fun
.add_parameter (new
CCodeFormalParameter ("value", st
.get_cname () + "*"));
438 value_hash_fun
.add_parameter (new
CCodeFormalParameter ("value_index", "int32_t"));
439 value_hash_fun
.block
= new
CCodeBlock ();
440 var val
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("value"), new
CCodeIdentifier ("value_index"));
441 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_hash".printf (st
.get_lower_case_cname ())));
442 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, val
));
443 value_hash_fun
.block
.add_statement (new
CCodeReturnStatement (ccall
));
444 source_type_member_definition
.append (value_hash_fun
);
446 declare_set_value_hash_function (source_declarations
);
448 var value_hash_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_value_hash"));
449 value_hash_call
.add_argument (new
CCodeIdentifier ("type"));
450 value_hash_call
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("%s_value_hash".printf (st
.get_lower_case_cname ())), "int32_t (*)(void *, int32_t)"));
451 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (value_hash_call
));
454 source_type_member_definition
.append (type_init_fun
);
456 add_struct_copy_function (st
);
459 void add_struct_copy_function (Struct st
) {
460 var function
= new
CCodeFunction (st
.get_copy_function (), "void");
461 if (st
.access
== SymbolAccessibility
.PRIVATE
) {
462 function
.modifiers
= CCodeModifiers
.STATIC
;
465 function
.add_parameter (new
CCodeFormalParameter ("dest", st
.get_cname () + "*"));
466 function
.add_parameter (new
CCodeFormalParameter ("dest_index", "int32_t"));
467 function
.add_parameter (new
CCodeFormalParameter ("src", st
.get_cname () + "*"));
468 function
.add_parameter (new
CCodeFormalParameter ("src_index", "int32_t"));
470 var cblock
= new
CCodeBlock ();
471 var cfrag
= new
CCodeFragment ();
472 cblock
.add_statement (cfrag
);
474 var dest
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("dest"), new
CCodeIdentifier ("dest_index"));
475 var src
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("src"), new
CCodeIdentifier ("src_index"));
477 foreach (var f
in st
.get_fields ()) {
478 if (f
.binding
== MemberBinding
.INSTANCE
) {
479 var field
= new CCodeMemberAccess
.pointer (dest
, f
.name
);
481 var array_type
= f
.field_type as ArrayType
;
482 if (array_type
!= null && array_type
.fixed_length
) {
483 for (int i
= 0; i
< array_type
.length
; i
++) {
484 var element
= new
CCodeElementAccess (field
, new
CCodeConstant (i
.to_string ()));
486 if (requires_destroy (array_type
.element_type
)) {
487 cblock
.add_statement (new
CCodeExpressionStatement (get_unref_expression (element
, array_type
.element_type
)));
493 if (requires_destroy (f
.field_type
)) {
494 var this_access
= new MemberAccess
.simple ("this");
495 this_access
.value_type
= get_data_type_for_symbol ((TypeSymbol
) f
.parent_symbol
);
496 this_access
.ccodenode
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, dest
);
497 var ma
= new
MemberAccess (this_access
, f
.name
);
498 ma
.symbol_reference
= f
;
499 ma
.value_type
= f
.field_type
.copy ();
500 cblock
.add_statement (new
CCodeExpressionStatement (get_unref_expression (field
, f
.field_type
, ma
)));
505 var copy_block
= new
CCodeBlock ();
507 if (st
.get_fields ().size
== 0) {
508 copy_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, dest
), new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, src
))));
510 foreach (var f
in st
.get_fields ()) {
511 if (f
.binding
== MemberBinding
.INSTANCE
) {
512 CCodeExpression copy
= new CCodeMemberAccess
.pointer (src
, f
.name
);
513 var dest_field
= new CCodeMemberAccess
.pointer (dest
, f
.name
);
515 var array_type
= f
.field_type as ArrayType
;
516 if (array_type
!= null && array_type
.fixed_length
) {
517 for (int i
= 0; i
< array_type
.length
; i
++) {
518 CCodeExpression copy_element
= new
CCodeElementAccess (copy
, new
CCodeConstant (i
.to_string ()));
519 var dest_field_element
= new
CCodeElementAccess (dest_field
, new
CCodeConstant (i
.to_string ()));
521 if (requires_copy (array_type
.element_type
)) {
522 copy_element
= get_ref_cexpression (array_type
.element_type
, copy_element
, null, f
);
525 copy_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (dest_field_element
, copy_element
)));
530 if (requires_copy (f
.field_type
)) {
531 var this_access
= new MemberAccess
.simple ("this");
532 this_access
.value_type
= get_data_type_for_symbol ((TypeSymbol
) f
.parent_symbol
);
533 this_access
.ccodenode
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, src
);
534 var ma
= new
MemberAccess (this_access
, f
.name
);
535 ma
.symbol_reference
= f
;
536 copy
= get_ref_cexpression (f
.field_type
, copy
, ma
, f
);
539 copy_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (dest_field
, copy
)));
544 cblock
.add_statement (new
CCodeIfStatement (new
CCodeIdentifier ("src"), copy_block
));
546 append_temp_decl (cfrag
, temp_vars
);
549 function
.block
= cblock
;
551 source_type_member_definition
.append (function
);
554 public override void visit_assignment (Assignment assignment
) {
555 var generic_type
= assignment
.left
.value_type as GenericType
;
556 if (generic_type
== null) {
557 base.visit_assignment (assignment
);
561 var dest
= assignment
.left
;
562 CCodeExpression cdest
;
563 CCodeExpression dest_index
= new
CCodeConstant ("0");
564 var src
= assignment
.right
;
565 CCodeExpression csrc
;
566 CCodeExpression src_index
= new
CCodeConstant ("0");
568 if (src is NullLiteral
) {
570 assignment
.ccodenode
= new
CCodeConstant ("0");
574 var dest_ea
= dest as ElementAccess
;
575 var src_ea
= src as ElementAccess
;
577 if (dest_ea
!= null) {
578 dest
= dest_ea
.container
;
580 var array_type
= dest
.value_type as ArrayType
;
581 if (array_type
!= null && !array_type
.inline_allocated
) {
582 generate_property_accessor_declaration (((Property
) array_class
.scope
.lookup ("data")).get_accessor
, source_declarations
);
584 var data_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_array_get_data"));
585 data_call
.add_argument ((CCodeExpression
) get_ccodenode (dest
));
588 cdest
= (CCodeExpression
) get_ccodenode (dest
);
590 dest_index
= (CCodeExpression
) get_ccodenode (dest_ea
.get_indices ().get (0));
592 cdest
= (CCodeExpression
) get_ccodenode (dest
);
595 if (src_ea
!= null) {
596 src
= src_ea
.container
;
598 var array_type
= src
.value_type as ArrayType
;
599 if (array_type
!= null && !array_type
.inline_allocated
) {
600 generate_property_accessor_declaration (((Property
) array_class
.scope
.lookup ("data")).get_accessor
, source_declarations
);
602 var data_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_array_get_data"));
603 data_call
.add_argument ((CCodeExpression
) get_ccodenode (src
));
606 csrc
= (CCodeExpression
) get_ccodenode (src
);
608 src_index
= (CCodeExpression
) get_ccodenode (src_ea
.get_indices ().get (0));
610 csrc
= (CCodeExpression
) get_ccodenode (src
);
613 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_value_copy"));
614 if (generic_type
.type_parameter
.parent_symbol is TypeSymbol
) {
616 ccall
.add_argument (new CCodeMemberAccess
.pointer (get_type_private_from_type ((ObjectTypeSymbol
) generic_type
.type_parameter
.parent_symbol
, new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("this"), "type")), "%s_type".printf (generic_type
.type_parameter
.name
.down ())));
619 ccall
.add_argument (new
CCodeIdentifier ("%s_type".printf (generic_type
.type_parameter
.name
.down ())));
621 ccall
.add_argument (cdest
);
622 ccall
.add_argument (dest_index
);
623 ccall
.add_argument (csrc
);
624 ccall
.add_argument (src_index
);
625 assignment
.ccodenode
= ccall
;
628 public override void visit_binary_expression (BinaryExpression expr
) {
629 var generic_type
= expr
.left
.value_type as GenericType
;
630 if (generic_type
== null) {
631 base.visit_binary_expression (expr
);
635 CCodeExpression cleft
;
636 CCodeExpression left_index
= new
CCodeConstant ("0");
637 CCodeExpression cright
;
638 CCodeExpression right_index
= new
CCodeConstant ("0");
640 var left_ea
= expr
.left as ElementAccess
;
641 var right_ea
= expr
.right as ElementAccess
;
643 if (left_ea
!= null) {
644 generate_property_accessor_declaration (((Property
) array_class
.scope
.lookup ("data")).get_accessor
, source_declarations
);
646 var data_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_array_get_data"));
647 data_call
.add_argument ((CCodeExpression
) get_ccodenode (left_ea
.container
));
649 left_index
= (CCodeExpression
) get_ccodenode (left_ea
.get_indices ().get (0));
651 cleft
= (CCodeExpression
) get_ccodenode (expr
.left
);
654 if (right_ea
!= null) {
655 generate_property_accessor_declaration (((Property
) array_class
.scope
.lookup ("data")).get_accessor
, source_declarations
);
657 var data_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_array_get_data"));
658 data_call
.add_argument ((CCodeExpression
) get_ccodenode (right_ea
.container
));
660 right_index
= (CCodeExpression
) get_ccodenode (right_ea
.get_indices ().get (0));
662 cright
= (CCodeExpression
) get_ccodenode (expr
.right
);
665 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_value_equals"));
666 ccall
.add_argument (get_type_id_expression (generic_type
));
667 ccall
.add_argument (cleft
);
668 ccall
.add_argument (left_index
);
669 ccall
.add_argument (cright
);
670 ccall
.add_argument (right_index
);
672 if (expr
.operator
== BinaryOperator
.EQUALITY
) {
673 expr
.ccodenode
= ccall
;
675 expr
.ccodenode
= new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, ccall
);
679 bool is_comparison (Expression expr
) {
680 var binary_expression
= expr as BinaryExpression
;
681 if (binary_expression
!= null) {
682 switch (binary_expression
.operator
) {
683 case BinaryOperator
.LESS_THAN
:
684 case BinaryOperator
.GREATER_THAN
:
685 case BinaryOperator
.LESS_THAN_OR_EQUAL
:
686 case BinaryOperator
.GREATER_THAN_OR_EQUAL
:
687 case BinaryOperator
.EQUALITY
:
688 case BinaryOperator
.INEQUALITY
:
697 bool handle_assert (MethodCall expr
) {
698 var args
= expr
.get_argument_list ();
699 var mtype
= expr
.call
.value_type as MethodType
;
700 if (mtype
== null || mtype
.method_symbol
.get_cname () != "dova_assert" ||
701 !(args
.get (1) is NullLiteral
) ||
702 !is_comparison (args
.get (0))) {
706 expr
.accept_children (codegen
);
708 var binary_expression
= (BinaryExpression
) args
.get (0);
709 var op1
= binary_expression
.left
;
710 var op2
= binary_expression
.right
;
712 var type
= op1
.value_type
.data_type
;
714 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_assert".printf (type
.get_lower_case_cname ())));
715 ccall
.add_argument ((CCodeExpression
) get_ccodenode (op1
));
716 ccall
.add_argument (new
CCodeConstant (binary_expression
.get_operator_string ()));
717 ccall
.add_argument ((CCodeExpression
) get_ccodenode (op2
));
718 expr
.ccodenode
= ccall
;
723 public override void visit_method_call (MethodCall expr
) {
724 if (handle_assert (expr
)) {
728 var ma
= expr
.call as MemberAccess
;
729 if (ma
== null || ma
.inner
== null || !(ma
.inner
.value_type is GenericType
)) {
730 base.visit_method_call (expr
);
734 // handle method calls on generic types
736 expr
.accept_children (codegen
);
738 if (ma
.member_name
== "hash") {
740 CCodeExpression cval
;
741 CCodeExpression val_index
= new
CCodeConstant ("0");
743 var val_ea
= val as ElementAccess
;
744 if (val_ea
!= null) {
745 val
= val_ea
.container
;
747 generate_property_accessor_declaration (((Property
) array_class
.scope
.lookup ("data")).get_accessor
, source_declarations
);
749 var data_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_array_get_data"));
750 data_call
.add_argument ((CCodeExpression
) get_ccodenode (val
));
752 val_index
= (CCodeExpression
) get_ccodenode (val_ea
.get_indices ().get (0));
754 cval
= (CCodeExpression
) get_ccodenode (val
);
757 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_value_hash"));
758 ccall
.add_argument (get_type_id_expression (ma
.inner
.value_type
));
759 ccall
.add_argument (cval
);
760 ccall
.add_argument (val_index
);
762 expr
.ccodenode
= ccall
;
766 public override void visit_list_literal (ListLiteral expr
) {
767 expr
.accept_children (codegen
);
769 var array_type
= new
ArrayType (expr
.element_type
, 1, expr
.source_reference
);
770 array_type
.inline_allocated
= true;
771 array_type
.fixed_length
= true;
772 array_type
.length
= expr
.get_expressions ().size
;
774 var ce
= new
CCodeCommaExpression ();
775 var temp_var
= get_temp_variable (array_type
, true, expr
);
776 var name_cnode
= get_variable_cexpression (temp_var
.name
);
778 temp_vars
.insert (0, temp_var
);
781 foreach (Expression e
in expr
.get_expressions ()) {
782 ce
.append_expression (new
CCodeAssignment (new
CCodeElementAccess (name_cnode
, new
CCodeConstant (i
.to_string ())), (CCodeExpression
) e
.ccodenode
));
786 ce
.append_expression (name_cnode
);
788 var list_creation
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_list_new"));
789 list_creation
.add_argument (get_type_id_expression (expr
.element_type
));
790 list_creation
.add_argument (new
CCodeConstant (array_type
.length
.to_string ()));
791 list_creation
.add_argument (ce
);
793 expr
.ccodenode
= list_creation
;
796 public override void visit_set_literal (SetLiteral expr
) {
797 expr
.accept_children (codegen
);
799 var array_type
= new
ArrayType (expr
.element_type
, 1, expr
.source_reference
);
800 array_type
.inline_allocated
= true;
801 array_type
.fixed_length
= true;
802 array_type
.length
= expr
.get_expressions ().size
;
804 var ce
= new
CCodeCommaExpression ();
805 var temp_var
= get_temp_variable (array_type
, true, expr
);
806 var name_cnode
= get_variable_cexpression (temp_var
.name
);
808 temp_vars
.insert (0, temp_var
);
811 foreach (Expression e
in expr
.get_expressions ()) {
812 ce
.append_expression (new
CCodeAssignment (new
CCodeElementAccess (name_cnode
, new
CCodeConstant (i
.to_string ())), (CCodeExpression
) e
.ccodenode
));
816 ce
.append_expression (name_cnode
);
818 var set_creation
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_set_new"));
819 set_creation
.add_argument (get_type_id_expression (expr
.element_type
));
820 set_creation
.add_argument (new
CCodeConstant (array_type
.length
.to_string ()));
821 set_creation
.add_argument (ce
);
823 expr
.ccodenode
= set_creation
;
826 public override void visit_map_literal (MapLiteral expr
) {
827 expr
.accept_children (codegen
);
829 var key_array_type
= new
ArrayType (expr
.map_key_type
, 1, expr
.source_reference
);
830 key_array_type
.inline_allocated
= true;
831 key_array_type
.fixed_length
= true;
832 key_array_type
.length
= expr
.get_keys ().size
;
834 var key_ce
= new
CCodeCommaExpression ();
835 var key_temp_var
= get_temp_variable (key_array_type
, true, expr
);
836 var key_name_cnode
= get_variable_cexpression (key_temp_var
.name
);
838 temp_vars
.insert (0, key_temp_var
);
840 var value_array_type
= new
ArrayType (expr
.map_value_type
, 1, expr
.source_reference
);
841 value_array_type
.inline_allocated
= true;
842 value_array_type
.fixed_length
= true;
843 value_array_type
.length
= expr
.get_values ().size
;
845 var value_ce
= new
CCodeCommaExpression ();
846 var value_temp_var
= get_temp_variable (value_array_type
, true, expr
);
847 var value_name_cnode
= get_variable_cexpression (value_temp_var
.name
);
849 temp_vars
.insert (0, value_temp_var
);
851 for (int i
= 0; i
< expr
.get_keys ().size
; i
++) {
852 key_ce
.append_expression (new
CCodeAssignment (new
CCodeElementAccess (key_name_cnode
, new
CCodeConstant (i
.to_string ())), (CCodeExpression
) expr
.get_keys ().get (i
).ccodenode
));
853 value_ce
.append_expression (new
CCodeAssignment (new
CCodeElementAccess (value_name_cnode
, new
CCodeConstant (i
.to_string ())), (CCodeExpression
) expr
.get_values ().get (i
).ccodenode
));
856 key_ce
.append_expression (key_name_cnode
);
857 value_ce
.append_expression (value_name_cnode
);
859 var map_creation
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_map_new"));
860 map_creation
.add_argument (get_type_id_expression (expr
.map_key_type
));
861 map_creation
.add_argument (get_type_id_expression (expr
.map_value_type
));
862 map_creation
.add_argument (new
CCodeConstant (key_array_type
.length
.to_string ()));
863 map_creation
.add_argument (key_ce
);
864 map_creation
.add_argument (value_ce
);
866 expr
.ccodenode
= map_creation
;
869 public override void visit_tuple (Tuple tuple
) {
870 tuple
.accept_children (codegen
);
872 var type_array_type
= new
ArrayType (new
PointerType (new
VoidType ()), 1, tuple
.source_reference
);
873 type_array_type
.inline_allocated
= true;
874 type_array_type
.fixed_length
= true;
875 type_array_type
.length
= tuple
.get_expressions ().size
;
877 var type_temp_var
= get_temp_variable (type_array_type
, true, tuple
);
878 var type_name_cnode
= get_variable_cexpression (type_temp_var
.name
);
879 temp_vars
.insert (0, type_temp_var
);
881 var array_type
= new
ArrayType (new
PointerType (new
VoidType ()), 1, tuple
.source_reference
);
882 array_type
.inline_allocated
= true;
883 array_type
.fixed_length
= true;
884 array_type
.length
= tuple
.get_expressions ().size
;
886 var temp_var
= get_temp_variable (array_type
, true, tuple
);
887 var name_cnode
= get_variable_cexpression (temp_var
.name
);
888 temp_vars
.insert (0, temp_var
);
890 var type_ce
= new
CCodeCommaExpression ();
891 var ce
= new
CCodeCommaExpression ();
894 foreach (Expression e
in tuple
.get_expressions ()) {
895 var element_type
= tuple
.value_type
.get_type_arguments ().get (i
);
897 type_ce
.append_expression (new
CCodeAssignment (new
CCodeElementAccess (type_name_cnode
, new
CCodeConstant (i
.to_string ())), get_type_id_expression (element_type
)));
899 var cexpr
= (CCodeExpression
) e
.ccodenode
;
901 var unary
= cexpr as CCodeUnaryExpression
;
902 if (unary
!= null && unary
.operator
== CCodeUnaryOperator
.POINTER_INDIRECTION
) {
905 } else if (cexpr is CCodeIdentifier
|| cexpr is CCodeMemberAccess
) {
906 cexpr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, cexpr
);
908 // if cexpr is e.g. a function call, we can't take the address of the expression
911 var element_temp_var
= get_temp_variable (element_type
);
912 temp_vars
.insert (0, element_temp_var
);
913 ce
.append_expression (new
CCodeAssignment (get_variable_cexpression (element_temp_var
.name
), cexpr
));
914 cexpr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (element_temp_var
.name
));
917 ce
.append_expression (new
CCodeAssignment (new
CCodeElementAccess (name_cnode
, new
CCodeConstant (i
.to_string ())), cexpr
));
922 type_ce
.append_expression (type_name_cnode
);
923 ce
.append_expression (name_cnode
);
925 var tuple_creation
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_tuple_new"));
926 tuple_creation
.add_argument (new
CCodeConstant (tuple
.get_expressions ().size
.to_string ()));
927 tuple_creation
.add_argument (type_ce
);
928 tuple_creation
.add_argument (ce
);
930 tuple
.ccodenode
= tuple_creation
;