formatEquation.frink

View or download formatEquation.frink in plain text format


/** This contains functions for formatting equations into a traditional form,
    notably putting numerators above denominators in the result.   For example,
    this turns

    a d^-2 (b + e)^-1

    to

         a    
    ──────────
    d² (b + e)

    Or the continued fraction:
    f = noEval[a0 + b1 / (a1 + b2/(a2 + b3/(a3 + b4/(a4 + x))))]
    formatExpression[f]

    to

               b1         
     ─────────────────────
                 b2       
          ────────────────
a0 +                b3    
     a1 +      ───────────
          a2 +        b4  
               a3 + ──────
                    a4 + x

    This will hopefully be put into Frink as a new formatter.
*/


/** Formats an expression */
formatExpression[eq] :=
{
   [num, denom] = frac = numeratorDenominator[eq]
   if denom != 1
//      return formatTable[frac, "center", "center", "\u2500"]
   return formatTable[[formatExpression[num], formatExpression[denom]], "center", "center", "\u2500"]

   type = type[eq]

   if  type == "Add"
      return formatAdd[eq]

   if type == "Multiply"
      return formatMultiply[eq]

   if type == "Power"
      return formatPower[eq]

   if type == "FunctionCall"
      return formatFunctionCall[eq]

   if isOperator[eq]
   {
      op = getOperatorSymbol[eq]
      if op == " === " or op == " = " or op == " -> "
         return formatOperator[eq]
   }
   
   return eq
}

// Formats an addition expression to separate fractions.
formatAdd[eq] :=
{
   size = getChildCount[eq]
   parts = new array
   for i=0 to size-1
   {
      child = getChild[eq,i]
      if type[child] == "Multiply" and isNegativeUnit[getChild[child,0]]
      {
         parts.push["-"]
         child = -child
      } else
      if i > 0
         parts.push["+"]
      
      // Format lower-precedence children in parentheses
      ep = getOperatorPrecedence[child]
      expF = formatExpression[child]
      if ep != undef and ep < getOperatorPrecedence[eq]
         expF = formatParensCompact[expF]
      
      parts.push[expF]
   }

   return formatTable[[parts]]
}

// Formats a multiplication expression.
formatMultiply[eq] :=
{
   size = getChildCount[eq]
   parts = new array
   for i=0 to size-1
   {
      child = getChild[eq,i]

      // Format lower-precedence children in parentheses
      ep = getOperatorPrecedence[child]
      expF = formatExpression[child]
      if ep != undef and ep < getOperatorPrecedence[eq]
         expF = formatParensCompact[expF]

      parts.push[expF]
   }

   return formatTable[[parts]]
}

// Formats a power expression.
formatPower[eq] :=
{
   base = getChild[eq,0]
   exp  = getChild[eq,1]
   seperate = false

      // Format lower-precedence children in parentheses
   baseF = formatExpression[base]
   bp = getOperatorPrecedence[base]
   if bp != undef and bp < getOperatorPrecedence[eq]
      baseF = formatParensCompact[baseF]

   if isInteger[exp]
      expF = toUnicodeSuperscript[exp]
   else
   {
      expF = formatExpression[exp]
      separate = true
   }
   
   ep = getOperatorPrecedence[exp]
   if ep != undef and ep < getOperatorPrecedence[eq]
      expF = formatParensCompact[expF]

   if separate
      return formatTable[[["",expF],[baseF,""]], "center", "top", "", ""]
   else
      return formatTable[[[baseF,expF]], "center", "top", "", ""]
}

// Formats a function call in mathematical notation.
formatFunctionCall[eq] :=
{
   args = new array
   for i = 1 to getChildCount[eq]-1
   {
      if i > 1
         args.push[", "]
      args.push[formatExpression[getChild[eq,i]]]
   }
   
   return formatTable[[[getChild[eq,0], formatBracketsCompact[[args]]]], "", "","", "" ]
}

// Format operator that has 2 children.
formatOperator[eq] :=
{
   left =  getChild[eq,0]
   right = getChild[eq,1]
   leftF = formatExpression[left]
   rightF = formatExpression[right]

   // Format lower-precedence children in parentheses
   lp = getOperatorPrecedence[left]
   if lp != undef and lp < getOperatorPrecedence[eq]
      leftF = formatParensCompact[leftF]
   
   rp = getOperatorPrecedence[right]
   if rp != undef and rp < getOperatorPrecedence[eq]
      rightF = formatParensCompact[rightF]
   
   return formatTable[[[leftF,
                       getOperatorSymbol[eq],
                       rightF]], "", "", "", ""]
}


View or download formatEquation.frink in plain text format


This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 19146 days, 2 hours, 59 minutes ago.