1 module Print (printAst, printBasicExp, printEnv) where
    2 
    3 import BasicNumber
    4 import BasicNumberApprox
    5 import Ast
    6 import Op
    7 import Parser
    8 import Env
    9 import Eval
   10 import Ratio--1.3
   11 
   12 -- print an abstract syntax tree
   13 printAst :: Ast -> Env -> String
   14 printAst (Set name bexp) env = "Set "++name++" to "++(printBasicExp bexp env)
   15 printAst (EvalSet name bexp) env = 
   16                 "Eval\t"++(printBasicExp bexp env)++"\n"++
   17                 "Set\t"++name++" to "
   18 printAst (Eval bexp) env = "Eval "++(printBasicExp bexp env)
   19 printAst SyntaxError _ = "Syntax error"
   20 printAst NullCmd _ = ""
   21 
   22 -- print a basic expression
   23 printBasicExp :: BasicExp -> Env -> String
   24 printBasicExp = printExp 10
   25 
   26 -- print an expression with a precedence argument
   27 printExp :: Int -> BasicExp -> Env -> String
   28 printExp p (Func name args) env =
   29                 case opname of
   30                     ""        -> name++"("++(printArgs args env)++")"
   31                     (x:xs) -> printOp p opname args env
   32                 where
   33                     opname = case args of
   34                                 [arg1,arg2] -> toOp name
   35                                 [arg]           -> toOp1 name
   36                                 _       -> ""
   37 printExp _ (Numb n) env = mybasicNumber2str n (getPrec env)
   38 printExp _ (Var s) _ = s
   39 printExp _ (EVar s) _ = s
   40 printExp _ BSError _ = "ERROR"
   41 
   42 -- print the arguments
   43 printArgs :: [BasicExp] -> Env -> String
   44 printArgs [] _ = ""
   45 printArgs [x] env = printBasicExp x env
   46 printArgs (x:xs) env = (printBasicExp x env)++(printArglist xs env)
   47 
   48 -- auxilury funtion for printing the arguments
   49 printArglist :: [BasicExp] -> Env -> String
   50 printArglist [] _ = ""
   51 printArglist (x:xs) env = ","++(printBasicExp x env)++(printArglist xs env)
   52 
   53 -- print expression with operators
   54 printOp :: Int -> String -> [BasicExp] -> Env -> String
   55 
   56 printOp p opname [arg] env =
   57         if mp>p then "("++res++")" else res
   58         where
   59                 res = opname ++ (printExp mp arg env)
   60                 mp = opPrec1 opname
   61 
   62 printOp p opname [arg1,arg2] env =
   63         if mp>=p then res2
   64                 else res1
   65         where
   66                 lmp = if massoc == "left" then mp+1 else mp
   67                 rmp = if massoc == "right" then mp+1 else mp
   68                 res1 = str1++opname++str2
   69                 res2 = "("++res1++")"
   70                 mp   = opPrec opname
   71                 massoc = opAssoc opname
   72                 str1 = printExp lmp arg1 env
   73                 str2 = printExp rmp arg2 env
   74 
   75 printOp _ _ _ _ = ""
   76 
   77 -- print an environment
   78 printEnv :: Env -> Env -> String
   79 printEnv [] _ = ""
   80 printEnv (e:es) env = pEnv e env ++ (printEnv es env)
   81         where
   82                 pEnv e@(str, bexp) env = 
   83                         str++"\t"++(printBasicExp bexp env)++"\n"
   84 
   85 mybasicNumber2str :: BasicNumber -> Integer -> String
   86 mybasicNumber2str (BasRationalC x) p =
   87         if numerator sx == 0 then "0"
   88         else if denominator sx == 1 then show (numerator sx) 
   89              else "("++(basicNumber2str (BasRationalC sx) p)++")"
   90                 where sx = x/1
   91 mybasicNumber2str x p = basicNumber2str x p