Skip to content

Commit

Permalink
Expanded some functions. Better compatibility with Octave
Browse files Browse the repository at this point in the history
* More consistent behaviour of the `im2col` function in MATLAB and in
Octave

* New section in the specification document about Octave compatibility

* `bitand`, `bitor`, `bitxor`, `lcm`, `gcd` now with singleton expansion

* Online help format compatible with Octave and Matlab versions older
than 7.13
  • Loading branch information
lmendo committed Dec 29, 2015
1 parent 77a5eba commit 98a2184
Show file tree
Hide file tree
Showing 13 changed files with 86 additions and 21 deletions.
Binary file modified MATL_spec.pdf
Binary file not shown.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# MATL
A programming language based on MATLAB and suitable for code golfing

The compiler works in MATLAB R2015b. Probably in older versions too, except for some specific functions.
The compiler works in MATLAB R2015b. Probably in older versions too, except for some specific functions. It is also compatible with Octave 4.0.0. The compiler tries to ensure consistent behaviour in both platforms.

Installation: unpack the compressed file to a folder, and make that folder part of MATLAB's path.
Installation: unpack the compressed file to a folder, and make that folder part of MATLAB's or Octave's search path.

Test: running `matl 10:t!*` from the MATLAB command window should produce a decimal multiplication table.
Test: running `matl 10:t!*` from the command window should produce a decimal multiplication table.

