MiniCalc Strikes Back!!!

User contributed sources that have become inactive, deprecated, or generally unusable. But ... we don't really want to throw them away either.
Post Reply
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

MiniCalc Strikes Back!!!

Post by KristopherWindsor »

Image

It has been a year since I wrote the original MiniCalc, and almost that long since I first ported it from QB.

I've kept MiniCalc in my QuickLaunch tray, and used it frequently, so I decided MiniCalc 2 would be very useful. MiniCalc is a console mode, command line based calculator that can process expressions such as, "1+COS(PI/2)+SQR(81)."

Now compilable with -lang fb, and much cleaner source, this version allows user-defined functions, which it saves for future sessions. It also adds ASIN(), ACOS(), LN(), LOG(), ABS(), INT(), FRAC(), equality tests, and many other functions, such as FT_MI() (feet to miles).

Read the changes.txt file, and type HELP into the calculator, for more info.

Sample I/O, showing MiniCalc capabilities:
(note the assignment operator, Chr(26), is shown here as " >> " and can be typed with the TAB key)

Code: Select all

MiniCalc2 > 1-2(-3-4(-5(-6)))
          > 247

MiniCalc2 > SQR(81)
          > 9

MiniCalc2 > COS(PI)
          > -1

MiniCalc2 > 55 >> MYVAR
          > 55

MiniCalc2 > 2MYVAR
          > 110

MiniCalc2 > LOG(10^(MYVAR+1))
          > 56

MiniCalc2 > ASIN(SIN(-1))
          > -1

MiniCalc2 > 3!!
          > 720

MiniCalc2 > 2X+5 >> MYFUNCTION()
          > 5

MiniCalc2 > MYFUNCTION(-6)
          > -7

MiniCalc2 > MYFUNCTION(MYVAR)
          > 115

MiniCalc2 > SQR(2^8)
          > 16

MiniCalc2 > 1=2
          > 0

MiniCalc2 > 8=9-1
          > 1

MiniCalc2 > 1>=-1
          > 1

MiniCalc2 > PI<>E
          > 1

MiniCalc2 > 20(50%)
          > 10

MiniCalc2 > *10
          > 100

MiniCalc2 > FT_IN(ANS/50)
          > 24

MiniCalc2 > F_C(212)
          > 100

MiniCalc2 > LB_TON(10000)
          > 5

MiniCalc2 > TBSP_TSP(1)
          > 3

MiniCalc2 > TINY
          > 1.e-014

MiniCalc2 > GAL_L(1)
          > 3.785411784

MiniCalc2 > FIX(PI)
          > 3

MiniCalc2 > FRAC(PI)
          > 0.1415926535897931

MiniCalc2 > ABS(-RND)
          > 0.2869140012189746

MiniCalc2 > ROUND(RND*100)
          > 68

MiniCalc2 > ROUND(RND*100)
          > 8

MiniCalc2 > 0 >> PI
          > 0

MiniCalc2 > SIN(PI)
          > 0

MiniCalc2 > PI
          > 0

MiniCalc2 > LN(256E)
          > 6.545177444479562

MiniCalc2 > LN(E^4)
          > 4

MiniCalc2 > 1+(E>2)+100(MYVAR=55)+10000(3<>3)
          > 102

changes.txt:

Code: Select all

MiniCalc change log
(C) 2007 i-TECH and Kristopher Windsor

New to version 2.0:
	Added:
		Supports functions (see variable changes)
		Supports Home and End keys
		Supports Logarithms, Arcsines, and Arccosines
		Saves user defined variables for future sessions
		Equality operators "= < > >= <= <>"
		Functions such as FIX() and CUBED(), and many measurement conversion functions, although not built into the calculator, are available (defined in external file)
		Individual variables can now be erased (just assign a null value to them, i.e. ">> F()")
	Changed:
		Now compiles without QB compatibility mode, in just 56K
		Support for more variables, history, recursion
		Parsing method now evaluates "3+!5" as "3!+5," not "3+5"
		Variables
			Variables are now equations, not scalar variables
			Variable names cannot use odd characters, but can be more than a single character long
			Parsing method now evaluates "PIPI" as the variable "PIPI," not as pi squared (use "PI*PI" or "PI(PI)" for pi squared)
			The equals sign is now an equality tester (not the assignment operator), and the TAB key produces the assignmnet operator is used for creating variables
			Variables and functions such as "PI" and "K_C()" are now defined in an external file, so they can be redefined by the user
			Supports functions, which are variables, where variable "X" in the expression is an input value
				Differentiated from variables with trailing parenthesis (i.e. "2^X >> EXPONENT()")
				Can be used with or without a value in parenthesis (i.e. "EXPONENT2" or "EXPONENT(1+2)")
		"F(" now validates to "F" (error), instead of "F(0)"
	Removed:
		Sketchpad (impractical)
		Width / Display option (smaller screen option was unnecessary)
		Virtual Keyboard support (impractical)
		Clear option (would erase all variables, including PI with the new variable structure)

