Hello folks
I had to build some kind of string calculator for some of my projects, so here you go:
// Project: string calculator
// Created: 2015-06-05
// Alex Schmidt 2015 - www.online-arts.de
// set window properties
SetWindowTitle( "string calculator" )
SetWindowSize( 1280, 720, 0 )
// set display properties
SetVirtualResolution( 1280, 720 )
SetOrientationAllowed( 1, 1, 1, 1 )
SetPrintSize(20)
calc$="10+14+sin(20)=10+14+sin(20)"
ca$=calculate2(calc$) // the first calculation will prepare and execute most of the steps
ca2$=calculate(ca$) // this can calculate the final value from the line
ca3$=evaluate(ca2$)
do
print("Main Calculation:")
print("Term: "+calc$)
print("First Calculation: "+ca$)
print("Second Calculation: "+ca2$)
print("Evaluate: "+ca3$)
Sync()
loop
function replace_vars(calc$)
dim rep[32] as string
rep[0]="sin("
rep[1]="cos("
rep[2]="tan("
rep[3]="rnd("
x as integer
rem calc_out$=calc$
while rep[x]<>""
if calc_out$<>""
remstart
do
print("herre")
print(calc_out$)
sync()
loop
remend
calc$=calc_out$
var$=""
in_var$=""
endif
cc=0
for i=1 to len(calc$)
si=0
if mid(calc$,i,len(rep[x]))=rep[x]
si=i
for o=i+len(rep[x]) to len(calc$)
if mid(calc$,o,1)=")"
in_val$=""
for p=i+len(rep[x]) to o-1
// get the value inside
in_val$=in_val$+mid(calc$,p,1)
next p
exit
endif
next o
endif
if x=0 and si>0
val$=str(sin(val(in_val$)))
calc_out$=left(calc$,si-1)+val$+right(calc$,len(calc$)-o)
cc=cc+1
endif
if x=1 and si>0
val$=str(cos(val(in_val$)))
calc_out$=left(calc$,si-1)+val$+right(calc$,len(calc$)-o)
cc=cc+1
endif
if x=2 and si>0
val$=str(tan(val(in_val$)))
calc_out$=left(calc$,si-1)+val$+right(calc$,len(calc$)-o)
cc=cc+1
endif
if x=3 and si>0
val$=str(random(0,val(in_val$)))
calc_out$=left(calc$,si-1)+val$+right(calc$,len(calc$)-o)
cc=cc+1
endif
rem calc_out$=left(calc$,i)+val$+right(calc$,len(calc$)-o)
next i
if cc=0
inc x
endif
endwhile
undim rep[ ]
endfunction calc_out$
function calculate2(calc$)
//replace vars and stuff first
// rnd(100)= random number between 0 and 100
calc$=replace_vars(calc$)
// brackets
// find the amount of brackets
brackamount=0
redraw=0
for i=1 to len(calc$)
ms$=mid(calc$,i,1)
if ms$="(" then inc brackamount
next i
for steps=1 to brackamount
// calculate all the brackets single
tocalc$=get_bracket_in_text(brackamount-steps+1,calc$)
bracket_result$=calculate(tocalc$)
calc$=remove_bracket_in_calc(brackamount-steps+1,calc$,bracket_result$)
if steps=1
endif
next steps
end$=calc$
endfunction end$
function remove_bracket_in_calc(steps,str$,result$)
brack=0
for i=1 to len(str$)
ms$=mid(str$,i,1)
if ms$="(" then inc brack
if brack=steps
exit
endif
next i
for o=i to len(str$)
ms$=mid(str$,o,1)
if ms$=")"
exit
endif
next o
txt$=left(str$,i-1)+result$+right(str$,len(str$)-o)
endfunction txt$
function get_bracket_in_text(steps,str$)
brack=0
for i=1 to len(str$)
ms$=mid(str$,i,1)
if ms$="(" then inc brack
if brack=steps
exit
endif
next i
for o=i to len(str$)
ms$=mid(str$,o,1)
if ms$=")"
exit
endif
next o
for p=i+1 to o-1
txt$=txt$+mid(str$,p,1)
next p
rem txt$=left(right(str$,len(str$)-i),len(str$)-o-1)
endfunction txt$
function evaluate(in_calc$)
max_token=CountStringTokens(in_calc$,"=<>")
for token=1 to max_token
// find the current token
ft=0
cur_token$=""
for ts=1 to len(in_calc$)
if mid(in_calc$,ts,1)="="
cur_token$="="
inc ft
endif
if mid(in_calc$,ts,1)=">"
cur_token$=">"
inc ft
endif
if mid(in_calc$,ts,1)="<"
cur_token$="<"
inc ft
endif
if ft=token then exit
next ts
calc$=GetStringToken(in_calc$,"=<>",token)
if first_operator$=""
first_operator$=cur_token$
endif
if first_calc$=""
first_calc$=calc$
else
if second_calc$=""
second_calc$=calc$
endif
endif
if first_operator$<>"" and first_calc$<>"" and second_calc$<>""
if first_operator$="="
if valfloat(first_calc$)=valfloat(second_calc$)
out_cal=out_cal+1
if token<max_token
first_operator$=cur_token$
first_calc$=second_calc$
second_calc$=calc$
endif
endif
endif
if first_operator$=">"
if valfloat(first_calc$)>valfloat(second_calc$)
out_cal=out_cal+1
if token<max_token
first_operator$=cur_token$
first_calc$=second_calc$
second_calc$=calc$
endif
endif
endif
if first_operator$="<"
if valfloat(first_calc$)<valfloat(second_calc$)
out_cal=out_cal+1
if token<max_token
first_operator$=cur_token$
first_calc$=second_calc$
second_calc$=calc$
endif
endif
endif
endif
remstart
repeat
print("token: "+str(token)+"/"+str(max_token))
print("op: "+first_operator$)
print("fc: "+first_calc$)
print("sc: "+second_calc$)
print("cal: "+str(out_cal))
sync()
until GetPointerReleased()=1
remend
next token
rem out_calc$="0"
rem out_calc$="1"
remstart
do
print(out_cal)
sync()
loop
remend
out_calc$=str(out_cal)
endfunction out_calc$
function calculate(in_calc$)
// this should be called, if all variables are replaced by real numbers in the string
// split the string into tokens
max_token=CountStringTokens(in_calc$,"=<>")
for token=1 to max_token
// find the current token
ft=0
cur_token$=""
for ts=1 to len(in_calc$)
if mid(in_calc$,ts,1)="="
cur_token$="="
inc ft
endif
if mid(in_calc$,ts,1)=">"
cur_token$=">"
inc ft
endif
if mid(in_calc$,ts,1)="<"
cur_token$="<"
inc ft
endif
if ft=token then exit
next ts
if token=max_token then cur_token$=""
calc$=GetStringToken(in_calc$,"=<>",token)
yescalc=0
// find out, if the given string is text, if so then end without change, just kill the last )
for i=1 to len(calc$)
ms$=lower(mid(calc$,i,1))
if ms$="1" or ms$="2" or ms$="3" or ms$="4" or ms$="5" or ms$="6" or ms$="7" or ms$="8" or ms$="9" or ms$="0" then inc yescalc
next i
if yescalc=0
calc$=left(calc$,len(calc$)-1)
exitfunction calc$
endif
sum#=0.0 // result of equation
getsum$="" //Current numer in equation
lastm$="" // last operator before number
// step through calc$ and calculate sum#
for pos=1 to len(calc$)+1
// get the character from pos
m$=mid(calc$,pos,1)
remstart
repeat
print("1."+lastm$)
print("2."+str(mul#))
print("3."+str(sum#))
print("4."+str(mul#))
print("5."+getsum$)
print("6."+m$)
print(calc$)
print(pos)
print(len(calc$)+1)
sync()
until GetPointerReleased()=1
remend
if m$="+" or m$="-" or m$="/" or m$="*" or pos=len(calc$)+1
mul#=valfloat(getsum$)*1.0
if lastm$=""
sum#=mul#
getsum$=""
else
if lastm$="+"
sum#=sum#+mul#
endif
if lastm$="-"
sum#=sum#-mul#
endif
if lastm$="/"
sum#=sum#/mul#
endif
if lastm$="*"
sum#=sum#*mul#
endif
getsum$=""
endif
lastm$=m$
else
getsum$=getsum$+m$
endif
ppt=0
next pos
rem out$=str(val(str(sum#)))
out_calc$=str(sum#)
out$=out$+out_calc$+cur_token$
next token
endfunction out$
What it can:
Calculate a string like (23489+(23482/234))*123478-123
sin(), cos(), tan()
Brackets
Evaluate (=<>
= 1 or 0 true of false
What it can`t:
2+2*2 will be 8 not 6, if you use brackets 2+(2*2) you get the right answer
Enjoy and improve