Mercurial > octave
view test/compile/bytecode_nested.m @ 32327:55ea70c8d00a
VM Remove forgotten feature block for nested functions (bug #64703)
Also allow compiling inline functions.
* libinterp/parse-tree/pt-bytecode-walk.cc: Remove check for nested, inline
* test/compile/bytecode_nested.m: Update tests
author | Petter T. <petter.vilhelm@gmail.com> |
---|---|
date | Sat, 23 Sep 2023 08:03:06 -0400 |
parents | 822314643f50 |
children | d738b7d335b5 |
line wrap: on
line source
function bytecode_nested () %% Empty function a = 1; b = 1; c = 1; function nested1 end nested1 nested1 (); %% Changes value of a function nested2 () assert (a == 1); a = 111; assert (a == 111); end nested2 (); assert (a == 111); %% Changes value of b function nested3 (a) assert (a == 2); a = 222; % Does not update a in parent b = 111; assert (a == 222); end a = 1; b = 1; c = 1; nested3 (2); assert (a == 1); % a still same, since argument in nested3 assert (b == 111); %% a, b and c are arguments and return values in nested4 %% and do not change in the outer frame function c = nested4 (a, b) assert (a == 3) assert (b == 4); a = 0; b = 0; c = 2; end a = 1; b = 1; c = 1; assert (nested4 (3, 4) == 2); assert (a == 1); assert (b == 1); assert (c == 1); %% Sets local variable that should not leak to this frame a = 1; b = 1; c = 1; nested5; assert (! exist ('d5')) function nested5 d5 = 3; assert (d5 == 3); end %% Calls empty nested function nested61 function nested6 function nested61 end end nested6; nested6 (); %% Nested function nested71 function nested7 a = 2; d7 = 2; function nested71 assert (a == 2) assert (d7 == 2) a = 3; d7 = 3; end nested71; assert (a == 3) assert (d7 == 3) end a = 1; b = 1; c = 1; nested7; assert (a == 3) %% Nested with args function b = nested8(a) assert (a == 2) b = 2; % Args and returns are not shared function b = nested81(a) assert (a == 3) b = 3; assert (b == 3) end nested81 (3); assert (a == 2) assert (b == 2) end a = 1; b = 1; c = 1; nested8 (2); assert (a == 1) assert (b == 1) %% Recursive nested function function b = nested9 (a) d9 = 0; % d9 is not shared with recursive calls assert (c == a + 1) c = a; a_cpy = a; % Test that argument are not changed by children if a == 0 b = 3; d9 = 3; % d9 does not change in parent frames return; end b = 0; b_tmp = nested9 (a - 1); assert (b == 0) b = b_tmp; assert (d9 == 0) assert (b == 3) assert (a == a_cpy) end a = 1; b = 1; c = 9; ret = nested9 (8); assert (a == 1) assert (b == 1) assert (c == 0) assert (ret == 3) %% Call siblings function b = nested10 (d10, e10=true) a = 1; b = 1; c = 1; nested7; assert (a == 3) a = 1; b = 1; c = 9; ret = nested9 (8); assert (a == 1) assert (b == 1) assert (c == 0) assert (ret == 3) if ! d10 return; end nested10 (d10 - 1, e10); % Test siblings from recursive call if e10 nested11 (); % Calls nested10 end end function nested11 nested10(2, false); a = 1; b = 1; c = 1; assert (nested4 (3, 4) == 2); assert (a == 1); assert (b == 1); assert (c == 1); end a = 1; b = 1; c = 1; nested10 (1); %% Test globals function nested12 assert (isglobal ("glb_d")) % Note: If a global is not added to the frame of nested12, % is is not marked as global. assert (!isglobal ("glb_e")) % Not a global, since not added to nested12's frame assert (glb_d == 3) glb_d = 4; eval ("glb_f = 24;"); % glb_f on dynamic frame in nested12 function nested12_1 assert (isglobal ("glb_d")) assert (isglobal ("glb_e")) assert (glb_d == 4) assert (glb_e == 13) eval ("assert (glb_f == 24)"); glb_d = 5; glb_e = 14; end nested12_1; nested_sibling13; end function nested_sibling13 assert (!isglobal ("glb_d")) assert (isglobal ("glb_e")) assert (glb_e == 14) glb_e = 15; end global glb_d; global glb_e; global glb_f; glb_d = 3; glb_e = 13; glb_f = 23; nested12; assert (glb_d == 5) assert (glb_e == 15) assert (glb_f == 24) %% Can't add dynamic variables function nested14 eval ("a14 = 3;") end try nested14; catch e assert (regexp (e.message, "can not add variable")); end try eval ("aaa = 3;") % Can't add dynamic variable in root either catch e assert (regexp (e.message, "can not add variable")); end %% evalin a = 1; b = 1; c = 1; function nested15 evalin ("caller", "assert (b == 3);"); a15 = 15; function nested15_1 (a15) evalin ("caller", "assert (a15 == 15);"); end nested15_1 (10); end b = 3; nested15; %% nargout, isargout a = 1; b = 1; c = 1; function [a, b, c] = nested16 () function [a, b, c] = nested16_1 () a = nargout; b = 2; c = 3; end a = nargout; b = 2; c = 3; glb_d = [isargout(1), isargout(2), isargout(3)]; [a2, b2, c2] = nested16_1 (); assert (a2 == 3); [a2, b2] = nested16_1 (); assert (a2 == 2); [a2] = nested16_1 (); assert (a2 == 1); end [a, b, c] = nested16 (); assert (a == 3); assert (glb_d == [1 1 1]) % isargout stored in glb_d [a, b] = nested16 (); assert (a == 2); assert (glb_d == [1 1 0]) [a] = nested16 (); assert (a == 1); assert (glb_d == [1 0 0]) [~] = nested16 (); assert (glb_d == [0 0 0]) [~, b] = nested16 (); assert (b == 2) assert (glb_d == [0 1 0]) [~, b, ~] = nested16 (); assert (b == 2) assert (glb_d == [0 1 0]) [~, b, c] = nested16 (); assert (b == 2) assert (c == 3) assert (glb_d == [0 1 1]) %% Call handle to nested function 1 function ret = nested17 ret = b; end b = 3; h1 = @nested17; assert (call_handle1 (h1) == 3); assert (h1 () == 3) b = 4; assert (call_handle1 (h1) == 4); %% Changes value in decoupled nested frame h2 = sub_returns_nested_fn; h3 = sub_returns_nested_fn; assert (h2() == 33) assert (h2() == 34) assert (call_handle1(h2) == 35) assert (h3() == 33) c1 = cdef_bar ("1"); % Two levels of nested nesting h4 = sub_returns_nested_fn2; assert (h4 () == 1) assert (h4 () == 2) % Try a function with both nested and anonymous functions (bug #64703) assert (sub_nestandanon (2) == [6; 8]) % Try some legacy inline functions h1i = inline ("x + 1"); assert (h1i (2) == 3) h2i = inline ("__vm_is_executing__()"); assert (h2i() == __vm_is_executing__); end function subby end function a = call_handle1 (h) a = h (); end function h = sub_returns_nested_fn () a = 33; c2 = cdef_bar ("2"); function ret = sub_nested1 ret = a; a++; c3 = cdef_bar ("3"); end h = @sub_nested1; end function h1 = sub_returns_nested_fn2 c2 = cdef_bar ("4"); function h2 = nested_fn1 a = 1; c3 = cdef_bar ("5"); function ret = nested_fn2 c4 = cdef_bar ("6"); ret = a; a++; end h2 = @nested_fn2; end h1 = nested_fn1 (); end function retval = sub_nestandanon(x) retval = zeros(2,1); f1 = @(x) 3 .* x; retval(1) = f1(x); function [ret] = f2(x) ret = 4 .* x; endfunction retval(2) = f2(x); endfunction