%% $Revision: 1.1.6.2 $
%% 
%%
%% Copyright 1994-2003 The MathWorks, Inc.
%%
%% Abstract: If block parser library (subset of Simulink Fcn block)

%if EXISTS("_IFLIB_") == 0
%assign _IFLIB_ = 1

%% Function: FcnPrec ===========================================================
%% Abstract:
%%      Return the precedence of operator, x
%%
%function FcnPrec( x )

  %switch x
    %case "OR"
      %return 1
    %case "AND"
      %return 3
    %case "EQ"
    %case "NEQ"
      %return 5
    %case "LT"
    %case "GT"
    %case "LEQ"
    %case "GEQ"
      %return 7
    %default
      %% NOT, UNARYM, others
      %return 20
  %endswitch

%endfunction  %% FcnPrec



%% Function: FcnOpMap ==========================================================
%% Abstract:
%%      Map an the .rtw operator to the corresponding C statement
%%
%function FcnOpMap( x )

  %switch x
    %case "GT"
      %return "> "
    %case "LT"
      %return "< "
    %case "EQ"
      %return "== "
    %case "NEQ"
      %return "!="
    %case "GEQ"
      %return ">= "
    %case "LEQ"
      %return "<= "
    %case "AND"
      %return "&& "
    %case "OR"
      %return "|| "
    %case "NOT"
      %return "! "
    %case "UNARYM"
      %return "-"
    %default
      %%START_ASSERT
      %return x + " "
      %%END_ASSERT
  %endswitch

%endfunction %% FcnOpMap


%% Function: FcnAppendGenExprWithStr ===========================================
%% Abstract:
%%      Update the Fcn block general expression global character count
%%      variable and add new line to cExpression if needed, then append str.
%%
%function FcnAppendGenExprWithStr(block, str, addNewlineIfNeeded) void

  %if addNewlineIfNeeded == 0
    %assign ::GblFcnDisableNewline = 1
  %endif

  %if ::GblFcnDisableNewline == 0 && ::GblFcnCharCount + SIZE(str,1) >= 74
    %assign ::GblFcnCharCount = 4 %% assume indentation of four spaces
    %assign block.cExpression = block.cExpression + "\n"
  %endif

  %assign ::GblFcnCharCount = ::GblFcnCharCount + SIZE(str,1)

  %<SETFIELD(block, "cExpression", (block.cExpression + str))>

  %if addNewlineIfNeeded == 1
    %assign ::GblFcnDisableNewline = 0
  %endif

%endfunction  %% FcnAppendGenExprWithStr



%% Function: GenExpr ===========================================================
%% Abstract:
%%      Load update Block.Expr with a general fcn expression (see the
%%      Simulink Fcn block.
%%
%function GenExpr( block, node, ilev ) void

  %assign olev   = FcnPrec( node.Op )

  %% Add parens when needed according to C precedence rules and for
  %%   u(1) < 2.0 && u(2) < 1.0 || u(1) > 5
  %% where in C (but not Ada), this is valid, however most people
  %% have trouble remembering this, so we add the parens to produce
  %%   (u(1) < 2.0 && u(2) < 1.0) || u(1) > 5
  
  %assign paren  = olev < ilev || (olev == 3 && ilev == 1)

  
  %if EXISTS("node.RHS")
    %assign ilev = FcnPrec( node.RHS.Op )
  %else
    %assign ilev = 0
  %endif

  %if olev && ilev == olev
    %assign olev = olev + 1
  %endif

  %if paren
    %<FcnAppendGenExprWithStr(block,"( ",0)>
  %endif


  %assign nodeOpIsInputPort = IDNUM(node.Op)
  %if nodeOpIsInputPort[0] == "U"
    %%
    %% Special case: If the index into U is a single parameter and we
    %% are inlining parameters, then cast the resulting parameter to an INT
    %% before printing it.  It makes the output look a little nicer
    %%
    %if node.LHS.Op == "NUM"
      %assign sigIdx = CAST("Number",node.LHS.Value-1)
      %assign iport = nodeOpIsInputPort[1] - 1
      %assign str    = "%<LibBlockInputSignal(iport, "", "", sigIdx)>"
      %<FcnAppendGenExprWithStr(block,str,1)>
    %else
      %%START_ASSERT
      %<LibBlockReportError(block, "Index to u must be an integer")>
      %%END_ASSERT
    %endif

  %elseif node.Op == "NUM"
    %<LibCheckValue(0, node.Value)>
    %% enclose negative numbers in quotes
    %assign nodeValue = CAST("%<block.numericCast>",node.Value)
    %if node.Value < 0
      %assign str = "(%<nodeValue>) "
    %else
      %assign str = "%<nodeValue>"
    %endif
    %<FcnAppendGenExprWithStr(block,str,1)>
  %else

    %if EXISTS( "node.RHS" )
      %% Binary operator
      %<GenExpr( block, node.LHS, olev )>
      %<FcnAppendGenExprWithStr(block," ",0)>
      %<FcnAppendGenExprWithStr(block,FcnOpMap(node.Op),1)>
      %<GenExpr(block, node.RHS, olev)>
    %else
      %% Unary operator
      %<FcnAppendGenExprWithStr(block,"( ",0)>
      %<FcnAppendGenExprWithStr(block,FcnOpMap(node.Op),0)>
      %<GenExpr( block, node.LHS, olev )>
      %<FcnAppendGenExprWithStr(block,") ",0)>
    %endif

  %endif

  %if paren
    %<FcnAppendGenExprWithStr(block,") ",0)>
  %endif

%endfunction  %% GenExpr


%% Function: IfInputExpression ================================================
%% Abstract:
%%      Y = <expression>, where expression was entered in a Fcn block.
%%      Evaluate the fcn expression and add it to block.  Calling GenExpr will
%%      have the side-effect of having mdlhdr.tlc include rtlibsrc.h if the
%%      fcn block contains either the SGN or HYPOT operator
%%
%function IfInputExpression(ifPortIdx, block, system) void
  %%
  %% GblFcnCharCount is used to break the fcn block at 74 columns. Here
  %% we assume indentation of four spaces add the space for the output
  %% variable, then add 3 for the ' = '
  %%
  %assign ::GblFcnCharCount = 4 + 3
  %assign ::GblFcnDisableNewline = 0
  %<SETFIELD(block, "cExpression", "")>
  %assign dTypeId = LibBlockInputSignalAliasedThruDataTypeId(0)
  %if dTypeId == tSS_DOUBLE || dTypeId == tSS_SINGLE
    %assign numericCast = "Real"
  %else
    %assign numericCast = "Number"
  %endif
  %<SETFIELD(block, "numericCast", numericCast)>

  %<GenExpr( block, IfActionInfo[ifPortIdx].IfExprASTNode, 0 )>\
  %%
%return cExpression

%endfunction  %% IfInputExpression

%endif %% _IFLIB_


%% [EOF] iflib.tlc
