module Tok where

type Prec = Int
type Var = String

data Op = Op String Prec Fixity
  deriving (Eq, Show)

data Fixity = Leftfix | Rightfix | Nonfix
  deriving (Eq, Show)

data Exp = Var Var | OpApp Exp Op Exp | Neg Exp
  deriving Eq

instance Show Exp where
  show e = case e of
    Var v -> v
    Neg e -> '-' : show e
    OpApp e1 (Op s _ _) e2 -> '(' : show e1 ++ s ++ show e2 ++ ")"

data Tok = TExp Exp | TOp Op | TNeg
  deriving (Eq, Show)

c2t :: Char -> Tok
c2t c = case c of
  '-' -> TNeg
  '<' -> TOp $ Op [c] 5 Leftfix
  ':' -> TOp $ Op [c] 5 Rightfix
  '+' -> TOp $ Op [c] 6 Leftfix
  '#' -> TOp $ Op [c] 6 Rightfix
  '%' -> TOp $ Op [c] 6 Nonfix
  '^' -> TOp $ Op [c] 8 Rightfix
  _ | elem c "*/" -> TOp $ Op [c] 7 Leftfix
  _ -> TExp $ Var [c]

test r = do
  s <- getLine
  putStrLn $ case r $ map c2t s of
    Nothing -> "unresolved: " ++ s
    Just e -> show e
  test r
