packages feed

cparsing-0.1.0.0: MiniC/GenTemplate.hs

{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, RebindableSyntax #-}

-- | A module to generate nodes with default source templates
module MiniC.GenTemplate where

import MiniC.AST
import MiniC.Instances
import MiniC.Representation
import MiniC.SourceNotation
import SourceCode.SourceTree
import SourceCode.ASTElems
import MiniC.Semantics
import Data.Maybe
import Control.Lens
import Debug.Trace

import qualified Prelude
import Prelude hiding (fromInteger)

-- A little hack to disable polymorphism of numeric literals
fromInteger :: Integer -> Int
fromInteger = Prelude.fromInteger

genInfo :: SourceTemplate -> NI
genInfo st = NodeInfo (TemplateInfo Nothing (Just st)) emptySemaInfo

infixr 6 +>

(+>) :: ToTemplateElem a => a -> SourceTemplate -> SourceTemplate
a +> st = toTemplateElem a : st

infixl 9 //

class ToNodeDir nd where
  (//) :: NodeIndex -> nd -> NodeIndex
  
instance ToNodeDir Int where
  ni // i = NthChildOf i ni
  
data Up = Up

instance ToNodeDir Up where
  ni // Up = ParentOf ni
  
class ToTemplateElem a where
  toTemplateElem :: a -> SourceTemplateElem

instance ToTemplateElem String where
  toTemplateElem = TextElem
  
instance ToTemplateElem NodeIndex where
  toTemplateElem = NodeElem
  
  
genScalarQual :: String -> TypeQualifierNI
genScalarQual s = Scalar (ASTJust (Ident s (genInfo (s +> [])))) (genInfo ( Current//0 +> [] ))
  
-- | Adds a pointer to the qualifier, looks for cases when have to put the qualifier in parentheses.
addPtrToQual :: Maybe TypeQualifierNI -> TypeQualifierNI -> TypeQualifierNI
addPtrToQual outer
  = wrap . genPtrQual
  where wrap = case outer of Just (ArrayQual {}) -> genParenQual
                             _                   -> id
        
removePtrFromQual :: Maybe TypeQualifierNI -> TypeQualifierNI -> TypeQualifierNI
removePtrFromQual _ ptrq@(PtrQual{}) = ptrq ^?! qualBase
removePtrFromQual _ tq = tq
        
genParenQual :: TypeQualifierNI -> TypeQualifierNI
genParenQual tq = ParenQual tq (genInfo ( "(" +> Current//0 +> ")" +> [] ))
        
genPtrQual :: TypeQualifierNI -> TypeQualifierNI
genPtrQual tq = PtrQual tq (genInfo ( "*" +> Current//0 +> [] ))
        
genArrayQual :: TypeQualifierNI -> TypeQualifierNI
genArrayQual elem
  = wrap $ ArrayQual (ArrayTypeQual ASTNothing ASTNothing (genInfo ( "[]" +> [] ))) elem
                     (genInfo ( Current//1 +> Current//0 +> [] ))
  where wrap = case elem of PtrQual {} -> \q -> ParenQual q (genInfo ( "(" +> Current//0 +> ")" +> [] ))
                            _          -> id 
    
genDerefExpr :: ExpressionNI -> ExpressionNI
genDerefExpr e 
  = let op = DereferenceOp (genInfo ( "*" +> [] ))
        unexpr = Unary op e (genInfo ( Current//0 +> Current//1 +> [] ))
     in ParenExpr unexpr (genInfo ( "(" +> Current//0 +> ")" +> [] ))
      
genMemberDeref :: MemberDerefNI
genMemberDeref = DerefMember (genInfo ( "->" +> [] ))    
  
genMemberSimple :: MemberDerefNI
genMemberSimple = SimpleMember (genInfo ( "." +> [] ))
                      
astFilter :: (e NI -> Maybe (f NI)) -> ASTList e NI -> ASTList f NI
astFilter pred (ASTCons listHead listTail listInfo) 
  = case pred listHead of Just x  -> ASTCons x (astFilter pred listTail) listInfo
                          Nothing -> astFilter pred listTail
astFilter pred ASTNil = ASTNil