How do you read an expression?

```*** Reply to note of 12/23/96 21:18
*** WARNING: a lot of code to follow ***

this will read an expression. there are a number of things that it will
*not* do, such as double unary signs (--3) and operator precedence. on the
other hand, it *will* handle the expressions you've got, as long as you
use parenthesis.

this code is *not* extensively tested. it does a parse-on-the-fly, rather
than a robust tokenize/parse/execute. on the other hand, it is fairly

if this is too large of a post, let me know, and i will avoid such in the
future. *please* no flames, etc. there are no guarantees to the fitness
of the code; etc. etc. etc. i put it together fairly rapidly.

--- CODE STARTS HERE ---
global atom x    -- your "x" variable
global integer p    -- current character being parsed in string

function math( atom a, integer op, atom b )
-- perform operation OP with A and B

if op = '+' then
return a + b
elsif op = '-' then
return a - b
elsif op = '*' then
return a * b
elsif op = '/' then
if b = 0 then
-- your error handler here. division by zero.
return 0
else
return a / b
end if
elsif op = '^' then
return power( a, b )
elsif op = '=' then
return b
elsif op = 0 then
return a
else
-- op was not recognized
return 1
end if
end function

function isNumber( integer i )

-- return true if character is part of a number

if i = '.' then
return -1 -- decimal place
else
return i >= '0' and i <= '9' -- true if ranges from '0' to '9'
end if

end function

function isOp( integer i )

-- return true if character is an operand

return i = '+' or i = '-' or i = '*' or i = '/' or i = '^'

end function

function parse1( sequence s )
integer op, decimal, sign
atom accum, num

op = '='    -- first operation is assignment to accumulator
accum = 0   -- initialize accumulator
sign = 1    -- unary minus
while p <= length(s) do -- scan

if s[p] = '(' then  -- left paren
p = p + 1  -- move past the paren
num = parse1( s )  -- recurse
accum = math( accum, op, num )  -- accumulate
elsif s[p] = ')' then
return accum  -- return parsed expression
elsif s[p] = '-' then
-- handle unary minus
if p = 1 then -- first character in string
sign = -1 -- unary minus
elsif isOp( s[p-1] ) then -- prior character was op
sign = -1 -- unary minus
else
op = s[p] -- operand
end if
elsif isOp( s[p] ) then
op = s[p] -- assign operand to pending operation
elsif s[p] = 'x' then
accum = math( accum, op, x * sign ) -- variable
sign = 1 -- clear the sign
elsif isNumber( s[p] ) then  -- number
num = 0  -- clear accumulator
decimal = 0 -- no decimal place
while isNumber( s[p] ) do  -- while it's a number
if s[p] = '.' then
decimal = 1
else
num = ( num * 10 ) + ( s[p] - '0' ) -- accumulate
decimal = decimal * 10 -- decimal place
end if
p = p + 1 -- increment pointer
end while

if decimal > 0 then  -- was there a decimal place?
num = num / decimal -- divide by the decimal amount
end if

p = p - 1 -- back up one character (we went too far)

num = num * sign -- add sign
sign = 1 -- clear sign

if s[p+1] = 'x' then -- handle stuff like 3x
p = p + 1 -- move past x
accum = math( accum, op, num * x ) -- include in operation
else
accum = math( accum, op, num ) -- perform pending operation
end if
else
-- there is an error in the expression
end if

p = p + 1 -- increment to the next character

end while

return accum

end function

function parse( sequence s )

-- main parsing function call
p = 1 -- set pointer to first character
return parse1( s ) -- parse expression

end function

-- test it
sequence expression
atom result

x = 22 -- put value in x
expression = ""  -- initialize
while compare( expression, "\n" ) do -- until a blank line is entered
puts( 1, "\n Give me an expression >" ) -- prompt
expression = gets(0) -- get expression
result = parse( expression )-- parse it
printf( 1, "\nThe result is: %g", result ) -- print results
end while

--- CODE ENDS HERE

merry christmas, all.

-- David Cuny
```