variables.dat:
(required for use of many variables and functions, including PI)
ABS()
X-2X(X<0)

C_F()
9X/5+32

CM_IN()
X/2.54

CUBED()
X*X*X

CUBEROOT()
X^(1/3)

CUP_FLOZ()
8X

CUP_GAL()
X/8

CUP_PT()
X/2

CUP_QT()
X/4

CUP_TBSP()
16X

CUP_TSP()
48X

DEG_RAD()
X*PI/180

E
2.718281828459045

F_C()
5*(X-32)/9

FIX()
INT(X)+((X<0)+(INT(X)<>X)=2)

FLOZ_CUP()
X/8

FLOZ_ML()
29.5735295625X

FLOZ_TBSP()
2X

FLOZ_TSP()
6X

FRAC()
X-FIX(X)

FT_IN()
12X

FT_MI()
X/5280

FT_YD()
X/3

GAL_CUP()
16X

GAL_L()
3.785411784X

GAL_PT()
8X

GAL_QT()
4X

HUGE
100000000000000

IN_CM()
2.54X

IN_FT()
X/12

IN_YD()
X/36

IN_MI()
X/63360

KM_MI()
.6213711922373341X

LB_OZ()
16X

LB_TON()
X/2000

L_GAL()
.2641720523581485X

L_QT()
1.056688209432594X

LOG()
LN(X)/LN(10)

M_YD()
1.093613298337708X

MI_FT()
5280X

MI_IN()
63360X

MI_KM()
1.609344X

MI_YD()
1760X

ML_FLOZ()
.033814022701843X

OZ_LB()
X/16

PI
3.141592653589793

PT_CUP()
2X

PT_GAL()
X/8

PT_QT()
X/2

QT_CUP()
4X

QT_GAL()
X/4

QT_L()
.946352946X

QT_PT()
2X

RAD_DEG()
X*180/PI

ROUND()
INT(X+.5)

SGN()
1-2(X<0)-(X=0)

SQUARED()
X*X

SQUAREROOT()
SQR(X)

TBSP_CUP()
X/16

TBSP_FLOZ()
X/2

TBSP_TSP()
3X

TON_LB()
2000X

TSP_CUP()
X/48

TSP_FLOZ()
X/6

TSP_TBSP()
X/3

TINY
1/HUGE

X
0

YD_FT()
3X

YD_IN()
36X

YD_M()
.9144X

YD_MI()
X/1760

MiniCalc2.bas:

Code: Select all


' MiniCalc! Version 2.0
' (C) 2007 i-TECH and Kristopher Windsor

Const true = -1, false = 0, program_title = "MiniCalc2 > "

Const history_max = 128

Const calculate_char_assignment = Chr(26)
Const calculate_char_number = "1234567890.", calculate_char_var = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_", calculate_char_operator = "=<>+-*/^"
Const calculate_char_allowed = calculate_char_number & calculate_char_var & calculate_char_operator & calculate_char_assignment & "()%!"
Const calculate_expression_max = 128
Const calculate_number_unspecified = -0.907379150390625 'random hidden value
Const calculate_variable_max = 2048

Const text_margin = 10, text_size_max = 147, text_line_max = 3, text_window_width = 80

Type calculate_variable
  As String title
  As String expression
  As Integer isfunction 'will replace 'x' in expression with another expression
  As Integer ison
End Type

Dim Shared As Integer calculate_error, calculate_depth
Dim Shared As calculate_variable calculate_variables(1 To calculate_variable_max)

'[C:\itech\Misc\MiniCalcReloaded\MiniCalc.bas]
'[Declarations generated at 22:00:27 on 09-15-2007]

