# formatEquation.frink

Download or view 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.     TODO:  Try to align vertically along midlines? */ /** Formats an expression.  This dispatches to the appropriate formatter     for the expression type and is generally called recursively. */ formatExpression[eq] := {    /* First, determine if an expression can be broken into a numerator and       denominator.  If the denominator is not 1, this means that it can be       broken up.  This takes care of division, exponentiation by negative       exponents, fractions, and more.  This formats into a vertically-separated       fraction divided by a horizontal line. */    [num, denom] = frac = numeratorDenominator[eq]    if denom != 1       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]    /** Handle other operators.  This should probably be extended to all        operator types like <=, >=, >, etc.  However, some operators have other        than 2 children and formatOperator currently only handles two-argument        infix operators.    */    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]    }    // Format the table into horizontally-separated sums.    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]    }    // Format the table into horizontally-separated sums with implicit operators    return formatTable[[parts]] } // Formats a power expression with raised exponent. formatPower[eq] := {    base = getChild[eq,0]    exp  = getChild[eq,1]    separate = false    // Format lower-precedence children in parentheses    baseF = formatExpression[base]    bp = getOperatorPrecedence[base]    if bp != undef and bp < getOperatorPrecedence[eq]       baseF = formatParensCompact[baseF]    /* If the exponent is an integer, format it inline as Unicode superscript       digits. */    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 and is infix. 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]], "", "", "", ""] }```

Download or view 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 19404 days, 6 hours, 17 minutes ago.