Skip to main content

SOME MORE PROGRAMMING - EVALUATING EXPRESSIONS
by Stefan Posthuma

If  you  like to be bored by mindintoxicatingly  boring  boredom, 
you are in for a treat here.  Just read the following article and 
you'll know what I mean.  It is about programming extreme  things 
in GfA,  doing difficult things in general. I wonder where I ever 
got  the  inspiration  to  write  things  that  are  probably  as 
difficult as getting the plastic wrapper of a cassette tape.

Evaluating  expressions has baffled me ever since I got the  idea 
of programming it.  In case you don't know what it is,  take  GfA 
basic, go into direct mode and type something like: Print 1+1

The  computer will do what it is made for and print  2.  It  just 
evaluated an expression,  being '1+1'.  Now this is very  simple, 
but what about something like:

1+2*4^(5-3)-4/(34-2)

Still simple to make a routine that calculates it?  Well,  it can 
be  done,  just  type  it  (and Print of  course)  and  GfA  will 
calculate it for you.  Just think about it. You will have to deal 
with  the  priority of  operators.  Multiplication  comes  before 
addition  and more of that.  Also,  you have to calculate  values 
between  parenthesis  first.  If you don't know  excatly  how  to 
program  it,  it will become hopelessly complicated.  But  I  was 
browsing  through a highly dedicated book on the AWK  programming 
language.  AWK is a text-processing language, most commonly found 
on  the bigger XENIX and UNIX systems.  I use it to  create  nice 
things,  and  the  book was just something I had to read  for  my 
work. But nothing can describe my amazement when I stumbled along 
a small algorithm programmed in the particular AWK language  that 
was able to evaluate expressions of almost unlimited  complexity! 
I immediately tossed the book in my briefcase,  and that night  I 
sat down and loaded GfA 3.0.  It can be done in GfA 2.0, but that 
will be very difficult.

I will now present you with the algorithm, in pseudo-code:

Function Expr()
   a=Muldiv()
   while element = "+" or element = "-"
      if element = "+" then
         add a,Muldiv()   
      else
         sub a,Muldiv()
      endif
   wend
   return a
End Function

Function Muldiv()
   a=Power()
   while element = "*" or element = "/"
      if element = "*" then
         mul a,Power()
      else
         div a,Power()
      end if
      call Getelement()
   wend
   return a
End Function

Function Power()
   a=Factor()
   call Getelement()
   while element = "^"
      a=a^Factor()
      call Getelement()
   wend
   return a
End Function

Function Factor()
   call Getelement()
   if element is a number then
      return element
   else
      if element = "("
         a=Expr()
         if element <> ")"
            error
         endif
         return a
      else
         error
      endif
   endif
End Function

That's it! Maybe it looks a little complicated, but it is easy to 
program. (Providing you use GfA 3.0 or C)

Now instead of giving you the literal GfA code, try to program it 
yourself.  I  will give a couple of hints though,  and the  basic 
source can be found in the programs folder on this disk.

This is the way my routine works:

I construct a string,  let's say E$ which contains the expression 
to be calculated.  You can easily enter program variables into it 
by means of STR$. So you want to calculate the function:

y=x/4

your statements would be this:

E$=str$(x)+"/4"
y=@expr

The  'element'  variable  used in the algorithm is  in  fact  any 
element from the expression. In this case ranging from any number 
to the operators + - * / and ^ and the parenthesis.  You'll  have 
to  write a procedure (called Getelement here) who gets the  next 
element from the string. If you want to simplify things a little, 
assume  that  the  various  elements  from  the  expression   are 
separated by blanks. So "1+-2" will become "1 + -2" which is much 
easier to break apart.  All routines (like Muldiv, Power and Expr 
itself)  will  have to be functions,  because  they  must  return 
values.  The 'Factor' routine will actually get a number from the 
expression (a number is expected) or it will calculate the  value 
of  a new expression between parenthesis by  recursively  calling 
the  Expr function again.  So the string and the pointer  to  the 
next  element in the string will have to be globals (outside  any 
function  or  routine).   In  this  way,  the  number  of  nested 
parenthesis only depends on the size of your stack.

Well,  it  needs  a  little programming  experience  and  a  good 
understanding of the algorithm,  but it is possible. If you don't 
feel like programming,  just take a look at the basic program  as 
to be found in the programs folder on this disk. It is a slightly 
enhanced  version that can also calculate things like  SIN,  COS, 
TAN,  LOG  and  the  likes.  It  is merely  an  addition  to  the 
Getelement  routine that will find the SIN or whatever  function, 
call  Expr (recursion again!) to calculate the value between  the 
parenthesis,  use  this value to calculate the sinus or  whatever 
and  return the obtained number just like there was  an  ordinary 
number in the string.

I wish you lots of succes programming it.

Stefan.

Disclaimer
The text of the articles is identical to the originals like they appeared in old ST NEWS issues. Please take into consideration that the author(s) was (were) a lot younger and less responsible back then. So bad jokes, bad English, youthful arrogance, insults, bravura, over-crediting and tastelessness should be taken with at least a grain of salt. Any contact and/or payment information, as well as deadlines/release dates of any kind should be regarded as outdated. Due to the fact that these pages are not actually contained in an Atari executable here, references to scroll texts, featured demo screens and hidden articles may also be irrelevant.