resource evaluator()
  op expr() returns int  ans
  op term() returns int  ans
  op factor() returns int  ans
  string[100] s   # string to evaluate
  int pos         # position in s to evaluate

  # read and evaluate expressions until end of input
  while (true) {
      if (read(s) == EOF) { write(); exit }
      s = s || "$"  # append sentinel to s
      pos = 1
      write(expr())
  }

  proc expr() returns ans  {
    ans = term()
    while (s[pos] == '+') {
	pos++
	ans += term()
    }
  }

  proc term() returns ans  {
    ans = factor()
    while (s[pos] == '*') {
	pos++
	ans *= factor()
    }
  }

  proc factor() returns ans  {
    if (s[pos] == '(') {
	pos++
	ans = expr()
	pos++ # skip over ')'
    } else { # convert substring to integer
	ans = 0
	while ('0' <= s[pos] & s[pos] <= '9') {
	    ans = 10*ans + int(s[pos]) - int('0')
	    pos++
	}
    }
  }
end evaluator
