_TITLE "Tabulator" ' B+ 2020-10-23 from Formula Saver ' More Evaluate.txt bplus started 2020-05-10 inspired by honkytonk app
' 2020-10-23 translate from JB but install latest Evaluate
' copy of Evaluate subs used in this Forumla Saver Project Folder
' Should be able to do all this without Word$ tools
' OK everything seems to be working now start Tabulator
' OK Had to rearrnge th eorder the formula string gets prepped, ie
' put spaces around all the "words", replace variable for their values
' or replace constants like pi and e. THEN running x in a FOR loop update
' only the X variable with it's value.
' The Tabulator.exe opens the file: TableIn.txt
' reads lines formated as:
' first line holds the start value of a FOR Loop
' 2nd the end value of same FOR loop
' 3rd the increament to STEP
' 4th the formula eg, X ^ 2 + b * X + pi
' 5th the dFlag use 0 for Radian units any other for Degrees units
' 6+ the variables separated by CHR$(10) eg
' a = 1
' b = 6
' c = 5
' inches = 42
' Tabulator runs the formula in a for loop and generates a table in the
' file TableOut.txt.
' So you can edit TableIn.txt in your favorite Text Editor and Run Tabulator
' and it will rewrite the TableOut.txt with the list of x and f(x).
' Or you can use Calling the Tabulator sub to write the TableIn.txt file,
' Shell and Run Tabulator then read the file into an array top use:
' SUB forXEqual (start, toFinish, incStep, formula$, dFlag%, variablesCHR10$, outputArr$())
' Calling the Tabulator.bas is a demo for the SUB mainly.
' BTW Tabulator does everything in background you will have no idea the TableOut.txt file
' has been rewritten or not!
'evaluate$ and evalW setup
debug = 0 ' this is for checking the Evaluate stuff
pi
= _PI: rad
= pi
/ 180: deg
= 180 / pi
'<<<<<<<<<<< true constantsvTopI = 0 'track variables and functions we have changeable global variables change as needed
Dflag = 0 ' degrees flag
evalErr$ = ""
Split "int, sin, cos, tan, asin, acos, atan, log, exp, sqr, rad, deg,", ", ", fList()
Split "^, %, /, *, -, +, =, <, >, <=, >=, <>, or, and, not", ", ", oList()
SELECT CASE i
' format first 5 lines set variables, more than 5 sets variable names and values WHILE NOT EOF(1) ' read in additional varaibles and values IF INSTR(fline$
, "=") THEN ' collect variable names and values vTopI = vTopI + 1
varNames$
(vTopI
) = _TRIM$(leftOf$
(fline$
, "=")): varValues
(vTopI
) = VAL(_TRIM$(rightOf$
(fline$
, "="))) PRINT " Sorry, TableIn.txt file is missing, goodbye!" e$ = prepEval$(frml$)
'PRINT "prep formula: "; e$
'INPUT " OK "; w$
PRINT #1, "Error: " + evalErr$
preEvalSubst e$ 'OK inject variable values into formula
' debug
'PRINT "Replace variables with values, except x: "; e$
'INPUT "After preEvalSubst OK "; w$
copy$ = e$
Split copy$, " ", ev$()
'rebuild eString$
copy$ = b$
result$
= _TRIM$(Evaluate$
(copy$
)) PRINT #1, ts$
(x
);
" "; result$
PRINT #1, ts$
(x
);
" Error: " + evalErr$
FUNCTION value
(vName$
) ' find vName$ index to get value of variable value = varValues(i)
value = -99.11 ' no value found can't be -1 or 0 too common
SUB preEvalSubst
(eString$
) ' this is meant to modify eString$ inserting values for variables Split eString$, " ", ev$()
v = value(ev$(i))
IF v
<> -99.11 THEN ev$
(i
) = ts$
(v
) 'rebuild eString$
eString$ = b$
' isolateNeg = 0
b$ = "" 'rebuild string with padded spaces
'this makes sure ( ) + * / % ^ are wrapped with spaces, ??????????? on your own with - sign fixed?
FOR i
= 1 TO LEN(e$
) 'filter chars and count () po = po - 1: b$ = b$ + " ) "
po = po + 1: b$ = b$ + " ( "
b$ = b$ + " " + c$ + " "
b$ = b$ + " " + c$ + " "
b$ = b$ + " " + c$
b$ = b$ + " " + c$
b$ = b$ + c$
prepEval$ = b$
' ================================================================================ from Evaluate
'this preps e$ string for actual evaluation function and makes call to it,
'checks results for error returns that or string form of result calculation
'the new goal is to do string functions along side math
Split e$, " ", ev()
c$ = evalW$(ev())
IF evalErr$
<> "" THEN Evaluate$
= evalErr$
ELSE Evaluate$
= c$
' the recursive part of EVAL
DIM fun$
, test$
, innerV$
, m$
, op$
PRINT "evalW rec'd a() as:" pop = find%(a(), "(") 'parenthesis open place
fun$ = "": lPlace = 1
test$ = a(pop - 1)
IF find%
(fList
(), test$
) > 0 THEN fun$ = test$: lPlace = pop - 1
fun$ = "": lPlace = pop
po = 1
IF a
(i
) = "(" THEN po
= po
+ 1 IF a
(i
) = ")" THEN po
= po
- 1 FOR i
= (pop
+ 1) TO (rPlace
- 1) index = index + 1
inner(index) = a(i)
IF find%
(oList
(), a
(i
)) > 0 THEN recurs
= -1 IF recurs
THEN innerV$
= evalW$
(inner
()) ELSE innerV$
= a
(pop
+ 1)
CASE "int": m$
= ts$
(INT(innerVal
)) CASE "exp" 'the error limit is inconsistent in JB IF -745 <= innerVal
AND innerVal
<= 709 THEN 'your system may have different results 'what the heck???? 708 works fine all alone as limit ?????
evalErr$
= "EXP(n) only works for n = -745 to 709.":
EXIT FUNCTION evalErr$
= "SQR only works for numbers >= 0.":
EXIT FUNCTION CASE "rad": m$
= ts$
(innerVal
* rad
) CASE "deg": m$
= ts$
(innerVal
* deg
) PRINT "lPlace, rPlace"; lPlace
, rPlace
arrSubst a(), lPlace, rPlace, m$
PRINT "After arrSubst a() is:" pop = find%(a(), "(")
'all parenthesis cleared
'ops$ = "% ^ / * + - = < > <= >= <> and or not" 'all () cleared, now for binary ops (not not binary but is last!)
op$ = oList(o)
p = find%(a(), op$)
evalErr$ = "For a Mod b, b value < 2."
m$ = ts$(a ^ b)
evalErr$ = "For a ^ b, a needs to be >= 0 when b not integer."
m$ = ts$(a / b)
evalErr$ = "Div by 0"
CASE "*": m$
= ts$
(a
* b
) CASE "-": m$
= ts$
(a
- b
) CASE "+": m$
= ts$
(a
+ b
) CASE "not":
IF b
= 0 THEN m$
= "-1" ELSE m$
= "0" 'use b as nothing should be left of not arrSubst a(), p - 1, p + 1, m$
PRINT "a() reloaded after " + op$
+ " as:"
p = find%(a(), op$)
fun$ = ""
fun$ = fun$ + " " + a(i)
a(substLow) = subst: index = substLow + 1
a(index) = a(i): index = index + 1
'notes: REDIM the array(0) to be loaded before calling Split '<<<<<<<<<<<<<<<<<<<<<<< IMPORTANT!!!!
' bplus modifications of Galleon fix of Bulrush Split reply #13
' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=1612.0
' this sub further developed and tested here: \test\Strings\Split test.bas
' 2018-09-16 modified for base 1 arrays
copy = mystr 'make copy since we are messing with mystr
'special case if delim is space, probably want to remove all excess space
copy
= MID$(copy
, 1, p
- 1) + MID$(copy
, p
+ 1) curpos = 1
arrpos = 1
dpos
= INSTR(curpos
, copy
, delim
) arr
(arrpos
) = MID$(copy
, curpos
, dpos
- curpos
) arrpos = arrpos + 1
curpos
= dpos
+ LEN(delim
) dpos
= INSTR(curpos
, copy
, delim
) arr
(arrpos
) = MID$(copy
, curpos
)
'assume a() is base 1 array so if find comes back as 0 then found nothing
'ltrim a number float