1 /******************************************************************************
2 * Copyright (c) 2000-2015 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 ******************************************************************************/
11 type function un_oper(in integer a) return integer;
12 type function bin_oper(in integer a, in integer b) return integer;
14 function neg(in integer a) return integer { return -a; }
16 function add(in integer a, in integer b) return integer { return a+b; }
17 function sub(in integer a, in integer b) return integer { return a-b; }
18 function mul(in integer a, in integer b) return integer { return a*b; }
20 type union operator_type
26 type record of operator_type operator_list;
27 type record of integer operand_list;
29 function calculate_expr(in operand_list operands, in operator_list operators)
32 var integer operand_count := sizeof(operands);
33 var integer operator_count := sizeof(operators);
35 var integer current_operand := 1;
36 var integer result := operands[0];
37 for (i:=0; i<operator_count; i:=i+1)
39 if (ischosen(operators[i].unary))
41 result := operators[i].unary.apply(result);
45 result := operators[i].binary.apply(result, operands[current_operand]);
46 current_operand := current_operand + 1;
52 type component FuncRef_comp {
53 port tcport TCP1, TCP2;
56 testcase calculationTest() runs on FuncRef_comp
58 var operand_list operands_1 := { 1, 2, 3 }; // -1 + 2 - 3 = -2
59 var operand_list operands_2 := { 2, 2, -6 }; // 2 * 2 + -6 = -2
60 var operator_list operators_1 := { { unary := refers(neg) },
61 { binary := refers(add) },
62 { binary := refers(sub) } };
63 var operator_list operators_2 := { { binary := refers(mul) },
64 { binary := refers(add) } };
65 var integer result_1 := calculate_expr(operands_1, operators_1);
66 var integer result_2 := calculate_expr(operands_2, operators_2);
67 if (result_1 == result_2) { setverdict(pass); }
68 else { setverdict(fail); }
71 template bin_oper bin_oper_tmpl := (refers(add), refers(sub));
72 template bin_oper bin_oper_tmpl2 := *;
73 template bin_oper bin_oper_tmpl3 := omit;
75 testcase funcTemplateTest() runs on FuncRef_comp
77 var bin_oper a := refers(add);
78 var bin_oper s := refers(sub);
79 var bin_oper m := refers(mul);
80 if ( match(a, bin_oper_tmpl) != match(s, bin_oper_tmpl) )
82 if ( match(a, bin_oper_tmpl) == match(m, bin_oper_tmpl) )
84 if ( match(s, bin_oper_tmpl) == match(m, bin_oper_tmpl) )
86 if ( match(a, bin_oper_tmpl) != match(a, bin_oper_tmpl) )
88 if ( match(s, bin_oper_tmpl) != match(s, bin_oper_tmpl) )
90 if ( match(m, bin_oper_tmpl) != match(m, bin_oper_tmpl) )
92 if (not match(m, bin_oper_tmpl2))
94 if (match(m, bin_oper_tmpl3))
99 type function fn_type();
102 function fn_fn(in fn_type f) return fn_type { return f; }
103 template fn_type fntmpl := refers(fn1);
105 type function fn_temp_ret_type() return template integer;
106 function fn_temp_ret_fn() return template integer { return 1; }
108 testcase funcRefOperTest() runs on FuncRef_comp
110 var fn_type f1 := refers(fn1);
111 var fn_type f2 := refers(fn2);
112 const fn_type f1c := refers(fn1);
113 var fn_temp_ret_type fn_temp_ret_var := refers(fn_temp_ret_fn);
114 if (not(f1==f1)) { setverdict(fail); }
115 if (f1==f2) { setverdict(fail); }
116 if (not(f1!=f2)) { setverdict(fail); }
117 if (f1!=f1) { setverdict(fail); }
118 if (not(f1c==f1)) { setverdict(fail); }
119 if (f1c!=f1) { setverdict(fail); }
120 if (valueof(fntmpl)!=f1) { setverdict(fail); }
121 if (fn_fn(f1)!=f1) { setverdict(fail); }
122 if (fn_fn(valueof(f2))!=f2) { setverdict(fail); }
123 if (fn_fn(valueof(f2))==f1) { setverdict(fail); }
124 if(not(1 == valueof(fn_temp_ret_var.apply()))) { setverdict(fail); }
125 if(not(match(valueof(fn_temp_ret_var.apply()),fn_temp_ret_var.apply()))) { setverdict(fail); }
129 type record my_message
134 type port TP message {
136 } with { extension "internal" }
138 type component main {
143 template my_message msg_tmpl := ?;
145 testcase transferTest() runs on main {
146 connect(mtc:tp, mtc:tp2);
147 const my_message sm1 := { refers(fn1) }
148 const my_message sm2 := { refers(fn2) }
153 tp2.receive(msg_tmpl) -> value rm1;
154 tp2.receive(msg_tmpl) -> value rm2;
155 if (rm1==rm2) { setverdict(fail); }
159 type function fact_func_type(in integer num, inout integer steps,
160 in fact_func_type ff) return integer;
162 function factorial1(in integer num, inout integer steps) return integer
165 if (num<2) { return 1; }
166 else { return num*factorial1(num-1,steps); }
170 function factorial2(in integer num, inout integer steps, in fact_func_type ff)
174 if (num<2) { return 1; }
175 else { return num*ff.apply(num-1,steps,refers(factorial3)); }
178 function factorial3(in integer num, inout integer steps, in fact_func_type ff)
182 if (num<2) { return 1; }
183 else { return num*ff.apply(num-1,steps,refers(factorial2)); }
186 testcase recursiveCallTest() runs on FuncRef_comp
188 var integer steps1 := 0;
189 var integer steps2 := 0;
190 if (factorial1(5,steps1) != factorial2(5,steps2,refers(factorial3)))
191 { setverdict(fail); }
192 if (steps1!=steps2) { setverdict(fail); }
197 type function nested_rec_func(inout rec_list rl, in nested_rec_func nrf,
202 rec_list rl optional,
205 function nrf_create_list_item(inout rec_list rl, in nested_rec_func nrf,
210 var rec_list rl2 := { rl.nrf, omit, depth-1 }
211 rl.nrf.apply(rl2, rl2.nrf, rl2.depth);
216 testcase listRecursionTest() runs on FuncRef_comp
218 var rec_list rl := { refers(nrf_create_list_item), omit, 5 }
219 rl.nrf.apply(rl, rl.nrf, rl.depth);
220 var integer expected_sum := 0+1+2+3+4+5;
221 var integer sum := rl.depth;
222 while (ispresent(rl.rl))
224 var rec_list rl2 := rl.rl;
226 sum := sum + rl.depth;
228 if (sum!=expected_sum) { setverdict(fail); }
233 type function fv_type_1() return integer;
234 function fv_1_1() return integer { return 11; }
235 function fv_1_2() return integer { return 12; }
236 type function fv_type_2() return integer;
237 function fv_2_1() return integer { return 21; }
238 function fv_2_2() return integer { return 22; }
239 // test refers and apply operations
240 testcase funcRefOperationsTest() runs on FuncRef_comp
242 var fv_type_1 f11 := refers(fv_1_1);
243 var fv_type_1 f12 := refers(fv_1_2);
244 var fv_type_2 f21 := refers(fv_2_1);
245 var fv_type_2 f22 := refers(fv_2_2);
246 var template fv_type_1 tf11 := f11;
247 var template fv_type_2 tf21 := f21;
248 if (f11.apply()!=f11.apply()) { setverdict(fail); }
249 if (f11.apply()==f12.apply()) { setverdict(fail); }
250 var fv_type_1 f10 := valueof(tf11);
251 var fv_type_2 f20 := valueof(tf21);
252 if (f10.apply()!=f11.apply()) { setverdict(fail); }
253 if (f10.apply()==f12.apply()) { setverdict(fail); }
254 if (f10.apply()==f20.apply()) { setverdict(fail); }
255 if (not match(refers(fv_1_1), tf11)) { setverdict(fail); }
256 if (match(refers(fv_1_2), tf11)) { setverdict(fail); }
257 if (match(refers(fv_1_1), tf21)) { setverdict(fail); }
262 type function fn_par() return fn_par;
263 function fnp0() return fn_par { return refers(fnp0) }
264 function fnp1() return fn_par { return refers(fnp1) }
265 function fnp2() return fn_par { return refers(fnp2) }
266 function fnp3() return fn_par { return refers(fnp3) }
267 function fnp4() return fn_par { return refers(fnp4) }
268 function fnpnull() return fn_par { return null; }
269 function fn_params(fn_par p1, in fn_par p2, out fn_par p3, inout fn_par p4)
271 if ( p1.apply()!=refers(fnp0) or p2.apply()!=refers(fnp0) or
272 p4.apply()!=refers(fnp0) ) { setverdict(fail); }
277 if (p1.apply()==null) { setverdict(fail); }
278 if (p1.apply()!=refers(fnp1)) { setverdict(fail); }
279 if (p2.apply()!=refers(fnp2)) { setverdict(fail); }
280 if (p3.apply()!=refers(fnp4)) { setverdict(fail); }
281 if (p4.apply()!=refers(fnp4)) { setverdict(fail); }
283 testcase funcRefParamsTest() runs on FuncRef_comp
285 var fn_par fnp := refers(fnp0);
286 if (fnp0()!=refers(fnp0)) { setverdict(fail); }
287 if (fnp.apply()!=fnp0()) { setverdict(fail); }
288 if (fnp.apply()==null) { setverdict(fail); }
289 //fn_params(fnp,fnp,fnp,fnp);
290 //if (fnp.apply()!=refers(fnp4)) { setverdict(fail); }
292 if (fnpnull()!=null) { setverdict(fail); }
293 fnp := refers(fnpnull);
294 if (fnp.apply()!=null) { setverdict(fail); }
295 if (fnp.apply()!=fnpnull()) { setverdict(fail); }
298 if (fnp.apply().apply().apply() != fnp.apply()) { setverdict(fail); }
299 if (fnp0().apply() != refers(fnp0)) { setverdict(fail); }
314 function () f1 optional,
315 function () f2 optional,
316 function () f3 optional
320 function () f1 optional,
321 function () f2 optional,
322 function () f3 optional
324 // test predefined functions: sizeof(), ispresent(), ischosen()
325 testcase predefFuncOnNestedCompoundTypesTest() runs on FuncRef_comp
327 var REKORD v_r := { refers(fff), omit, refers(fff) }
328 var SET v_s := { f1 := refers(fff), f2 := omit, f3 := refers(fff) }
329 var UNION v_u := { f2 := refers(fff) }
330 var template REKORD t_r := v_r;
331 var template SET t_s := v_s;
332 var template UNION t_u := v_u;
333 if ( sizeof(v_r)!=2 or not ispresent(v_r.f1) or ispresent(v_r.f2) or
334 not ispresent(v_r.f3) )
335 { setverdict(fail); }
336 if ( sizeof(t_r)!=2 or not ispresent(t_r.f1) or ispresent(t_r.f2) or
337 not ispresent(t_r.f3) )
338 { setverdict(fail); }
339 if ( sizeof(v_s)!=2 or not ispresent(v_s.f1) or ispresent(v_s.f2) or
340 not ispresent(v_s.f3) )
341 { setverdict(fail); }
342 if ( sizeof(t_s)!=2 or not ispresent(t_s.f1) or ispresent(t_s.f2) or
343 not ispresent(t_s.f3) )
344 { setverdict(fail); }
345 if ( ischosen(v_u.f1) or not ischosen(v_u.f2) or ischosen(v_u.f3) )
346 { setverdict(fail); }
347 if ( ischosen(t_u.f1) or not ischosen(t_u.f2) or ischosen(t_u.f3) )
348 { setverdict(fail); }
353 type testcase tc_type() runs on FuncRef_comp;
354 type record of tc_type tc_recof;
356 type function MyFunction_RunsOnParent() runs on Parent_CT;
357 type function MyFunction_RunsOnChild() runs on Child_CT;
358 type function MyFunction_RunsOnSelf() runs on self;
360 type component Parent_CT
362 var MyFunction_RunsOnParent fs_parent := null;
363 var MyFunction_RunsOnSelf fs_self := null;
364 var charstring parent := "parent";
367 type component Child_CT extends Parent_CT
369 var MyFunction_RunsOnChild fs_child := null;
370 var charstring child := "child";
373 function f_parent(in MyFunction_RunsOnSelf p_self) runs on Parent_CT
378 function f_child() runs on Child_CT
380 child := "Running child function is done";
383 testcase tc_runsonself() runs on Child_CT
385 fs_self := refers(f_child);
389 if(child != "Running child function is done")
393 else { setverdict(pass); }
396 type port tcport message {
399 with { extension "internal" }
401 testcase tc_send_tc() runs on FuncRef_comp
403 var tc_recof sent_testcases := {
405 }, received_testcases;
406 connect(mtc:TCP1, mtc:TCP2);
407 TCP1.send(sent_testcases);
408 TCP2.receive(tc_recof : ?) -> value received_testcases;
409 if (received_testcases == sent_testcases) { setverdict(pass); }
410 else { setverdict(fail, match(received_testcases, sent_testcases)); }
411 disconnect(mtc:TCP1, mtc:TCP2);
415 type function f_myfunctype1(in charstring p1) runs on self
416 function f_myfunc1(in charstring p1) runs on empty_ct {}
417 type component empty_ct {var f_myfunctype1 v_myfuncvar1 := refers(f_myfunc1)}
419 testcase tc_functionrefIsbound() runs on FuncRef_comp
422 var fv_type_1 f1 := refers(fv_1_1);
423 if ( isvalue(f0) ) { setverdict(fail); } else { setverdict(pass); };
424 if ( isvalue(f1) ) { setverdict(pass); } else { setverdict(fail); };
428 type function f_FT();
430 function f_refers() {
431 var f_FT vf := valueof(f_FT:refers(f_refers));
438 var tc_recof testcases := {
439 refers(calculationTest),
440 refers(funcTemplateTest),
441 refers(funcRefOperTest),
442 refers(recursiveCallTest),
443 refers(listRecursionTest),
444 refers(funcRefOperationsTest),
445 refers(funcRefParamsTest),
446 refers(predefFuncOnNestedCompoundTypesTest)
448 for(i := 0; i < sizeof(testcases); i := i+1)
450 execute(derefers(testcases[i])());
452 execute(transferTest());
453 execute(tc_runsonself());
454 execute(tc_functionrefIsbound());
455 execute(tc_send_tc());