Usage: see [specification document](https://github.com/lmendo/MATL/blob/master/MATL_spec.pdf).
Binary file modified funDef.mat
Binary file not shown.
59 changes: 52 additions & 7 deletions funDef.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,15 @@ Z% 2 2 2 1 1 1 true true out{1} = typecast(in{:}); convert datatypes without cha
& 1 inf 2 1 1 1 true true y = in{1}; for n=2:numel(in), y = bsxfun(@and, y, in{n}); end; if numel(in)==1, y = logical(y); end; out{1} = y; clear y n; logical 'and' (element-wise, singleton expansion) \matlab+&+ (\matlab+and+), element-wise with singleton expansion
X& 2 4 2 1 3 1 true true [out{:}] = intersect(in{:}); set intersection \matlab+intersect+
Y&
Z& 2 3 2 1 1 1 true true out{1} = bitand(in{:}); bit-wise logical 'and' \matlab+bitand+
Z& 2 3 2 1 1 1 true true if max(size(in{1}))==1 || max(size(in{2}))==1 || isequal(size(in{1}), size(in{2})) bit-wise logical 'and' (element-wise, singleton expansion) \matlab+bitand+, element-wise with singleton expansion
out{1} = bitand(in{:});
else
nd = max(ndims(in{1}), ndims(in{2})); sz1 = arrayfun(@(n)size(in{1},n), 1:nd); sz2 = arrayfun(@(n)size(in{2},n), 1:nd);
assert(all(sz1==sz2 | sz1==1 | sz2==1), 'MATL:runtime', 'MATL run-time error: inputs have incompatible sizes')
rm1 = ones(1,nd); rm1(sz1==1) = sz2(sz1==1); rm2 = ones(1,nd); rm2(sz2==1) = sz1(sz2==1);
insx1 = repmat(in{1}, rm1); insx2 = repmat(in{2}, rm2); out{1} = bitand(insx1, insx2, in{3:end});
clear nd sz1 sz2 rm1 rm2 insx1 insx2
end
'
X'
Y' 1 1 1 2 2 2 true true data = in{1}(:); run-length encoding run-length encoding (inverse of \matlab+repelem+). Input may be an array or cell array. Numeric values must be finite
Expand Down Expand Up @@ -455,8 +463,18 @@ Zc 1 2 1 1 1 1 true true out{1} = strjoin(in{:}); join cell array of strings int
d 1 3 1 1 1 1 true true out{1} = diff(in{:}); difference \matlab+diff+
Xd 1 2 1 1 1 1 true true out{1} = diag(in{:}); diagonal matrices and diagonals of a matrix \matlab+diag+
Yd 1 inf 2 1 1 1 true true out{1} = blkdiag(in{:}); block diagonal concatenation \matlab+blkdiag+
Zd 1 2 2 1 3 1 true true if numel(in)==1 && numel(out)==1, x=in{1}(1); for t=in{1}, x=gcd(x,t); end; out{1}=x; greatest common divisor \matlab+gcd+. With $1$ input and $1$ output, computes the greatest common divisor of all elements of the input
else [out{:}] = gcd(in{:}); end
Zd 1 2 2 1 3 1 true true if numel(in)==1 && numel(out)==1, x=in{1}(1); for t=in{1}, x=gcd(x,t); end; out{1}=x; greatest common divisor (element-wise, singleton expansion) \matlab+gcd+, element-wise with singleton expansion. With $1$ input and $1$ output, computes the greatest common divisor of all elements of the input
else
if max(size(in{1}))==1 || max(size(in{2}))==1 || isequal(size(in{1}), size(in{2}))
[out{:}] = gcd(in{:});
else
nd = max(ndims(in{1}), ndims(in{2})); sz1 = arrayfun(@(n)size(in{1},n), 1:nd); sz2 = arrayfun(@(n)size(in{2},n), 1:nd);
assert(all(sz1==sz2 | sz1==1 | sz2==1), 'MATL:runtime', 'MATL run-time error: inputs have incompatible sizes')
rm1 = ones(1,nd); rm1(sz1==1) = sz2(sz1==1); rm2 = ones(1,nd); rm2(sz2==1) = sz1(sz2==1);
insx1 = repmat(in{1}, rm1); insx2 = repmat(in{2}, rm2); [out{:}] = gcd(insx1, insx2);
clear nd sz1 sz2 rm1 rm2 insx1 insx2
end
end
e 1 inf 3 1 1 1 true true if numel(in)>1, out{1} = reshape(in{:}); reshape array / remove singleton dimensions With more than $1$ input: \matlab+reshape+. With $1$ input: \matlab+squeeze+.
else out{1} = squeeze(in{:}); end
Xe
Expand Down Expand Up @@ -499,8 +517,18 @@ Zl 1 1 1 1 2 1 true true [out{:}] = log2(in{:}); base 2 logarithm \matlab+log2+
m 2 4 2 1 2 1 true true [out{:}] = ismember(in{:}); true for set member \matlab+ismember+. \sa \matl+Xm+
Xm 2 3 2 1 2 1 true true [out{:}] = ismember(in{1},in{2},'rows',in{3:end}); true for set member, row-wise \matlab+ismember(..., 'rows', ...)+. \sa \matl+m+
Ym 1 4 1 1 1 1 true true out{1} = mean(in{:}); mean value \matlab+mean+
Zm 1 2 2 1 1 1 true true if numel(in)==1, x=1; for t=in{1}, x=lcm(x,t); end; out{1}=x; least common multiple \matlab+lcm+. With $1$ input, computes the least common multiple of all elements of the input
else out{1} = lcm(in{:}); end
Zm 1 2 2 1 1 1 true true if numel(in)==1, x=1; for t=in{1}, x=lcm(x,t); end; out{1}=x; least common multiple (element-wise, singleton expansion) \matlab+lcm+, element-wise with singleton expansion. With $1$ input, computes the least common multiple of all elements of the input
else
if max(size(in{1}))==1 || max(size(in{2}))==1 || isequal(size(in{1}), size(in{2}))
out{1} = lcm(in{:});
else
nd = max(ndims(in{1}), ndims(in{2})); sz1 = arrayfun(@(n)size(in{1},n), 1:nd); sz2 = arrayfun(@(n)size(in{2},n), 1:nd);
assert(all(sz1==sz2 | sz1==1 | sz2==1), 'MATL:runtime', 'MATL run-time error: inputs have incompatible sizes')
rm1 = ones(1,nd); rm1(sz1==1) = sz2(sz1==1); rm2 = ones(1,nd); rm2(sz2==1) = sz1(sz2==1);
insx1 = repmat(in{1}, rm1); insx2 = repmat(in{2}, rm2); out{1} = lcm(insx1, insx2);
clear nd sz1 sz2 rm1 rm2 insx1 insx2
end
end
n 1 1 1 1 1 1 true true out{1} = numel(in{:}); number of elements in array \matlab+numel+
Xn 2 2 2 1 1 1 true true out{1} = nchoosek(in{:}); binomial coefficient or all combinations \matlab+nchoosek+
Yn 1 5 2 1 1 1 true true out{1} = interp1(in{:}); interpolation (table lookup) \matlab+interp1+. \matlab+'pp'+ option not supported
Expand Down Expand Up @@ -562,7 +590,15 @@ Z{ 1 1 1 1 1 1 true true sz = num2cell(size(in{1})); out{1} = mat2cell(in{1}, on
| 1 inf 2 1 1 1 true true y = in{1}; for n=2:numel(in), y = bsxfun(@or, y, in{n}); end; if numel(in)==1, y = logical(y); end; out{1} = y; clear y n; logical 'or' (element-wise, singleton expansion) \matlab+|+ (\matlab+or+), element-wise with singleton expansion
X| 2 4 2 1 3 1 true true [out{:}] = union(in{:}); set union \matlab+union+
Y| 1 2 1 1 1 1 true true out{1} = norm(in{:}); matrix or vector norm \matlab+norm+
Z| 2 3 2 1 1 1 true true out{1} = bitor(in{:}); bit-wise logical 'or' \matlab+bitor+
Z| 2 3 2 1 1 1 true true if max(size(in{1}))==1 || max(size(in{2}))==1 || isequal(size(in{1}), size(in{2})) bit-wise logical 'or' (element-wise, singleton expansion) \matlab+bitor+, element-wise with singleton expansion
out{1} = bitor(in{:});
else
nd = max(ndims(in{1}), ndims(in{2})); sz1 = arrayfun(@(n)size(in{1},n), 1:nd); sz2 = arrayfun(@(n)size(in{2},n), 1:nd);
assert(all(sz1==sz2 | sz1==1 | sz2==1), 'MATL:runtime', 'MATL run-time error: inputs have incompatible sizes')
rm1 = ones(1,nd); rm1(sz1==1) = sz2(sz1==1); rm2 = ones(1,nd); rm2(sz2==1) = sz1(sz2==1);
insx1 = repmat(in{1}, rm1); insx2 = repmat(in{2}, rm2); out{1} = bitor(insx1, insx2, in{3:end});
clear nd sz1 sz2 rm1 rm2 insx1 insx2
end
}
X}
Y} 1 1 1 1 1 1 true true out{1} = cell2mat(in{:}); convert contents of cell array into single array \matlab+cell2mat+
Expand All @@ -571,5 +607,14 @@ Z} 1 1 1 0 inf numel(in{1}) true true outall = mat2cell(in{1}(:), ones(1,numel(i
~ 1 1 1 1 1 1 true true out{1} = ~in{1}; logical 'not' (element-wise) \matlab+~+ (\matlab+not+)
X~ 2 4 2 1 3 1 true true [out{:}] = setxor(in{:}); set exclusive-or \matlab+setxor+
Y~ 2 2 2 1 1 1 true true out{1} = bsxfun(@xor, in{1}, in{2}); logical 'xor' (element-wise, singleton expansion) \matlab+xor+, element-wise with singleton expansion
Z~ 1 3 2 1 1 1 true true if numel(in)>=2 && isnumeric(in{2}), out{1} = bitxor(in{:}); bit-wise logical 'xor' or complement bits \matlab+bitxor+. With $1$ numeric input (and optionally a second string input): \matlab+bitcmp+
Z~ 1 3 2 1 1 1 true true if numel(in)>=2 && isnumeric(in{2}) bit-wise logical 'xor' (element-wise, singleton expanstion) or complement bits \matlab+bitxor+, element-wise with singleton expansion. With $1$ numeric input (and optionally a second string input): \matlab+bitcmp+
if max(size(in{1}))==1 || max(size(in{2}))==1 || isequal(size(in{1}), size(in{2}))
out{1} = bitxor(in{:});
else
nd = max(ndims(in{1}), ndims(in{2})); sz1 = arrayfun(@(n)size(in{1},n), 1:nd); sz2 = arrayfun(@(n)size(in{2},n), 1:nd);
assert(all(sz1==sz2 | sz1==1 | sz2==1), 'MATL:runtime', 'MATL run-time error: inputs have incompatible sizes')
rm1 = ones(1,nd); rm1(sz1==1) = sz2(sz1==1); rm2 = ones(1,nd); rm2(sz2==1) = sz1(sz2==1);
insx1 = repmat(in{1}, rm1); insx2 = repmat(in{2}, rm2); out{1} = bitxor(insx1, insx2, in{3:end});
clear nd sz1 sz2 rm1 rm2 insx1 insx2
end
else out{1} = bitcmp(in{:}); end
6 changes: 5 additions & 1 deletion genHelp.m
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,13 @@
end
end

%
descrNoTags = regexprep(descrFormatted,{'<strong>', '</strong>'}, '');

H.source = sourceFormatted;
H.comm = commFormatted;
H.descr = descrFormatted;
H.descr = descrFormatted; % description with format including tags
H.descrNoTags = descrNoTags; % description with format but without tags
H.in = inFormatted;
H.out = outFormatted;
H.sourcePlain = sourcePlain;
Expand Down
Binary file modified help.mat
Binary file not shown.
7 changes: 4 additions & 3 deletions matl.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function matl(varargin)
indentCommentText = 1; % number of spaces before actual comment. Default value
pOutFile = 'MATLp.txt'; % temporary file for parsed code
cOutFile = 'MATLc.m'; % temporary file for compiled code
cOutFileNoExt = regexprep('MATLc.m', '\.m$', ''); % without extension. Needed to run file in olf Matlab versions
cOutFileNoExt = regexprep('MATLc.m', '\.m$', ''); % without extension. Needed to run file in old Matlab versions
funDefMasterFile = 'funDef.txt'; % function definition master file
funDefMatFile = 'funDef.mat'; % function definition processed file
preLitMasterFile = 'preLit.txt'; % master file that defines predefined strings with (key, value) pairs
Expand All @@ -24,6 +24,7 @@ function matl(varargin)
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
verNum = str2double(regexp(verNum, '\.', 'split')); % version number as a vector

if numel(varargin)==0
options = 'r';
Expand Down Expand Up @@ -201,9 +202,9 @@ function matl(varargin)
% Call help, if required, and quit
if any(options=='h')
if nargin>1
matl_help(H, s, verbose)
matl_help(H, s, verbose, isMatlab, verNum)
else
matl_help(H, '', verbose)
matl_help(H, '', verbose, isMatlab, verNum)
end
return
end
Expand Down
11 changes: 9 additions & 2 deletions matl_compile.m
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@
appendLines('', 0)
appendLines('end', 0) % close function, in case there are subfunctions

% Define subfunctions
% Define subfunctions for compatibility with Octave
if ~isMatlab
appendLines('', 0)
% num2str
appendLines('% Define subfunctions', 0)
appendLines('', 0)
appendLines({...
Expand All @@ -202,6 +202,13 @@
'y = reshape(y.'',[],size(x,1)).''; y = strtrim(y);';
'end';
'end'}, 0)
% im2col
appendLines('', 0)
appendLines({...
'function y = im2col(varargin)';
'argin1 = varargin{1}; argin1 = reshape(argin1, size(argin1,1), []);';
'y = builtin(''im2col'', argin1, varargin{2:end});';
'end'}, 0)
end

if verbose
Expand Down
13 changes: 10 additions & 3 deletions matl_help.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function matl_help(H, strHelp, verbose)
function matl_help(H, strHelp, verbose, isMatlab, verNum)
%
% MATL help.
%
Expand Down Expand Up @@ -46,12 +46,19 @@ function matl_help(H, strHelp, verbose)
if verbose && ~isempty(ind)
disp(' ')
end
if isMatlab && (verNum(1)>7 || (verNum(1)==7 && verNum(2)>=13))
descrFieldName = 'descr';
sourceFieldName = 'source';
else
descrFieldName = 'descrNoTags';
sourceFieldName = 'sourcePlain';
end
for n = ind
disp([H.source{n} repmat(' ',1,4-numel(H.sourcePlain{n})) H.comm{n}]) % one or two spaces for left margin, total four characters
disp([H.(sourceFieldName){n} repmat(' ',1,4-numel(H.sourcePlain{n})) H.comm{n}]) % one or two spaces for left margin, total four characters
if ~isempty(H.in{n}) && ~isempty(H.in{n})
disp([' ' H.in{n}, '; ' H.out{n}]) % four spaces for left margin
end
disp(H.descr{n})
disp(H.(descrFieldName){n})
end
if verbose && ~isempty(ind)
disp(' ')
Expand Down
2 changes: 1 addition & 1 deletion matl_parse.m
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@
elseif any(s(pos)=='XYZ') && pos==L
error('MATL:parser', 'MATL error while parsing: <strong>%s</strong> not recognized at position %d', s(pos), pos)
else
error('MATL:parser:internal', 'MATL internal error while parsing')
error('MATL:parser', 'MATL error while parsing: unknown character <strong>%s</strong> at position %d', s(pos), pos)
end
end

Expand Down
2 changes: 1 addition & 1 deletion matl_run.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function matl_run(S, pOutFile, cOutFileNoExt, dbstopLines, isMatlab)
end

try
% run(cOutFileNoExt) % This doesn't seem to worl in Octave (4.0.0)
% run(cOutFileNoExt) % This doesn't seem to work in Octave (4.0.0)
evalin('caller', [cOutFileNoExt ';']);
catch ME
h = find(strcmp({ME.stack.name},cOutFileNoExt),1); % first error that refers to cOutFileNoExt
Expand Down
Binary file modified preLit.mat
Binary file not shown.
1 change: 1 addition & 0 deletions preLit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ X9
10 'v5uniform'
11 'v5normal'
12 'v4'
20 'seed'


Y0
Expand Down

0 comments on commit 98a2184

Please sign in to comment.