{- Module : Highlighter.hs Description : . Maintainer : Chritoph Graebnitz, Marcus Hoffmann(c) License : MIT Stability : experimental This Modul provides a function to color the colorMap of textAreaContent. It uses primary the Lexer modul to step the IP of the code and highlight by the way. -} module Highlighter ( highlight -- highlights all entries saved in the data structur of the TextAreaCotent-module ) where import InterfaceDT as IDT import Preprocessor as PRE import Lexer import qualified TextAreaContent as TAC import qualified Control.Exception as EXC import Graphics.UI.Gtk.Abstract.Widget import System.IO import Data.IORef import Data.Maybe import qualified Data.Map as Map --returns the grid2D from a IDT.IPL grid2D getGrid2dFromPreProc2Lexer(IDT.IPL grid2D) = grid2D -- highlights all entries saved in the data structur of the TextAreaCotent-module highlight :: TAC.TextAreaContent -> IO() highlight textAC = EXC.catch (do pGrid <- TAC.getPositionedGrid textAC let (IDT.IPL positionedGrid) = pGrid (xm,ym) <- TAC.size textAC paintItRed textAC highlightFcts positionedGrid textAC return () ) handleErrors --Handels errors and prints them out used in context of Lexer and Preprocessor handleErrors :: EXC.ErrorCall -> IO () handleErrors e = print(show e) -- highlight all rail-functions highlightFcts :: [PositionedGrid]-- List of funtions in line-representation with y coord of function(position of $) -> TAC.TextAreaContent -- Char coloring information -> IO IP highlightFcts [] _ = return crash highlightFcts (x:xs) textAC = do highlightFct (fst x) start (snd x) textAC Map.empty highlightFcts xs textAC {- main highlighting process which highlights a single rail-function. Colors: comments : red $ # : gold rails : black built in function blue constans green parseIP returns the current lexeme and IP. In case of constants IP is at the closing char. -} highlightFct :: Grid2D -> IP -> Int -> TAC.TextAreaContent -> Map.Map (Int,Int) [Lexer.Direction] --Map of colored positions -> IO IP highlightFct grid2D ip yOffset textAC mOCPos | ip == crash = return crash |otherwise = if isPosColored mOCPos (posx ip,posy ip) (dir ip) then return crash else case lex of Nothing -> do TAC.putColor textAC (xC,yC) TAC.black highlightFct grid2D nextIP yOffset textAC inMap Just (Junction _) -> do TAC.putColor textAC (xC,yC) TAC.gold let (falseIP,trueIP) = junctionturns grid2D parseIP highlightFct grid2D falseIP yOffset textAC inMap highlightFct grid2D trueIP yOffset textAC inMap Just (Lambda _) -> do TAC.putColor textAC (xC,yC) TAC.gold let (lip,bip) = lambdadirs parseIP highlightFct grid2D (step grid2D lip) yOffset textAC inMap highlightFct grid2D (step grid2D bip) yOffset textAC inMap Just (Constant str) -> if [current grid2D parseIP] == "]" || [current grid2D parseIP] == "[" then colorStrCommand str TAC.green else do TAC.putColor textAC (xC,yC) TAC.green highlightFct grid2D (step grid2D parseIP)yOffset textAC inMap Just (Push str)-> colorStrCommand str TAC.blue Just (Pop str) -> colorStrCommand str TAC.green Just (Call str) -> colorStrCommand str TAC.green _ -> do cBlue cGold if lex == Just Finish then return crash else highlightFct grid2D nextIP yOffset textAC inMap where (lex, parseIP) = parse grid2D ip nextIP = step grid2D parseIP x = posx ip y = posy ip xC = fromIntegral x yC = fromIntegral $ y+yOffset inMap = Map.alter (Just . maybe [dir ip] ((:) (dir ip))) (x,y) mOCPos -- colors Start and finish gold cGold ::IO () cGold | fromJust lex `elem` [Start,Finish] = TAC.putColor textAC (xC,yC) TAC.gold | otherwise = return() -- colors rail-builtins blue cBlue :: IO () cBlue | fromJust lex `elem` [NOP,Boom,EOF,Input,Output,IDT.Underflow, RType,Add1,Divide,Multiply,Subtract,Remainder,Cut,Append,Size,Nil, Cons,Breakup,Greater,Equal] = TAC.putColor textAC (xC,yC) TAC.blue | otherwise = return() --function to color commands with strings like [], {} colorStrCommand :: String -> TAC.RGBColor -> IO IP colorStrCommand str color = do colorMoves grid2D (turnaround ip) (turnaround parseIP) color textAC highlightFct grid2D (step grid2D parseIP) yOffset textAC inMap --steps the IP to the beginning of an constant, call or pop colorMoves :: Grid2D -> IP -> IP -> TAC.RGBColor -> TAC.TextAreaContent-> IO IP colorMoves grid2D endIP curIP color textAC | endIP == curIP = do TAC.putColor textAC (x,y) color return crash | otherwise = do TAC.putColor textAC (x,y) color colorMoves grid2D endIP (move curIP Forward) color textAC return crash where x = fromIntegral $ posx curIP y = fromIntegral $ posy curIP+yOffset -- colors all entry red -- This function is needed to recolor after editing paintItRed :: TAC.TextAreaContent -> IO () paintItRed = TAC.deleteColors -- Is the position colored? isPosColored :: Map.Map (Int,Int) [Lexer.Direction] -> (Int,Int) -> Lexer.Direction -> Bool isPosColored mOCPos pos dir = elem dir $ Map.findWithDefault [] pos mOCPos