----------------------------------------------------------------------
-- The modified shunting-yard algorithm
----------------------------------------------------------------------

-- | Parse a list of s-expressions according to an operator table.
-- Usually the s-expressions will be the result of applying 'Atom'
-- to each token.
shunt :: Token a => Table a -> [SExpr a] -> Either (Failure a) (SExpr a)
shunt table ts = case fix $ initial ts of
  S [] [] [[o']] (Done Success) -> Right o'
  S _ _ _ (Done (Failure f)) -> Left f
  _ -> error "can't happen" -- the Success case has only the previous form.
  where fix s = let s' = step table s in
                if isDone s' then s' else fix s'

-- Perfom one step of the shunting-yard, moving it from one state to the next.
shunt :: Token a => Table a -> [SExpr a] -> Either (Failure a) (SExpr a)
shunt table ts = case fix $ initial ts of
  S [] [] [[o']] (Done Success) -> Right o'
  S _ _ _ (Done (Failure f)) -> Left f
  _ -> error "can't happen" -- the Success case has only the previous form.
  where fix s = let s' = step table s in
                if isDone s' then s' else fix s'

-- Perfom one step of the shunting-yard, moving it from one state to the next.
shunt table ts = case fix $ initial ts of
  S [] [] [[o']] (Done Success) -> Right o'
  S _ _ _ (Done (Failure f)) -> Left f
  _ -> error "can't happen" -- the Success case has only the previous form.
  where fix s = let s' = step table s in
                if isDone s' then s' else fix s'

-- Perfom one step of the shunting-yard, moving it from one state to the next.