Skip to content

Commit 77a5eba

Browse files
committed
Compatibility with Octave
The compiler now works with Octave. I have been able to run all example programs I have tried. However, this doesn't assure complete compatibility; more extensive testing needs to be done. Also, HTML tags in online help need to be removed in Octave (also in old Matlab versions) because they are not displayed properly. That will be done in a next release.
1 parent 9150028 commit 77a5eba

4 files changed

Lines changed: 66 additions & 22 deletions

File tree

‎matl.m‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ function matl(varargin)
2020
helpFile = 'help.mat';
2121
matlInputPrompt = ' > ';
2222

23+
version = ver;
24+
indMainName = find(ismember({version.Name}, {'MATLAB','Octave'}));
25+
isMatlab = strcmp(version(indMainName).Name, 'MATLAB'); % 1 if Matlab, 0 if Octave
26+
verNum = version(indMainName).Version; % version number as a string
27+
2328
if numel(varargin)==0
2429
options = 'r';
2530
inputNeeded = true;
@@ -233,7 +238,7 @@ function matl(varargin)
233238
if verbose
234239
disp('Compiling program')
235240
end
236-
S = matl_compile(S, F, L, pOutFile, cOutFile, verbose);
241+
S = matl_compile(S, F, L, pOutFile, cOutFile, verbose, isMatlab);
237242
%if verbose
238243
% disp(' Done.')
239244
%end
@@ -247,7 +252,7 @@ function matl(varargin)
247252
%disp('--') %disp(repmat('-',size(str)))
248253
pause
249254
end
250-
matl_run(S, pOutFile, cOutFileNoExt, []) % ...NoExt because a file name without extension is
255+
matl_run(S, pOutFile, cOutFileNoExt, [], isMatlab) % ...NoExt because a file name without extension is
251256
% needed in old Matlab versions
252257
end
253258

@@ -257,7 +262,7 @@ function matl(varargin)
257262
disp('Press any key to run MATL program in debug mode')
258263
pause
259264
end
260-
matl_run(S, pOutFile, cOutFileNoExt, [S.compileLine]) % ...NoExt because a file name without
265+
matl_run(S, pOutFile, cOutFileNoExt, [S.compileLine], isMatlab) % ...NoExt because a file name without
261266
% extension is needed in old Matlab versions
262267
end
263268

‎matl_compile.m‎

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function S = matl_compile(S, F, L, pOutFile, cOutFile, verbose)
1+
function S = matl_compile(S, F, L, pOutFile, cOutFile, verbose, isMatlab)
22
%
33
% MATL compiler. Compiles into MATLAB code.
44
% Input: struct array with parsed statements.
@@ -48,10 +48,11 @@
4848
appendLines('% Set initial conditions', 0)
4949
appendLines('warningState = warning;', 0);
5050
appendLines('format compact; format long; warning(''off'',''all'');', 0) % clc
51-
if exist('rng', 'file') % in case an old Matlab version is used
51+
if isMatlab && exist('rng', 'file') % recent Matlab version
5252
appendLines('rng(''shuffle'')', 0)
53-
else
54-
warning('MATL has not been able to seed random number generator')
53+
elseif isMatlab % old Matlab version
54+
appendLines('rand(''seed'',sum(clock)); randn(''seed'',sum(clock))');
55+
% else % Octave: seeds are set randomly automatically by Octave
5556
end
5657
appendLines('diary off; delete defout; diary defout', 0)
5758
% For arrays with brackets or curly braces: F = false; T = true;
@@ -182,6 +183,26 @@
182183
appendLines('', 0)
183184
appendLines('% Set final conditions', 0)
184185
appendLines('diary off; warning(warningState);', 0);
186+
appendLines('', 0)
187+
appendLines('end', 0) % close function, in case there are subfunctions
188+
189+
% Define subfunctions
190+
if ~isMatlab
191+
appendLines('', 0)
192+
appendLines('% Define subfunctions', 0)
193+
appendLines('', 0)
194+
appendLines({...
195+
'function y = num2str(varargin)';
196+
'x = varargin{1}; x = reshape(x, size(x,1),[]);';
197+
'if nargin==1 || ischar(varargin{1}) || isnumeric(varargin{2})'; % normal `num2str` function
198+
'y = builtin(''num2str'', varargin{:});';
199+
'else'; % interception
200+
'fmt = varargin{2}; y = sprintf([fmt ''\n''], x.''); y = regexp(y, ''\n'', ''split''); y = y(1:end-1).'';';
201+
'y = cellfun(@fliplr, y, ''uniformoutput'', false); y = char(y); y = fliplr(y);';
202+
'y = reshape(y.'',[],size(x,1)).''; y = strtrim(y);';
203+
'end';
204+
'end'}, 0)
205+
end
185206

