function [stat,post] = blklogexp(path,prop,bstr,bint,bflt,parent,name,catalog,ws,node,sbSample)
%BLKLOGEXP Defines a set of logical expressions.
%
%  See also BLKALGEXP

% Initial coding by A S Bozin, 5-30-97
% Copyright 1997-2000 The MathWorks, Inc.
% $Revision: 1.8 $ $Date: 2000/06/14 16:09:52 $

   stat = 0;					   % Error flag
   nInputs = bint(5);
   nOutputs = bint(6);
   %
   % Add mux and demux blocks if necessary
   %
   [post,rect] = blkio('port',nInputs,nOutputs,prop,path);
   %
   % Get the pseudo code and the parameter vector
   %
   indInt = bint(15)+1;
   indStr = bint(17)+1;
   npar = 2;
   symInd = zeros(1,npar);
   if (bitand(bint(indInt),16))
      indVar = indInt+2;
      vRange = 1:bint(indVar);
      symInd(bint(indVar+vRange)) = 1;
   end
   str = cell(npar,1);
   for (k = find(symInd))
      ind = mfindstr(bstr,indStr,'|');
      str{k} = bstr(indStr:ind-1);
      indStr = ind+1;
   end
   %
   % Get the block parameter variables
   %
   [symInd,str] = mgetscope(symInd,str,catalog,ws,node);
   indFlt = bint(19);
   bFile = bint(18)+1;
   bFile = bFile+bint(bFile);			   % Skip icon data
   nData = bint(bFile);
   nPara = bint(bFile+1);
   stkSize = bint(bFile+3);
   nCode = bint(bFile+4);
   pLen = [nData;nPara];
   ub = cumsum(pLen);
   lb = [0;ub(1:end-1)]+1;
   for (k = find(~symInd))
      if (k == 1)
	 bCode = bFile+4;
	 cRange = 1:nCode;
	 code = bint(bCode+cRange);
	 dRange = lb(k):ub(k);
	 data = bflt(indFlt+dRange);
	 str{1} = pdecode(code,data,stkSize);
      else
	 pRange = lb(k):ub(k);
	 str{k} = mat2char(bflt(indFlt+pRange));
      end
   end
   %
   % Logical and/or relational expression block
   %
   logexp = 'libsb2sl/LOG/LogExpression';
   bh = add_block(logexp,path,...
		  'ForegroundColor',prop.fgColor,...
		  'BackgroundColor',prop.bgColor,...
		  'Orientation',prop.orientation,...
		  'DropShadow',prop.border,...
		  'Position',rect,...
		  'SRC',str{1},...
		  'P0',str{2},...
		  'TS',mat2char(sbSample));
   %
   % Connect the current logical expression block with the mux and demux blocks
   %
   blkio('line',nInputs,nOutputs,post,parent,name);
   return					   % Last card of BLKLOGEXP

