procedure drv(exp,var)
   local arg1, op, arg2
   if exp ? {
      op := tab(upto('(')) &
      move(1) &
      arg1 := tab(bal(',')) &
      move(1) &
      arg2 := tab(bal(')'))
      }
   then return case op of {
      "+":  add(drv(arg1,var),drv(arg2,var))
      "-":  sub(drv(arg1,var),drv(arg2,var))
      "*":  add(mpy(arg1,drv(arg2,var)),
               mpy(arg2,drv(arg1,var)))
      "/":  div(sub(mpy(arg2,drv(arg1,var)),
               mpy(arg1,drv(arg2,var))),rse(arg2,"2"))
      "^":  mpy(mpy(arg2,rse(arg1,sub(arg2,"1"))),
               drv(arg1,var))
      }
   else return if exp == var then "1" else "0"
end
