Path: news.mathworks.com!newsfeed-00.mathworks.com!newsfeed2.dallas1.level3.net!news.level3.com!postnews.google.com!73g2000cwn.googlegroups.com!not-for-mail
From: daniel_nordlund_1982@hotmail.com
Newsgroups: comp.soft-sys.matlab
Subject: How to do GOTO in Matlab
Date: 10 Dec 2006 11:29:44 -0800
Organization: http://groups.google.com
Lines: 62
Message-ID: <1165778984.266098.310630@73g2000cwn.googlegroups.com>
NNTP-Posting-Host: 85.112.156.82
Mime-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"
X-Trace: posting.google.com 1165778990 18106 127.0.0.1 (10 Dec 2006 19:29:50 GMT)
X-Complaints-To: groups-abuse@google.com
NNTP-Posting-Date: Sun, 10 Dec 2006 19:29:50 +0000 (UTC)
User-Agent: G2/1.0
X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727),gzip(gfe),gzip(gfe)
Complaints-To: groups-abuse@google.com
Injection-Info: 73g2000cwn.googlegroups.com; posting-host=85.112.156.82;
Xref: news.mathworks.com comp.soft-sys.matlab:383093



I've seen many people on this newsgroup ask for a GOTO statement. Since
such a statement doesn't exist, I've decided to help MathWorks
implement one. Rather than a line number approach, I've based it on
named labels. Here's a fine example of how you can use it:

s=input('Are you sure (Y)es, (N)o, (M)aybe? ','s');
goto lower(s(1));
m:: goto 'n'+(rand>.5)*11;
y:: fprintf('You are sure\n'), goto 'ok';
n:: fprintf('You are not sure\n')
ok::

Note that labels end with :: and goto statements end with a ;. The
expression in a goto statement is converted to a string and execution
continues at the corresponding label. Illegal label names simply
terminate the program.

To be able to run this code, you must first transform it to valid
Matlab code. Just use the following helper function:

function s=gotofix(g)
f=fopen(g,'rt'); s=char(fread(f)'); fclose(f);
s=sprintf(['IP=pi; while IP try switch IP case pi\n%s  IP=[];' ...
' otherwise,IP=[];\nend,catch,[EM IP]=lasterr;if nnz(IP)<2|' ...
'IP(1)*IP(2)-6554\nerror(IP,EM),end,IP(1:2)=[];end,end\n'], ...
regexprep(s,{'(?m)^(.)','([\s,;])goto\s*([^;]+)','(\w+)\s*::' ...
},{'  $1','$1error([''q:'' $2],'''')','IP=''$1''; case''$1'','}));

Send the input m-file as an argument and the transformed file will be
returned. The result can be stored to a new m-file or executed
directly:

>> eval(gotofix('areyousure.m'))

For those interested, here's what the transformed version of the
example will look like:

IP=pi; while IP try switch IP case pi
  s=input('Are you sure (Y)es, (N)o, (M)aybe? ','s');
  error(['q:' lower(s(1))],'');
  IP='m'; case'm', error(['q:' 'n'+(rand>.5)*11],'');
  IP='y'; case'y', fprintf('You are sure\n'), error('q:ok','');
  IP='n'; case'n', fprintf('You are not sure\n')
  IP='ok'; case'ok',
  IP=[]; otherwise,IP=[];
end,catch,[EM IP]=lasterr;if nnz(IP)<2|IP(1)*IP(2)-6554
error(IP,EM),end,IP(1:2)=[];end,end

This technique can be used to make a more versatile goto statement
(work is in progress). Here are some limitations and notes for the
above version of GOTOFIX:
- Only works with scripts, not functions. (Easily fixed.)
- You can use it to jump OUT of for-loops, nested for-loops, if-blocks,
etc, but you can not jump INTO or BETWEEN them. You can fix this by
replacing all for, while, if-blocks, etc in your code with appropriate
GOTO constructs.
- The variables IP and EM are reserved and should not be used in your
code.
- The ASCII code for 'q' is prime. (Why is this important?)

Daniel