module FreeC.Pass.PragmaPass ( pragmaPass ) where
import Data.List ( find, findIndex )
import FreeC.Environment
import qualified FreeC.IR.Syntax as IR
import FreeC.Monad.Converter
import FreeC.Monad.Reporter
import FreeC.Pass
import FreeC.Pretty
pragmaPass :: Pass IR.Module IR.Module
pragmaPass ast = do
mapM_ (addDecArgPragma (IR.modFuncDecls ast)) (IR.modPragmas ast)
return ast
addDecArgPragma :: [IR.FuncDecl] -> IR.Pragma -> Converter ()
addDecArgPragma funcDecls (IR.DecArgPragma srcSpan funcName decArg)
= case find ((== funcName) . IR.funcDeclQName) funcDecls of
Just IR.FuncDecl { IR.funcDeclArgs = args } -> case decArg of
Left decArgIdent ->
case findIndex ((== decArgIdent) . IR.varPatIdent) args of
Just decArgIndex ->
modifyEnv $ defineDecArg funcName decArgIndex decArgIdent
Nothing -> reportFatal
$ Message srcSpan Error
$ "The function '"
++ showPretty funcName
++ "' does not have an argument pattern '"
++ decArgIdent
++ "'."
Right decArgPosition
| decArgPosition > 0 && decArgPosition <= length args -> do
let decArgIndex = decArgPosition - 1
decArgIdent = IR.varPatIdent (args !! decArgIndex)
modifyEnv $ defineDecArg funcName decArgIndex decArgIdent
| otherwise -> reportFatal
$ Message srcSpan Error
$ "The function '"
++ showPretty funcName
++ "' does not have an argument at index "
++ show decArgPosition
++ "."
Nothing -> reportFatal
$ Message srcSpan Error
$ "The module does not declare a function '"
++ showPretty funcName
++ "'."