sync on
type coords
   x as float
   y as float
endtype
global pi$="3.14159265358"
global e$="2.71828183"
global choice$
ink rgb(0,255,0),0
set text font "Arial"
set text size 24
do
dim elements(1000) as string
dim holdx(1000) as string
dim plotter(10000) as coords
if choice$=""
   print "Options=   "
   print "Solver"
   print "Plotter"
   print ""
   text 0,72,"_____________________________________________________"
   text 0,100,"_____________________________________________________"
 
   sync
 
   input ">   ",choice$
   choice$=lower$(choice$)
   if choice$<>"plotter" and choice$<>"solver" then Error("This mode does not exist (yet)")
   cls
endif
print "p=pi        e=e       c=cosine       b=absolute value"
print "s=sine         t=tangent       a=previous answer"
print "r=square root     (x=variable - only for plotter)"
print "l=log                Allowed Operations:    +     -"
print "*      !      /       ^        (        )        E"
print "Spacekey when answer is shown to go back"
text 0,122,"_____________________________________________________"
text 0,150,"_____________________________________________________"
 
sync
 
input ">   ",equation$
if equation$="" then equation$=pe$
numofele=Store_In_Array(equation$)
numofele=Hidden_Multiplication(numofele)
for i=1 to numofele
   numofele=Check_For_Negatives(i,numofele)
next i
if choice$="solver"
   for i=1 to numofele
      if elements(i)="x" then Error("Variable only supported in plotter")
   next i
   if elements(1)="+" or elements(1)="*" or elements(1)="/" or elements(1)="^" or elements(1)="!" or elements(1)="E"
      Insert_Position(1,numofele)
      inc numofele
      elements(1)="a"
   endif
   Substitute_Values(numofele)
   while numofele>1
      numofele=Solve(numofele)
      print ""
      for i=1 to numofele
         printc elements(i)
      next i
   endwhile
   print ""
   print "_______________"
   if elements(1)="1.#INF" or elements(1)="-1.#INF" then Error("Overflow!")
   print elements(1)
   pe$=equation$
   global pans$
   pans$=elements(1)
