2 * Copyright (c) 2011 Jiri Svoboda
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 /** @file Run expressions. */
42 #include "run_texpr.h"
50 static void run_nameref(run_t
*run
, stree_nameref_t
*nameref
,
53 static void run_literal(run_t
*run
, stree_literal_t
*literal
,
55 static void run_lit_bool(run_t
*run
, stree_lit_bool_t
*lit_bool
,
57 static void run_lit_char(run_t
*run
, stree_lit_char_t
*lit_char
,
59 static void run_lit_int(run_t
*run
, stree_lit_int_t
*lit_int
,
61 static void run_lit_ref(run_t
*run
, stree_lit_ref_t
*lit_ref
,
63 static void run_lit_string(run_t
*run
, stree_lit_string_t
*lit_string
,
66 static void run_self_ref(run_t
*run
, stree_self_ref_t
*self_ref
,
69 static void run_binop(run_t
*run
, stree_binop_t
*binop
, rdata_item_t
**res
);
70 static void run_binop_bool(run_t
*run
, stree_binop_t
*binop
, rdata_value_t
*v1
,
71 rdata_value_t
*v2
, rdata_item_t
**res
);
72 static void run_binop_char(run_t
*run
, stree_binop_t
*binop
, rdata_value_t
*v1
,
73 rdata_value_t
*v2
, rdata_item_t
**res
);
74 static void run_binop_int(run_t
*run
, stree_binop_t
*binop
, rdata_value_t
*v1
,
75 rdata_value_t
*v2
, rdata_item_t
**res
);
76 static void run_binop_string(run_t
*run
, stree_binop_t
*binop
, rdata_value_t
*v1
,
77 rdata_value_t
*v2
, rdata_item_t
**res
);
78 static void run_binop_ref(run_t
*run
, stree_binop_t
*binop
, rdata_value_t
*v1
,
79 rdata_value_t
*v2
, rdata_item_t
**res
);
80 static void run_binop_enum(run_t
*run
, stree_binop_t
*binop
, rdata_value_t
*v1
,
81 rdata_value_t
*v2
, rdata_item_t
**res
);
83 static void run_unop(run_t
*run
, stree_unop_t
*unop
, rdata_item_t
**res
);
84 static void run_unop_bool(run_t
*run
, stree_unop_t
*unop
, rdata_value_t
*val
,
86 static void run_unop_int(run_t
*run
, stree_unop_t
*unop
, rdata_value_t
*val
,
89 static void run_new(run_t
*run
, stree_new_t
*new_op
, rdata_item_t
**res
);
90 static void run_new_array(run_t
*run
, stree_new_t
*new_op
,
91 tdata_item_t
*titem
, rdata_item_t
**res
);
92 static void run_new_object(run_t
*run
, stree_new_t
*new_op
,
93 tdata_item_t
*titem
, rdata_item_t
**res
);
95 static void run_object_ctor(run_t
*run
, rdata_var_t
*obj
, list_t
*arg_vals
);
97 static void run_access(run_t
*run
, stree_access_t
*access
, rdata_item_t
**res
);
98 static void run_access_item(run_t
*run
, stree_access_t
*access
,
99 rdata_item_t
*arg
, rdata_item_t
**res
);
100 static void run_access_ref(run_t
*run
, stree_access_t
*access
,
101 rdata_item_t
*arg
, rdata_item_t
**res
);
102 static void run_access_deleg(run_t
*run
, stree_access_t
*access
,
103 rdata_item_t
*arg
, rdata_item_t
**res
);
104 static void run_access_object(run_t
*run
, stree_access_t
*access
,
105 rdata_item_t
*arg
, rdata_item_t
**res
);
106 static void run_access_object_static(run_t
*run
, stree_access_t
*access
,
107 rdata_var_t
*obj_var
, rdata_item_t
**res
);
108 static void run_access_object_nonstatic(run_t
*run
, stree_access_t
*access
,
109 rdata_var_t
*obj_var
, rdata_item_t
**res
);
110 static void run_access_symbol(run_t
*run
, stree_access_t
*access
,
111 rdata_item_t
*arg
, rdata_item_t
**res
);
113 static void run_call(run_t
*run
, stree_call_t
*call
, rdata_item_t
**res
);
114 static void run_call_args(run_t
*run
, list_t
*args
, list_t
*arg_vals
);
115 static void run_destroy_arg_vals(list_t
*arg_vals
);
117 static void run_index(run_t
*run
, stree_index_t
*index
, rdata_item_t
**res
);
118 static void run_index_array(run_t
*run
, stree_index_t
*index
,
119 rdata_item_t
*base
, list_t
*args
, rdata_item_t
**res
);
120 static void run_index_object(run_t
*run
, stree_index_t
*index
,
121 rdata_item_t
*base
, list_t
*args
, rdata_item_t
**res
);
122 static void run_index_string(run_t
*run
, stree_index_t
*index
,
123 rdata_item_t
*base
, list_t
*args
, rdata_item_t
**res
);
124 static void run_assign(run_t
*run
, stree_assign_t
*assign
, rdata_item_t
**res
);
125 static void run_as(run_t
*run
, stree_as_t
*as_op
, rdata_item_t
**res
);
126 static void run_box(run_t
*run
, stree_box_t
*box
, rdata_item_t
**res
);
128 /** Evaluate expression.
130 * Run the expression @a expr and store pointer to the result in *(@a res).
131 * If the expression has on value (assignment) then @c NULL is returned.
132 * @c NULL is also returned if an error or exception occurs.
134 * @param run Runner object
135 * @param expr Expression to run
136 * @param res Place to store result
138 void run_expr(run_t
*run
, stree_expr_t
*expr
, rdata_item_t
**res
)
140 #ifdef DEBUG_RUN_TRACE
141 printf("Executing expression.\n");
146 run_nameref(run
, expr
->u
.nameref
, res
);
149 run_literal(run
, expr
->u
.literal
, res
);
152 run_self_ref(run
, expr
->u
.self_ref
, res
);
155 run_binop(run
, expr
->u
.binop
, res
);
158 run_unop(run
, expr
->u
.unop
, res
);
161 run_new(run
, expr
->u
.new_op
, res
);
164 run_access(run
, expr
->u
.access
, res
);
167 run_call(run
, expr
->u
.call
, res
);
170 run_index(run
, expr
->u
.index
, res
);
173 run_assign(run
, expr
->u
.assign
, res
);
176 run_as(run
, expr
->u
.as_op
, res
);
179 run_box(run
, expr
->u
.box
, res
);
183 #ifdef DEBUG_RUN_TRACE
184 printf("Expression result: ");
185 rdata_item_print(*res
);
190 /** Evaluate name reference expression.
192 * @param run Runner object
193 * @param nameref Name reference
194 * @param res Place to store result
196 static void run_nameref(run_t
*run
, stree_nameref_t
*nameref
,
201 rdata_address_t
*address
;
202 rdata_addr_var_t
*addr_var
;
203 rdata_addr_prop_t
*addr_prop
;
204 rdata_aprop_named_t
*aprop_named
;
205 rdata_deleg_t
*deleg_p
;
206 rdata_value_t
*value
;
208 rdata_deleg_t
*deleg_v
;
209 rdata_symbol_t
*symbol_v
;
211 run_proc_ar_t
*proc_ar
;
212 stree_symbol_t
*csi_sym
;
215 rdata_var_t
*member_var
;
219 rdata_object_t
*aobj
;
221 #ifdef DEBUG_RUN_TRACE
222 printf("Run nameref.\n");
226 * Look for a local variable.
228 var
= run_local_vars_lookup(run
, nameref
->name
->sid
);
230 /* Found a local variable. */
231 item
= rdata_item_new(ic_address
);
232 address
= rdata_address_new(ac_var
);
233 addr_var
= rdata_addr_var_new();
235 item
->u
.address
= address
;
236 address
->u
.var_a
= addr_var
;
237 addr_var
->vref
= var
;
240 #ifdef DEBUG_RUN_TRACE
241 printf("Found local variable.\n");
247 * Look for a class-wide or global symbol.
250 /* Determine currently active object or CSI. */
251 proc_ar
= run_get_current_proc_ar(run
);
253 assert (proc_ar
->obj
!= NULL
);
254 assert(proc_ar
->obj
->vc
== vc_object
);
255 obj
= proc_ar
->obj
->u
.object_v
;
256 csi_sym
= obj
->class_sym
;
258 if (csi_sym
!= NULL
) {
259 csi
= symbol_to_csi(csi_sym
);
262 /* This happens in interactive mode. */
266 sym
= symbol_lookup_in_csi(run
->program
, csi
, nameref
->name
);
268 /* Existence should have been verified in type checking phase. */
273 #ifdef DEBUG_RUN_TRACE
274 printf("Referencing CSI.\n");
276 /* Obtain static object for the referenced CSI. */
277 psobj
= run
->gdata
; /* XXX */
278 sobj
= run_sobject_get(run
, sym
->u
.csi
, psobj
,
281 /* Return reference to the object. */
282 run_reference(run
, sobj
, res
);
285 /* It is not possible to reference a constructor explicitly. */
289 #ifdef DEBUG_RUN_TRACE
290 printf("Referencing enum.\n");
292 item
= rdata_item_new(ic_value
);
293 value
= rdata_value_new();
294 var
= rdata_var_new(vc_symbol
);
295 symbol_v
= rdata_symbol_new();
297 item
->u
.value
= value
;
299 var
->u
.symbol_v
= symbol_v
;
306 printf("Unimplemented: Delegate name reference.\n");
310 /* There should be no global functions. */
313 if (symbol_search_csi(run
->program
, csi
, nameref
->name
) ==
315 /* Function is not in the current object. */
316 printf("Error: Cannot access non-static member "
318 symbol_print_fqn(sym
);
319 printf("' from nested CSI '");
320 symbol_print_fqn(csi_sym
);
325 /* Construct delegate. */
326 item
= rdata_item_new(ic_value
);
327 value
= rdata_value_new();
328 item
->u
.value
= value
;
330 var
= rdata_var_new(vc_deleg
);
331 deleg_v
= rdata_deleg_new();
333 var
->u
.deleg_v
= deleg_v
;
335 deleg_v
->obj
= proc_ar
->obj
;
342 #ifdef DEBUG_RUN_TRACE
343 if (sym
->sc
== sc_var
)
344 printf("Referencing member variable.\n");
346 printf("Referencing unqualified property.\n");
348 /* There should be no global variables or properties. */
351 if (symbol_search_csi(run
->program
, csi
, nameref
->name
) ==
352 NULL
&& !stree_symbol_is_static(sym
)) {
353 /* Symbol is not in the current object. */
354 printf("Error: Cannot access non-static member "
356 symbol_print_fqn(sym
);
357 printf("' from nested CSI '");
358 symbol_print_fqn(csi_sym
);
364 * Determine object in which the symbol resides
366 if (stree_symbol_is_static(sym
)) {
369 * XXX This is too slow!
371 * However fixing this is non-trivial. We would
372 * have to have pointer to static object available
373 * for each object (therefore also for each object
376 sobj
= run_sobject_find(run
, sym
->outer_csi
);
377 assert(sobj
->vc
== vc_object
);
378 aobj
= sobj
->u
.object_v
;
381 * Instance object. Currently we don't support
382 * true inner classes, thus we know the symbol is
383 * in the active object (there is no dynamic parent).
386 aobj
= sobj
->u
.object_v
;
389 if (sym
->sc
== sc_var
) {
390 /* Find member variable in object. */
391 member_var
= intmap_get(&aobj
->fields
,
393 assert(member_var
!= NULL
);
395 /* Return address of the variable. */
396 item
= rdata_item_new(ic_address
);
397 address
= rdata_address_new(ac_var
);
398 addr_var
= rdata_addr_var_new();
400 item
->u
.address
= address
;
401 address
->u
.var_a
= addr_var
;
402 addr_var
->vref
= member_var
;
406 /* Construct named property address. */
407 item
= rdata_item_new(ic_address
);
408 address
= rdata_address_new(ac_prop
);
409 addr_prop
= rdata_addr_prop_new(apc_named
);
410 aprop_named
= rdata_aprop_named_new();
411 item
->u
.address
= address
;
412 address
->u
.prop_a
= addr_prop
;
413 addr_prop
->u
.named
= aprop_named
;
415 deleg_p
= rdata_deleg_new();
418 addr_prop
->u
.named
->prop_d
= deleg_p
;
426 /** Evaluate literal.
428 * @param run Runner object
429 * @param literal Literal
430 * @param res Place to store result
432 static void run_literal(run_t
*run
, stree_literal_t
*literal
,
435 #ifdef DEBUG_RUN_TRACE
436 printf("Run literal.\n");
438 switch (literal
->ltc
) {
440 run_lit_bool(run
, &literal
->u
.lit_bool
, res
);
443 run_lit_char(run
, &literal
->u
.lit_char
, res
);
446 run_lit_int(run
, &literal
->u
.lit_int
, res
);
449 run_lit_ref(run
, &literal
->u
.lit_ref
, res
);
452 run_lit_string(run
, &literal
->u
.lit_string
, res
);
457 /** Evaluate Boolean literal.
459 * @param run Runner object
460 * @param lit_bool Boolean literal
461 * @param res Place to store result
463 static void run_lit_bool(run_t
*run
, stree_lit_bool_t
*lit_bool
,
467 rdata_value_t
*value
;
469 rdata_bool_t
*bool_v
;
471 #ifdef DEBUG_RUN_TRACE
472 printf("Run Boolean literal.\n");
476 item
= rdata_item_new(ic_value
);
477 value
= rdata_value_new();
478 var
= rdata_var_new(vc_bool
);
479 bool_v
= rdata_bool_new();
481 item
->u
.value
= value
;
483 var
->u
.bool_v
= bool_v
;
484 bool_v
->value
= lit_bool
->value
;
489 /** Evaluate character literal. */
490 static void run_lit_char(run_t
*run
, stree_lit_char_t
*lit_char
,
494 rdata_value_t
*value
;
496 rdata_char_t
*char_v
;
498 #ifdef DEBUG_RUN_TRACE
499 printf("Run character literal.\n");
503 item
= rdata_item_new(ic_value
);
504 value
= rdata_value_new();
505 var
= rdata_var_new(vc_char
);
506 char_v
= rdata_char_new();
508 item
->u
.value
= value
;
510 var
->u
.char_v
= char_v
;
511 bigint_clone(&lit_char
->value
, &char_v
->value
);
516 /** Evaluate integer literal.
518 * @param run Runner object
519 * @param lit_int Integer literal
520 * @param res Place to store result
522 static void run_lit_int(run_t
*run
, stree_lit_int_t
*lit_int
,
526 rdata_value_t
*value
;
530 #ifdef DEBUG_RUN_TRACE
531 printf("Run integer literal.\n");
535 item
= rdata_item_new(ic_value
);
536 value
= rdata_value_new();
537 var
= rdata_var_new(vc_int
);
538 int_v
= rdata_int_new();
540 item
->u
.value
= value
;
542 var
->u
.int_v
= int_v
;
543 bigint_clone(&lit_int
->value
, &int_v
->value
);
548 /** Evaluate reference literal (@c nil).
550 * @param run Runner object
551 * @param lit_ref Reference literal
552 * @param res Place to store result
554 static void run_lit_ref(run_t
*run
, stree_lit_ref_t
*lit_ref
,
558 rdata_value_t
*value
;
562 #ifdef DEBUG_RUN_TRACE
563 printf("Run reference literal (nil).\n");
568 item
= rdata_item_new(ic_value
);
569 value
= rdata_value_new();
570 var
= rdata_var_new(vc_ref
);
571 ref_v
= rdata_ref_new();
573 item
->u
.value
= value
;
575 var
->u
.ref_v
= ref_v
;
581 /** Evaluate string literal.
583 * @param run Runner object
584 * @param lit_string String literal
585 * @param res Place to store result
587 static void run_lit_string(run_t
*run
, stree_lit_string_t
*lit_string
,
591 rdata_value_t
*value
;
593 rdata_string_t
*string_v
;
595 #ifdef DEBUG_RUN_TRACE
596 printf("Run integer literal.\n");
600 item
= rdata_item_new(ic_value
);
601 value
= rdata_value_new();
602 var
= rdata_var_new(vc_string
);
603 string_v
= rdata_string_new();
605 item
->u
.value
= value
;
607 var
->u
.string_v
= string_v
;
608 string_v
->value
= lit_string
->value
;
613 /** Evaluate @c self reference.
615 * @param run Runner object
616 * @param self_ref Self reference
617 * @param res Place to store result
619 static void run_self_ref(run_t
*run
, stree_self_ref_t
*self_ref
,
622 run_proc_ar_t
*proc_ar
;
624 #ifdef DEBUG_RUN_TRACE
625 printf("Run self reference.\n");
628 proc_ar
= run_get_current_proc_ar(run
);
630 /* Return reference to the currently active object. */
631 run_reference(run
, proc_ar
->obj
, res
);
634 /** Evaluate binary operation.
636 * @param run Runner object
637 * @param binop Binary operation
638 * @param res Place to store result
640 static void run_binop(run_t
*run
, stree_binop_t
*binop
, rdata_item_t
**res
)
642 rdata_item_t
*rarg1_i
, *rarg2_i
;
643 rdata_item_t
*rarg1_vi
, *rarg2_vi
;
644 rdata_value_t
*v1
, *v2
;
651 #ifdef DEBUG_RUN_TRACE
652 printf("Run binary operation.\n");
654 run_expr(run
, binop
->arg1
, &rarg1_i
);
655 if (run_is_bo(run
)) {
656 *res
= run_recovery_item(run
);
660 #ifdef DEBUG_RUN_TRACE
661 printf("Check binop argument result.\n");
663 run_cvt_value_item(run
, rarg1_i
, &rarg1_vi
);
664 if (run_is_bo(run
)) {
665 *res
= run_recovery_item(run
);
669 run_expr(run
, binop
->arg2
, &rarg2_i
);
670 if (run_is_bo(run
)) {
671 *res
= run_recovery_item(run
);
675 #ifdef DEBUG_RUN_TRACE
676 printf("Check binop argument result.\n");
678 run_cvt_value_item(run
, rarg2_i
, &rarg2_vi
);
679 if (run_is_bo(run
)) {
680 *res
= run_recovery_item(run
);
684 v1
= rarg1_vi
->u
.value
;
685 v2
= rarg2_vi
->u
.value
;
687 if (v1
->var
->vc
!= v2
->var
->vc
) {
688 printf("Unimplemented: Binary operation arguments have "
689 "different type.\n");
693 switch (v1
->var
->vc
) {
695 run_binop_bool(run
, binop
, v1
, v2
, res
);
698 run_binop_char(run
, binop
, v1
, v2
, res
);
701 run_binop_int(run
, binop
, v1
, v2
, res
);
704 run_binop_string(run
, binop
, v1
, v2
, res
);
707 run_binop_ref(run
, binop
, v1
, v2
, res
);
710 run_binop_enum(run
, binop
, v1
, v2
, res
);
722 rdata_item_destroy(rarg1_i
);
724 rdata_item_destroy(rarg2_i
);
725 if (rarg1_vi
!= NULL
)
726 rdata_item_destroy(rarg1_vi
);
727 if (rarg2_vi
!= NULL
)
728 rdata_item_destroy(rarg2_vi
);
731 /** Evaluate binary operation on bool arguments.
733 * @param run Runner object
734 * @param binop Binary operation
735 * @param v1 Value of first argument
736 * @param v2 Value of second argument
737 * @param res Place to store result
739 static void run_binop_bool(run_t
*run
, stree_binop_t
*binop
, rdata_value_t
*v1
,
740 rdata_value_t
*v2
, rdata_item_t
**res
)
743 rdata_value_t
*value
;
745 rdata_bool_t
*bool_v
;
751 item
= rdata_item_new(ic_value
);
752 value
= rdata_value_new();
753 var
= rdata_var_new(vc_bool
);
754 bool_v
= rdata_bool_new();
756 item
->u
.value
= value
;
758 var
->u
.bool_v
= bool_v
;
760 b1
= v1
->var
->u
.bool_v
->value
;
761 b2
= v2
->var
->u
.bool_v
->value
;
771 bool_v
->value
= (b1
== b2
);
774 bool_v
->value
= (b1
!= b2
);
777 bool_v
->value
= (b1
== b_false
) && (b2
== b_true
);
780 bool_v
->value
= (b1
== b_true
) && (b2
== b_false
);
783 bool_v
->value
= (b1
== b_false
) || (b2
== b_true
);
786 bool_v
->value
= (b1
== b_true
) || (b2
== b_false
);
790 bool_v
->value
= (b1
== b_true
) && (b2
== b_true
);
793 bool_v
->value
= (b1
== b_true
) || (b2
== b_true
);
800 /** Evaluate binary operation on char arguments.
802 * @param run Runner object
803 * @param binop Binary operation
804 * @param v1 Value of first argument
805 * @param v2 Value of second argument
806 * @param res Place to store result
808 static void run_binop_char(run_t
*run
, stree_binop_t
*binop
, rdata_value_t
*v1
,
809 rdata_value_t
*v2
, rdata_item_t
**res
)
812 rdata_value_t
*value
;
814 rdata_bool_t
*bool_v
;
822 item
= rdata_item_new(ic_value
);
823 value
= rdata_value_new();
825 item
->u
.value
= value
;
827 c1
= &v1
->var
->u
.char_v
->value
;
828 c2
= &v2
->var
->u
.char_v
->value
;
830 var
= rdata_var_new(vc_bool
);
831 bool_v
= rdata_bool_new();
832 var
->u
.bool_v
= bool_v
;
835 bigint_sub(c1
, c2
, &diff
);
836 zf
= bigint_is_zero(&diff
);
837 nf
= bigint_is_negative(&diff
);
853 bool_v
->value
= (!zf
&& nf
);
856 bool_v
->value
= (!zf
&& !nf
);
859 bool_v
->value
= (zf
|| nf
);
873 /** Evaluate binary operation on int arguments.
875 * @param run Runner object
876 * @param binop Binary operation
877 * @param v1 Value of first argument
878 * @param v2 Value of second argument
879 * @param res Place to store result
881 static void run_binop_int(run_t
*run
, stree_binop_t
*binop
, rdata_value_t
*v1
,
882 rdata_value_t
*v2
, rdata_item_t
**res
)
885 rdata_value_t
*value
;
888 rdata_bool_t
*bool_v
;
897 item
= rdata_item_new(ic_value
);
898 value
= rdata_value_new();
900 item
->u
.value
= value
;
902 i1
= &v1
->var
->u
.int_v
->value
;
903 i2
= &v2
->var
->u
.int_v
->value
;
909 int_v
= rdata_int_new();
910 bigint_add(i1
, i2
, &int_v
->value
);
913 int_v
= rdata_int_new();
914 bigint_sub(i1
, i2
, &int_v
->value
);
917 int_v
= rdata_int_new();
918 bigint_mul(i1
, i2
, &int_v
->value
);
926 var
= rdata_var_new(vc_int
);
927 var
->u
.int_v
= int_v
;
933 var
= rdata_var_new(vc_bool
);
934 bool_v
= rdata_bool_new();
935 var
->u
.bool_v
= bool_v
;
938 /* Relational operation. */
940 bigint_sub(i1
, i2
, &diff
);
941 zf
= bigint_is_zero(&diff
);
942 nf
= bigint_is_negative(&diff
);
958 bool_v
->value
= (!zf
&& nf
);
961 bool_v
->value
= (!zf
&& !nf
);
964 bool_v
->value
= (zf
|| nf
);
977 /** Evaluate binary operation on string arguments.
979 * @param run Runner object
980 * @param binop Binary operation
981 * @param v1 Value of first argument
982 * @param v2 Value of second argument
983 * @param res Place to store result
985 static void run_binop_string(run_t
*run
, stree_binop_t
*binop
, rdata_value_t
*v1
,
986 rdata_value_t
*v2
, rdata_item_t
**res
)
989 rdata_value_t
*value
;
991 rdata_string_t
*string_v
;
992 rdata_bool_t
*bool_v
;
1000 item
= rdata_item_new(ic_value
);
1001 value
= rdata_value_new();
1003 item
->u
.value
= value
;
1005 s1
= v1
->var
->u
.string_v
->value
;
1006 s2
= v2
->var
->u
.string_v
->value
;
1010 switch (binop
->bc
) {
1012 /* Concatenate strings. */
1013 string_v
= rdata_string_new();
1014 string_v
->value
= os_str_acat(s1
, s2
);
1022 var
= rdata_var_new(vc_string
);
1023 var
->u
.string_v
= string_v
;
1029 var
= rdata_var_new(vc_bool
);
1030 bool_v
= rdata_bool_new();
1031 var
->u
.bool_v
= bool_v
;
1034 /* Relational operation. */
1036 zf
= os_str_cmp(s1
, s2
) == 0;
1038 switch (binop
->bc
) {
1043 bool_v
->value
= !zf
;
1046 printf("Error: Invalid binary operation on string "
1047 "arguments (%d).\n", binop
->bc
);
1054 /** Evaluate binary operation on ref arguments.
1056 * @param run Runner object
1057 * @param binop Binary operation
1058 * @param v1 Value of first argument
1059 * @param v2 Value of second argument
1060 * @param res Place to store result
1062 static void run_binop_ref(run_t
*run
, stree_binop_t
*binop
, rdata_value_t
*v1
,
1063 rdata_value_t
*v2
, rdata_item_t
**res
)
1066 rdata_value_t
*value
;
1068 rdata_bool_t
*bool_v
;
1070 rdata_var_t
*ref1
, *ref2
;
1074 item
= rdata_item_new(ic_value
);
1075 value
= rdata_value_new();
1076 var
= rdata_var_new(vc_bool
);
1077 bool_v
= rdata_bool_new();
1079 item
->u
.value
= value
;
1081 var
->u
.bool_v
= bool_v
;
1083 ref1
= v1
->var
->u
.ref_v
->vref
;
1084 ref2
= v2
->var
->u
.ref_v
->vref
;
1086 switch (binop
->bc
) {
1088 bool_v
->value
= (ref1
== ref2
);
1091 bool_v
->value
= (ref1
!= ref2
);
1094 printf("Error: Invalid binary operation on reference "
1095 "arguments (%d).\n", binop
->bc
);
1102 /** Evaluate binary operation on enum arguments.
1104 * @param run Runner object
1105 * @param binop Binary operation
1106 * @param v1 Value of first argument
1107 * @param v2 Value of second argument
1108 * @param res Place to store result
1110 static void run_binop_enum(run_t
*run
, stree_binop_t
*binop
, rdata_value_t
*v1
,
1111 rdata_value_t
*v2
, rdata_item_t
**res
)
1114 rdata_value_t
*value
;
1116 rdata_bool_t
*bool_v
;
1118 stree_embr_t
*e1
, *e2
;
1122 item
= rdata_item_new(ic_value
);
1123 value
= rdata_value_new();
1124 var
= rdata_var_new(vc_bool
);
1125 bool_v
= rdata_bool_new();
1127 item
->u
.value
= value
;
1129 var
->u
.bool_v
= bool_v
;
1131 e1
= v1
->var
->u
.enum_v
->value
;
1132 e2
= v2
->var
->u
.enum_v
->value
;
1134 switch (binop
->bc
) {
1136 bool_v
->value
= (e1
== e2
);
1139 bool_v
->value
= (e1
!= e2
);
1142 /* Should have been caught by static typing. */
1149 /** Evaluate unary operation.
1151 * @param run Runner object
1152 * @param unop Unary operation
1153 * @param res Place to store result
1155 static void run_unop(run_t
*run
, stree_unop_t
*unop
, rdata_item_t
**res
)
1157 rdata_item_t
*rarg_i
;
1158 rdata_item_t
*rarg_vi
;
1161 #ifdef DEBUG_RUN_TRACE
1162 printf("Run unary operation.\n");
1167 run_expr(run
, unop
->arg
, &rarg_i
);
1168 if (run_is_bo(run
)) {
1169 *res
= run_recovery_item(run
);
1173 #ifdef DEBUG_RUN_TRACE
1174 printf("Check unop argument result.\n");
1176 run_cvt_value_item(run
, rarg_i
, &rarg_vi
);
1177 if (run_is_bo(run
)) {
1178 *res
= run_recovery_item(run
);
1182 val
= rarg_vi
->u
.value
;
1184 switch (val
->var
->vc
) {
1186 run_unop_bool(run
, unop
, val
, res
);
1189 run_unop_int(run
, unop
, val
, res
);
1192 printf("Unimplemented: Unrary operation argument of "
1193 "type %d.\n", val
->var
->vc
);
1194 run_raise_error(run
);
1195 *res
= run_recovery_item(run
);
1200 rdata_item_destroy(rarg_i
);
1201 if (rarg_vi
!= NULL
)
1202 rdata_item_destroy(rarg_vi
);
1205 /** Evaluate unary operation on bool argument.
1207 * @param run Runner object
1208 * @param unop Unary operation
1209 * @param val Value of argument
1210 * @param res Place to store result
1212 static void run_unop_bool(run_t
*run
, stree_unop_t
*unop
, rdata_value_t
*val
,
1216 rdata_value_t
*value
;
1218 rdata_bool_t
*bool_v
;
1222 item
= rdata_item_new(ic_value
);
1223 value
= rdata_value_new();
1224 var
= rdata_var_new(vc_bool
);
1225 bool_v
= rdata_bool_new();
1227 item
->u
.value
= value
;
1229 var
->u
.bool_v
= bool_v
;
1238 bool_v
->value
= !val
->var
->u
.bool_v
->value
;
1245 /** Evaluate unary operation on int argument.
1247 * @param run Runner object
1248 * @param unop Unary operation
1249 * @param val Value of argument
1250 * @param res Place to store result
1252 static void run_unop_int(run_t
*run
, stree_unop_t
*unop
, rdata_value_t
*val
,
1256 rdata_value_t
*value
;
1262 item
= rdata_item_new(ic_value
);
1263 value
= rdata_value_new();
1264 var
= rdata_var_new(vc_int
);
1265 int_v
= rdata_int_new();
1267 item
->u
.value
= value
;
1269 var
->u
.int_v
= int_v
;
1273 bigint_clone(&val
->var
->u
.int_v
->value
, &int_v
->value
);
1276 bigint_reverse_sign(&val
->var
->u
.int_v
->value
,
1286 /** Run equality comparison of two values
1288 * This should be equivalent to equality ('==') binary operation.
1289 * XXX Duplicating code of run_binop_xxx().
1291 * @param run Runner object
1292 * @param v1 Value of first argument
1293 * @param v2 Value of second argument
1294 * @param res Place to store result (plain boolean value)
1296 void run_equal(run_t
*run
, rdata_value_t
*v1
, rdata_value_t
*v2
, bool_t
*res
)
1302 const char *s1
, *s2
;
1303 rdata_var_t
*ref1
, *ref2
;
1304 stree_embr_t
*e1
, *e2
;
1307 assert(v1
->var
->vc
== v2
->var
->vc
);
1309 switch (v1
->var
->vc
) {
1311 b1
= v1
->var
->u
.bool_v
->value
;
1312 b2
= v2
->var
->u
.bool_v
->value
;
1317 c1
= &v1
->var
->u
.char_v
->value
;
1318 c2
= &v2
->var
->u
.char_v
->value
;
1320 bigint_sub(c1
, c2
, &diff
);
1321 *res
= bigint_is_zero(&diff
);
1324 i1
= &v1
->var
->u
.int_v
->value
;
1325 i2
= &v2
->var
->u
.int_v
->value
;
1327 bigint_sub(i1
, i2
, &diff
);
1328 *res
= bigint_is_zero(&diff
);
1331 s1
= v1
->var
->u
.string_v
->value
;
1332 s2
= v2
->var
->u
.string_v
->value
;
1334 *res
= os_str_cmp(s1
, s2
) == 0;
1337 ref1
= v1
->var
->u
.ref_v
->vref
;
1338 ref2
= v2
->var
->u
.ref_v
->vref
;
1340 *res
= (ref1
== ref2
);
1343 e1
= v1
->var
->u
.enum_v
->value
;
1344 e2
= v2
->var
->u
.enum_v
->value
;
1358 /** Evaluate @c new operation.
1360 * Evaluates operation per the @c new operator that creates a new
1361 * instance of some type.
1363 * @param run Runner object
1364 * @param unop Unary operation
1365 * @param res Place to store result
1367 static void run_new(run_t
*run
, stree_new_t
*new_op
, rdata_item_t
**res
)
1369 tdata_item_t
*titem
;
1371 #ifdef DEBUG_RUN_TRACE
1372 printf("Run 'new' operation.\n");
1374 /* Evaluate type expression */
1375 run_texpr(run
->program
, run_get_current_csi(run
), new_op
->texpr
,
1378 switch (titem
->tic
) {
1380 run_new_array(run
, new_op
, titem
, res
);
1383 run_new_object(run
, new_op
, titem
, res
);
1386 printf("Error: Invalid argument to operator 'new', "
1387 "expected object.\n");
1392 /** Create new array.
1394 * @param run Runner object
1395 * @param new_op New operation
1396 * @param titem Type of new var node (tic_tarray)
1397 * @param res Place to store result
1399 static void run_new_array(run_t
*run
, stree_new_t
*new_op
,
1400 tdata_item_t
*titem
, rdata_item_t
**res
)
1402 tdata_array_t
*tarray
;
1403 rdata_array_t
*array
;
1404 rdata_var_t
*array_var
;
1405 rdata_var_t
*elem_var
;
1407 rdata_item_t
*rexpr
, *rexpr_vi
;
1408 rdata_var_t
*rexpr_var
;
1418 #ifdef DEBUG_RUN_TRACE
1419 printf("Create new array.\n");
1424 assert(titem
->tic
== tic_tarray
);
1425 tarray
= titem
->u
.tarray
;
1427 /* Create the array. */
1428 assert(titem
->u
.tarray
->rank
> 0);
1429 array
= rdata_array_new(titem
->u
.tarray
->rank
);
1431 /* Compute extents. */
1432 node
= list_first(&tarray
->extents
);
1434 printf("Error: Extents must be specified when constructing "
1435 "an array with 'new'.\n");
1441 while (node
!= NULL
) {
1442 expr
= list_node_data(node
, stree_expr_t
*);
1444 /* Evaluate extent argument. */
1445 run_expr(run
, expr
, &rexpr
);
1446 if (run_is_bo(run
)) {
1447 *res
= run_recovery_item(run
);
1451 run_cvt_value_item(run
, rexpr
, &rexpr_vi
);
1452 if (run_is_bo(run
)) {
1453 *res
= run_recovery_item(run
);
1457 assert(rexpr_vi
->ic
== ic_value
);
1458 rexpr_var
= rexpr_vi
->u
.value
->var
;
1460 if (rexpr_var
->vc
!= vc_int
) {
1461 printf("Error: Array extent must be an integer.\n");
1465 #ifdef DEBUG_RUN_TRACE
1466 printf("Array extent: ");
1467 bigint_print(&rexpr_var
->u
.int_v
->value
);
1470 rc
= bigint_get_value_int(&rexpr_var
->u
.int_v
->value
,
1473 printf("Memory allocation failed (big int used).\n");
1477 array
->extent
[i
] = iextent
;
1478 length
= length
* array
->extent
[i
];
1480 node
= list_next(&tarray
->extents
, node
);
1484 array
->element
= calloc(length
, sizeof(rdata_var_t
*));
1485 if (array
->element
== NULL
) {
1486 printf("Memory allocation failed.\n");
1490 /* Create member variables */
1491 for (i
= 0; i
< length
; ++i
) {
1492 /* Create and initialize element. */
1493 run_var_new(run
, tarray
->base_ti
, &elem_var
);
1495 array
->element
[i
] = elem_var
;
1498 /* Create array variable. */
1499 array_var
= rdata_var_new(vc_array
);
1500 array_var
->u
.array_v
= array
;
1502 /* Create reference to the new array. */
1503 run_reference(run
, array_var
, res
);
1506 /** Create new object.
1508 * @param run Runner object
1509 * @param new_op New operation
1510 * @param titem Type of new var node (tic_tobject)
1511 * @param res Place to store result
1513 static void run_new_object(run_t
*run
, stree_new_t
*new_op
,
1514 tdata_item_t
*titem
, rdata_item_t
**res
)
1517 rdata_item_t
*obj_i
;
1520 #ifdef DEBUG_RUN_TRACE
1521 printf("Create new object.\n");
1523 /* Lookup object CSI. */
1524 assert(titem
->tic
== tic_tobject
);
1525 csi
= titem
->u
.tobject
->csi
;
1527 /* Evaluate constructor arguments. */
1528 run_call_args(run
, &new_op
->ctor_args
, &arg_vals
);
1529 if (run_is_bo(run
)) {
1530 *res
= run_recovery_item(run
);
1534 /* Create CSI instance. */
1535 run_new_csi_inst_ref(run
, csi
, sn_nonstatic
, res
);
1537 /* Run the constructor. */
1538 run_dereference(run
, *res
, NULL
, &obj_i
);
1539 assert(obj_i
->ic
== ic_address
);
1540 assert(obj_i
->u
.address
->ac
== ac_var
);
1541 run_object_ctor(run
, obj_i
->u
.address
->u
.var_a
->vref
, &arg_vals
);
1542 rdata_item_destroy(obj_i
);
1544 /* Destroy argument values */
1545 run_destroy_arg_vals(&arg_vals
);
1548 /** Evaluate member acccess.
1550 * Evaluate operation per the member access ('.') operator.
1552 * @param run Runner object
1553 * @param access Access operation
1554 * @param res Place to store result
1556 static void run_access(run_t
*run
, stree_access_t
*access
, rdata_item_t
**res
)
1560 #ifdef DEBUG_RUN_TRACE
1561 printf("Run access operation.\n");
1565 run_expr(run
, access
->arg
, &rarg
);
1566 if (run_is_bo(run
)) {
1567 *res
= run_recovery_item(run
);
1572 printf("Error: Sub-expression has no value.\n");
1576 run_access_item(run
, access
, rarg
, res
);
1579 rdata_item_destroy(rarg
);
1582 /** Evaluate member acccess (with base already evaluated).
1584 * @param run Runner object
1585 * @param access Access operation
1586 * @param arg Evaluated base expression
1587 * @param res Place to store result
1589 static void run_access_item(run_t
*run
, stree_access_t
*access
,
1590 rdata_item_t
*arg
, rdata_item_t
**res
)
1594 #ifdef DEBUG_RUN_TRACE
1595 printf("Run access operation on pre-evaluated base.\n");
1597 vc
= run_item_get_vc(run
, arg
);
1601 run_access_ref(run
, access
, arg
, res
);
1604 run_access_deleg(run
, access
, arg
, res
);
1607 run_access_object(run
, access
, arg
, res
);
1610 run_access_symbol(run
, access
, arg
, res
);
1620 printf("Unimplemented: Using access operator ('.') "
1621 "with unsupported data type (value/%d).\n", vc
);
1626 /** Evaluate reference acccess.
1628 * @param run Runner object
1629 * @param access Access operation
1630 * @param arg Evaluated base expression
1631 * @param res Place to store result
1633 static void run_access_ref(run_t
*run
, stree_access_t
*access
,
1634 rdata_item_t
*arg
, rdata_item_t
**res
)
1638 /* Implicitly dereference. */
1639 run_dereference(run
, arg
, access
->arg
->cspan
, &darg
);
1641 if (run
->thread_ar
->bo_mode
!= bm_none
) {
1642 *res
= run_recovery_item(run
);
1647 run_access_item(run
, access
, darg
, res
);
1649 /* Destroy temporary */
1650 rdata_item_destroy(darg
);
1653 /** Evaluate delegate member acccess.
1655 * @param run Runner object
1656 * @param access Access operation
1657 * @param arg Evaluated base expression
1658 * @param res Place to store result
1660 static void run_access_deleg(run_t
*run
, stree_access_t
*access
,
1661 rdata_item_t
*arg
, rdata_item_t
**res
)
1668 printf("Error: Using '.' with delegate.\n");
1672 /** Evaluate object member acccess.
1674 * @param run Runner object
1675 * @param access Access operation
1676 * @param arg Evaluated base expression
1677 * @param res Place to store result
1679 static void run_access_object(run_t
*run
, stree_access_t
*access
,
1680 rdata_item_t
*arg
, rdata_item_t
**res
)
1682 rdata_var_t
*obj_var
;
1683 rdata_object_t
*object
;
1685 #ifdef DEBUG_RUN_TRACE
1686 printf("Run object access operation.\n");
1688 assert(arg
->ic
== ic_address
);
1689 assert(arg
->u
.address
->ac
== ac_var
);
1691 obj_var
= arg
->u
.address
->u
.var_a
->vref
;
1692 assert(obj_var
->vc
== vc_object
);
1694 object
= obj_var
->u
.object_v
;
1696 if (object
->static_obj
== sn_static
)
1697 run_access_object_static(run
, access
, obj_var
, res
);
1699 run_access_object_nonstatic(run
, access
, obj_var
, res
);
1702 /** Evaluate static object member acccess.
1704 * @param run Runner object
1705 * @param access Access operation
1706 * @param arg Evaluated base expression
1707 * @param res Place to store result
1709 static void run_access_object_static(run_t
*run
, stree_access_t
*access
,
1710 rdata_var_t
*obj_var
, rdata_item_t
**res
)
1712 rdata_object_t
*object
;
1713 stree_symbol_t
*member
;
1714 stree_csi_t
*member_csi
;
1716 rdata_deleg_t
*deleg_v
;
1717 rdata_item_t
*ritem
;
1718 rdata_value_t
*rvalue
;
1720 rdata_address_t
*address
;
1721 rdata_addr_var_t
*addr_var
;
1722 rdata_addr_prop_t
*addr_prop
;
1723 rdata_aprop_named_t
*aprop_named
;
1724 rdata_deleg_t
*deleg_p
;
1727 #ifdef DEBUG_RUN_TRACE
1728 printf("Run static object access operation.\n");
1730 assert(obj_var
->vc
== vc_object
);
1731 object
= obj_var
->u
.object_v
;
1733 assert(object
->static_obj
== sn_static
);
1735 member
= symbol_search_csi(run
->program
, object
->class_sym
->u
.csi
,
1736 access
->member_name
);
1738 /* Member existence should be ensured by static type checking. */
1739 assert(member
!= NULL
);
1741 #ifdef DEBUG_RUN_TRACE
1742 printf("Found member '%s'.\n",
1743 strtab_get_str(access
->member_name
->sid
));
1746 switch (member
->sc
) {
1748 /* Get child static object. */
1749 member_csi
= symbol_to_csi(member
);
1750 assert(member_csi
!= NULL
);
1752 mvar
= run_sobject_get(run
, member_csi
, obj_var
,
1753 access
->member_name
->sid
);
1755 ritem
= rdata_item_new(ic_address
);
1756 address
= rdata_address_new(ac_var
);
1757 ritem
->u
.address
= address
;
1759 addr_var
= rdata_addr_var_new();
1760 address
->u
.var_a
= addr_var
;
1761 addr_var
->vref
= mvar
;
1766 /* It is not possible to reference a constructor explicitly. */
1770 printf("Error: Accessing object member which is a delegate.\n");
1773 printf("Error: Accessing object member which is an enum.\n");
1776 /* Construct anonymous delegate. */
1777 ritem
= rdata_item_new(ic_value
);
1778 rvalue
= rdata_value_new();
1779 ritem
->u
.value
= rvalue
;
1781 rvar
= rdata_var_new(vc_deleg
);
1784 deleg_v
= rdata_deleg_new();
1785 rvar
->u
.deleg_v
= deleg_v
;
1787 deleg_v
->obj
= obj_var
;
1788 deleg_v
->sym
= member
;
1792 /* Get static object member variable. */
1793 mvar
= intmap_get(&object
->fields
, access
->member_name
->sid
);
1795 ritem
= rdata_item_new(ic_address
);
1796 address
= rdata_address_new(ac_var
);
1797 ritem
->u
.address
= address
;
1799 addr_var
= rdata_addr_var_new();
1800 address
->u
.var_a
= addr_var
;
1801 addr_var
->vref
= mvar
;
1806 /* Construct named property address. */
1807 ritem
= rdata_item_new(ic_address
);
1808 address
= rdata_address_new(ac_prop
);
1809 addr_prop
= rdata_addr_prop_new(apc_named
);
1810 aprop_named
= rdata_aprop_named_new();
1811 ritem
->u
.address
= address
;
1812 address
->u
.prop_a
= addr_prop
;
1813 addr_prop
->u
.named
= aprop_named
;
1815 deleg_p
= rdata_deleg_new();
1816 deleg_p
->obj
= obj_var
;
1817 deleg_p
->sym
= member
;
1818 addr_prop
->u
.named
->prop_d
= deleg_p
;
1825 /** Evaluate object member acccess.
1827 * @param run Runner object
1828 * @param access Access operation
1829 * @param arg Evaluated base expression
1830 * @param res Place to store result
1832 static void run_access_object_nonstatic(run_t
*run
, stree_access_t
*access
,
1833 rdata_var_t
*obj_var
, rdata_item_t
**res
)
1835 rdata_object_t
*object
;
1836 stree_symbol_t
*member
;
1837 rdata_item_t
*ritem
;
1838 rdata_address_t
*address
;
1839 rdata_addr_var_t
*addr_var
;
1840 rdata_addr_prop_t
*addr_prop
;
1841 rdata_aprop_named_t
*aprop_named
;
1842 rdata_deleg_t
*deleg_p
;
1844 rdata_value_t
*value
;
1845 rdata_deleg_t
*deleg_v
;
1848 #ifdef DEBUG_RUN_TRACE
1849 printf("Run nonstatic object access operation.\n");
1851 assert(obj_var
->vc
== vc_object
);
1852 object
= obj_var
->u
.object_v
;
1854 assert(object
->static_obj
== sn_nonstatic
);
1856 member
= symbol_search_csi(run
->program
, object
->class_sym
->u
.csi
,
1857 access
->member_name
);
1859 if (member
== NULL
) {
1860 printf("Error: Object of class '");
1861 symbol_print_fqn(object
->class_sym
);
1862 printf("' has no member named '%s'.\n",
1863 strtab_get_str(access
->member_name
->sid
));
1867 #ifdef DEBUG_RUN_TRACE
1868 printf("Found member '%s'.\n",
1869 strtab_get_str(access
->member_name
->sid
));
1872 /* Make compiler happy. */
1875 switch (member
->sc
) {
1877 printf("Error: Accessing object member which is nested CSI.\n");
1880 /* It is not possible to reference a constructor explicitly. */
1884 printf("Error: Accessing object member which is a delegate.\n");
1887 printf("Error: Accessing object member which is an enum.\n");
1890 /* Construct anonymous delegate. */
1891 ritem
= rdata_item_new(ic_value
);
1892 value
= rdata_value_new();
1893 ritem
->u
.value
= value
;
1895 var
= rdata_var_new(vc_deleg
);
1897 deleg_v
= rdata_deleg_new();
1898 var
->u
.deleg_v
= deleg_v
;
1900 deleg_v
->obj
= obj_var
;
1901 deleg_v
->sym
= member
;
1904 /* Construct variable address item. */
1905 ritem
= rdata_item_new(ic_address
);
1906 address
= rdata_address_new(ac_var
);
1907 addr_var
= rdata_addr_var_new();
1908 ritem
->u
.address
= address
;
1909 address
->u
.var_a
= addr_var
;
1911 addr_var
->vref
= intmap_get(&object
->fields
,
1912 access
->member_name
->sid
);
1913 assert(addr_var
->vref
!= NULL
);
1916 /* Construct named property address. */
1917 ritem
= rdata_item_new(ic_address
);
1918 address
= rdata_address_new(ac_prop
);
1919 addr_prop
= rdata_addr_prop_new(apc_named
);
1920 aprop_named
= rdata_aprop_named_new();
1921 ritem
->u
.address
= address
;
1922 address
->u
.prop_a
= addr_prop
;
1923 addr_prop
->u
.named
= aprop_named
;
1925 deleg_p
= rdata_deleg_new();
1926 deleg_p
->obj
= obj_var
;
1927 deleg_p
->sym
= member
;
1928 addr_prop
->u
.named
->prop_d
= deleg_p
;
1935 /** Evaluate symbol member acccess.
1937 * @param run Runner object
1938 * @param access Access operation
1939 * @param arg Evaluated base expression
1940 * @param res Place to store result
1942 static void run_access_symbol(run_t
*run
, stree_access_t
*access
,
1943 rdata_item_t
*arg
, rdata_item_t
**res
)
1945 rdata_item_t
*arg_vi
;
1946 rdata_value_t
*arg_val
;
1947 rdata_symbol_t
*symbol_v
;
1950 rdata_item_t
*ritem
;
1951 rdata_value_t
*rvalue
;
1953 rdata_enum_t
*enum_v
;
1955 #ifdef DEBUG_RUN_TRACE
1956 printf("Run symbol access operation.\n");
1958 run_cvt_value_item(run
, arg
, &arg_vi
);
1959 if (run_is_bo(run
)) {
1960 *res
= run_recovery_item(run
);
1964 arg_val
= arg_vi
->u
.value
;
1965 assert(arg_val
->var
->vc
== vc_symbol
);
1967 symbol_v
= arg_val
->var
->u
.symbol_v
;
1969 /* XXX Port CSI symbol reference to using vc_symbol */
1970 assert(symbol_v
->sym
->sc
== sc_enum
);
1972 embr
= stree_enum_find_mbr(symbol_v
->sym
->u
.enum_d
,
1973 access
->member_name
);
1975 rdata_item_destroy(arg_vi
);
1977 /* Member existence should be ensured by static type checking. */
1978 assert(embr
!= NULL
);
1980 #ifdef DEBUG_RUN_TRACE
1981 printf("Found enum member '%s'.\n",
1982 strtab_get_str(access
->member_name
->sid
));
1984 ritem
= rdata_item_new(ic_value
);
1985 rvalue
= rdata_value_new();
1986 rvar
= rdata_var_new(vc_enum
);
1987 enum_v
= rdata_enum_new();
1989 ritem
->u
.value
= rvalue
;
1991 rvar
->u
.enum_v
= enum_v
;
1992 enum_v
->value
= embr
;
1997 /** Call a function.
1999 * Call a function and return the result in @a res.
2001 * @param run Runner object
2002 * @param call Call operation
2003 * @param res Place to store result
2005 static void run_call(run_t
*run
, stree_call_t
*call
, rdata_item_t
**res
)
2007 rdata_item_t
*rdeleg
, *rdeleg_vi
;
2008 rdata_deleg_t
*deleg_v
;
2012 run_proc_ar_t
*proc_ar
;
2014 #ifdef DEBUG_RUN_TRACE
2015 printf("Run call operation.\n");
2020 run_expr(run
, call
->fun
, &rdeleg
);
2021 if (run_is_bo(run
)) {
2022 *res
= run_recovery_item(run
);
2026 run_cvt_value_item(run
, rdeleg
, &rdeleg_vi
);
2027 if (run_is_bo(run
)) {
2028 *res
= run_recovery_item(run
);
2032 assert(rdeleg_vi
->ic
== ic_value
);
2034 if (rdeleg_vi
->u
.value
->var
->vc
!= vc_deleg
) {
2035 printf("Unimplemented: Call expression of this type (");
2036 rdata_item_print(rdeleg_vi
);
2041 deleg_v
= rdeleg_vi
->u
.value
->var
->u
.deleg_v
;
2043 if (deleg_v
->sym
->sc
!= sc_fun
) {
2044 printf("Error: Called symbol is not a function.\n");
2048 #ifdef DEBUG_RUN_TRACE
2049 printf("Call function '");
2050 symbol_print_fqn(deleg_v
->sym
);
2053 /* Evaluate function arguments. */
2054 run_call_args(run
, &call
->args
, &arg_vals
);
2055 if (run_is_bo(run
)) {
2056 *res
= run_recovery_item(run
);
2060 fun
= symbol_to_fun(deleg_v
->sym
);
2061 assert(fun
!= NULL
);
2063 /* Create procedure activation record. */
2064 run_proc_ar_create(run
, deleg_v
->obj
, fun
->proc
, &proc_ar
);
2066 /* Fill in argument values. */
2067 run_proc_ar_set_args(run
, proc_ar
, &arg_vals
);
2069 /* Destroy arg_vals, they are no longer needed. */
2070 run_destroy_arg_vals(&arg_vals
);
2072 /* Run the function. */
2073 run_proc(run
, proc_ar
, res
);
2075 if (!run_is_bo(run
) && fun
->sig
->rtype
!= NULL
&& *res
== NULL
) {
2076 printf("Error: Function '");
2077 symbol_print_fqn(deleg_v
->sym
);
2078 printf("' did not return a value.\n");
2082 /* Destroy procedure activation record. */
2083 run_proc_ar_destroy(run
, proc_ar
);
2087 rdata_item_destroy(rdeleg
);
2088 if (rdeleg_vi
!= NULL
)
2089 rdata_item_destroy(rdeleg_vi
);
2091 #ifdef DEBUG_RUN_TRACE
2092 printf("Returned from function call.\n");
2096 /** Evaluate call arguments.
2098 * Evaluate arguments to function or constructor.
2100 * @param run Runner object
2101 * @param args Real arguments (list of stree_expr_t)
2102 * @param arg_vals Address of uninitialized list to store argument values
2103 * (list of rdata_item_t).
2105 static void run_call_args(run_t
*run
, list_t
*args
, list_t
*arg_vals
)
2109 rdata_item_t
*rarg_i
, *rarg_vi
;
2111 /* Evaluate function arguments. */
2112 list_init(arg_vals
);
2113 arg_n
= list_first(args
);
2115 while (arg_n
!= NULL
) {
2116 arg
= list_node_data(arg_n
, stree_expr_t
*);
2117 run_expr(run
, arg
, &rarg_i
);
2121 run_cvt_value_item(run
, rarg_i
, &rarg_vi
);
2122 rdata_item_destroy(rarg_i
);
2126 list_append(arg_vals
, rarg_vi
);
2127 arg_n
= list_next(args
, arg_n
);
2133 * An exception or error occured while evaluating one of the
2134 * arguments. Destroy already obtained argument values and
2135 * dismantle the list.
2137 run_destroy_arg_vals(arg_vals
);
2140 /** Destroy list of evaluated arguments.
2142 * Provided a list of evaluated arguments, destroy them, removing them
2143 * from the list and fini the list itself.
2145 * @param arg_vals List of evaluated arguments (value items,
2148 static void run_destroy_arg_vals(list_t
*arg_vals
)
2151 rdata_item_t
*val_i
;
2154 * An exception or error occured while evaluating one of the
2155 * arguments. Destroy already obtained argument values and
2156 * dismantle the list.
2158 while (!list_is_empty(arg_vals
)) {
2159 val_n
= list_first(arg_vals
);
2160 val_i
= list_node_data(val_n
, rdata_item_t
*);
2162 rdata_item_destroy(val_i
);
2163 list_remove(arg_vals
, val_n
);
2165 list_fini(arg_vals
);
2168 /** Run index operation.
2170 * Evaluate operation per the indexing ('[', ']') operator.
2172 * @param run Runner object
2173 * @param index Index operation
2174 * @param res Place to store result
2176 static void run_index(run_t
*run
, stree_index_t
*index
, rdata_item_t
**res
)
2178 rdata_item_t
*rbase
;
2179 rdata_item_t
*base_i
;
2182 rdata_item_t
*rarg_i
, *rarg_vi
;
2186 rdata_item_t
*val_i
;
2188 #ifdef DEBUG_RUN_TRACE
2189 printf("Run index operation.\n");
2191 run_expr(run
, index
->base
, &rbase
);
2192 if (run_is_bo(run
)) {
2193 *res
= run_recovery_item(run
);
2197 vc
= run_item_get_vc(run
, rbase
);
2199 /* Implicitly dereference. */
2201 run_dereference(run
, rbase
, index
->base
->cspan
, &base_i
);
2202 rdata_item_destroy(rbase
);
2203 if (run_is_bo(run
)) {
2204 *res
= run_recovery_item(run
);
2211 vc
= run_item_get_vc(run
, base_i
);
2213 /* Evaluate arguments (indices). */
2214 node
= list_first(&index
->args
);
2215 list_init(&arg_vals
);
2217 while (node
!= NULL
) {
2218 arg
= list_node_data(node
, stree_expr_t
*);
2219 run_expr(run
, arg
, &rarg_i
);
2220 if (run_is_bo(run
)) {
2221 *res
= run_recovery_item(run
);
2225 run_cvt_value_item(run
, rarg_i
, &rarg_vi
);
2226 rdata_item_destroy(rarg_i
);
2227 if (run_is_bo(run
)) {
2228 *res
= run_recovery_item(run
);
2232 list_append(&arg_vals
, rarg_vi
);
2234 node
= list_next(&index
->args
, node
);
2239 run_index_array(run
, index
, base_i
, &arg_vals
, res
);
2242 run_index_object(run
, index
, base_i
, &arg_vals
, res
);
2245 run_index_string(run
, index
, base_i
, &arg_vals
, res
);
2248 printf("Error: Indexing object of bad type (%d).\n", vc
);
2252 /* Destroy the indexing base temporary */
2253 rdata_item_destroy(base_i
);
2256 * An exception or error occured while evaluating one of the
2257 * arguments. Destroy already obtained argument values and
2258 * dismantle the list.
2260 while (!list_is_empty(&arg_vals
)) {
2261 val_n
= list_first(&arg_vals
);
2262 val_i
= list_node_data(val_n
, rdata_item_t
*);
2264 rdata_item_destroy(val_i
);
2265 list_remove(&arg_vals
, val_n
);
2268 list_fini(&arg_vals
);
2271 /** Run index operation on array.
2273 * @param run Runner object
2274 * @param index Index operation
2275 * @param base Evaluated base expression
2276 * @param args Evaluated indices (list of rdata_item_t)
2277 * @param res Place to store result
2279 static void run_index_array(run_t
*run
, stree_index_t
*index
,
2280 rdata_item_t
*base
, list_t
*args
, rdata_item_t
**res
)
2283 rdata_array_t
*array
;
2291 rdata_item_t
*ritem
;
2292 rdata_address_t
*address
;
2293 rdata_addr_var_t
*addr_var
;
2295 #ifdef DEBUG_RUN_TRACE
2296 printf("Run array index operation.\n");
2300 assert(base
->ic
== ic_address
);
2301 assert(base
->u
.address
->ac
== ac_var
);
2302 assert(base
->u
.address
->u
.var_a
->vref
->vc
== vc_array
);
2303 array
= base
->u
.address
->u
.var_a
->vref
->u
.array_v
;
2306 * Linear index of the desired element. Elements are stored in
2307 * lexicographic order with the last index changing the fastest.
2311 node
= list_first(args
);
2314 while (node
!= NULL
) {
2315 if (i
>= array
->rank
) {
2316 printf("Error: Too many indices for array of rank %d",
2321 arg
= list_node_data(node
, rdata_item_t
*);
2322 assert(arg
->ic
== ic_value
);
2324 if (arg
->u
.value
->var
->vc
!= vc_int
) {
2325 printf("Error: Array index is not an integer.\n");
2329 rc
= bigint_get_value_int(
2330 &arg
->u
.value
->var
->u
.int_v
->value
,
2333 if (rc
!= EOK
|| arg_val
< 0 || arg_val
>= array
->extent
[i
]) {
2334 #ifdef DEBUG_RUN_TRACE
2335 printf("Error: Array index (value: %d) is out of range.\n",
2338 /* Raise Error.OutOfBounds */
2340 run
->program
->builtin
->error_outofbounds
,
2341 index
->expr
->cspan
);
2342 /* XXX It should be cspan of the argument. */
2343 *res
= run_recovery_item(run
);
2347 elem_index
= elem_index
* array
->extent
[i
] + arg_val
;
2349 node
= list_next(args
, node
);
2353 if (i
< array
->rank
) {
2354 printf("Error: Too few indices for array of rank %d",
2359 /* Construct variable address item. */
2360 ritem
= rdata_item_new(ic_address
);
2361 address
= rdata_address_new(ac_var
);
2362 addr_var
= rdata_addr_var_new();
2363 ritem
->u
.address
= address
;
2364 address
->u
.var_a
= addr_var
;
2366 addr_var
->vref
= array
->element
[elem_index
];
2371 /** Index an object (via its indexer).
2373 * @param run Runner object
2374 * @param index Index operation
2375 * @param base Evaluated base expression
2376 * @param args Evaluated indices (list of rdata_item_t)
2377 * @param res Place to store result
2379 static void run_index_object(run_t
*run
, stree_index_t
*index
,
2380 rdata_item_t
*base
, list_t
*args
, rdata_item_t
**res
)
2382 rdata_item_t
*ritem
;
2383 rdata_address_t
*address
;
2384 rdata_addr_prop_t
*addr_prop
;
2385 rdata_aprop_indexed_t
*aprop_indexed
;
2386 rdata_var_t
*obj_var
;
2387 stree_csi_t
*obj_csi
;
2388 rdata_deleg_t
*object_d
;
2389 stree_symbol_t
*indexer_sym
;
2390 stree_ident_t
*indexer_ident
;
2393 rdata_item_t
*arg
, *arg_copy
;
2395 #ifdef DEBUG_RUN_TRACE
2396 printf("Run object index operation.\n");
2400 /* Construct property address item. */
2401 ritem
= rdata_item_new(ic_address
);
2402 address
= rdata_address_new(ac_prop
);
2403 addr_prop
= rdata_addr_prop_new(apc_indexed
);
2404 aprop_indexed
= rdata_aprop_indexed_new();
2405 ritem
->u
.address
= address
;
2406 address
->u
.prop_a
= addr_prop
;
2407 addr_prop
->u
.indexed
= aprop_indexed
;
2409 if (base
->ic
!= ic_address
|| base
->u
.address
->ac
!= ac_var
) {
2410 /* XXX Several other cases can occur. */
2411 printf("Unimplemented: Indexing object varclass via something "
2412 "which is not a simple variable reference.\n");
2416 /* Find indexer symbol. */
2417 obj_var
= base
->u
.address
->u
.var_a
->vref
;
2418 assert(obj_var
->vc
== vc_object
);
2419 indexer_ident
= stree_ident_new();
2420 indexer_ident
->sid
= strtab_get_sid(INDEXER_IDENT
);
2421 obj_csi
= symbol_to_csi(obj_var
->u
.object_v
->class_sym
);
2422 assert(obj_csi
!= NULL
);
2423 indexer_sym
= symbol_search_csi(run
->program
, obj_csi
, indexer_ident
);
2425 if (indexer_sym
== NULL
) {
2426 printf("Error: Accessing object which does not have an "
2431 /* Construct delegate. */
2432 object_d
= rdata_deleg_new();
2433 object_d
->obj
= obj_var
;
2434 object_d
->sym
= indexer_sym
;
2435 aprop_indexed
->object_d
= object_d
;
2437 /* Copy list of argument values. */
2438 list_init(&aprop_indexed
->args
);
2440 node
= list_first(args
);
2441 while (node
!= NULL
) {
2442 arg
= list_node_data(node
, rdata_item_t
*);
2445 * Clone argument so that original can
2448 assert(arg
->ic
== ic_value
);
2449 arg_copy
= rdata_item_new(ic_value
);
2450 rdata_value_copy(arg
->u
.value
, &arg_copy
->u
.value
);
2452 list_append(&aprop_indexed
->args
, arg_copy
);
2453 node
= list_next(args
, node
);
2459 /** Run index operation on string.
2461 * @param run Runner object
2462 * @param index Index operation
2463 * @param base Evaluated base expression
2464 * @param args Evaluated indices (list of rdata_item_t)
2465 * @param res Place to store result
2467 static void run_index_string(run_t
*run
, stree_index_t
*index
,
2468 rdata_item_t
*base
, list_t
*args
, rdata_item_t
**res
)
2471 rdata_string_t
*string
;
2472 rdata_item_t
*base_vi
;
2480 rdata_value_t
*value
;
2482 rdata_item_t
*ritem
;
2485 #ifdef DEBUG_RUN_TRACE
2486 printf("Run string index operation.\n");
2490 run_cvt_value_item(run
, base
, &base_vi
);
2491 if (run_is_bo(run
)) {
2492 *res
= run_recovery_item(run
);
2496 assert(base_vi
->u
.value
->var
->vc
== vc_string
);
2497 string
= base_vi
->u
.value
->var
->u
.string_v
;
2500 * Linear index of the desired element. Elements are stored in
2501 * lexicographic order with the last index changing the fastest.
2503 node
= list_first(args
);
2506 assert(node
!= NULL
);
2511 printf("Error: Too many indices string.\n");
2515 arg
= list_node_data(node
, rdata_item_t
*);
2516 assert(arg
->ic
== ic_value
);
2518 if (arg
->u
.value
->var
->vc
!= vc_int
) {
2519 printf("Error: String index is not an integer.\n");
2523 rc1
= bigint_get_value_int(
2524 &arg
->u
.value
->var
->u
.int_v
->value
,
2527 elem_index
= arg_val
;
2529 node
= list_next(args
, node
);
2531 } while (node
!= NULL
);
2534 printf("Error: Too few indices for string.\n");
2539 rc2
= os_str_get_char(string
->value
, elem_index
, &cval
);
2543 if (rc1
!= EOK
|| rc2
!= EOK
) {
2544 #ifdef DEBUG_RUN_TRACE
2545 printf("Error: String index (value: %d) is out of range.\n",
2548 /* Raise Error.OutOfBounds */
2549 run_raise_exc(run
, run
->program
->builtin
->error_outofbounds
,
2550 index
->expr
->cspan
);
2551 *res
= run_recovery_item(run
);
2555 /* Construct character value. */
2556 ritem
= rdata_item_new(ic_value
);
2557 value
= rdata_value_new();
2558 ritem
->u
.value
= value
;
2560 cvar
= rdata_var_new(vc_char
);
2561 cvar
->u
.char_v
= rdata_char_new();
2562 bigint_init(&cvar
->u
.char_v
->value
, cval
);
2567 rdata_item_destroy(base_vi
);
2572 * Executes an assignment. @c NULL is always stored to @a res because
2573 * an assignment does not have a value.
2575 * @param run Runner object
2576 * @param assign Assignment expression
2577 * @param res Place to store result
2579 static void run_assign(run_t
*run
, stree_assign_t
*assign
, rdata_item_t
**res
)
2581 rdata_item_t
*rdest_i
, *rsrc_i
;
2582 rdata_item_t
*rsrc_vi
;
2584 #ifdef DEBUG_RUN_TRACE
2585 printf("Run assign operation.\n");
2591 run_expr(run
, assign
->dest
, &rdest_i
);
2592 if (run_is_bo(run
)) {
2593 *res
= run_recovery_item(run
);
2597 run_expr(run
, assign
->src
, &rsrc_i
);
2598 if (run_is_bo(run
)) {
2599 *res
= run_recovery_item(run
);
2603 run_cvt_value_item(run
, rsrc_i
, &rsrc_vi
);
2604 if (run_is_bo(run
)) {
2605 *res
= run_recovery_item(run
);
2609 assert(rsrc_vi
->ic
== ic_value
);
2611 if (rdest_i
->ic
!= ic_address
) {
2612 printf("Error: Address expression required on left side of "
2613 "assignment operator.\n");
2617 run_address_write(run
, rdest_i
->u
.address
, rsrc_vi
->u
.value
);
2621 if (rdest_i
!= NULL
)
2622 rdata_item_destroy(rdest_i
);
2624 rdata_item_destroy(rsrc_i
);
2625 if (rsrc_vi
!= NULL
)
2626 rdata_item_destroy(rsrc_vi
);
2629 /** Execute @c as conversion.
2631 * @param run Runner object
2632 * @param as_op @c as conversion expression
2633 * @param res Place to store result
2635 static void run_as(run_t
*run
, stree_as_t
*as_op
, rdata_item_t
**res
)
2637 rdata_item_t
*rarg_i
;
2638 rdata_item_t
*rarg_vi
;
2639 rdata_item_t
*rarg_di
;
2640 rdata_var_t
*arg_vref
;
2641 tdata_item_t
*dtype
;
2642 run_proc_ar_t
*proc_ar
;
2644 stree_symbol_t
*obj_csi_sym
;
2645 stree_csi_t
*obj_csi
;
2647 #ifdef DEBUG_RUN_TRACE
2648 printf("Run @c as conversion operation.\n");
2650 run_expr(run
, as_op
->arg
, &rarg_i
);
2651 if (run_is_bo(run
)) {
2652 *res
= run_recovery_item(run
);
2657 * This should always be a reference if the argument is indeed
2660 assert(run_item_get_vc(run
, rarg_i
) == vc_ref
);
2661 run_cvt_value_item(run
, rarg_i
, &rarg_vi
);
2662 rdata_item_destroy(rarg_i
);
2664 if (run_is_bo(run
)) {
2665 *res
= run_recovery_item(run
);
2669 assert(rarg_vi
->ic
== ic_value
);
2671 if (rarg_vi
->u
.value
->var
->u
.ref_v
->vref
== NULL
) {
2672 /* Nil reference is always okay. */
2677 run_dereference(run
, rarg_vi
, NULL
, &rarg_di
);
2679 /* Now we should have a variable address. */
2680 assert(rarg_di
->ic
== ic_address
);
2681 assert(rarg_di
->u
.address
->ac
== ac_var
);
2683 arg_vref
= rarg_di
->u
.address
->u
.var_a
->vref
;
2685 proc_ar
= run_get_current_proc_ar(run
);
2686 /* XXX Memoize to avoid recomputing. */
2687 run_texpr(run
->program
, proc_ar
->proc
->outer_symbol
->outer_csi
,
2688 as_op
->dtype
, &dtype
);
2690 assert(arg_vref
->vc
== vc_object
);
2691 obj_csi_sym
= arg_vref
->u
.object_v
->class_sym
;
2692 obj_csi
= symbol_to_csi(obj_csi_sym
);
2693 assert(obj_csi
!= NULL
);
2695 if (tdata_is_csi_derived_from_ti(obj_csi
, dtype
) != b_true
) {
2696 printf("Error: Run-time type conversion error. Object is "
2698 symbol_print_fqn(obj_csi_sym
);
2699 printf("' which is not derived from '");
2700 tdata_item_print(dtype
);
2705 /* The dereferenced item is not used anymore. */
2706 rdata_item_destroy(rarg_di
);
2711 /** Execute boxing operation.
2713 * XXX We can scrap this special operation once we have constructors.
2715 * @param run Runner object
2716 * @param box Boxing operation
2717 * @param res Place to store result
2719 static void run_box(run_t
*run
, stree_box_t
*box
, rdata_item_t
**res
)
2721 rdata_item_t
*rarg_i
;
2722 rdata_item_t
*rarg_vi
;
2724 stree_symbol_t
*csi_sym
;
2728 rdata_object_t
*object
;
2731 rdata_var_t
*mbr_var
;
2733 #ifdef DEBUG_RUN_TRACE
2734 printf("Run boxing operation.\n");
2736 run_expr(run
, box
->arg
, &rarg_i
);
2737 if (run_is_bo(run
)) {
2738 *res
= run_recovery_item(run
);
2742 run_cvt_value_item(run
, rarg_i
, &rarg_vi
);
2743 rdata_item_destroy(rarg_i
);
2744 if (run_is_bo(run
)) {
2745 *res
= run_recovery_item(run
);
2749 assert(rarg_vi
->ic
== ic_value
);
2751 bi
= run
->program
->builtin
;
2753 /* Just to keep the compiler happy. */
2756 switch (rarg_vi
->u
.value
->var
->vc
) {
2758 csi_sym
= bi
->boxed_bool
;
2761 csi_sym
= bi
->boxed_char
;
2764 csi_sym
= bi
->boxed_int
;
2767 csi_sym
= bi
->boxed_string
;
2780 csi
= symbol_to_csi(csi_sym
);
2781 assert(csi
!= NULL
);
2783 /* Construct object of the relevant boxed type. */
2784 run_new_csi_inst_ref(run
, csi
, sn_nonstatic
, res
);
2786 /* Set the 'Value' field */
2788 assert((*res
)->ic
== ic_value
);
2789 assert((*res
)->u
.value
->var
->vc
== vc_ref
);
2790 var
= (*res
)->u
.value
->var
->u
.ref_v
->vref
;
2791 assert(var
->vc
== vc_object
);
2792 object
= var
->u
.object_v
;
2794 mbr_name_sid
= strtab_get_sid("Value");
2795 mbr_var
= intmap_get(&object
->fields
, mbr_name_sid
);
2796 assert(mbr_var
!= NULL
);
2798 rdata_var_write(mbr_var
, rarg_vi
->u
.value
);
2799 rdata_item_destroy(rarg_vi
);
2802 /** Create new CSI instance and return reference to it.
2804 * Create a new object, instance of @a csi.
2805 * XXX This does not work with generics as @a csi cannot specify a generic
2808 * Initialize the fields with default values of their types, but do not
2809 * run any constructor.
2811 * If @a sn is @c sn_nonstatic a regular object is created, containing all
2812 * non-static member variables. If @a sn is @c sn_static a static object
2813 * is created, containing all static member variables.
2815 * @param run Runner object
2816 * @param csi CSI to create instance of
2817 * @param sn @c sn_static to create a static (class) object,
2818 * @c sn_nonstatic to create a regular object
2819 * @param res Place to store result
2821 void run_new_csi_inst_ref(run_t
*run
, stree_csi_t
*csi
, statns_t sn
,
2824 rdata_var_t
*obj_var
;
2826 /* Create object. */
2827 run_new_csi_inst(run
, csi
, sn
, &obj_var
);
2829 /* Create reference to the new object. */
2830 run_reference(run
, obj_var
, res
);
2833 /** Create new CSI instance.
2835 * Create a new object, instance of @a csi.
2836 * XXX This does not work with generics as @a csi cannot specify a generic
2839 * Initialize the fields with default values of their types, but do not
2840 * run any constructor.
2842 * If @a sn is @c sn_nonstatic a regular object is created, containing all
2843 * non-static member variables. If @a sn is @c sn_static a static object
2844 * is created, containing all static member variables.
2846 * @param run Runner object
2847 * @param csi CSI to create instance of
2848 * @param sn @c sn_static to create a static (class) object,
2849 * @c sn_nonstatic to create a regular object
2850 * @param res Place to store result
2852 void run_new_csi_inst(run_t
*run
, stree_csi_t
*csi
, statns_t sn
,
2855 rdata_object_t
*obj
;
2856 rdata_var_t
*obj_var
;
2858 stree_symbol_t
*csi_sym
;
2859 stree_csimbr_t
*csimbr
;
2863 rdata_var_t
*mbr_var
;
2865 tdata_item_t
*field_ti
;
2867 csi_sym
= csi_to_symbol(csi
);
2869 #ifdef DEBUG_RUN_TRACE
2870 printf("Create new instance of CSI '");
2871 symbol_print_fqn(csi_sym
);
2875 /* Create the object. */
2876 obj
= rdata_object_new();
2877 obj
->class_sym
= csi_sym
;
2878 obj
->static_obj
= sn
;
2879 intmap_init(&obj
->fields
);
2881 obj_var
= rdata_var_new(vc_object
);
2882 obj_var
->u
.object_v
= obj
;
2884 /* For this CSI and all base CSIs */
2885 while (csi
!= NULL
) {
2887 /* For all members */
2888 node
= list_first(&csi
->members
);
2889 while (node
!= NULL
) {
2890 csimbr
= list_node_data(node
, stree_csimbr_t
*);
2892 /* Is it a member variable? */
2893 if (csimbr
->cc
== csimbr_var
) {
2894 var
= csimbr
->u
.var
;
2896 /* Is it static/nonstatic? */
2897 var_sn
= stree_symbol_has_attr(
2898 var_to_symbol(var
), sac_static
) ? sn_static
: sn_nonstatic
;
2900 /* Compute field type. XXX Memoize. */
2901 run_texpr(run
->program
, csi
, var
->type
,
2904 /* Create and initialize field. */
2905 run_var_new(run
, field_ti
, &mbr_var
);
2907 /* Add to field map. */
2908 intmap_set(&obj
->fields
, var
->name
->sid
,
2913 node
= list_next(&csi
->members
, node
);
2916 /* Continue with base CSI */
2917 csi
= csi
->base_csi
;
2923 /** Run constructor on an object.
2925 * @param run Runner object
2926 * @param obj Object to run constructor on
2927 * @param arg_vals Argument values (list of rdata_item_t)
2929 static void run_object_ctor(run_t
*run
, rdata_var_t
*obj
, list_t
*arg_vals
)
2931 stree_ident_t
*ctor_ident
;
2932 stree_symbol_t
*csi_sym
;
2934 stree_symbol_t
*ctor_sym
;
2936 run_proc_ar_t
*proc_ar
;
2939 csi_sym
= obj
->u
.object_v
->class_sym
;
2940 csi
= symbol_to_csi(csi_sym
);
2941 assert(csi
!= NULL
);
2943 #ifdef DEBUG_RUN_TRACE
2944 printf("Run object constructor from CSI '");
2945 symbol_print_fqn(csi_sym
);
2948 ctor_ident
= stree_ident_new();
2949 ctor_ident
->sid
= strtab_get_sid(CTOR_IDENT
);
2951 /* Find constructor. */
2952 ctor_sym
= symbol_search_csi_no_base(run
->program
, csi
, ctor_ident
);
2953 if (ctor_sym
== NULL
) {
2954 #ifdef DEBUG_RUN_TRACE
2955 printf("No constructor found.\n");
2960 ctor
= symbol_to_ctor(ctor_sym
);
2961 assert(ctor
!= NULL
);
2963 /* Create procedure activation record. */
2964 run_proc_ar_create(run
, obj
, ctor
->proc
, &proc_ar
);
2966 /* Fill in argument values. */
2967 run_proc_ar_set_args(run
, proc_ar
, arg_vals
);
2969 /* Run the procedure. */
2970 run_proc(run
, proc_ar
, &res
);
2972 /* Constructor does not return a value. */
2973 assert(res
== NULL
);
2975 /* Destroy procedure activation record. */
2976 run_proc_ar_destroy(run
, proc_ar
);
2978 #ifdef DEBUG_RUN_TRACE
2979 printf("Returned from constructor..\n");
2983 /** Return boolean value of an item.
2985 * Try to interpret @a item as a boolean value. If it is not a boolean
2986 * value, generate an error.
2988 * @param run Runner object
2989 * @param item Input item
2990 * @return Resulting boolean value
2992 bool_t
run_item_boolean_value(run_t
*run
, rdata_item_t
*item
)
2994 rdata_item_t
*vitem
;
2999 run_cvt_value_item(run
, item
, &vitem
);
3003 assert(vitem
->ic
== ic_value
);
3004 var
= vitem
->u
.value
->var
;
3006 assert(var
->vc
== vc_bool
);
3007 res
= var
->u
.bool_v
->value
;
3009 /* Free value item */
3010 rdata_item_destroy(vitem
);