function src = pdecode(code,data,stksize)
%PDECODE
%
%

   nCode = size(code,2);
   pc = 1;
   stack = cell(stksize,1);			   % Stack
   stype = zeros(stksize,1);
   tos = 0;					   % Top of the stack
   quote = char(39);				   % String delimiter
   src = quote;
   opsym = cell(32,1);
   opsym(13:17) = {'-';' + ';' - '; ...
		   ' * ';' / '};
   opsym(20:32) = {' EQV ';' NEQV '; ...
		   ' OR ';' NOR '; ...
		   ' AND ';' NAND '; ...
		   'NOT '; ...
		   ' <> ';' = ';' < ';' <= ';' > ';' >= '};
   while (pc < nCode)
      opCode = code(pc);
      pc = pc+1;
      switch (opCode)
      case 1					   % Push T
	 tos = tos+1;
	 stack{tos} = 'T';
	 stype(tos) = 0;
      case 2					   % Push U
	 tos = tos+1;
	 stack{tos} = sprintf('U%d',code(pc));
	 stype(tos) = 0;
	 pc = pc+1;
      case 4					   % Push NUM
	 tos = tos+1;
	 stack{tos} = sprintf('%g',data(code(pc)));
	 stype(tos) = 0;
	 pc = pc+1;
      case 5					   % Push P
	 tos = tos+1;
	 stack{tos} = sprintf('P%d',code(pc));
	 stype(tos) = 0;
	 pc = pc+1;
      case 7					   % Push Y
	 tos = tos+1;
	 stack{tos} = sprintf('Y%d',code(pc));
	 stype(tos) = 0;
	 pc = pc+1;
      case 9					   % Pop P
	 src = sprintf('%sP%d = %s;',src,code(pc),stack{tos});
	 pc = pc+1;
	 tos = tos-1;
      case 11				   	   % Pop Y
	 src = sprintf('%sY%d = %s;',src,code(pc),stack{tos});
	 pc = pc+1;
	 tos = tos-1;
      case 13				   	   % Unary minus
	 if (stype(tos) < 3)
	    fmt = '%s%s';
	 else
	    fmt = '%s(%s)';
	 end
	 stack{tos} = sprintf(fmt,opsym{opCode},stack{tos});
	 stype(tos) = 3;
      case {14,15}			   	   % Plus, minus
	 tos = tos-1;
	 if (stype(tos) <= 3)
	    if (stype(tos+1) < 3)
	       fmt = '%s%s%s';
	    else
	       fmt = '%s%s(%s)';
	    end
	 else
	    if (stype(tos+1) < 3)
	       fmt = '(%s)+%s';
	    else
	       fmt = '(%s)+(%s)';
	    end
	 end
	 stack{tos} = sprintf(fmt,stack{tos},opsym{opCode},stack{tos+1});
	 stype(tos) = 3;
      case {16,17}			   	   % Multiply, divide
	 tos = tos-1;
	 if (stype(tos) <= 2)
	    if (stype(tos+1) < 2)
	       fmt = '%s%s%s';
	    else
	       fmt = '%s%s(%s)';
	    end
	 else
	    if (stype(tos+1) < 2)
	       fmt = '(%s)%s%s';
	    else
	       fmt = '(%s)%s(%s)';
	    end
	 end
	 stack{tos} = sprintf(fmt,stack{tos},opsym{opCode},stack{tos+1});
	 stype(tos) = 2;
      case {18,19}				   % Power
	 tos = tos-1;
	 if (stype(tos) <= 1)
	    if (stype(tos+1) <= 1)
	       fmt = '%s ** %s';
	    else
	       fmt = '%s ** (%s)';
	    end
	 else
	    if (stype(tos+1) <= 1)
	       fmt = '(%s) ** %s';
	    else
	       fmt = '(%s) ** (%s)';
	    end
	 end
	 stack{tos} = sprintf(fmt,stack{tos},stack{tos+1});
	 stype(tos) = 1;
      case {20,21}			   	   % Equivalent, not equivalent
	 tos = tos-1;
	 if (stype(tos+1) < 8)
	    fmt = '%s%s%s';
	 else
	    fmt = '%s%s(%s)';
	 end
	 stack{tos} = sprintf(fmt,stack{tos},opsym{opCode},stack{tos+1});
	 stype(tos) = 8;
      case {22,23}			   	   % Or, nor
	 tos = tos-1;
	 if (stype(tos) <= 7)
	    if (stype(tos+1) < 7)
	       fmt = '%s%s%s';
	    else
	       fmt = '%s%s(%s)';
	    end
	 else
	    if (stype(tos+1) < 7)
	       fmt = '(%s)%s%s';
	    else
	       fmt = '(%s)%s(%s)';
	    end
	 end
	 stack{tos} = sprintf(fmt',stack{tos},opsym{opCode},stack{tos+1});
	 stype(tos) = 7;
      case {24,25}				   % And, nand
	 tos = tos-1;
	 if (stype(tos) <= 6)
	    if (stype(tos+1) < 6)
	       fmt = '%s%s%s';
	    else
	       fmt = '%s%s(%s)';
	    end
	 else
	    if (stype(tos+1) < 6)
	       fmt = '(%s)%s%s';
	    else
	       fmt = '(%s)%s(%s)';
	    end
	 end
	 stack{tos} = sprintf(fmt',stack{tos},opsym{opCode},stack{tos+1});
	 stype(tos) = 6;
      case 26				   	   % Not
	 if (stype(tos) < 5)
	    fmt = '%s%s';
	 else
	    fmt = '%s(%s)';
	 end
	 stack{tos} = sprintf(fmt,opsym{opCode},stack{tos});
	 stype(tos) = 5;
      case {27,28,29,30,31,32}			   % Not equal, equal, less than, less or equal,
                                                   % greater than, greater or equal
	 tos = tos-1;
	 if (stype(tos) <= 4)
	    if (stype(tos+1) < 4)
	       fmt = '%s%s%s';
	    else
	       fmt = '%s%s(%s)';
	    end
	 else
	    if (stype(tos+1) < 4)
	       fmt = '(%s)%s%s';
	    else
	       fmt = '(%s)%s(%s)';
	    end
	 end
	 stack{tos} = sprintf(fmt',stack{tos},opsym{opCode},stack{tos+1});
	 stype(tos) = 4;
      otherwise
      end
   end
   src = cat(2,src,quote);
   return					   % Last card of PDECODE