endif
if choice$="plotter"
   cls
   Substitute_Values(numofele)
   ink rgb(0,255,0),0
   sync
   input "Xmin  ",xmin$
   sync
   input "Xmax  ",xmax$
   sync
   input "Ymin  ",ymin$
   sync
   input "Ymax  ",ymax$
   sync
   input "Step  ",stp$
   sync
   input "Connected (1 for yes, 0 for no)  ",con
   if xmin$=""
      xmin#=-100
   else
      xmin#=val(xmin$)
   endif
   if xmax$=""
      xmax#=100
   else
      xmax#=val(xmax$)
   endif
   if ymin$=""
      ymin#=-100
   else
      ymin#=val(ymin$)
   endif
   if ymax$=""
      ymax#=100
   else
      ymax#=val(ymax$)
   endif
   if stp$=""
      stp#=0.5
   else
      stp#=val(stp$)
   endif
   cls
   n=0
   noe=numofele
   for x#=xmin# to xmax# step stp#
      inc n
      for i=1 to noe
         a$=elements(i)
         holdx(i)=a$
         if a$="x"
            elements(i)=str$(x#)
         endif
         if a$="-x"
            elements(i)=str$(-x#)
         endif
      next i
      while numofele>1
         numofele=Solve(numofele)
      endwhile
      y#=val(elements(1))
      plotter(n).x=x#
      plotter(n).y=y#
      for i=1 to noe
         elements(i)=holdx(i)
         holdx(i)=""
      next i
      numofele=noe
   next x#
   xsize#=xmax#-xmin#
   ysize#=ymax#-ymin#
   xoff#=(xmin#+xmax#)/2
   yoff#=(ymin#+ymax#)/2
   nax=n
   if con=1
      nop=1
      for n=2 to nax
         line (plotter(n-1).x-xoff#)*screen width()/(xsize#+0.0)+screen width()/2,(screen height()/2)-((plotter(n-1).y-yoff#)*screen height()/(ysize#+0.0)),(plotter(n).x-xoff#)*screen width()/(xsize#+0.0)+screen width()/2,(screen height()/2)-((plotter(n).y-yoff#)*screen height()/(ysize#+0.0))
         inc nop
      next n
   else
      nop=0
      for n=1 to nax
         dot (plotter(n).x-xoff#)*screen width()/(xsize#+0.0)+screen width()/2,(screen height()/2)-((plotter(n).y-yoff#)*screen height()/(ysize#+0.0))
         inc nop
      next n
   endif
   ink -1,0
   line (xmin#-xoff#)*screen width()/(xsize#+0.0)+screen width()/2,(screen height()/2)-((-yoff#)*screen height()/(ysize#+0.0)),(xmax#)*screen width()/(xsize#+0.0)+screen width()/2,(screen height()/2)-((-yoff#)*screen height()/(ysize#+0.0))
   line (-xoff#)*screen width()/(xsize#+0.0)+screen width()/2,(screen height()/2)-((ymin#-yoff#)*screen height()/(ysize#+0.0)),(-xoff#)*screen width()/(xsize#+0.0)+screen width()/2,(screen height()/2)-((ymax#)*screen height()/(ysize#+0.0))
   ink rgb(0,255,0),0
   top=1
   s=0
   while returnkey()=1
   endwhile
   set text size 15
   s=0
   while returnkey()+spacekey()+s=0
      sync
      s=scancode()
      move=downkey()-upkey()
      if move<>0
         s=0
         wait 20
      endif
      top=top+move
      if top>nop then top=nop
      if top<1 then top=1
      box 0,0,mr*6,200,rgb(0,0,0),rgb(0,0,0),rgb(0,0,0),rgb(0,0,0)
      mr=0
      set cursor 0,0
      for i=top to top+10
         if i<=nop
            disp$="( "+str$(plotter(i).x)+","+str$(plotter(i).y)+" )"
            r=len(disp$)
            if r>mr then mr=r
            print disp$
         endif
      next i
   endwhile
   set text size 24
endif
sync
wait key
s=0
while s=0
   s=scancode()
   if spacekey()=1
      choice$=""
      s=1
   endif
endwhile
undim elements()
undim plotter()
undim holdx()
cls
loop
 
function Store_In_Array(equation$)
element=1
for i=1 to len(equation$)
   a$=mid$(equation$,i)
   number=Is_Number(a$)
   if number=0
      inc element
      elements(element)=a$
      inc element
   else
      if number=1
         elements(element)=elements(element)+a$
      else
         Error("Symbol not recognized")
      endif
   endif
next i
endfunction element
 
function Is_Number(a$)
if a$="." or a$="0" or val(a$)<>0
   number=1
else
   if a$="+" or a$="-" or a$="*" or a$="/" or a$="^" or a$="p" or a$="e" or a$="c" or a$="s" or a$="t" or a$="(" or a$=")" or a$="!" or a$="a" or a$="b" or a$="r" or a$="E" or a$="x" or a$="l"
      number=0
   else
      number=-1
   endif
endif
endfunction number
 
function Error(caption$)
if choice$="solver"
   exit prompt caption$,"Error!"
   end
else
   for i=1 to 1000
      elements(i)=""
   next i
endif
endfunction
 
function Hidden_Multiplication(numofele)
for i=1 to numofele
   a$=elements(i)
   if a$=""
      Delete_Position(i,numofele)
      dec numofele
      dec i
   endif
   if a$="(" or a$="c" or a$="s" or a$="t" or a$="p" or a$="e" or a$="a" or a$="b" or a$="r" or a$="x" or a$="l"
      if i>1
         pa$=elements(i-1)
         if pa$=")" or pa$="p" or pa$="e" or pa$="a" or Is_Number(pa$)=1
            Insert_Position(i,numofele)
            inc numofele
            elements(i)="*"
         endif
      endif
   endif
   if a$=")" or a$="p" or a$="e" or a$="!" or a$="a" or a$="x"
      if i<numofele
         na$=elements(i+1)
         if Is_Number(na$)=1
            inc i
            Insert_Position(i,numofele)
            inc numofele
            elements(i)="*"
         endif
      endif
   endif
next i
endfunction numofele
 
function Check_For_Negatives(i,numofele)
a$=elements(i)
if a$="-"
   if i=1
      negative=1
   else
      pa$=elements(i-1)
      if Is_Number(pa$)=1 or pa$=")" or pa$="p" or pa$="e" or pa$="a" or pa$="x"
         negative=0
      else
         negative=1
      endif
   endif
   if negative=1
      na$=elements(i+1)
      if na$="(" then negative=0
   endif
   if negative=1
      elements(i+1)="-"+elements(i+1)
      Delete_Position(i,numofele)
      dec numofele
   endif
endif
endfunction numofele
 
function Delete_Position(pos,numofele)
for i=pos to numofele
   elements(i)=elements(i+1)
next i
endfunction
 
function Insert_Position(pos,numofele)
for i=numofele to pos step -1
   elements(i+1)=elements(i)
next i
elements(pos)=""
endfunction
 
function Substitute_Values(numofele)
for i=1 to numofele
   a$=elements(i)
   if a$="p"
      elements(i)=pi$
   endif
   if a$="e"
      elements(i)=e$
   endif
   if a$="a"
      elements(i)=pans$
   endif
next i
endfunction
 
function Solve(numofele)
lop=0
mlop=0
open=0
close=numofele+1
for i=1 to numofele
   a$=elements(i)
   if a$="("
      inc lop
   endif
   if a$=")"
      dec lop
   endif
   if lop>mlop
      mlop=lop
      open=i
   endif
   if lop<0 then Error("Illegal Brackets")
next i
if lop>0 then Error("Failure to Close Brackets")
for i=open to numofele
   a$=elements(i)
   if a$=")"
      close=i
      exit
   endif
next i
highest=0
now=0
if close-open=2
   Delete_Position(close,numofele)
   Delete_Position(open,numofele-1)
   dec numofele,2
   if open>1
      pa$=elements(open-1)
      if pa$="-"
         numofele=Check_For_Negatives(open-1,numofele)
      endif
   endif
else
   for i=open to close
      a$=elements(i)
      if a$="+" then now=1
      if a$="-" then now=2
      if a$="*" then now=3
      if a$="/" then now=4
      if a$="!" then now=5
      if a$="c" then now=6
      if a$="s" then now=7
      if a$="t" then now=8
      if a$="^" then now=9
      if a$="r" then now=10
      if a$="l" then now=11
      if a$="E" then now=12
      if a$="b" then now=13
      if now>highest
         highest=now
         sp=i
      endif
   next i
   newval#=0
   if highest<5 or highest=9 or highest=12
      if highest=1 then newval#=val(elements(sp-1))+val(elements(sp+1))
      if highest=2 then newval#=val(elements(sp-1))-val(elements(sp+1))
      if highest=3 then newval#=val(elements(sp-1))*val(elements(sp+1))
      if highest=4
         if val(elements(sp+1))=0.0
            Error("Divide by 0")
         else
            newval#=val(elements(sp-1))/val(elements(sp+1))
         endif
      endif
      if highest=9 then newval#=val(elements(sp-1))^val(elements(sp+1))
      if highest=12 then newval#=val(elements(sp-1))*10^val(elements(sp+1))
      Delete_Position(sp-1,numofele)
      dec numofele
      Delete_Position(sp-1,numofele)
      dec numofele
      elements(sp-1)=str$(newval#)
   endif
   if highest=5
      cval#=val(elements(sp-1))
      if cval#>int(cval#) then Error("Factorial must use integer")
      if cval#<0 then Error("Factorial of a negative number!")
      newval#=1
      for i=1 to cval#
         newval#=newval#*i
      next i
      Delete_Position(sp-1,numofele)
      dec numofele
      elements(sp-1)=str$(newval#)
   endif
   if highest>5 and highest<9 or highest=10 or highest=11 or highest=13
      if highest=6 then newval#=cos(val(elements(sp+1)))
      if highest=7 then newval#=sin(val(elements(sp+1)))
      if highest=8 then newval#=tan(val(elements(sp+1)))
      if highest=10
         test#=val(elements(sp+1))
         if test#<0 then Error("Square root of a negative number!")
         newval#=sqrt(test#)
      endif
      if highest=11 then newval#=log(val(elements(sp+1)),6)
      if highest=13 then newval#=abs(val(elements(sp+1)))
      Delete_Position(sp,numofele)
      dec numofele
      elements(sp)=str$(newval#)
   endif
endif
endfunction numofele
 
function log(nr#, acc)
   result# = 0.00
   for c = 0 to acc
      repeat
         inc result#, 10.0^(c*-1)
      until 10.0^result# >= nr#
      if 10.0^result# = nr#
         exitfunction result#
      else
         dec result#, 10.0^(c*-1)
      endif
   next c
endfunction result#