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 20136 days, 4 hours, 21 minutes ago.