186207
if verbose
187208
fprintf(' Writing to file ''%s''\n', cOutFile')

‎matl_parse.m‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,10 @@
299299
% Include implicit statements in source code
300300

301301
% Mark existing statements as not implicit
302-
[S(:).implicit] = deal(false);
302+
%[S(:).implicit] = deal(false); % doesn't work in Octave (4.0.0)
303+
for s = 1:numel(S)
304+
S(s).implicit = false;
305+
end
303306

304307
% Implicit ]
305308
while parseNesting % While there is some loop or branch yet to be closed

‎matl_run.m‎

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function matl_run(S, pOutFile, cOutFile, dbstopLines)
1+
function matl_run(S, pOutFile, cOutFileNoExt, dbstopLines, isMatlab)
22
%
33
% MATL runner and debugger: runs MATL code that has been compiled into MATLAB code. Catches MATLAB
44
% errors and references them to the MATL statement that caused them.
@@ -10,26 +10,41 @@ function matl_run(S, pOutFile, cOutFile, dbstopLines)
1010
% Luis Mendo
1111

1212
if ~isempty(dbstopLines) % debug mode
13-
for line = dbstopLines
14-
eval([ 'dbstop in ' cOutFile ' at ' num2str(line) ])
13+
if isMatlab
14+
for line = dbstopLines
15+
eval([ 'dbstop in ' cOutFileNoExt ' at ' num2str(line) ])
16+
end
17+
openvar('STACK')
18+
openvar('S_IN'), openvar('S_OUT')
19+
openvar('CB_H'), openvar('CB_I'), openvar('CB_J'), openvar('CB_K'), openvar('CB_L')
20+
openvar('STACK') % This is to bring this variable to front
21+
else % Octave
22+
for line = dbstopLines
23+
dbstop(cOutFileNoExt, line);
24+
end
25+
% No `openvar` in Octave (4.0.0)
1526
end
16-
openvar('STACK')
17-
openvar('S_IN'), openvar('S_OUT')
18-
openvar('CB_H'), openvar('CB_I'), openvar('CB_J'), openvar('CB_K'), openvar('CB_L')
19-
openvar('STACK') % This is to bring this variable to front
2027
else % non-debug mode
21-
if exist(cOutFile,'file')
22-
eval([ 'dbclear in ' cOutFile ]) % `eval`: I know, I know...
28+
if isMatlab
29+
if exist(cOutFileNoExt,'file')
30+
eval([ 'dbclear in ' cOutFileNoExt ]) % `eval`: I know, I know...
31+
end
32+
else % Octave
33+
if exist(cOutFileNoExt,'file')
34+
dbclear(cOutFileNoExt);
35+
delete([cOutFileNoExt '.m']) % Sometimes it looks like an old version of the file is run
36+
% instead of the new compiled one. So I'm deleting the file just in case
37+
end
2338
end
2439
end
2540

2641
try
27-
run(cOutFile)
42+
% run(cOutFileNoExt) % This doesn't seem to worl in Octave (4.0.0)
43+
evalin('caller', [cOutFileNoExt ';']);
2844
catch ME
29-
[~, cOutFileNoExt] = fileparts(cOutFile);
30-
h = find(strcmp({ME.stack.name},cOutFileNoExt),1); % first error that refers to cOutFile
31-
% This is necessary because the error may have been issued not by cOutFile directly, but
32-
% by a function called by cOutFile
45+
h = find(strcmp({ME.stack.name},cOutFileNoExt),1); % first error that refers to cOutFileNoExt
46+
% This is necessary because the error may have been issued not by cOutFileNoExt directly, but
47+
% by a function called by cOutFileNoExt
3348
if ~isempty(ME.stack(h))
3449
k = ME.stack(h).line;
3550
n = find([S(:).compileLine]<=k, 1, 'last');

0 commit comments

Comments
 (0)