Declare Function calculate_evaluate (Byref equation As String, ans As Double = 0, Byref xvalue As Double = calculate_number_unspecified) As Double
  '[starts at line #90; ends at line #342; is 251 lines long]
  '[this function is called by the following subs and functions]
    'calculate_evaluate at line #130
    'calculate_evaluate at line #216
    'calculate_evaluate at line #259
    'calculate_evaluate at line #260
    'calculate_evaluate at line #262
    'program_main at line #609
  '[this function calls the following subs and functions]
    'calculate_evaluate at line #130
    'calculate_evaluate at line #216
    'calculate_evaluate at line #259
    'calculate_evaluate at line #260
    'calculate_evaluate at line #262

Declare Sub calculate_validate (Byref t As String)
  '[starts at line #344; ends at line #399; is 54 lines long]
  '[this sub is called by the following subs and functions]
    'program_main at line #565

Declare Sub calculate_variable_add (Byref t As String)
  '[starts at line #401; ends at line #434; is 32 lines long]
  '[this sub is called by the following subs and functions]
    'program_main at line #608

Declare Sub calculate_variable_load
  '[starts at line #436; ends at line #458; is 21 lines long]
  '[this sub is called by the following subs and functions]
    'program_start at line #478

Declare Sub calculate_variable_save
  '[starts at line #460; ends at line #475; is 14 lines long]
  '[this sub is called by the following subs and functions]
    'program_finish at line #619

Declare Sub program_start
  '[starts at line #477; ends at line #479; is 1 lines long]
  '[this sub is called by the following subs and functions]
    'the main program at line #625
  '[this sub calls the following subs and functions]
    'calculate_variable_load at line #478

Declare Sub program_main
  '[starts at line #481; ends at line #616; is 134 lines long]
  '[this sub is called by the following subs and functions]
    'the main program at line #626
  '[this sub calls the following subs and functions]
    'calculate_validate at line #565
    'calculate_variable_add at line #608
    'calculate_evaluate at line #609

Declare Sub program_finish
  '[starts at line #618; ends at line #623; is 4 lines long]
  '[this sub is called by the following subs and functions]
    'the main program at line #627
  '[this sub calls the following subs and functions]
    'calculate_variable_save at line #619

