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 19152 days, 20 hours, 59 minutes ago.