blob: 2965d9c77164f7fbdda4da3956c370ba472438e7 [file] [log] [blame]
/* main rpn parser and lexical analysis, part of the RPN calculator */
#include <rational>
#include <string>
enum token
{
t_type, /* operator or token type */
Rational: t_value, /* value, if t_type is "Number" */
t_word[20], /* raw string */
}
const Number = '0'
const EndOfExpr = '#'
rpncalc(const string[])
{
new index
new field[token]
for ( ;; )
{
field = gettoken(string, index)
switch (field[t_type])
{
case Number:
push field[t_value]
case '+':
push pop() + pop()
case '-':
push - pop() + pop()
case '*':
push pop() * pop()
case '/', ':':
push 1.0 / pop() * pop()
case EndOfExpr:
break /* exit "for" loop */
default:
printf "Unknown operator '%s'\n", field[t_word]
}
}
printf "Result = %r\n", pop()
if (clearstack())
print "Stack not empty\n", red
}
gettoken(const string[], &index)
{
/* first get the next "word" from the string */
new word[20]
word = strtok(string, index)
/* then parse it */
new field[token]
field[t_word] = word
if (strlen(word) == 0)
{
field[t_type] = EndOfExpr /* special "stop" symbol */
field[t_value] = 0
}
else if ('0' <= word[0] <= '9')
{
field[t_type] = Number
field[t_value] = rationalstr(word)
}
else
{
field[t_type] = word[0]
field[t_value] = 0
}
return field
}