Function calculate_evaluate (Byref equation As String, ans As Double = 0, Byref xvalue As Double = calculate_number_unspecified) As Double
  Dim As Integer a, b, d, u, factorial_power, number_current, number_negation, operator_current, string_start, variable_index
  Dim As Double temp, numbers(1 To calculate_expression_max)
  Dim As String character_current, temp_string, variable_title
  Dim As String operators(1 To calculate_expression_max)

  #macro calculate_number_add()
  number_current = number_current + 1: numbers(number_current) = temp * number_negation: number_negation = 1
  #endmacro
  
  #macro calculate_simplify()
  For b = a + 1 To number_current - 1
    Swap numbers(b), numbers(b + 1)
  Next b
  number_current -= 1
  For b = a To operator_current - 1
    Swap operators(b), operators(b + 1)
  Next b
  operator_current -= 1
  #endmacro
  
  If equation = "" Or calculate_depth > 64 Then calculate_error = -1: Return 0
  
  calculate_depth += 1: number_negation = 1
  
  'step 1 - extract numbers and operators
  For a = 1 To Len(equation)
    character_current = Mid(equation, a, 1)
    If number_current > operator_current Then operator_current = operator_current + 1: operators(operator_current) = "*"
    
    'parenthesis
    If character_current = "(" Then
      string_start = a: d = 1
      Do
        a = a + 1
        Select Case Mid(equation, a, 1)
        Case "(": d = d + 1
        Case ")": d = d - 1
        End Select
      Loop Until d = 0
      temp = calculate_evaluate(Mid(equation, string_start + 1, a - string_start - 1), ans, xvalue)
      calculate_number_add()
    Elseif Instr(calculate_char_number, character_current) Then
      string_start = a
      Do
        a += 1
      Loop Until Instr(calculate_char_number, Mid(equation, a, 1)) = 0 Or a > Len(equation)
      temp = Val(Mid(equation, string_start, a - string_start))
      a -= 1
      calculate_number_add()
    Elseif Instr(calculate_char_operator, character_current) Then
      'operators
      string_start = a
      Do
        a += 1
      Loop Until Instr(calculate_char_operator, Mid(equation, a, 1)) = 0 Or a > Len(equation)
      a -= 1
      temp_string = Mid(equation, string_start, a - string_start + 1) 'overrides default (implied) multiplication
      For b = 1 To Len(temp_string)
        If Mid(temp_string, b, 1) = "-" Then Mid(temp_string, b, 1) = "+": number_negation *= -1
      Next b
      If Instr(" <> >< >= => <= =< ", " " & temp_string & " ") = 0 Then temp_string = Left(temp_string, 1)
      
      If number_current + operator_current = 0 Then
        number_current = 1: operator_current = 1
        operators(1) = temp_string
        If temp_string = "+" Then
          numbers(1) = 0 'changes [+2] to [0+2]
        Else
          numbers(1) = ans 'changes [*2] to [ans*2]
        End If
      Else
        operators(operator_current) = temp_string
      End If
    Elseif character_current = "%" Then
      If number_current = 0 Then number_current = 1: numbers(1) = ans
      numbers(number_current) /= 100
    Elseif character_current = "!" Then
      'factorials (like an operator, but not because 2!+3 cannot be calculated if factorials are operators)
      If number_current = 0 Then number_current = 1: numbers(1) = ans
      numbers(number_current) = Abs(Int(numbers(number_current)))
      factorial_power = numbers(number_current): numbers(number_current) = 1
      If factorial_power > 171 Then factorial_power = 171
      For b = 2 To factorial_power
        numbers(number_current) *= b
      Next b
      numbers(number_current) = numbers(number_current) * Sgn(factorial_power)
      If numbers(number_current) = -1 Then calculate_error = -1
    Elseif Instr(calculate_char_var, character_current) Then
      'functions and varibles
      'find length of variable name
      string_start = a
      Do
        a += 1
      Loop Until Instr(calculate_char_var, Mid(equation, a, 1)) = 0 Or a > Len(equation)
      variable_title = Mid(equation, string_start, a - string_start)
      a -= 1
      
      If variable_title = "X" And xvalue <> calculate_number_unspecified Then
        temp = xvalue 'calculate_evaluate(expression, ans)
      Elseif variable_title = "ANS" Then
        temp = ans
      Elseif variable_title = "RND" Then
        temp = Rnd
      Else
        If Instr(" ACOS ASIN ATAN COS INT LN SIN SQR TAN ", " " & variable_title & " ") Then
          'built-in functions
          'get function x value
          string_start = a + 1
          If Mid(equation, a + 1, 1) = "(" Then
            'loop until proper depth is reached
            d = 0
            Do
              a += 1
              If Mid(equation, a, 1) = "(" Then d += 1
              If Mid(equation, a, 1) = ")" Then d -= 1
            Loop Until d = 0
          Else
            'loop until end of number is found
            Do
              a += 1
            Loop Until (Instr(calculate_char_number, Mid(equation, a, 1)) = 0 Or a > Len(equation))
            a -= 1
          End If
          
          temp_string = Mid(equation, string_start, a - string_start + 1)
          temp = calculate_evaluate(temp_string, ans, xvalue) 'calculate xvalue for built-in function
          
          Select Case variable_title
          Case "ACOS": temp = Acos(temp)
          Case "ASIN": temp = Asin(temp)
          Case "ATAN": temp = Atn(temp)
          Case "COS": temp = Cos(temp)
          Case "INT": temp = Int(temp)
          Case "LN": temp = Log(temp)
          Case "SIN": temp = Sin(temp)
          Case "SQR": temp = Sqr(temp)
          Case "TAN": temp = Tan(temp)
          End Select
        Else
          'see if variable is defined
          variable_index = 0
          For b = 1 To calculate_variable_max
            With calculate_variables(b)
              If variable_title = .title And .ison Then variable_index = b
            End With
          Next b
          
          If variable_index > 0 Then
            'if a function, then get xvalue (next value in equation)
            If calculate_variables(variable_index).isfunction Then
              'get function input value
              string_start = a + 1
              If Mid(equation, a + 1, 1) = "(" Then
                'loop until proper depth is reached
                d = 0
                Do
                  a += 1
                  If Mid(equation, a, 1) = "(" Then d += 1
                  If Mid(equation, a, 1) = ")" Then d -= 1
                Loop Until d = 0
              Else
                'loop until end of number is found
                Do
                  a += 1
                Loop Until (Instr(calculate_char_number, Mid(equation, a, 1)) = 0 Or a > Len(equation))
                a -= 1
              End If
              temp_string = Mid(equation, string_start, a - string_start + 1)
              temp = calculate_evaluate(temp_string, ans, xvalue) 'calculate xvalue for function
              temp = calculate_evaluate(calculate_variables(variable_index).expression, ans, temp) 'calculate function value
            Else
              temp = calculate_evaluate(calculate_variables(variable_index).expression, ans) 'calculate variable value
            End If
          Else
            Print Spc(12); variable_title & " is undefined"
            temp = 0
            calculate_error = true
          End If
        End If
      End If
      calculate_number_add() 'built-in variable, built-in function, user defined: all add temp variable
    End If
  Next a
  If number_current = operator_current Then operator_current -= 1
  
  'step 2 - simplify
  If operator_current Then
    a = 1
    Do
      If operators(a) = "^" Then
        numbers(a) ^= numbers(a + 1)
        calculate_simplify()
      Else
        a += 1
      End If
    Loop Until a > operator_current
    
    a = 1
    Do
      b = a
      Select Case operators(a)
      Case "*"
        numbers(a) *= numbers(a + 1)
      Case "/"
        numbers(a) /= numbers(a + 1)
      Case Else: a += 1
      End Select
      
      If a = b Then
        calculate_simplify()
      End If
    Loop Until a > operator_current
    
    a = 1
    Do
      If operators(a) = "+" Then
        numbers(a) += numbers(a + 1)
        calculate_simplify()
      Else
        a += 1
      End If
    Loop Until a > operator_current
    
    a = 1
    Do
      b = a
      Select Case operators(a)
      Case "="
        numbers(a) = Iif(numbers(a) = numbers(a + 1), 1, 0)
      Case "<"
        numbers(a) = Iif(numbers(a) < numbers(a + 1), 1, 0)
      Case ">"
        numbers(a) = Iif(numbers(a) > numbers(a + 1), 1, 0)
      Case "<=", "=<"
        numbers(a) = Iif(numbers(a) <= numbers(a + 1), 1, 0)
      Case ">=", "=>"
        numbers(a) = Iif(numbers(a) >= numbers(a + 1), 1, 0)
      Case "<>", "><"
        numbers(a) = Iif(numbers(a) <> numbers(a + 1), 1, 0)
      Case Else
        a += 1
      End Select
      
      If a = b Then
        calculate_simplify()
      End If
    Loop Until a > operator_current
  End If
  
  calculate_depth -= 1
  If calculate_error Then Return 0 Else Return numbers(1)
