' CLEAN UP THE CODE!!!

''''' Use a new way to enter distance abbrev's in the equation.
''''' Instead of ac for acre perhaps Ctrl+a.
' Allow variables.
' Enable the calculator to evaluate algebraic equations.

'''''''''''''''''''''''''
'  Note:  AND overpowers OR
'  (Ex:  1 OR 2 AND 3, 2 and 3 must be true, or 1 must be true.)
'       (1) OR (2 AND 3)
'
'  (   The nth Root = EXP(LOG(a) / n)    )
'  (e ^ x = y: LOG(y) = x
'''''''''''''''''''''''''

'------------------------------------------------'
'-  Calculator                                  -'
'------------------------------------------------'
'-  Symbols
'-
'-  ! = Factorial
'-  ^ = Exponential   :  û = Root
'-  * = Multiplication:  / = Division
'-  + = Addition:        - = Subtraction
'-  ~ = Pie


'------------------------------------------------'
' Make sure that all unspecified types are of type integer.
DEFINT A-Z

'------------------------------------------------'
'- Declaration Of Sub Procedures And Functions. -'
'------------------------------------------------'
'  Initialization
DECLARE SUB Initialize ()
DECLARE SUB TextMain ()


'  Error Testing Functions
DECLARE FUNCTION CheckForPar (equation$)
DECLARE FUNCTION CheckForNumAndOper (equation$)
DECLARE FUNCTION Interperet$ (equation$)

DECLARE SUB ReportError (errnum, str1$, num1, str2$, num2, str3$, num3)
                                         

'  Retrieval Functions
DECLARE FUNCTION GetNums (equation$, befaft, symbol$, symnum)
DECLARE FUNCTION GetNumOfSymbol (equation$, symbol$, symnum)
DECLARE FUNCTION GetPosOfSymbol (equation$, symbol$, symnum, Start)
DECLARE FUNCTION GetPosOfSymbols (equation$, symbols$, symnum)
DECLARE FUNCTION GetPosOfPoint (num)

DECLARE FUNCTION Inputex$ (IntroStr$, InputStr$, Valid$, maxlen%)


