Skip to content

Commit

Permalink
Compatibility with Octave
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lmendo committed Dec 28, 2015
1 parent 9150028 commit 77a5eba
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 22 deletions.
11 changes: 8 additions & 3 deletions matl.m
Expand Up @@ -20,6 +20,11 @@ function matl(varargin)
helpFile = 'help.mat';
matlInputPrompt = ' > ';

version = ver;
indMainName = find(ismember({version.Name}, {'MATLAB','Octave'}));
isMatlab = strcmp(version(indMainName).Name, 'MATLAB'); % 1 if Matlab, 0 if Octave
verNum = version(indMainName).Version; % version number as a string

if numel(varargin)==0
options = 'r';
inputNeeded = true;
Expand Down Expand Up @@ -233,7 +238,7 @@ function matl(varargin)
if verbose
disp('Compiling program')
end
S = matl_compile(S, F, L, pOutFile, cOutFile, verbose);
S = matl_compile(S, F, L, pOutFile, cOutFile, verbose, isMatlab);
%if verbose
% disp(' Done.')
%end
Expand All @@ -247,7 +252,7 @@ function matl(varargin)
%disp('--') %disp(repmat('-',size(str)))
pause
end
matl_run(S, pOutFile, cOutFileNoExt, []) % ...NoExt because a file name without extension is
matl_run(S, pOutFile, cOutFileNoExt, [], isMatlab) % ...NoExt because a file name without extension is
% needed in old Matlab versions
end

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

Expand Down
29 changes: 25 additions & 4 deletions matl_compile.m
@@ -1,4 +1,4 @@
function S = matl_compile(S, F, L, pOutFile, cOutFile, verbose)
function S = matl_compile(S, F, L, pOutFile, cOutFile, verbose, isMatlab)
%
% MATL compiler. Compiles into MATLAB code.
% Input: struct array with parsed statements.
Expand Down Expand Up @@ -48,10 +48,11 @@
appendLines('% Set initial conditions', 0)
appendLines('warningState = warning;', 0);
appendLines('format compact; format long; warning(''off'',''all'');', 0) % clc
if exist('rng', 'file') % in case an old Matlab version is used
if isMatlab && exist('rng', 'file') % recent Matlab version
appendLines('rng(''shuffle'')', 0)
else
warning('MATL has not been able to seed random number generator')
elseif isMatlab % old Matlab version
appendLines('rand(''seed'',sum(clock)); randn(''seed'',sum(clock))');
% else % Octave: seeds are set randomly automatically by Octave
end
appendLines('diary off; delete defout; diary defout', 0)
% For arrays with brackets or curly braces: F = false; T = true;
Expand Down Expand Up @@ -182,6 +183,26 @@
appendLines('', 0)
appendLines('% Set final conditions', 0)
appendLines('diary off; warning(warningState);', 0);
appendLines('', 0)
appendLines('end', 0) % close function, in case there are subfunctions

% Define subfunctions
if ~isMatlab
appendLines('', 0)
appendLines('% Define subfunctions', 0)
appendLines('', 0)
appendLines({...
'function y = num2str(varargin)';
'x = varargin{1}; x = reshape(x, size(x,1),[]);';
'if nargin==1 || ischar(varargin{1}) || isnumeric(varargin{2})'; % normal `num2str` function
'y = builtin(''num2str'', varargin{:});';
'else'; % interception
'fmt = varargin{2}; y = sprintf([fmt ''\n''], x.''); y = regexp(y, ''\n'', ''split''); y = y(1:end-1).'';';
'y = cellfun(@fliplr, y, ''uniformoutput'', false); y = char(y); y = fliplr(y);';
'y = reshape(y.'',[],size(x,1)).''; y = strtrim(y);';
'end';
'end'}, 0)
end

if verbose
fprintf(' Writing to file ''%s''\n', cOutFile')
Expand Down
5 changes: 4 additions & 1 deletion matl_parse.m
Expand Up @@ -299,7 +299,10 @@
% Include implicit statements in source code

% Mark existing statements as not implicit
[S(:).implicit] = deal(false);
%[S(:).implicit] = deal(false); % doesn't work in Octave (4.0.0)
for s = 1:numel(S)
S(s).implicit = false;
end

% Implicit ]
while parseNesting % While there is some loop or branch yet to be closed
Expand Down
43 changes: 29 additions & 14 deletions matl_run.m
@@ -1,4 +1,4 @@
function matl_run(S, pOutFile, cOutFile, dbstopLines)
function matl_run(S, pOutFile, cOutFileNoExt, dbstopLines, isMatlab)
%
% MATL runner and debugger: runs MATL code that has been compiled into MATLAB code. Catches MATLAB
% errors and references them to the MATL statement that caused them.
Expand All @@ -10,26 +10,41 @@ function matl_run(S, pOutFile, cOutFile, dbstopLines)
% Luis Mendo

if ~isempty(dbstopLines) % debug mode
for line = dbstopLines
eval([ 'dbstop in ' cOutFile ' at ' num2str(line) ])
if isMatlab
for line = dbstopLines
eval([ 'dbstop in ' cOutFileNoExt ' at ' num2str(line) ])
end
openvar('STACK')
openvar('S_IN'), openvar('S_OUT')
openvar('CB_H'), openvar('CB_I'), openvar('CB_J'), openvar('CB_K'), openvar('CB_L')
openvar('STACK') % This is to bring this variable to front
else % Octave
for line = dbstopLines
dbstop(cOutFileNoExt, line);
end
% No `openvar` in Octave (4.0.0)
end
openvar('STACK')
openvar('S_IN'), openvar('S_OUT')
openvar('CB_H'), openvar('CB_I'), openvar('CB_J'), openvar('CB_K'), openvar('CB_L')
openvar('STACK') % This is to bring this variable to front
else % non-debug mode
if exist(cOutFile,'file')
eval([ 'dbclear in ' cOutFile ]) % `eval`: I know, I know...
if isMatlab
if exist(cOutFileNoExt,'file')
eval([ 'dbclear in ' cOutFileNoExt ]) % `eval`: I know, I know...
end
else % Octave
if exist(cOutFileNoExt,'file')
dbclear(cOutFileNoExt);
delete([cOutFileNoExt '.m']) % Sometimes it looks like an old version of the file is run
% instead of the new compiled one. So I'm deleting the file just in case
end
end
end

try
run(cOutFile)
% run(cOutFileNoExt) % This doesn't seem to worl in Octave (4.0.0)
evalin('caller', [cOutFileNoExt ';']);
catch ME
[~, cOutFileNoExt] = fileparts(cOutFile);
h = find(strcmp({ME.stack.name},cOutFileNoExt),1); % first error that refers to cOutFile
% This is necessary because the error may have been issued not by cOutFile directly, but
% by a function called by cOutFile
h = find(strcmp({ME.stack.name},cOutFileNoExt),1); % first error that refers to cOutFileNoExt
% This is necessary because the error may have been issued not by cOutFileNoExt directly, but
% by a function called by cOutFileNoExt
if ~isempty(ME.stack(h))
k = ME.stack(h).line;
n = find([S(:).compileLine]<=k, 1, 'last');
Expand Down

0 comments on commit 77a5eba

Please sign in to comment.