End Function

Sub calculate_validate (Byref t As String)
  Dim As Integer a, b, d
  Dim As String assignment
  
  a = Instr(t, calculate_char_assignment)
  If a > 0 Then
    'remove duplicate assignment characters
    While Instr(a + 1, t, calculate_char_assignment) > 0
      b = Instr(a + 1, t, calculate_char_assignment)
      t = Left(t, b - 1) + Right(t, Len(t) - b)
      b -= 1
    Wend
    'mode assignment to a seperate string
    assignment = Right(t, Len(t) - a)
    t = Left(t, a - 1)
  End If
  
  For a = 1 To Len(t)
    If Instr(calculate_char_allowed, Mid(t, a, 1)) = 0 Then t = Left(t, a - 1) + Right(t, Len(t) - a): a -= 1
  Next a
  
  d = 0
  For a = 1 To Len(t)
    Select Case Mid(t, a, 1)
    Case "("
      d = d + 1
    Case ")"
      If d = 0 Then
        Mid(t, a, 1) = "(": d = d + 1
      Else
        d = d - 1
      End If
    End Select
  Next a
  t = Ucase(t) + String(d, ")")
  
  Do
    a = Instr(t, "()")
    If a Then t = Left(t, a - 1) + Right(t, Len(t) - a - 1)
  Loop Until a = 0
  
  If Len(assignment) Then
    'avoid parenthesis while validating function name
    d = Right(assignment, 2) = "()"
    If d Then assignment = Left(assignment, Len(assignment) - 2)
    'see if variable did not have a name
    If Len(assignment) > 0 Then
      'validate variable / function name
      For a = 1 To Len(assignment)
        If Instr(calculate_char_var, Mid(assignment, a, 1)) = false Then Mid(assignment, a, 1) = "_"
      Next a
      t += calculate_char_assignment & assignment
      If d Then t += "()"
    End If
  End If