'  String Functions
DECLARE FUNCTION RepPi$ (Orig$)
DECLARE FUNCTION Squeeze$ (Orig$, Char$)
DECLARE FUNCTION PrepareForAndReplace$ (equation$, symbol$, num#, Start, negnum)
DECLARE FUNCTION Replacer$ (equation$, Replace$, pos1, pos2)


'  Calculation Functions
DECLARE FUNCTION Calculate# (equation$, Start)
DECLARE FUNCTION CalcFac# (num#)
DECLARE FUNCTION CalcRoo# (num#, root#)
DECLARE FUNCTION CalcPow# (num#, exponent#)
DECLARE FUNCTION CalcMul# (factor1#, factor2#)
DECLARE FUNCTION CalcDiv# (dividend#, divisor#)
DECLARE FUNCTION CalcAdd# (addend1#, addend2#)
DECLARE FUNCTION CalcSub# (minuend#, subtrahend#)

DECLARE FUNCTION ConvertNum# (num#, str1$, str2$)
DECLARE FUNCTION ScienNotat# (num#)

'- Math Handling Routines
DECLARE SUB mInc (num)
DECLARE SUB mDec (num)
DECLARE SUB mToggle (num)


'  Help Subs
DECLARE SUB Help ()




'------------------------------------------------'
'- All Variables Shared Between Programs        -'
'------------------------------------------------'
' If debugging = 1, then the output will be altered to help with debugging.
COMMON SHARED debugging




'------------------------------------------------'
'- All Error Trapping Routines                  -'
'------------------------------------------------'
' If F1 is pressed, call the Help sub.
ON KEY(1) GOSUB CallHelpSub




'------------------------------------------------'
'- Declare All Global Variables                 -'
'------------------------------------------------'
'OPTION BASE 1
'------------------------------------------------'
CONST TRUE = 0
CONST FALSE = -1
CONST GRAPHICAL = TRUE
CONST TEXTONLY = FALSE

'Stores 0(GRAPHICAL) or -1(TEXTONLY) determining whether to use the
' graphical calculator interface or the command line type interface.
DIM SHARED CalcMode AS INTEGER

' Set the Pi CONST(can't be of type CONST due to being able to set
'                  the number of digits after the decimal.)
' You can choose from 2 to 15 decimal places of precision for Pi.
DIM SHARED Pi#

'The number of digits after the decimal.
DIM SHARED piprec

'Original - The exact string as entered by the user.
DIM SHARED Orig        AS STRING

'Solve - The strings to contain each step of the problem as it is solved.
DIM SHARED Solve(101)  AS STRING

'Solve Number - The number of strings in Solve used so far.
DIM SHARED solnum      AS INTEGER

'Previous String - The previously entered Orig's.
DIM SHARED PrevStr(26) AS STRING

'Do not remember what "Conv" means, Conv Number -
'1 - The line to put the checkmark on when displaying help.
'2 - The line after all of the help.
'    The line that begins where the equation is displayed.
DIM SHARED ConvNum(2)  AS INTEGER

'This should be gone.
DIM SHARED GoneToHelp  AS INTEGER

'Sub Level - The amount of times that Calculate has been
'            called before exiting the first call.
DIM SHARED sublvl      AS INTEGER

'All Symbols - The string containing all of the available operation symbols.
DIM SHARED allsym      AS STRING

'Legal Keys - The string containing all of the legally entered characters.
DIM SHARED legalkeys   AS STRING

'Any Error - If an error occured then this is -1.
DIM SHARED anyerror    AS INTEGER









'------------------------------------------------'
'- Begin The Program                            -'
'------------------------------------------------'
' Initialize all of the global variables.
Initialize
TextMain



'------------------------------------------------'
CallHelpSub:
  Help
  RETURN

FUNCTION CalcAdd# (addend1#, addend2#)
  'Add the numbers.
  z# = (addend1# + addend2#)
  'Get rid of any scientific notation in it.
  z# = ScienNotat#(z#)
  'Return the value.
  CalcAdd# = z#
END FUNCTION

FUNCTION CalcDiv# (dividend#, divisor#)
  'Divide the dividend by the divisor.
  z# = (dividend# / divisor#)
  'Get rid of any scientific notation in it.
  z# = ScienNotat#(z#)
  'Return the value.
  CalcDiv# = z#
END FUNCTION

FUNCTION CalcFac# (num#)
  'Begin at 1.
  z# = 1
  'Multiply by each whole number until you reach the current one.
  FOR i = 1 TO num#
    z# = z# * i
  NEXT i
  'Get rid of any scientific notation in it.
  z# = ScienNotat#(z#)
  'Return the value.
  CalcFac# = z#
END FUNCTION

FUNCTION CalcMul# (factor1#, factor2#)
  'Multpily the numbers.
  z# = (factor1# * factor2#)
  'Get rid of any scientific notation in it.
  z# = ScienNotat#(z#)
  'Return the value.
  CalcMul# = z#
END FUNCTION

FUNCTION CalcPow# (num#, exponent#)
' Calculates the exponent# power of num#
  'Begin negative toggle at TRUE.
  neg = 1
  'If the number is less than 0.
  IF num# < 0 THEN
    'For each in exponent toggle whether the result will be negative or positive.
    FOR i = 1 TO exponent#
      neg = neg * -1
    NEXT i
  END IF

  'Get the absolute value of the number.
  z# = ABS(num#)
 
  'Find the exponent# power of num#.
  z# = EXP(LOG(z#) * exponent#)
 
  'Make the result negative or positive depending on the toggle variable.
  z# = z# * neg
 
  'Get rid of any scientific notation in it.
  z# = ScienNotat#(z#)
 
  'If the exponent = 0 then return 1.
  IF exponent# = 0 THEN
    CalcPow# = 1

  'Otherwise return the value.
  ELSE
    'Return the value.
    CalcPow# = z#
  END IF
END FUNCTION

FUNCTION CalcRoo# (num#, root#)
' Calculates the root# root of num#
  'If either value is 0 then just return 0.
  IF num# = 0 OR root# = 0 THEN
    CalcRoo# = 0
  'Otherwise return the root# root of num#.
  ELSE
    CalcRoo# = EXP(LOG(num#) / root#)
  END IF
END FUNCTION

FUNCTION CalcSub# (minuend#, subtrahend#)
  'Subtract the subtrahend from the minuend.
  z# = (minuend# - subtrahend#)
  'Get rid of any scientific notation in it.
  z# = ScienNotat#(z#)
  'Return the value.
  CalcSub# = z#
END FUNCTION

FUNCTION Calculate# (equation$, Start)
  'Increment the number of times Calculate has been called without returning.
  mInc sublvl
 
  'Remember this step in the solving process.
  Solve(solnum) = (STRING$(Start, " ") + LEFT$(equation$, LEN(equation$) - 1)): mInc solnum
 
  'Display this step in the solving process.
  PRINT (STRING$(Start, " ") + LEFT$(equation$, (LEN(equation$) - 1)))

'Return to this after completing a set of parentheses.
FindParentheses:
  'For each character in the string.
  FOR i = 1 TO LEN(equation$)
    'Get the character.
    Middle$ = MID$(equation$, i, 1)

    'If it is a parenthesis.
    SELECT CASE Middle$
      CASE "(":
          'If it is an '(', then remember the position of it.
          parpos1 = i

      CASE ")":
          'If it is a ')', then remember the position of it and...
          parpos2 = i

          'Get the equation within the set of ().
          new$ = MID$(equation$, (parpos1 + 1), (parpos2 - parpos1 - 1))

          'Add an end-of-string marker to it.
          new$ = new$ + "`"

          'Do the equation within the ().
          num# = Calculate#(new$, (parpos1 + 1))

          'Get the string version of the answer and squeeze out all spaces.
          Replace$ = STR$(num#): Replace$ = Squeeze$(Replace$, " ")

          'If the answer is negative then change the '-' to a ':' to
          ' prevent confusion between negative and subtract.
          IF LEFT$(Replace$, 1) = "-" THEN
            MID$(Replace$, 1, 1) = ":"
          END IF
         
          'Replace the equation, and () within THIS equation with
          ' the answer to THAT equation.
          equation$ = Replacer$(equation$, Replace$, parpos1, parpos2)
          i = 0
         
          'Remember this step in the solving process.
          Solve(solnum) = (STRING$(Start, " ") + LEFT$(equation$, LEN(equation$) - 1)): mInc solnum
         
          'Display this step in the solving process.
          PRINT (STRING$(Start, " ") + LEFT$(equation$, (LEN(equation$) - 1)))

          'Go back, and search for any more ().
          GOTO FindParentheses

    END SELECT
  NEXT i 'Next character.

  'If this is the first call then there are is only 1 value left.  The answer.
  IF sublvl = 1 THEN
    'Return the answer
    Calculate# = VAL(equation$)
    'and exit the function.
    EXIT FUNCTION
  END IF

 
  'Otherwise...
  ' Extract Numbers and Operations
  DIM numbers(26)    AS DOUBLE
  DIM operations(25) AS STRING
  numstr$ = ""
  numnum = 1
  numoper = 1
  FOR i = 1 TO LEN(equation$)
    now$ = MID$(equation$, i, 1)
    IF INSTR(allsym$, now$) = 0 THEN : numstr$ = numstr$ + now$
    IF INSTR(allsym$, now$) > 0 THEN
      IF now$ = "`" THEN
        IF numstr$ <> "" THEN
          IF LEFT$(numstr$, 1) = ":" THEN
            MID$(numstr$, 1, 1) = "-"
          END IF
          numbers(numnum) = VAL(numstr$): mInc numnum: numstr$ = ""
        END IF
        EXIT FOR
      END IF
      IF numstr$ <> "" THEN
        nnum = numnum
        IF LEFT$(numstr$, 1) = ":" THEN
          MID$(numstr$, 1, 1) = "-"
        END IF
        numbers(numnum) = VAL(numstr$):  mInc numnum: numstr$ = ""
      END IF
      operations(numoper) = now$: mInc numoper
    END IF
  NEXT i


  'Calculate Factorials
  FOR i = 1 TO (numoper - 1)
    IF operations(i) = "!" THEN
      IF numbers(i) < 0 THEN : negnum = 1
      nownum# = CalcFac#(numbers(i))
      numbers(i) = nownum#
      numoper = numoper - 1
      FOR i2 = i TO 24
        operations(i2) = operations((i2 + 1))
      NEXT i2
      'Replace equation string piece with new number.
        equation$ = PrepareForAndReplace(equation$, "!", numbers(i), Start, negnum)
        equation$ = Squeeze$(equation$, " ")
        'Remember this step in the solving process.
        Solve(solnum) = (STRING$(Start, " ") + LEFT$(equation$, LEN(equation$) - 1)): mInc solnum
        PRINT (STRING$(Start, " ") + LEFT$(equation$, (LEN(equation$) - 1)))
      i = 0
    END IF
    IF numoper = 1 THEN EXIT FOR
  NEXT i

 
  'Calculate Powers
  FOR i = 1 TO (numoper - 1)
    IF operations(i) = "^" THEN
      IF numbers(i) < 0 THEN : negnum = 1
      IF numbers(i + 1) < 0 THEN : negnum = 2
      IF numbers(i) < 0 AND numbers(i + 1) < 0 THEN : negnum = 3
      nownum# = CalcPow#(numbers(i), numbers(i + 1))
      numbers(i) = nownum#
      mInc numnum
      FOR i2 = (i + 1) TO 24
        numbers(i2) = numbers((i2 + 1))
      NEXT i2
      mDec numoper
      FOR i2 = i TO 24
        operations(i2) = operations((i2 + 1))
      NEXT i2
      'Replace equation string piece with new number.
        equation$ = PrepareForAndReplace(equation$, "^", numbers(i), Start, negnum)
         'Remember this step in the solving process.
         Solve(solnum) = (STRING$(Start, " ") + LEFT$(equation$, LEN(equation$) - 1)): mInc solnum
         PRINT (STRING$(Start, " ") + LEFT$(equation$, (LEN(equation$) - 1)))
      i = 0
    END IF
    IF operations(i) = "û" THEN
      IF numbers(i) < 0 THEN : negnum = 1
      IF numbers(i + 1) < 0 THEN : negnum = 2
      IF numbers(i) < 0 AND numbers(i + 1) < 0 THEN : negnum = 3
      nownum# = CalcRoo#(numbers(i + 1), numbers(i))
      numbers(i) = nownum#
      numnum = numnum - 1
      FOR i2 = (i + 1) TO 24
        numbers(i2) = numbers((i2 + 1))
      NEXT i2
      numoper = numoper - 1
      FOR i2 = i TO 24
        operations(i2) = operations((i2 + 1))
      NEXT i2
      'Replace equation string piece with new number.
        equation$ = PrepareForAndReplace(equation$, "û", numbers(i), Start, negnum)
        'Remember this step in the solving process.
        Solve(solnum) = (STRING$(Start, " ") + LEFT$(equation$, LEN(equation$) - 1)): mInc solnum
        PRINT (STRING$(Start, " ") + LEFT$(equation$, (LEN(equation$) - 1)))
      i = 0
    END IF
    IF numoper = 1 THEN EXIT FOR
  NEXT i


  'Calculate Multiplication and Division from the Left to the Right
  FOR i = 1 TO (numoper - 1)
    IF operations(i) = "*" THEN
      IF numbers(i) < 0 THEN : negnum = 1
      IF numbers(i + 1) < 0 THEN : negnum = 2
      IF numbers(i) < 0 AND numbers(i + 1) < 0 THEN : negnum = 3
      nownum# = CalcMul#(numbers(i), numbers(i + 1))
      numbers(i) = nownum#
      numnum = numnum - 1
      FOR i2 = (i + 1) TO 24
        numbers(i2) = numbers((i2 + 1))
      NEXT i2
      numoper = numoper - 1
      FOR i2 = i TO 24
        operations(i2) = operations((i2 + 1))
      NEXT i2
      'Replace equation string piece with new number.
        equation$ = PrepareForAndReplace(equation$, "*", numbers(i), Start, negnum)
        equation$ = Squeeze$(equation$, " ")
        'Remember this step in the solving process.
        Solve(solnum) = (STRING$(Start, " ") + LEFT$(equation$, LEN(equation$) - 1)): mInc solnum
        PRINT (STRING$(Start, " ") + LEFT$(equation$, (LEN(equation$) - 1)))
      i = 0
    END IF
    IF operations(i) = "/" THEN
      IF numbers(i) < 0 THEN : negnum = 1
      IF numbers(i + 1) < 0 THEN : negnum = 2
      IF numbers(i) < 0 AND numbers(i + 1) < 0 THEN : negnum = 3
      nownum# = CalcDiv#(numbers(i), numbers(i + 1))
      numbers(i) = nownum#
      numnum = numnum - 1
      FOR i2 = (i + 1) TO 24
        numbers(i2) = numbers((i2 + 1))
      NEXT i2
      numoper = numoper - 1
      FOR i2 = i TO 24
        operations(i2) = operations((i2 + 1))
      NEXT i2
      'Replace equation string piece with new number.
        equation$ = PrepareForAndReplace(equation$, "/", numbers(i), Start, negnum)
        equation$ = Squeeze$(equation$, " ")
        'Remember this step in the solving process.
        Solve(solnum) = (STRING$(Start, " ") + LEFT$(equation$, LEN(equation$) - 1)): mInc solnum
        PRINT (STRING$(Start, " ") + LEFT$(equation$, (LEN(equation$) - 1)))
      i = 0
    END IF
    IF numoper = 1 THEN EXIT FOR
  NEXT i


  'Calculate Addition and Subtraction from the Left to the Right
  FOR i = 1 TO (numoper - 1)
    IF operations(i) = "+" THEN
      IF numbers(i) < 0 THEN : negnum = 1
      IF numbers(i + 1) < 0 THEN : negnum = 2
      IF numbers(i) < 0 AND numbers(i + 1) < 0 THEN : negnum = 3
      nownum# = CalcAdd#(numbers(i), numbers(i + 1))
      numbers(i) = nownum#
      numnum = numnum - 1
      FOR i2 = (i + 1) TO 24
        numbers(i2) = numbers((i2 + 1))
      NEXT i2
      numoper = numoper - 1
      FOR i2 = i TO 24
        operations(i2) = operations((i2 + 1))
      NEXT i2
      'Replace equation string piece with new number.
        equation$ = PrepareForAndReplace(equation$, "+", numbers(i), Start, negnum)
        equation$ = Squeeze$(equation$, " ")
        'Remember this step in the solving process.
        Solve(solnum) = (STRING$(Start, " ") + LEFT$(equation$, LEN(equation$) - 1)): mInc solnum
        PRINT (STRING$(Start, " ") + LEFT$(equation$, (LEN(equation$) - 1)))
      i = 0
    END IF
    IF operations(i) = "-" THEN
      IF numbers(i) < 0 THEN : negnum = 1
      IF numbers(i + 1) < 0 THEN : negnum = 2
      IF numbers(i) < 0 AND numbers(i + 1) < 0 THEN : negnum = 3
      nownum# = CalcSub#(numbers(i), numbers(i + 1))
      numbers(i) = nownum#
      numnum = numnum - 1
      FOR i2 = (i + 1) TO 24
        numbers(i2) = numbers((i2 + 1))
      NEXT i2
      numoper = numoper - 1
      FOR i2 = i TO 24
        operations(i2) = operations((i2 + 1))
      NEXT i2
      'Replace equation string piece with new number.
        equation$ = PrepareForAndReplace(equation$, "-", numbers(i), Start, negnum)
        equation$ = Squeeze$(equation$, " ")
        'Remember this step in the solving process.
        Solve(solnum) = (STRING$(Start, " ") + LEFT$(equation$, LEN(equation$) - 1)): mInc solnum
        PRINT (STRING$(Start, " ") + LEFT$(equation$, (LEN(equation$) - 1)))
      i = 0
    END IF
    IF numoper = 1 THEN EXIT FOR
  NEXT i
  
  Calculate# = numbers(1)
  sublvl = sublvl - 1
END FUNCTION

FUNCTION CheckForNumAndOper (equation$)
  ' Extract Numbers and Operations
  DIM numbers(26)    AS STRING
  DIM operations(25) AS STRING
  numstr$ = ""
  numnum = 1
  numoper = 1
  FOR i = 1 TO LEN(equation$)
    IF numoper > 24 THEN : numerror = 2: EXIT FOR
    now$ = MID$(equation$, i, 1)
    IF INSTR(allsym$, now$) = 0 THEN : numstr$ = numstr$ + now$
    IF INSTR(allsym$, now$) > 0 THEN
      IF now$ = "`" THEN
        IF numstr$ <> "" THEN
          IF LEFT$(numstr$, 1) = ":" THEN
            MID$(numstr$, 1, 1) = "-"
          END IF
          numbers(numnum) = numstr$: numnum = numnum + 1: numstr$ = ""
        END IF
        EXIT FOR
      END IF
      IF numstr$ <> "" THEN
        IF LEFT$(numstr$, 1) = ":" THEN
          MID$(numstr$, 1, 1) = "-"
        END IF
        numbers(numnum) = numstr$: mInc numnum: numstr$ = ""
      END IF
      operations(numoper) = now$: mInc numoper
    END IF
  NEXT i

 
  ' Check to make sure that there are no more than 24 operations.
  IF numerror = 2 THEN
    CALL ReportError(2, "", 0, "", 0, "", 0)
    CheckForNumAndOper = -1
    EXIT FUNCTION
  END IF

  ' Check to make sure there is at least one number.
  IF numnum = 1 THEN
    CALL ReportError(3, "", 0, "", 0, "", 0)
    CheckForNumAndOper = -1
    EXIT FUNCTION
  END IF
 
  ' Check for more than one decimal point in a number.
  FOR i = 1 TO 24
    FOR i2 = 1 TO LEN(numbers(i))
      IF MID$(numbers(i), i2, 1) = "." THEN
        mInc a
      END IF
      IF a > 1 THEN
        CALL ReportError(4, numbers(i), i2, "", 0, "", 0)
        CheckForNumAndOper = -1
        numerror = 0
        EXIT FUNCTION
      END IF
    NEXT i2
    a = 0
  NEXT i


  ' Check for two signs without a number between.
RestartCheckingForNumAndOper:
  allsym2$ = "(^*/+-"
  allsym3$ = ")!^*/+-`"
  x = LEN(equation$) - 1
  FOR i = 1 TO x
    now1$ = MID$(equation$, i, 1)
    now2$ = MID$(equation$, i + 1, 1)
    IF INSTR(allsym2$, now1$) > 0 THEN
      IF INSTR(allsym3$, now2$) > 0 THEN
        numerror = i
        EXIT FOR
      END IF
    END IF
    IF now1$ = "!" AND now2$ = "!" THEN
      numerror = i
      EXIT FOR
    END IF
  NEXT i
  IF numerror > 0 THEN
    CALL ReportError(5, equation$, i, now1$, 0, now2$, 0)
    CheckForNumAndOper = -1
    EXIT FUNCTION
  END IF
 
 
  ' Check for other parenthesis problems.
  allsym2$ = "(û^*/+-"
  allsym3$ = ")û!^*/+-`"
  x = LEN(equation$) - 1
  FOR i = 1 TO x
    now1$ = MID$(equation$, i, 1)
    now2$ = MID$(equation$, i + 1, 1)
    IF now2$ = "(" THEN                  'If a parenthesis is preceded by
      IF INSTR(allsym2$, now1$) = 0 THEN 'something OTHER than allsym2$
        equation$ = LEFT$(equation$, i) + "*" + RIGHT$(equation$, ((x + 1) - i))
        x = LEN(equation$) - 1: i = 0
      END IF
    ELSEIF now1$ = ")" THEN              'If a parenthesis is preceded by
      IF INSTR(allsym3$, now2$) = 0 THEN 'something OTHER than allsym3$
        equation$ = LEFT$(equation$, i) + "*" + RIGHT$(equation$, ((x + 1) - i))
        x = LEN(equation$) - 1: i = 0
      END IF
    END IF
  NEXT i
  IF numerror > 0 THEN
    CALL ReportError(6, now1$, 0, now2$, 0, "", 0)
    CheckForNumAndOper = -1
    EXIT FUNCTION
  END IF


  'Check for a non-whole number next to a factorial.
  FOR i = 1 TO 24
    FOR i2 = 1 TO LEN(numbers(i))
      IF MID$(numbers(i), i2, 1) = "." AND operations(i) = "!" THEN
        now1$ = numbers(i)
        CALL ReportError(7, now1$, 0, "", 0, "", 0)
        CheckForNumAndOper = 0
        numerror = 0
      END IF
    NEXT i2
  NEXT i

END FUNCTION

FUNCTION CheckForPar (equation$)
  FOR i = 1 TO LEN(equation$)
    mideq$ = MID$(equation$, i, 1)
    IF mideq$ = "(" THEN : mInc numL: IF last = 0 THEN : last = i
    IF mideq$ = ")" THEN : mDec numL:  IF numL = 0 THEN : last = 0
    IF mideq$ = "`" THEN
      IF numL > 0 THEN : parerror = last: EXIT FOR
    END IF
    IF numL < 0 THEN : parerror = i: EXIT FOR
    IF numL = 100 THEN : parerror = -1: EXIT FOR
  NEXT i
  CheckForPar = 0
  IF parerror > 0 THEN
    PRINT
    PRINT "Error:  Parentheses."
    PRINT LEFT$(equation$, LEN(equation$) - 1)
    LOCATE CSRLIN - 1, parerror
    COLOR 4: PRINT MID$(equation$, parerror, 1): COLOR 7
    CheckForPar = -1
  END IF
  IF parerror = -1 THEN
    PRINT
    PRINT "Error:  Parentheses."
    COLOR 4: PRINT "Over 100 parenthesis sets.": COLOR 7
    CheckForPar = -1
  END IF
END FUNCTION

FUNCTION ConvertNum# (num#, str1$, str2$)
  prefixlist$ = "MKHADCIæ"
  prefix1$ = LEFT$(str1$, 1)
  prefix2$ = LEFT$(str2$, 1)
  IF INSTR(prefixlist$, prefix1$) > 0 THEN
    MID$(str1$, 1, 1) = " "
    str1$ = Squeeze$(str1$, " ")
  END IF
  IF INSTR(prefixlist$, prefix2$) > 0 THEN
    MID$(str2$, 1, 1) = " "
    str2$ = Squeeze$(str2$, " ")
  END IF


  SELECT CASE prefix1$
    CASE "M": num# = ScienNotat#((num# / 1000000))
    CASE "K": num# = ScienNotat#((num# / 1000))
    CASE "H": num# = ScienNotat#((num# / 100))
    CASE "A": num# = ScienNotat#((num# / 10))

    CASE "D": num# = ScienNotat#((num# * 10))
    CASE "C": num# = ScienNotat#((num# * 100))
    CASE "I": num# = ScienNotat#((num# * 1000))
    CASE "æ": num# = ScienNotat#((num# * 1000000))
  END SELECT

 
  SELECT CASE str1$
    CASE "f"
      SELECT CASE str2$
        CASE "f": new# = num#
        CASE "c": new# = (5 / 9) * (num# - 32)
        CASE "k": new# = (5 / 9) * (num# - 32) + 273
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "c"
      SELECT CASE str2$
        CASE "f": new# = (9 / 5) * num# + 32
        CASE "c": new# = num#
        CASE "k": new# = num# + 273
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "k"
      SELECT CASE str2$
        CASE "f": new# = (num# - 273) * (9 / 5) + 32
        CASE "c": new# = num# - 273
        CASE "k": new# = num#
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT

    CASE "in"
      SELECT CASE str2$
        CASE "in": new# = num#
        CASE "ft": new# = num# / 12
        CASE "yd": new# = num# / 36
        CASE "rd": new# = num# / (16.5 * 12)
        CASE "smi": new# = num# / (5280 * 12)
        CASE "nmi": new# = num# / (1.151# * (5280# * 12#))
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "ft"
      SELECT CASE str2$
        CASE "in": new# = num# * 12
        CASE "ft": new# = num#
        CASE "yd": new# = num# / 3
        CASE "rd": new# = num# / 16.5
        CASE "smi": new# = num# / 5280
        CASE "nmi": new# = num# / (1.151 * 5280)
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "yd"
      SELECT CASE str2$
        CASE "in": new# = num# * 36
        CASE "ft": new# = num# * 3
        CASE "yd": new# = num#
        CASE "rd": new# = num# / 5.5
        CASE "smi": new# = num# / 1760
        CASE "nmi": new# = num# / (1.151 * 1760)
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "rd"
      SELECT CASE str2$
        CASE "in": new# = num# * 5.5 * 36
        CASE "ft": new# = num# * 5.5 * 3
        CASE "yd": new# = num# * 5.5
        CASE "rd": new# = num#
        CASE "smi": new# = num# / (1760 / 5.5)
        CASE "nmi": new# = num# / (1.151# * (1760# / 5.5#))
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "smi"
      SELECT CASE str2$
        CASE "in": new# = num# * (5280 * 12)
        CASE "ft": new# = num# * 5280
        CASE "yd": new# = num# * 1760
        CASE "rd": new# = num# * (1760 / 5.5)
        CASE "smi": new# = num#
        CASE "nmi": new# = num# / 1.151
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "nmi"
      SELECT CASE str2$
        CASE "in": new# = num# * ((5280# * 12#) * 1.151#)
        CASE "ft": new# = num# * (5280 * 1.151)
        CASE "yd": new# = num# * (1760 * 1.151)
        CASE "rd": new# = num# * ((1760# / 5.5#) * 1.151#)
        CASE "smi": new# = num# * 1.151
        CASE "nmi": new# = num#
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
   
    CASE "sqin"
      SELECT CASE str2$
        CASE "sqin": new# = num#
        CASE "sqft": new# = num# / 144
        CASE "sqyd": new# = num# / (9 * 144)
        CASE "ac":   new# = num# / (4840# * 9# * 144#)
        CASE "sqmi": new# = num# / (640# * 4840# * 9# * 144#)
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "sqft"
      SELECT CASE str2$
        CASE "sqin": new# = num# * 144
        CASE "sqft": new# = num#
        CASE "sqyd": new# = num# / 9
        CASE "ac":   new# = num# / (4840 * 9)
        CASE "sqmi": new# = num# / (640# * 4840# * 9#)
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "sqyd"
      SELECT CASE str2$
        CASE "sqin": new# = num# * (9 * 144)
        CASE "sqft": new# = num# * 9
        CASE "sqyd": new# = num#
        CASE "ac":   new# = num# / 4840
        CASE "sqmi": new# = num# / (4840 * 640)
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "ac"
      SELECT CASE str2$
        CASE "sqin": new# = num# * (4840# * 9# * 144#)
        CASE "sqft": new# = num# * (4840 * 9)
        CASE "sqyd": new# = num# * 4840
        CASE "ac":   new# = num#
        CASE "sqmi": new# = num# / 640
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "sqmi"
      SELECT CASE str2$
        CASE "sqin": new# = num# * (640# * 4840# * 9# * 144#)
        CASE "sqft": new# = num# * (640# * 4840# * 9#)
        CASE "sqyd": new# = num# * (640 * 4840)
        CASE "ac":   new# = num# * 640
        CASE "sqmi": new# = num#
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT

    CASE "cbin"
      SELECT CASE str2$
        CASE "cbin": new# = num#
        CASE "cbft": new# = num# / 1728
        CASE "cbyd": new# = num# / (27 * 1728)
        CASE "flou": new# = num# / 1.804
        CASE "pt": new# = num# / 28.875
        CASE "qt": new# = num# / 57.75
        CASE "gl": new# = num# / 231
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "cbft"
      SELECT CASE str2$
        CASE "cbin": new# = num# * 1728
        CASE "cbft": new# = num#
        CASE "cbyd": new# = num# / 27
        CASE "flou": new# = num# / (1.804 / 1728)
        CASE "pt": new# = num# / (28.875 / 1728)
        CASE "qt": new# = num# / (57.75 / 1728)
        CASE "gl": new# = num# / (231 / 1728)
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "cbyd"
      SELECT CASE str2$
        CASE "cbin": new# = num# * (27 * 1728)
        CASE "cbft": new# = num# * 27
        CASE "cbyd": new# = num#
        CASE "flou": new# = num# / (1.804 / (27 * 1728))
        CASE "pt": new# = num# / (28.875 / (27 * 1728))
        CASE "qt": new# = num# / (57.75 / (27 * 1728))
        CASE "gl": new# = num# / (231 / (27 * 1728))
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "flou"
      SELECT CASE str2$
        CASE "cbin": new# = num# * 1.804
        CASE "cbft": new# = num# * (1728 * 1.804)
        CASE "cbyd": new# = num# * (27 * 1728 * 1.804)
        CASE "flou": new# = num#
        CASE "pt": new# = num# / 16
        CASE "qt": new# = num# / (2 * 16)
        CASE "gl": new# = num# / (4 * 2 * 16)
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "pt"
      SELECT CASE str2$
        CASE "cbin": new# = num# * (16 * 1.804)
        CASE "cbft": new# = num# * (16 * 1728 * 1.804)
        CASE "cbyd": new# = num# * (16 * 27 * 1728 * 1.804)
        CASE "flou": new# = num# * 16
        CASE "pt": new# = num#
        CASE "qt": new# = num# / 2
        CASE "gl": new# = num# / (4 * 2)
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "qt"
      SELECT CASE str2$
        CASE "cbin": new# = num# * (2 * 16 * 1.804)
        CASE "cbft": new# = num# * (2 * 16 * 1728 * 1.804)
        CASE "cbyd": new# = num# * (2 * 16 * 27 * 1728 * 1.804)
        CASE "flou": new# = num# * (2 * 16)
        CASE "pt": new# = num# * 2
        CASE "qt": new# = num#
        CASE "gl": new# = num# / 4
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
    CASE "gl"
      SELECT CASE str2$
        CASE "cbin": new# = num# * (4 * 2 * 16 * 1.804)
        CASE "cbft": new# = num# * (4 * 2 * 16 * 1728 * 1.804)
        CASE "cbyd": new# = num# * (4 * 2 * 16 * 27 * 1728 * 1.804)
        CASE "flou": new# = num# * (4 * 2 * 16)
        CASE "pt": new# = num# * (4 * 2)
        CASE "qt": new# = num# * 4
        CASE "gl": new# = num#
        CASE ELSE: CALL ReportError(9, str1$, 0, str2$, 0, "", 0)
      END SELECT
  END SELECT



  SELECT CASE prefix2$
    CASE "M": new# = ScienNotat#((new# * 1000000))
    CASE "K": new# = ScienNotat#((new# * 1000))
    CASE "H": new# = ScienNotat#((new# * 100))
    CASE "A": new# = ScienNotat#((new# * 10))

    CASE "D": new# = ScienNotat#((new# / 10))
    CASE "C": new# = ScienNotat#((new# / 100))
    CASE "I": new# = ScienNotat#((new# / 1000))
    CASE "æ": new# = ScienNotat#((new# / 1000000))
  END SELECT


  ConvertNum# = new#
END FUNCTION

FUNCTION GetNumOfSymbol (equation$, symbol$, symnum)
  symnums = 0
  totalsyms = 0
  FOR i2 = 1 TO LEN(equation$)
    nowstr$ = MID$(equation$, i2, 1)
    IF INSTR(allsym$, nowstr$) > 0 THEN : mInc totalsyms
    IF nowstr$ = symbol$ THEN : mInc symnums
    IF symnums = symnum THEN : EXIT FOR
  NEXT i2
  GetNumOfSymbol = totalsyms
END FUNCTION

FUNCTION GetNums (equation$, befaft, symbol$, symnum)
' befaft - Before or after the symbol.
' symnum - Use the symnum occurence of the symbol.

'  IF befaft = 1 THEN 'Before
'    numofsym = GetNumOfSymbol(equation$, symbol$, symnum)
'    prevsympos = GetPosOfSymbols(equation$, allsym$, (numofsym - 1))
'    numofprevsym = Get
'    GetNums(equation$, 2, ,
'    GetNums = 0
'  ELSEIF befaft = 2 THEN 'After
'    sympos = GetPosOfSymbol(equation$, symbol$, symnum, 1)
'    FOR i = (sympos + 1) TO LEN(equation$)
'      now$ = MID$(equation$, i, 1)
'      IF INSTR(allsym$, now$) > 0 THEN : nextsym = i: EXIT FOR
'    NEXT i
'    numstr$ = MID$(equation$, (sympos + 1), (nextsym - (sympos + 1)))
'    GetNums = VAL(numstr$)
'  END IF
END FUNCTION

FUNCTION GetPosOfPoint (num)
  GetPosOfPoint = 0
  numstr$ = Squeeze$(STR$(num), " ")
  FOR i = 1 TO LEN(numstr$)
    IF MID$(numstr$, i, 1) = "." THEN : GetPosOfPoint = i
  NEXT i
END FUNCTION

FUNCTION GetPosOfSymbol (equation$, symbol$, symnum, Start)
  sympos = 0
  FOR i = 1 TO symnum
    FOR i2 = (sympos + 1) TO LEN(equation$)
      IF MID$(equation$, i2, 1) = symbol$ THEN : sympos = i2: EXIT FOR
    NEXT i2
  NEXT i
  GetPosOfSymbol = sympos + Start
END FUNCTION

FUNCTION GetPosOfSymbols (equation$, symbols$, symnum)
  sympos = 0
  FOR i = 1 TO symnum
    FOR i2 = (sympos + 1) TO LEN(equation$)
      nowstr$ = MID$(equation$, i2, 1)
      IF INSTR(symbols$, nowstr$) > 0 THEN : sympos = i2: EXIT FOR
    NEXT i2
  NEXT i
  GetPosOfSymbols = sympos
END FUNCTION

SUB Help
  VIEW PRINT 1 TO 24
  CLS 2
  oldConvNum = ConvNum(1)
  LOCATE 1, 1, 0
  PRINT "-----------------------------------------------------"
  PRINT "|                                                   |"
  PRINT "| 0. _ None                                         |"
  PRINT "| 1. _ Order of Operations                          |"
  PRINT "| 2. _ Temperature Conversions                      |"
  PRINT "| 3. _ Prefix Conversions                           |"
  PRINT "| 4. _ Measurement Table 1                          |"
  PRINT "| 5. _ Measurement Table 2                          |"
  PRINT "| 6. _ Measurement Table 3                          |"
  PRINT "| 7.   Set the precision level for Pi.              |"
  IF CalcMode = GRAPHICAL THEN
    PRINT "| 8.   Use Calculator With Graphics                 |"
  ELSEIF CalcMode = TEXTONLY THEN
    PRINT "| 8.   Use Calculator With Text Only                |"
  END IF
  PRINT "| Shft+Tab = Example                                |"
  PRINT "| Ctrl+R for Root(û)                                |"
  PRINT "| Enter nothing to quit.                            |"
  PRINT "|                                                   |"
  PRINT "-----------------------------------------------------"
  PRINT
  PRINT " Press Enter(Return) to Return."


  COLOR 15
  LOCATE (ConvNum(1) + 3), 6
  PRINT "û": LOCATE 12, 1

  DO
    old = ConvNum(1)
    SELECT CASE INKEY$
      CASE "0": ConvNum(1) = 0
      CASE "1": ConvNum(1) = 1
      CASE "2": ConvNum(1) = 2
      CASE "3": ConvNum(1) = 3
      CASE "4": ConvNum(1) = 4
      CASE "5": ConvNum(1) = 5
      CASE "6": ConvNum(1) = 6
      ' They choose to set the precision level of Pi.
      CASE "7"
        oldConvNum = ConvNum(2)
        ConvNum(2) = 18
        piprec = piprec - 2
        COLOR 7
        Start$ = "Set the number of decimal places to use for Pi: "
        star2$ = Squeeze$(STR$(piprec), " ")
        num$ = Inputex$(Start$, star2$, "1234567890", 2)
        IF num$ <> "" THEN
          piprec = VAL(num$)
          IF piprec > 15 THEN piprec = 15
          Pi# = VAL(LEFT$("3.141592653589793", piprec))
        END IF
        ConvNum(2) = oldConvNum
        piprec = piprec + 2
        LOCATE 18, 1, 0: PRINT STRING$(80, " ")
        LOCATE 18, 1, 0: PRINT " Press Enter(Return) to Return."
       
      CASE CHR$(13): EXIT DO
    END SELECT
    IF ConvNum(1) <> old THEN
      LOCATE (old + 3), 6
      PRINT "_": LOCATE 12, 1
      LOCATE (ConvNum(1) + 3), 6
      PRINT "û": LOCATE 12, 1
    END IF
  LOOP
  COLOR 7

  IF ConvNum(1) <> oldConvNum THEN
    VIEW PRINT 1 TO 24
    CLS 2
    SELECT CASE ConvNum(1)
      CASE 0
        ConvNum(2) = 1

      CASE 1
        PRINT "'''''''''''''''''''''''''''''''''''''''''''''''''''''''"
        PRINT "' Order of Operations                                 '"
        PRINT "'                                                     '"
        PRINT "' ([] Conversions in this program.)                   '"
        PRINT "' Parentheses                                         '"
        PRINT "' Exponents                                           '"
        PRINT "' Multiplication and Division from left to right.     '"
        PRINT "' Addition and Subtraction from left to right.        '"
        PRINT "'''''''''''''''''''''''''''''''''''''''''''''''''''''''"
        VIEW PRINT 10 TO 24
        ConvNum(2) = 10

      CASE 2
        PRINT "'''''''''''''''''''''''''''''''''''''''''''''''''''''''"
        PRINT "' Temperature Conversions (Centigrade is Celsius)     '"
        PRINT "'                                                     '"
        PRINT "'  Fahrenheit-Centigrade | øC = (5/9)(xøF - 32)       '"
        PRINT "'  Fahrenheit-Kelvin     | øK = (5/9)(xøF - 32) + 273 '"
        PRINT "'  Centigrade-Fahrenheit | øF = (9/5)xøC + 32         '"
        PRINT "'  Centigrade-Kelvin     | øK = xøC + 273             '"
        PRINT "'  Kelvin    -Fahrenheit | øF = (xøK - 273)(9/5) + 32 '"
        PRINT "'  Kelvin    -Centigrade | øC = xøK - 273             '"
        PRINT "'                        |                            '"
        PRINT "'''''''''''''''''''''''''''''''''''''''''''''''''''''''"
        VIEW PRINT 12 TO 24
        ConvNum(2) = 12

      CASE 3
        PRINT "'''''''''''''''''''''''''''''''''''''''''''''''''''''''"
        PRINT "' Prefix Conversions                                  '"
        PRINT "' Prefix:  Sym:  Multiple: | Prefix:  Sym:  Multiple: '"
        PRINT "' tera-(T) ----  10^12     | deci-(d)  D    10^-1     '"
        PRINT "' giga-(G) ----  10^9      | centi-(c) C    10^-2     '"
        PRINT "' mega-(M)  M    10^6      | milli-(m) I    10^-3     '"
        PRINT "' kilo-(k)  K    10^3      | micro-(æ) æ    10^-6     '"
        PRINT "' hecto-(h) H    10^2      | nano-(n) ----  10^-9     '"
        PRINT "' deka-(da) A    10        | pico-(p) ----  10^-12    '"
        PRINT "'                          | femto-(f)----  10^-15    '"
        PRINT "' Type Ctrl+U for 'æ'.     | atto-(a) ----  10^-18    '"
        PRINT "'''''''''''''''''''''''''''''''''''''''''''''''''''''''"
        VIEW PRINT 13 TO 24
        ConvNum(2) = 13
     
      CASE 4
        PRINT "'''''''''''''''''''''''''''''''''''''''''''''''''''''''"
        PRINT "' Distance Table 1                                    '"
        PRINT "' Linear                                              '"
        PRINT "' Customary Units:   | Equivalents:                   '"
        PRINT "'  Inch(in)          | 0.083...ft; 2.54cm             '"
        PRINT "'  Foot(ft)          | 0.3...yd; 12in; 0.3048m        '"
        PRINT "'  Yard(yd)          | 3ft; 36in; 0.9144m             '"
        PRINT "'  Rod(rd)           | 5.5yd; 16ft; 5.0292m           '"
        PRINT "'  Statute Mile(smi) | 1760yd; 5280ft; 1.609km        '"
        PRINT "'  Nautical Mile(nmi)| 1.151smi; 1.852km              '"
        PRINT "'                                                     '"
        PRINT "'''''''''''''''''''''''''''''''''''''''''''''''''''''''"
        VIEW PRINT 13 TO 24
        ConvNum(2) = 13

      CASE 5
        PRINT "'''''''''''''''''''''''''''''''''''''''''''''''''''''''"
        PRINT "' Distance Table 2                                    '"
        PRINT "' Area                                                '"
        PRINT "' Customary Units:   | Equivalents:                   '"
        PRINT "'  Sq.Inch(sqin)     | 0.007sqft; 6.4516sqcm          '"
        PRINT "'  Sq.Foot(sqft)     | 144sqin; 929.030sqcm           '"
        PRINT "'  Sq.Yard(sqyd)     | 1296sqin; 9sqft; 0.836sqm      '"
        PRINT "'  Acre(ac)          | 43560sqft; 4840sqyd; 4047sqm   '"
        PRINT "'  Sq.Mile(sqmi)     | 640ac; 2.590sqkm               '"
        PRINT "'                    |                                '"
        PRINT "'''''''''''''''''''''''''''''''''''''''''''''''''''''''"
        VIEW PRINT 12 TO 24
        ConvNum(2) = 12

      CASE 6
        PRINT "'''''''''''''''''''''''''''''''''''''''''''''''''''''''"
        PRINT "' Distance Table 3                                    '"
        PRINT "' Volume                                              '"
        PRINT "' Customary Units:   | Equivalents:                   '"
        PRINT "'  Cb.Inch(cbin)     | 0.00058cbft; 16.387cbcm        '"
        PRINT "'  Cb.Foot(cbft)     | 1728cbin; 0.028cbm             '"
        PRINT "'  Cb.Yard(cbyd)     | 27cbft; 0.765cbm               '"
        PRINT "'  Fluid Ounce(flou) | 8fl.drams; 1.804cbin; 29.573mL '"
        PRINT "'  Pint(pt)          | 16flou; 28.875cbin; 0.473L     '"
        PRINT "'  Quart(qt)         | 2p; 57.75cbin; 0.946L          '"
        PRINT "'  Gallons(gl)       | 4q; 231cbin; 3.785L            '"
        PRINT "'''''''''''''''''''''''''''''''''''''''''''''''''''''''"
        VIEW PRINT 13 TO 24
        ConvNum(2) = 13

    END SELECT
  END IF
 
 
  GoneToHelp = 1
END SUB

SUB Initialize
  ' Initialize all of the globals.
 
  ' Set pi to start at level 5 precision.
  Pi# = 3.14159#
  '    Five decimal places.
  piprec = 5
 
 
  ' Orig$ starts as nothing, no equation has yet been entered.
  Orig$ = ""
 
  ' Set all equation strings to nothing.
  FOR i = 1 TO 101
    Solve(i) = ""
  NEXT i

  ' Set to begin recording in string 1.
  solnum = 1
 
  ' Set all previously entered string to nothing.
  FOR i = 1 TO 24
    PrevStr(i) = ""
  NEXT i
  'Set the unaccessable previous string to the example.
  PrevStr(26) = "~ *2û25*((-6+-5)-8+ 3û[1273k_c] - 5*(7 / ~) * 2) ^ 2"

  ' Set the current help to nothing and the line to start text on as 1.
  ConvNum(1) = 0: ConvNum(2) = 1

  ' Set that the help sub has not been run through.
  GoneToHelp = 0

  ' Set the level of parentheses at 0.  Not in a parenthesis set.
  '(Calculate has not been called.)
  sublvl = 0
 
  ' All of the possible symbols.
  'Factorial,Root,Open-Close Parenthesis,Carrot,Multiply,Divide,Add,Subtract,EndEquation
  allsym$ = "!û()^*/+-`"

  ' All keys that are allowed to be entered are in this string.
  '  The characters are allowed so that conversions can be done.
  legalkeys$ = ".1234567890~[_]()!^*/+- ûéñMKHADCIæ"
  morekeys$ = Squeeze$("f c k in ft yd rd smi nmi", " ")
  morekey2$ = Squeeze$("sq ac cb flou pt qt gl", " ")
  legalkeys$ = legalkeys$ + morekeys$ + morekey2$ + CHR$(9)

  ' Start anyerror off as false.(No error)
  anyerror = 0
END SUB

FUNCTION Inputex$ (IntroStr$, InputStr$, Valid$, maxlen%)
'*************************************************************************
'* This functions generates the ERROR code 80 if the end of the rectangle*
'* is reached.  Simply handle the error with a RESUME NEXT statement to  *
'* ignore it, and the function will return as though it had completed    *
'* it's process.                                                         *
'*************************************************************************

'*************************************************************************
'* IntroStr$ - uneditable introductorial string                          *
'*                                                                       *
'* InputStr$ - preentered string                                         *
'*                                                                       *
'* Valid$ - list of allowable input characters: "" = all are allowed     *
'*************************************************************************

  prevConvNum = ConvNum(1)

  EnterKey$ = CHR$(13)                  ' signifies end of entry
  Backspace$ = CHR$(8)                  ' dragging, destructive backspace
  UpArrow$ = "H"                        ' copy and edit the last entry
  DownArrow$ = "P"                      ' copy and edit the next entry
  LeftArrow$ = "K"                      ' input cursor left
  RightArrow$ = "M"                     ' input cursor right
  InsertKey$ = "R"                      ' insert mode toggle
  DeleteKey$ = "S"                      ' character delete
  HomeKey$ = "G"                        ' input cursor start of field
  EndKey$ = "O"                         ' input cursor after last char

  SqrRoot$ = CHR$(18)                   ' Ctrl+R = Square Root Symbol.

  ' If the last input had an error, begin with the last input.
  IF anyerror = -1 THEN
    InputStr$ = PrevStr(1)
    prevstrnum = 1
  END IF
  LOCATE ConvNum(2), 1, 1
  PRINT IntroStr$;
  charnum = 1
  PRINT InputStr$;
  charnum = charnum + LEN(InputStr$)

  IF anyerror = 0 THEN
    FOR i = 25 TO 2 STEP -1
      PrevStr(i) = PrevStr(i - 1)
    NEXT i
    PrevStr(1) = InputStr$
    prevstrnum = 1
  END IF


  KEY(1) ON
  DO
    ccol = POS(0): crow = CSRLIN               'Get the current cursor pos
    InputKey$ = ""
    WHILE InputKey$ = ""
      InputKey$ = INKEY$                       ' get a keystroke if present
      IF GoneToHelp = 1 THEN
        Inputex$ = "\"
        GoneToHelp = 0
        EXIT FUNCTION
      END IF
    WEND
    EditKey$ = MID$(InputKey$, 2, 1)           ' editing key pressed?
    
    IF InputKey$ = CHR$(18) THEN : InputKey$ = CHR$(251)
    IF InputKey$ = CHR$(21) THEN : InputKey$ = CHR$(230)
    IF EditKey$ <> "" THEN
      SELECT CASE EditKey$
        CASE UpArrow$
            IF prevstrnum < 25 AND PrevStr(prevstrnum + 1) <> "" THEN
              IF prevstrnum = 1 THEN
                PrevStr(1) = InputStr$
              END IF
              mInc prevstrnum
              InputStr$ = PrevStr(prevstrnum)
              LOCATE ConvNum(2), 1
              PRINT STRING$(maxlen%, " ")
              LOCATE ConvNum(2), 1
              PRINT IntroStr$ + InputStr$;
              charnum = LEN(InputStr$) + 1
            END IF
       
        CASE DownArrow$
            IF prevstrnum > 1 THEN
              prevstrnum = prevstrnum - 1
              InputStr$ = PrevStr(prevstrnum)
              LOCATE ConvNum(2), 1
              PRINT STRING$(maxlen%, " ")
              LOCATE ConvNum(2), 1
              PRINT IntroStr$ + InputStr$;
              charnum = LEN(InputStr$) + 1
            END IF
       
        CASE RightArrow$
            IF charnum < (LEN(InputStr$) + 1) THEN
              mInc charnum
              crow = CSRLIN: clin = (POS(0) + 1)
              IF clin = 81 THEN : mInc crow: clin = 1
              LOCATE crow, clin
            END IF

        CASE LeftArrow$
            IF charnum > 1 THEN
              mDec charnum
              crow = CSRLIN: clin = (POS(0) - 1)
              IF clin = 0 THEN : mDec crow: clin = 80
              LOCATE crow, clin
            END IF

        CASE DeleteKey$
            IF charnum < (LEN(InputStr$) + 1) THEN
            
              IF MID$(InputStr$, charnum) = "(" THEN : mDec parennum
              IF MID$(InputStr$, charnum) = ")" THEN : mInc parennum

              InputStr$ = LEFT$(InputStr$, charnum - 1) + RIGHT$(InputStr$, (LEN(InputStr$) - charnum))
              clin = POS(0)
              LOCATE ConvNum(2), 1: PRINT IntroStr$ + InputStr$ + " ";
              LOCATE crow, clin
            END IF

        CASE HomeKey$
            LOCATE ConvNum(2), 1: PRINT IntroStr$;
            charnum = 1

        CASE EndKey$
            LOCATE ConvNum(2), 1: PRINT IntroStr$ + InputStr$;
            charnum = (LEN(InputStr$) + 1)
                      
        CASE CHR$(15)
            IF prevstrnum = 1 THEN
              PrevStr(1) = InputStr$
            END IF
            mInc prevstrnum
            InputStr$ = PrevStr(26)
            LOCATE ConvNum(2), 1
            PRINT STRING$(maxlen%, " ")
            LOCATE ConvNum(2), 1
            PRINT IntroStr$ + InputStr$;
            charnum = LEN(InputStr$) + 1

      END SELECT
      
    ELSE  'EditKey$ <> ""
      prevstrnum = 1
      SELECT CASE InputKey$
        CASE EnterKey$
            IF GoneToHelp = 1 THEN
              Inputex$ = "\"
              GoneToHelp = 0
              EXIT FUNCTION
            END IF
            PrevStr(1) = InputStr$
            Inputex$ = InputStr$
            EXIT DO

        CASE Backspace$
            IF charnum > 1 THEN
              mDec charnum
              crow = CSRLIN: clin = (POS(0) - 1)
              IF clin = 0 THEN : mDec crow: clin = 80
             
              IF MID$(InputStr$, charnum) = "(" THEN : mDec parennum
              IF MID$(InputStr$, charnum) = ")" THEN : mInc parennum

              InputStr$ = LEFT$(InputStr$, charnum - 1) + RIGHT$(InputStr$, (LEN(InputStr$) - charnum))
              LOCATE ConvNum(2), 1: PRINT IntroStr$ + InputStr$ + " ";
              LOCATE crow, clin
            END IF

        CASE ELSE
            IF INSTR(Valid$, InputKey$) > 0 AND LEN(InputStr$) < maxlen% THEN
              crow = CSRLIN: clin = (POS(0) + 1)
              IF clin = 81 THEN : mInc crow: clin = 1
              InputStr$ = LEFT$(InputStr$, charnum - 1) + InputKey$ + RIGHT$(InputStr$, (LEN(InputStr$) - (charnum - 1)))
              mInc charnum
              LOCATE ConvNum(2), 1: PRINT IntroStr$ + InputStr$;
              LOCATE crow, clin
            END IF

      END SELECT
    END IF

  LOOP
  KEY(1) OFF

  PrevStr(1) = InputStr$
  Inputex$ = InputStr$

END FUNCTION

FUNCTION Interperet$ (equation$)
  ' Interperets things such as ')(' = ')*(' or
  ' '+-' = '-' or '--' = '+' or '-+' = '-'
 
  ' Change all negative(not subtraction) symbols to ':'
  ' Also eliminate and "+"'s indicating a positive number.
  allsym2$ = "(û^*/+-"
  FOR i = 1 TO LEN(equation$)
    now1$ = MID$(equation$, i, 1)
    now2$ = MID$(equation$, i + 1, 1)
    IF now1$ = "-" AND i = 1 THEN
      MID$(equation$, i, 1) = ":"
    END IF
    IF INSTR(allsym2$, now1$) > 0 AND now2$ = "-" THEN
      IF now1$ = "û" THEN
        MID$(equation$, i + 1, 1) = " "
      ELSE
        MID$(equation$, i + 1, 1) = ":"
      END IF
    END IF
    IF INSTR(allsym2$, now1$) > 0 AND now2$ = "+" THEN
      MID$(equation$, i + 1, 1) = " "
    END IF
  NEXT i


  ' Replace all instances of '~' with '3.14'... using specified precision.
RestartRepPi:
  length = LEN(equation$)
  FOR i = 1 TO length
    IF MID$(equation$, i, 1) = "~" THEN
      equation$ = Replacer$(equation$, Squeeze$(STR$(Pi#), " "), i, i)
      GOTO RestartRepPi
    END IF
  NEXT i
 
 
  ' Change any of several things to multiplication.
  'If any of these statements are true then DON'T put a '*' sign.
  allsym2$ = ")û!^*/+-`"  'Is one of these after ')' or '!'.
  allsym3$ = "(!^*/+-"    'Is one of these before 'û'.
  'allsym2$ takes care of those before a '('.
  'Simply don't put a multiplication symbol right in front of a ')'.
InterperetCheckForMultiplication:
  x = LEN(equation$) - 1
  FOR i = 1 TO x
    now1$ = MID$(equation$, i, 1)
    now2$ = MID$(equation$, i + 1, 1)
    IF now1$ = ")" AND INSTR(allsym2$, now2$) = 0 THEN
      equation$ = LEFT$(equation$, i) + "*" + RIGHT$(equation$, ((x + 1) - i))
      i = 0
      GOTO InterperetCheckForMultiplication
    END IF
    IF now1$ = "!" AND INSTR(allsym2$, now2$) = 0 THEN
      equation$ = LEFT$(equation$, i) + "*" + RIGHT$(equation$, ((x + 1) - i))
      i = 0
      GOTO InterperetCheckForMultiplication
    END IF
    IF now1$ = "û" AND i = 1 THEN
      equation$ = "2" + equation$
      i = 0
      GOTO InterperetCheckForMultiplication
    END IF
    IF now2$ = "û" AND INSTR(allsym3$, now1$) > 0 THEN
      equation$ = LEFT$(equation$, i) + "2" + RIGHT$(equation$, ((x + 1) - i))
      i = 0
      GOTO InterperetCheckForMultiplication
    END IF
    'allsym2$ takes care of those before a '('.
    'Simply don't put a multiplication symbol left in front of a ')'.
  NEXT i


  ' Interperet a "()" as a '0'.
  FOR i = 1 TO x
    now1$ = MID$(equation$, i, 1)
    now2$ = MID$(equation$, i + 1, 1)
    IF now1$ = "(" THEN         'If an open parenthesis is followed by
      IF now2$ = ")" THEN       'the closing parenthesis.
        equation$ = LEFT$(equation$, (i - 1)) + "0" + RIGHT$(equation$, ((x + 1) - (i + 1)))
        x = LEN(equation$) - 1: i = 0
        CALL ReportError(1, "", 0, "", 0, "", 0)
      END IF
    END IF
  NEXT i
                       

''' CONVERSIONS
  numlegalkeys$ = "1234567890.-"
  ' Find if there is anything to convert.
  DIM convstrings(2) AS STRING
CheckForConvert:
  FOR i = 1 TO LEN(equation$)
    convstrings(1) = ""
    convstrings(2) = ""
    now$ = MID$(equation$, i, 1)
    startpart = i
    IF now$ = "[" THEN
      numtoconv$ = ""
      convto = 1
      FOR i2 = (i + 1) TO LEN(equation$)
        now2$ = MID$(equation$, i2, 1)
        IF INSTR(numlegalkeys$, now2$) = 0 THEN EXIT FOR
        numtoconv$ = numtoconv$ + now2$
      NEXT i2
      numtoconv# = VAL(numtoconv$)
      FOR i2 = i2 TO LEN(equation$)
        now2$ = MID$(equation$, i2, 1)
        IF now2$ = "]" OR now2$ = "`" THEN
          endpart = i2
          EXIT FOR
        END IF
        IF now2$ = "_" THEN
          convto = 2
        ELSE
          convstrings(convto) = convstrings(convto) + now2$
        END IF
      NEXT i2
      IF now2$ = "`" THEN
        'ReportError (10)
      END IF
     
      ' Convert the number.
      IF convto = 2 THEN
        num# = ConvertNum#(numtoconv#, convstrings(1), convstrings(2))
        equation$ = Replacer$(equation$, Squeeze$(STR$(num#), " "), startpart, endpart)
        GOTO CheckForConvert
      ELSE
        'ReportError (10)
      END IF
    END IF
  NEXT i

  equation$ = Squeeze$(equation$, " ")
  Interperet$ = equation$
END FUNCTION

SUB mDec (num)
  num = num - 1
END SUB

SUB mInc (num)
  num = num + 1
END SUB

SUB mToggle (num)
  num = (num XOR 1)
END SUB

FUNCTION PrepareForAndReplace$ (equation$, symbol$, num#, Start, negnum)
  'Find the operation sign.
  numofoper = GetNumOfSymbol(equation$, symbol$, 1)
  midsympos = GetPosOfSymbols(equation$, allsym$, numofoper)

  'Find the beginning of this Operation.
  sympos = (GetPosOfSymbols(equation$, allsym$, (numofoper - 1)) + 1)
 
  'Find the end of this Operation.
  sympos2 = (GetPosOfSymbols(equation$, allsym$, (numofoper + 1)) - 1)
 
  Replace$ = STR$(num#): Replace$ = Squeeze$(Replace$, " ")

  equation$ = Replacer$(equation$, Replace$, sympos, sympos2)
  PrepareForAndReplace$ = equation$
END FUNCTION

FUNCTION Replacer$ (equation$, Replace$, pos1, pos2)
  IF LEFT$(Replace$, 1) = "-" THEN
    MID$(Replace$, 1, 1) = ":"
  END IF
  fpartstr$ = LEFT$(equation$, (pos1 - 1))
  lpartstr$ = RIGHT$(equation$, (LEN(equation$) - pos2))
  equation$ = fpartstr$ + Replace$ + lpartstr$
  Replacer$ = equation$
END FUNCTION

SUB ReportError (errnum, str1$, num1, str2$, num2, str3$, num3)
  ' Reports to the user any errors in calculation or in the equation.
  SELECT CASE errnum
    CASE 1
      PRINT "Error:  Empty Parentheses."
      COLOR 1: PRINT "Empty parentheses set replaced with 0.": COLOR 7
      EXIT SUB

    CASE 2
      PRINT
      PRINT "Error:  Numbers."
      COLOR 4: PRINT "There are more than 24 operations.": COLOR 7
      EXIT SUB

    CASE 3
      PRINT
      PRINT "Error:  Numbers."
      COLOR 4: PRINT "There are no numbers.": COLOR 7
      EXIT SUB

    CASE 4
      PRINT
      PRINT "Error:  Numbers."
      PRINT str1$
      LOCATE CSRLIN - 1, num1
      COLOR 4: PRINT ".": COLOR 7
      EXIT SUB

    CASE 5
      PRINT
      PRINT "Error:  Operations."
      y = CSRLIN
      PRINT str1$;
      LOCATE y, num1
      COLOR 4: PRINT str2$; str3$: COLOR 7

    CASE 6
      PRINT
      PRINT "Error:  Operations."
      COLOR 4: PRINT str1$; str2$: COLOR 7
      EXIT SUB

    CASE 7
      PRINT
      PRINT "Error:  Factorials."
      COLOR 1: PRINT "Cannot get the factorial of a non-whole number.": COLOR 7
      COLOR 1: PRINT "The number was truncated to"; STR$(FIX(VAL(str1$))); ".": COLOR 7
      EXIT SUB

    CASE 8


    CASE 9
      PRINT
      PRINT "Error:  Conversions."
      COLOR 4: PRINT "Cannot convert "; str1$; " to "; str2$; ".": COLOR 7
      EXIT SUB

  END SELECT

END SUB

FUNCTION ScienNotat# (num#)
  number# = num#
  num$ = Squeeze$(STR$(num#), " ")
  IF LEN(num$) > 15 THEN
    sym$ = MID$(num$, 19, 1)
    IF sym$ = "+" THEN
      expnum = VAL(RIGHT$(num$, LEN(num$) - 19))
      FOR i = 1 TO expnum
        number# = number# * 10
      NEXT i
    END IF
    IF sym$ = "-" THEN
      expnum = VAL(RIGHT$(num$, LEN(num$) - 19))
      num$ = LEFT$(num$, 15)
      FOR i = 1 TO expnum
        num$ = LEFT$(num$, LEN(num$) - 1)
        number# = VAL(num$)
        number# = number# / 10
        num$ = Squeeze$(STR$(number#), " ")
      NEXT i
    END IF
  END IF
  ScienNotat# = number#
END FUNCTION

FUNCTION Squeeze$ (Orig$, Char$)

'*******************************************************************************
'*  removes all occurrences of a substring from within a string                *
'*  example: Squeeze$("Peter Piper","er") --> "Pet Pip"                        *
'*******************************************************************************

    IF Orig$ = "" OR Char$ = "" THEN
       Squeeze$ = Orig$
       EXIT FUNCTION
    END IF

    new$ = Orig$

    DO WHILE INSTR(new$, Char$) > 0
       x% = INSTR(new$, Char$)
       L$ = LEFT$(new$, x% - 1)
       R$ = MID$(new$, x% + LEN(Char$))
       new$ = L$ + R$
    LOOP
                                       
    Squeeze$ = new$
END FUNCTION

SUB TextMain
  'Clear the text viewport.
  CLS 2



'Label to return to getting the new equation.
Start:
  sublvl = 0

  ' Set all equation strings to nothing.
  FOR i = 1 TO 101
    Solve(i) = ""
  NEXT i

  ' Set to begin recording in string 1.
  solnum = 1

' Don't scroll whatever Help part there is on screen.
  VIEW PRINT ConvNum(2) TO 24: CLS 2


' Set the cursor on the row below the Help selection display.
  LOCATE ConvNum(2), 1
' Get a string for the equation, it cannot be over 141 characters.
  InputStr$ = Inputex$("Enter an equation: ", "", legalkeys$, (160 - 19))

' If returned from Help.
  IF InputStr$ = "\" THEN GOTO Start

' Leave first two lines unscrolled.
  VIEW PRINT ConvNum(2) + 2 TO 24: CLS 2
  ' If they enter an empty line then exit the program.
  IF InputStr$ = "" THEN : PRINT : PRINT : PRINT "Goodbye!": END

  ' Get rid of all spaces in the equation.
  equation$ = Squeeze$(InputStr$, " ")


'------------------------------------------------'
' Error Checking
  ' Interperet many things in the equation.
  equation$ = Interperet$(equation$)

  ' Add an "end of string" marker to the end of the string.
  equation$ = equation$ + "`"

  ' Check for problems with the set up of parentheses.
  IF CheckForPar(equation$) = -1 THEN : GOTO Restart

  ' Check for errors in the setup of operations and/or numbers.
  IF CheckForNumAndOper(equation$) = -1 THEN : GOTO Restart

  ' Put a set of parenthesis around the equation not including the "end of
  ' string" marker and add the eos marker to the end of the new string.
  equation$ = "(" + LEFT$(equation$, LEN(equation$) - 1) + ")`"

  ' Save the original string in Orig$
  Orig$ = LEFT$(equation$, LEN(equation$) - 1)

  ' Calculate the equation and store the answer in num.
  num# = Calculate#(equation$, 1)

  ' Set color to blue, print the original equation.
  COLOR 1: PRINT Orig$; " = ";

  ' Squeeze spaces out of number.
  num$ = Squeeze$(STR$(num#), " ")

  ' Set color to green, print the answer to the equation.
  COLOR 2: PRINT num$
  Solve(solnum) = Orig$ + " = " + num$: mInc solnum

  ' Set the color back to normal, grey.
  COLOR 7

  ' Print two extra spaces, not sure why, just in case I guess.
  PRINT
  PRINT
  Solve(solnum) = " ": mInc solnum
  Solve(solnum) = " ": mInc solnum

  ' Restart the process, get another equation, and so on.
  GOTO Restart


' Tell them to press enter to continue and wait for a key before restarting.
Restart:
  'Inform the user to press enter to continue.
  Solve(solnum) = "Press enter to continue.": mInc solnum
  PRINT "Press enter to continue.";
 
  'Start Row = The first row to view the solving process in.
  srow = ConvNum(2) + 2

  'End Row   = The last row to view the solving process in.
  erow = 24

  'Don't know. (More Rows?)
  mrow = (solnum - 1) - (erow - srow)

  'Don't know. (Top Row?)
  trow = mrow

  'If the cursor is on the 24th line then the entire equation is not visible,
  ' so allow scrolling.
  IF CSRLIN = 24 THEN
    canscroll = 1
    'Inform the user to press enter to continue or view their equation.
    Solve(solnum - 1) = "Press enter to continue or use the arrow keys to view your equation."
    LOCATE CSRLIN, 1: PRINT Solve(solnum - 1);
  END IF

  'Init a$.
  a$ = ""

  'Until the user presses Enter, wait or scroll.
  WHILE a$ <> CHR$(13)
    'Get the users input.
    a$ = INKEY$

    'If the equation can be scrolled.
    IF canscroll = 1 THEN
      'Get the second value from INKEY$
      EditKey$ = MID$(a$, 2, 1)           ' editing key pressed?
   
      'If the second value is not nothing.
      IF EditKey$ <> "" THEN
        SELECT CASE EditKey$
          CASE "H" 'Up
            'If the top currently visible row is NOT the first row
            ' in the solving process.
            IF trow > 1 THEN
              'Start viewing from one row previous.
              trow = trow - 1

              'Clear the text viewport.
              CLS 2
            
              'Display the visible part of the solving process.
              FOR i = srow TO erow
                IF trow + (i - srow) = solnum - 1 - 3 THEN
                  ' Set color to blue, print the original equation.
                  COLOR 1: LOCATE i, 1: PRINT Orig$; " = ";

                  ' Squeeze spaces out of number.
                  num$ = Squeeze$(STR$(num#), " ")

                  ' Set color to green, print the answer to the equation.
                  COLOR 2: PRINT num$;

                  ' Set the color back to normal, grey.
                  COLOR 7
                ELSE
                  LOCATE i, 1: PRINT Solve(trow + (i - srow));
                END IF
              NEXT i
            END IF

          CASE "P" 'Down
            'If the last currently visible row is NOT the last row
            ' in the solving process.
            IF trow < mrow THEN
              'Start viewing from one row after.
              mInc trow

              'Clear the text viewport.
              CLS 2

              'Display the visible part of the solving process.
              FOR i = srow TO erow
                IF trow + (i - srow) = solnum - 1 - 3 THEN
                  ' Set color to blue, print the original equation.
                  COLOR 1: LOCATE i, 1: PRINT Orig$; " = ";

                  ' Squeeze spaces out of number.
                  num$ = Squeeze$(STR$(num#), " ")

                  ' Set color to green, print the answer to the equation.
                  COLOR 2: PRINT num$;

                  ' Set the color back to normal, grey.
                  COLOR 7
                ELSE
                  LOCATE i, 1: PRINT Solve(trow + (i - srow));
                END IF
              NEXT i
            END IF
        END SELECT
      END IF 'EditKey$ <> ""
    END IF 'canscroll = 1
  WEND 'Until Enter is pressed.

  'After Enter is pressed, return to Start to get a new equation.
  GOTO Start
END SUB

