Titan Core Initial Contribution
[deliverable/titan.core.git] / regression_test / functionReference / FuncRef.ttcn
1 /******************************************************************************
2 * Copyright (c) 2000-2014 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 ******************************************************************************/
8 module FuncRef
9 {
10
11 type function un_oper(in integer a) return integer;
12 type function bin_oper(in integer a, in integer b) return integer;
13
14 function neg(in integer a) return integer { return -a; }
15
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; }
19
20 type union operator_type
21 {
22 un_oper unary,
23 bin_oper binary
24 }
25
26 type record of operator_type operator_list;
27 type record of integer operand_list;
28
29 function calculate_expr(in operand_list operands, in operator_list operators)
30 return integer
31 {
32 var integer operand_count := sizeof(operands);
33 var integer operator_count := sizeof(operators);
34 var integer i;
35 var integer current_operand := 1;
36 var integer result := operands[0];
37 for (i:=0; i<operator_count; i:=i+1)
38 {
39 if (ischosen(operators[i].unary))
40 {
41 result := operators[i].unary.apply(result);
42 }
43 else
44 {
45 result := operators[i].binary.apply(result, operands[current_operand]);
46 current_operand := current_operand + 1;
47 }
48 }
49 return result;
50 }
51
52 type component FuncRef_comp {
53 port tcport TCP1, TCP2;
54 };
55
56 testcase calculationTest() runs on FuncRef_comp
57 {
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 log("result 1 = ", result_1);
68 log("result 2 = ", result_2);
69 if (result_1 == result_2) { setverdict(pass); }
70 else { setverdict(fail); }
71 }
72
73 template bin_oper bin_oper_tmpl := (refers(add), refers(sub));
74 template bin_oper bin_oper_tmpl2 := *;
75 template bin_oper bin_oper_tmpl3 := omit;
76
77 testcase funcTemplateTest() runs on FuncRef_comp
78 {
79 log(bin_oper_tmpl);
80 log(bin_oper_tmpl2);
81 log(bin_oper_tmpl3);
82 var bin_oper a := refers(add);
83 var bin_oper s := refers(sub);
84 var bin_oper m := refers(mul);
85 if ( match(a, bin_oper_tmpl) != match(s, bin_oper_tmpl) )
86 { setverdict(fail); }
87 if ( match(a, bin_oper_tmpl) == match(m, bin_oper_tmpl) )
88 { setverdict(fail); }
89 if ( match(s, bin_oper_tmpl) == match(m, bin_oper_tmpl) )
90 { setverdict(fail); }
91 if ( match(a, bin_oper_tmpl) != match(a, bin_oper_tmpl) )
92 { setverdict(fail); }
93 if ( match(s, bin_oper_tmpl) != match(s, bin_oper_tmpl) )
94 { setverdict(fail); }
95 if ( match(m, bin_oper_tmpl) != match(m, bin_oper_tmpl) )
96 { setverdict(fail); }
97 if (not match(m, bin_oper_tmpl2))
98 { setverdict(fail); }
99 if (match(m, bin_oper_tmpl3))
100 { setverdict(fail); }
101 setverdict(pass);
102 }
103
104 type function fn_type();
105 function fn1() { }
106 function fn2() { }
107 function fn_fn(in fn_type f) return fn_type { return f; }
108 template fn_type fntmpl := refers(fn1);
109
110 type function fn_temp_ret_type() return template integer;
111 function fn_temp_ret_fn() return template integer { return 1; }
112
113 testcase funcRefOperTest() runs on FuncRef_comp
114 {
115 var fn_type f1 := refers(fn1);
116 var fn_type f2 := refers(fn2);
117 const fn_type f1c := refers(fn1);
118 var fn_temp_ret_type fn_temp_ret_var := refers(fn_temp_ret_fn);
119 if (not(f1==f1)) { setverdict(fail); }
120 if (f1==f2) { setverdict(fail); }
121 if (not(f1!=f2)) { setverdict(fail); }
122 if (f1!=f1) { setverdict(fail); }
123 if (not(f1c==f1)) { setverdict(fail); }
124 if (f1c!=f1) { setverdict(fail); }
125 if (valueof(fntmpl)!=f1) { setverdict(fail); }
126 if (fn_fn(f1)!=f1) { setverdict(fail); }
127 if (fn_fn(valueof(f2))!=f2) { setverdict(fail); }
128 if (fn_fn(valueof(f2))==f1) { setverdict(fail); }
129 if(not(1 == valueof(fn_temp_ret_var.apply()))) { setverdict(fail); }
130 if(not(match(valueof(fn_temp_ret_var.apply()),fn_temp_ret_var.apply()))) { setverdict(fail); }
131 setverdict(pass);
132 }
133
134 type record my_message
135 {
136 fn_type f
137 }
138
139 type port TP message {
140 inout my_message;
141 } with { extension "internal" }
142
143 type component main {
144 port TP tp;
145 port TP tp2;
146 }
147
148 template my_message msg_tmpl := ?;
149
150 testcase transferTest() runs on main {
151 connect(mtc:tp, mtc:tp2);
152 const my_message sm1 := { refers(fn1) }
153 const my_message sm2 := { refers(fn2) }
154 var my_message rm1;
155 var my_message rm2;
156 tp.send(sm1);
157 tp.send(sm2);
158 tp2.receive(msg_tmpl) -> value rm1;
159 tp2.receive(msg_tmpl) -> value rm2;
160 if (rm1==rm2) { setverdict(fail); }
161 setverdict(pass);
162 }
163
164 type function fact_func_type(in integer num, inout integer steps,
165 in fact_func_type ff) return integer;
166
167 function factorial1(in integer num, inout integer steps) return integer
168 {
169 //log("factorial1 called");
170 steps := steps + 1;
171 if (num<2) { return 1; }
172 else { return num*factorial1(num-1,steps); }
173 }
174
175
176 function factorial2(in integer num, inout integer steps, in fact_func_type ff)
177 return integer
178 {
179 //log("factorial2 called");
180 steps := steps + 1;
181 if (num<2) { return 1; }
182 else { return num*ff.apply(num-1,steps,refers(factorial3)); }
183 }
184
185 function factorial3(in integer num, inout integer steps, in fact_func_type ff)
186 return integer
187 {
188 //log("factorial3 called");
189 steps := steps + 1;
190 if (num<2) { return 1; }
191 else { return num*ff.apply(num-1,steps,refers(factorial2)); }
192 }
193
194 testcase recursiveCallTest() runs on FuncRef_comp
195 {
196 var integer steps1 := 0;
197 var integer steps2 := 0;
198 if (factorial1(5,steps1) != factorial2(5,steps2,refers(factorial3)))
199 { setverdict(fail); }
200 if (steps1!=steps2) { setverdict(fail); }
201 setverdict(pass);
202 }
203
204
205 type function nested_rec_func(inout rec_list rl, in nested_rec_func nrf,
206 in integer depth);
207 type record rec_list
208 {
209 nested_rec_func nrf,
210 rec_list rl optional,
211 integer depth
212 }
213 function nrf_create_list_item(inout rec_list rl, in nested_rec_func nrf,
214 in integer depth)
215 {
216 if (depth>0)
217 {
218 var rec_list rl2 := { rl.nrf, omit, depth-1 }
219 rl.nrf.apply(rl2, rl2.nrf, rl2.depth);
220 rl.rl := rl2;
221 }
222 }
223
224 testcase listRecursionTest() runs on FuncRef_comp
225 {
226 var rec_list rl := { refers(nrf_create_list_item), omit, 5 }
227 rl.nrf.apply(rl, rl.nrf, rl.depth);
228 var integer expected_sum := 0+1+2+3+4+5;
229 var integer sum := rl.depth;
230 while (ispresent(rl.rl))
231 {
232 var rec_list rl2 := rl.rl;
233 rl := rl2;
234 sum := sum + rl.depth;
235 }
236 if (sum!=expected_sum) { setverdict(fail); }
237 setverdict(pass);
238 }
239
240
241 type function fv_type_1() return integer;
242 function fv_1_1() return integer { return 11; }
243 function fv_1_2() return integer { return 12; }
244 type function fv_type_2() return integer;
245 function fv_2_1() return integer { return 21; }
246 function fv_2_2() return integer { return 22; }
247 // test refers and apply operations
248 testcase funcRefOperationsTest() runs on FuncRef_comp
249 {
250 var fv_type_1 f11 := refers(fv_1_1);
251 var fv_type_1 f12 := refers(fv_1_2);
252 var fv_type_2 f21 := refers(fv_2_1);
253 var fv_type_2 f22 := refers(fv_2_2);
254 var template fv_type_1 tf11 := f11;
255 var template fv_type_2 tf21 := f21;
256 if (f11.apply()!=f11.apply()) { setverdict(fail); }
257 if (f11.apply()==f12.apply()) { setverdict(fail); }
258 var fv_type_1 f10 := valueof(tf11);
259 var fv_type_2 f20 := valueof(tf21);
260 if (f10.apply()!=f11.apply()) { setverdict(fail); }
261 if (f10.apply()==f12.apply()) { setverdict(fail); }
262 if (f10.apply()==f20.apply()) { setverdict(fail); }
263 if (not match(refers(fv_1_1), tf11)) { setverdict(fail); }
264 if (match(refers(fv_1_2), tf11)) { setverdict(fail); }
265 if (match(refers(fv_1_1), tf21)) { setverdict(fail); }
266 setverdict(pass);
267 }
268
269
270 type function fn_par() return fn_par;
271 function fnp0() return fn_par { return refers(fnp0) }
272 function fnp1() return fn_par { return refers(fnp1) }
273 function fnp2() return fn_par { return refers(fnp2) }
274 function fnp3() return fn_par { return refers(fnp3) }
275 function fnp4() return fn_par { return refers(fnp4) }
276 function fnpnull() return fn_par { return null; }
277 function fn_params(fn_par p1, in fn_par p2, out fn_par p3, inout fn_par p4)
278 {
279 if ( p1.apply()!=refers(fnp0) or p2.apply()!=refers(fnp0) or
280 p4.apply()!=refers(fnp0) ) { setverdict(fail); }
281 p1 := refers(fnp1);
282 p2 := refers(fnp2);
283 p3 := refers(fnp3);
284 p4 := refers(fnp4);
285 if (p1.apply()==null) { setverdict(fail); }
286 if (p1.apply()!=refers(fnp1)) { setverdict(fail); }
287 if (p2.apply()!=refers(fnp2)) { setverdict(fail); }
288 if (p3.apply()!=refers(fnp4)) { setverdict(fail); }
289 if (p4.apply()!=refers(fnp4)) { setverdict(fail); }
290 }
291 testcase funcRefParamsTest() runs on FuncRef_comp
292 {
293 var fn_par fnp := refers(fnp0);
294 if (fnp0()!=refers(fnp0)) { setverdict(fail); }
295 if (fnp.apply()!=fnp0()) { setverdict(fail); }
296 if (fnp.apply()==null) { setverdict(fail); }
297 //fn_params(fnp,fnp,fnp,fnp);
298 //if (fnp.apply()!=refers(fnp4)) { setverdict(fail); }
299
300 if (fnpnull()!=null) { setverdict(fail); }
301 fnp := refers(fnpnull);
302 if (fnp.apply()!=null) { setverdict(fail); }
303 if (fnp.apply()!=fnpnull()) { setverdict(fail); }
304
305 fnp := refers(fnp0);
306 if (fnp.apply().apply().apply() != fnp.apply()) { setverdict(fail); }
307 if (fnp0().apply() != refers(fnp0)) { setverdict(fail); }
308
309 setverdict(pass);
310 }
311
312
313 function fff() { }
314 type union UNION
315 {
316 function () f1,
317 function () f2,
318 function () f3
319 }
320 type set SET
321 {
322 function () f1 optional,
323 function () f2 optional,
324 function () f3 optional
325 }
326 type record REKORD
327 {
328 function () f1 optional,
329 function () f2 optional,
330 function () f3 optional
331 }
332 // test predefined functions: sizeof(), ispresent(), ischosen()
333 testcase predefFuncOnNestedCompoundTypesTest() runs on FuncRef_comp
334 {
335 var REKORD v_r := { refers(fff), omit, refers(fff) }
336 var SET v_s := { f1 := refers(fff), f2 := omit, f3 := refers(fff) }
337 var UNION v_u := { f2 := refers(fff) }
338 var template REKORD t_r := v_r;
339 var template SET t_s := v_s;
340 var template UNION t_u := v_u;
341 if ( sizeof(v_r)!=2 or not ispresent(v_r.f1) or ispresent(v_r.f2) or
342 not ispresent(v_r.f3) )
343 { setverdict(fail); }
344 if ( sizeof(t_r)!=2 or not ispresent(t_r.f1) or ispresent(t_r.f2) or
345 not ispresent(t_r.f3) )
346 { setverdict(fail); }
347 if ( sizeof(v_s)!=2 or not ispresent(v_s.f1) or ispresent(v_s.f2) or
348 not ispresent(v_s.f3) )
349 { setverdict(fail); }
350 if ( sizeof(t_s)!=2 or not ispresent(t_s.f1) or ispresent(t_s.f2) or
351 not ispresent(t_s.f3) )
352 { setverdict(fail); }
353 if ( ischosen(v_u.f1) or not ischosen(v_u.f2) or ischosen(v_u.f3) )
354 { setverdict(fail); }
355 if ( ischosen(t_u.f1) or not ischosen(t_u.f2) or ischosen(t_u.f3) )
356 { setverdict(fail); }
357 setverdict(pass);
358 }
359
360
361 type testcase tc_type() runs on FuncRef_comp;
362 type record of tc_type tc_recof;
363
364 type function MyFunction_RunsOnParent() runs on Parent_CT;
365 type function MyFunction_RunsOnChild() runs on Child_CT;
366 type function MyFunction_RunsOnSelf() runs on self;
367
368 type component Parent_CT
369 {
370 var MyFunction_RunsOnParent fs_parent := null;
371 var MyFunction_RunsOnSelf fs_self := null;
372 var charstring parent := "parent";
373 }
374
375 type component Child_CT extends Parent_CT
376 {
377 var MyFunction_RunsOnChild fs_child := null;
378 var charstring child := "child";
379 }
380
381 function f_parent(in MyFunction_RunsOnSelf p_self) runs on Parent_CT
382 {
383 p_self.apply();
384 }
385
386 function f_child() runs on Child_CT
387 {
388 child := "Running child function is done";
389 }
390
391 testcase tc_runsonself() runs on Child_CT
392 {
393 fs_self := refers(f_child);
394
395 f_parent(fs_self);
396
397 if(child != "Running child function is done")
398 {
399 setverdict(fail);
400 }
401 else { setverdict(pass); }
402 }
403
404 type port tcport message {
405 inout tc_recof
406 }
407 with { extension "internal" }
408
409 testcase tc_send_tc() runs on FuncRef_comp
410 {
411 var tc_recof sent_testcases := {
412 refers(tc_send_tc)
413 }, received_testcases;
414 connect(mtc:TCP1, mtc:TCP2);
415 TCP1.send(sent_testcases);
416 TCP2.receive(tc_recof : ?) -> value received_testcases;
417 if (received_testcases == sent_testcases) { setverdict(pass); }
418 else { setverdict(fail, match(received_testcases, sent_testcases)); }
419 disconnect(mtc:TCP1, mtc:TCP2);
420 }
421
422 // For TR HL26179.
423 type function f_myfunctype1(in charstring p1) runs on self
424 function f_myfunc1(in charstring p1) runs on empty_ct {}
425 type component empty_ct {var f_myfunctype1 v_myfuncvar1 := refers(f_myfunc1)}
426
427 testcase tc_functionrefIsbound() runs on FuncRef_comp
428 {
429 var fv_type_1 f0;
430 var fv_type_1 f1 := refers(fv_1_1);
431 if ( isvalue(f0) ) { setverdict(fail); } else { setverdict(pass); };
432 if ( isvalue(f1) ) { setverdict(pass); } else { setverdict(fail); };
433 }
434
435 // for TR H029700
436 type function f_FT();
437
438 function f_refers() {
439 var f_FT vf := valueof(f_FT:refers(f_refers));
440 }
441
442
443 control
444 {
445 var integer i;
446 var tc_recof testcases := {
447 refers(calculationTest),
448 refers(funcTemplateTest),
449 refers(funcRefOperTest),
450 refers(recursiveCallTest),
451 refers(listRecursionTest),
452 refers(funcRefOperationsTest),
453 refers(funcRefParamsTest),
454 refers(predefFuncOnNestedCompoundTypesTest)
455 }
456 for(i := 0; i < sizeof(testcases); i := i+1)
457 {
458 execute(derefers(testcases[i])());
459 }
460 execute(transferTest());
461 execute(tc_runsonself());
462 execute(tc_functionrefIsbound());
463 execute(tc_send_tc());
464 }
465 }
466
This page took 0.041645 seconds and 5 git commands to generate.