End Sub

Sub calculate_variable_add (Byref t As String)
  'add a variable, and remove variable assignment character from string
  Dim As Integer a, isfunction, variable_free, variable_index
  Dim As String variable_title
  
  a = Instr(t, calculate_char_assignment)
  If a = 0 Then Exit Sub
  
  variable_title = Right(t, Len(t) - a)
  isfunction = Right(variable_title, 2) = "()"
  If isfunction Then variable_title = Left(variable_title, Len(variable_title) - 2)
  t = Left(t, a - 1)
  
  For a = 1 To calculate_variable_max
    With calculate_variables(a)
      If .ison Then
        If .title = variable_title Then variable_index = a
      Else
        variable_free = a
      End If
    End With
  Next a
  
  If variable_index = 0 Then variable_index = variable_free
  If variable_index = 0 Then calculate_error = true: Exit Sub
  
  'works whether variable was already created, or not
  With calculate_variables(variable_index)
    .title = variable_title
    .expression = t
    .isfunction = isfunction
    .ison = Len(t) > 0
  End With
End Sub

Sub calculate_variable_load
  Dim As Integer a
  Dim As String l
  
  Open "variables.dat" For Input As #1
  If Err Then Exit Sub
  While Not Eof(1)
    a += 1
    With calculate_variables(a)
      Line Input #1, l
      .isfunction = Right(l, 2) = "()"
      
      If .isfunction Then l = Left(l, Len(l) - 2)
      .title = l
      
      Line Input #1, .expression
      .ison = true
      
      Line Input #1, l 'blank line
    End With
  Wend
  Close #1
End Sub

Sub calculate_variable_save
  Dim As Integer a
  
  Open "variables.dat" For Output As #1
  For a = 1 To calculate_variable_max
    With calculate_variables(a)
      If .ison Then
        Print #1, .title;
        If .isfunction Then Print #1, "()" Else Print #1,
        Print #1, .expression
        Print #1,
      End If
    End With
  Next a
  Close #1
End Sub

Sub program_start
  calculate_variable_load
End Sub

Sub program_main
  Dim As Integer a, b, history_current, text_color, text_cursor_location, text_cursor_row, text_cursor_toggle
  Dim As Double ans
  Dim As String key, t
  Dim As String history(1 To history_max)
  
  Randomize Timer
  Width 80,25
  Color 15
  Cls
  Locate 1, 1, 0
  text_color = 9
  Print program_title + "(C) 2007 Kristopher Windsor"
  Print
  
  Do
    text_color = (text_color - 9) Mod 5 + 10: Color text_color
    text_cursor_row = Csrlin
    While text_cursor_row > 20
      text_cursor_row = text_cursor_row - 1
      Locate 25: Print
    Wend
    
    If t > "" And t <> history(history_max) Then
      For a = 1 To history_max - 1
        Swap history(a), history(a + 1)
      Next a
      history(history_max) = t
    End If
    
    history_current = history_max + 1
    text_cursor_location = 0
    text_cursor_toggle = 0
    key = ""
    t = ""
    Do
      Select Case key
      Case Chr(255, 71) 'home
        text_cursor_location = 0
      Case Chr(255, 72) 'up arrow
        If history_current > 1 Then
          If Len(history(history_current - 1)) > 0 Then
            history_current -= 1
            t = history(history_current)
            text_cursor_location = Len(t)
          End If
        End If
      Case Chr(255, 75) 'left arrow
        If text_cursor_location > 0 Then text_cursor_location -= 1
      Case Chr(255, 77) 'right arrow
        If text_cursor_location < Len(t) Then text_cursor_location += 1
      Case Chr(255, 79) 'end
        text_cursor_location = Len(t)
      Case Chr(255, 80) 'down arrow
        Select Case history_max - history_current
        Case 0
          history_current += 1
          t = ""
        Case Is >= 1
          history_current += 1
          t = history(history_current)
          text_cursor_location = Len(t)
        End Select
      Case Chr(255, 83) 'delete
        If text_cursor_location < Len(t) Then t = Left(t, text_cursor_location) + Right(t, Len(t) - text_cursor_location - 1)
      Case Chr(8) 'backspace
        If text_cursor_location > 0 Then t = Left(t, text_cursor_location - 1) + Right(t, Len(t) - text_cursor_location): text_cursor_location -= 1
      Case Chr(27), Chr(255, 107) 'escape or alt-f4
        Exit Sub 'program_quit
      Case Else
        If Len(key) = 1 And Len(t) < text_size_max And Instr(calculate_char_allowed, key) > 0 Then
          t = Left(t, text_cursor_location) + key + Right(t, Len(t) - text_cursor_location)
          text_cursor_location += 1
        End If
      End Select
      
      Locate text_cursor_row, 1
      Print Left(program_title + Left(t, text_cursor_location) + Chr(95 + (text_cursor_toggle) * 73) + Right(t, Len(t) - text_cursor_location) + Space(text_line_max * text_window_width), _
        text_line_max * text_window_width);
      If Len(key) = 0 Then Sleep 250: text_cursor_toggle = Not text_cursor_toggle
      key = Ucase(Inkey)
      If key = Chr(9) Then key = calculate_char_assignment
    Loop Until key = Chr(13)
    
    calculate_validate t
    For a = text_cursor_row To text_cursor_row + text_line_max - 1
      Locate a, 1
      Print Space(text_window_width);
    Next a
    Locate text_cursor_row, 1: Print program_title + t
    
    Select Case t
    Case ""
      Print Spc(12); "Press [Esc] to Quit"
    Case "CLS": Cls : Print program_title + "CLS"
    Case "EXIT": Exit Sub
    Case "HELP"
      Print
      Print Spc(12); "--Built-in Variables--"
      Print Spc(12); "ACOS() ASIN() ANS RND ATAN() COS()"
      Print Spc(12); "INT() LN() SIN() SQR() TAN()"
      Print
      Print Spc(12); "--Commands--"
      Print Spc(12); "CLS,EXIT,HELP,SMILEY,VARS"
      Print
      Print Spc(12); "--Assigning Variables--"
      Print Spc(12); "1+(2*3)" & calculate_char_assignment & "X || 2X+3" & calculate_char_assignment & "FUNCTION()"
      Print
    Case "SMILEY"
      Print Spc(12); Chr(1, 32, 2)
    Case "VARS"
      Print
      Print Spc(12); "--Assigned Variables--"
      For a = 1 To calculate_variable_max
        With calculate_variables(a)
          If .ison Then
            Print Spc(12);
            Print .title;
            If .isfunction Then Print "()";
            Print "=" & .expression
            Sleep 100
          End If
        End With
      Next a
      Print
    Case Else
      calculate_error = 0
      calculate_variable_add t 'attempt to add variable
      If Len(t) > 0 Then ans = calculate_evaluate(t, ans)
      If Abs(ans) < 1E-15 Then ans = 0
    End Select
    
    Print Spc(text_margin); "> " + Ltrim(Str(ans)); : If calculate_error Then Print " (Error)";
    Print : Print
  Loop
End Sub

Sub program_finish
  calculate_variable_save
  Color 7
  Locate ,, 1
  Cls
End Sub

program_start
program_main
program_finish
System

This program can also be downloaded here (with EXE):
http://fbc.ourproject.org/view.php?t=minicalc_2

The thread for the original MiniCalc is here:
http://www.freebasic.net/forum/viewtopi ... t=minicalc

XD
Dr_D
Posts: 2451
Joined: May 27, 2005 4:59
Contact:

Post by Dr_D »

Well, I like this program. Like I said on irc, I think you should make a version of this wth a gui that can be controlled with the mouse. That would make it something I would use on a regular basis. :)
notthecheatr
Posts: 1759
Joined: May 23, 2007 21:52
Location: Cut Bank, MT
Contact:

Post by notthecheatr »

I don't like to use the mouse much for that type of thing (typing is much easier and faster) but it would be great to have a simple GUI version - if nothing else, just a text box for typing and answer area.
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Post by KristopherWindsor »

notthecheatr wrote:I don't like to use the mouse much for that type of thing.
Then use this version without the GUI. :-P

---

Okay, I designed a GUI concept, but I'm not sure if it is complete enough; I could add features that I forgot, if you have any suggestions. One thing I really want to add, and will, is the graph tool, which will allow free-form scrolling and zooming. The only thing I notice this lacks is a complete keyboard, so if you want to name your own variables, then you will need to use the keyboard.
(I just noticed there is no backspace button, but I will add that.)

Image

:-)
Post Reply