Get name linking right again, through post-processing.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
module Bang.AST.Expression
|
module Bang.AST.Expression
|
||||||
( Expression
|
( Expression(..)
|
||||||
, ppExpression
|
, ppExpression
|
||||||
-- * Constant Expressions
|
-- * Constant Expressions
|
||||||
, ConstantExpression
|
, ConstantExpression
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ module Bang.Monad(
|
|||||||
, runCompiler
|
, runCompiler
|
||||||
, runPass
|
, runPass
|
||||||
, getPassState, setPassState, overPassState, viewPassState
|
, getPassState, setPassState, overPassState, viewPassState
|
||||||
, registerNewName, genName, genTypeRef, genVarRef
|
, registerName, registerNewName, genName, genTypeRef, genVarRef
|
||||||
, warn, err
|
, warn, err, err'
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
import Bang.AST.Expression(Expression, mkRefExp)
|
import Bang.AST.Expression(Expression, mkRefExp)
|
||||||
import Bang.AST.Name(NameEnvironment(..), Name, mkName)
|
import Bang.AST.Name(NameEnvironment(..), Name, mkName, nameIndex)
|
||||||
import Bang.AST.Type(Kind(..), Type, mkTypeRef)
|
import Bang.AST.Type(Kind(..), Type, mkTypeRef)
|
||||||
import Bang.CommandLine(BangCommand, CommandsWithInputFile(..))
|
import Bang.CommandLine(BangCommand, CommandsWithInputFile(..))
|
||||||
import Bang.Error(exit)
|
import Bang.Error(exit)
|
||||||
@@ -26,7 +26,7 @@ import Bang.Utils.Pretty(BangDoc)
|
|||||||
import Control.Exception(tryJust)
|
import Control.Exception(tryJust)
|
||||||
import Control.Lens(Lens', over, set, view)
|
import Control.Lens(Lens', over, set, view)
|
||||||
import Control.Lens.TH(makeLenses)
|
import Control.Lens.TH(makeLenses)
|
||||||
import Control.Monad(guard)
|
import Control.Monad(guard, when)
|
||||||
import Data.Text.Lazy(Text, pack)
|
import Data.Text.Lazy(Text, pack)
|
||||||
import qualified Data.Text.Lazy.IO as T
|
import qualified Data.Text.Lazy.IO as T
|
||||||
import System.Exit(ExitCode(..), exitWith)
|
import System.Exit(ExitCode(..), exitWith)
|
||||||
@@ -107,6 +107,12 @@ viewPassState l = Compiler (\ st -> return (st, view (csPassState . l) st))
|
|||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
registerName :: Name -> Compiler s Name
|
||||||
|
registerName name =
|
||||||
|
Compiler (\ st ->
|
||||||
|
do let current = view csNextIdent st
|
||||||
|
return (over csNextIdent (+1) st, set nameIndex current name))
|
||||||
|
|
||||||
registerNewName :: NameEnvironment -> Text -> Compiler s Name
|
registerNewName :: NameEnvironment -> Text -> Compiler s Name
|
||||||
registerNewName env name =
|
registerNewName env name =
|
||||||
Compiler (\ st ->
|
Compiler (\ st ->
|
||||||
@@ -141,19 +147,22 @@ instance BangWarning w => BangError (WErrorWarning w) where
|
|||||||
warn :: BangWarning w => w -> Compiler s ()
|
warn :: BangWarning w => w -> Compiler s ()
|
||||||
warn w = Compiler (\ st ->
|
warn w = Compiler (\ st ->
|
||||||
if view csPromoteWarnings st
|
if view csPromoteWarnings st
|
||||||
then runError (WErrorWarning w)
|
then runError (WErrorWarning w) False >> return (st, ())
|
||||||
else runWarning w >> return (st, ()))
|
else runWarning w >> return (st, ()))
|
||||||
|
|
||||||
err :: BangError w => w -> Compiler s a
|
err :: BangError w => w -> Compiler s a
|
||||||
err w = Compiler (\ _ -> runError w)
|
err w = Compiler (\ _ -> runError w True >> undefined)
|
||||||
|
|
||||||
|
err' :: BangError e => e -> Compiler s ()
|
||||||
|
err' e = Compiler (\ st -> runError e False >> return (st, ()))
|
||||||
|
|
||||||
runWarning :: BangWarning w => w -> IO ()
|
runWarning :: BangWarning w => w -> IO ()
|
||||||
runWarning = undefined
|
runWarning = undefined
|
||||||
|
|
||||||
runError :: BangError w => w -> IO a
|
runError :: BangError w => w -> Bool -> IO ()
|
||||||
runError e =
|
runError e die =
|
||||||
do putStrLn (go (ppError e))
|
do putStrLn (go (ppError e))
|
||||||
exitWith (ExitFailure 1)
|
when die $ exitWith (ExitFailure 1)
|
||||||
where
|
where
|
||||||
go (Nothing, doc) = render doc
|
go (Nothing, doc) = render doc
|
||||||
go (Just a, doc) = render (ppLocation a $+$ nest 3 doc)
|
go (Just a, doc) = render (ppLocation a $+$ nest 3 doc)
|
||||||
|
|||||||
@@ -11,15 +11,13 @@ module Bang.Syntax.Parser(
|
|||||||
where
|
where
|
||||||
|
|
||||||
import Bang.Monad(err)
|
import Bang.Monad(err)
|
||||||
import Bang.AST(Name, Module, NameEnvironment(..), mkModule, emptyExpression)
|
import Bang.AST(Name, Module, NameEnvironment(..), mkModule, mkName, emptyExpression)
|
||||||
import Bang.AST.Declaration(Declaration, mkTypeDecl, mkValueDecl)
|
import Bang.AST.Declaration(Declaration, mkTypeDecl, mkValueDecl)
|
||||||
import Bang.AST.Expression(ConstantValue(..), Expression, mkConstExp, mkRefExp, mkLambdaExp)
|
import Bang.AST.Expression(ConstantValue(..), Expression, mkConstExp, mkRefExp, mkLambdaExp)
|
||||||
import Bang.AST.Type(Type, Kind(..), mkTypeRef, mkFunType, mkTypeApp, mkPrimType)
|
import Bang.AST.Type(Type, Kind(..), mkTypeRef, mkFunType, mkTypeApp, mkPrimType)
|
||||||
import Bang.Syntax.Location(Located(..), Origin, Position)
|
import Bang.Syntax.Location(Located(..), Origin, Position)
|
||||||
import Bang.Syntax.ParserError(ParserError(..))
|
import Bang.Syntax.ParserError(ParserError(..))
|
||||||
import Bang.Syntax.ParserMonad(Parser, addFixities, registerName,
|
import Bang.Syntax.ParserMonad(Parser, addFixities, parseError, runNextToken, runParser)
|
||||||
unregisterNames, lookupName, parseError,
|
|
||||||
runNextToken, runParser)
|
|
||||||
import Bang.Syntax.Token(Token(..), Fixity(..))
|
import Bang.Syntax.Token(Token(..), Fixity(..))
|
||||||
import Control.Monad(forM)
|
import Control.Monad(forM)
|
||||||
import Data.List(union)
|
import Data.List(union)
|
||||||
@@ -119,8 +117,7 @@ top_module :: { Module }
|
|||||||
: 'module' TypeIdent listopt(Declaration)
|
: 'module' TypeIdent listopt(Declaration)
|
||||||
{%
|
{%
|
||||||
do let Located src (TypeIdent rawName) = $2
|
do let Located src (TypeIdent rawName) = $2
|
||||||
name <- registerName False src ModuleEnv rawName
|
return (mkModule (mkName rawName ModuleEnv src 0) [$3]) }
|
||||||
return (mkModule name [$3]) }
|
|
||||||
|
|
||||||
Declaration :: { Maybe Declaration }
|
Declaration :: { Maybe Declaration }
|
||||||
: ValueDeclaration { Just $1 }
|
: ValueDeclaration { Just $1 }
|
||||||
@@ -128,28 +125,21 @@ Declaration :: { Maybe Declaration }
|
|||||||
| TypeDeclaration { Just $1 }
|
| TypeDeclaration { Just $1 }
|
||||||
|
|
||||||
ValueDeclaration :: { Declaration }
|
ValueDeclaration :: { Declaration }
|
||||||
: ValueDeclLHS Expression
|
: list1(ValIdent) '=' Expression
|
||||||
{%
|
|
||||||
do let (builder, argNames) = $1
|
|
||||||
unregisterNames VarEnv argNames
|
|
||||||
return (builder $2)
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueDeclLHS :: { (Expression -> Declaration, [Name]) }
|
|
||||||
: list1(ValIdent) '='
|
|
||||||
{%
|
{%
|
||||||
case $1 of
|
case $1 of
|
||||||
[] ->
|
[] ->
|
||||||
err (InternalError $2 "ValDeclLHS")
|
err (InternalError $2 "ValDeclLHS")
|
||||||
[Located src (ValIdent rawName)] ->
|
[Located src (ValIdent rawName)] ->
|
||||||
do name <- registerName True src VarEnv rawName
|
do let name = mkName rawName VarEnv src 0
|
||||||
return (mkValueDecl name src Nothing, [name])
|
return (mkValueDecl name src Nothing $3)
|
||||||
((Located src (ValIdent rawName)) : args) ->
|
((Located src (ValIdent rawName)) : args) ->
|
||||||
do name <- registerName True src VarEnv rawName
|
do let name = mkName rawName VarEnv src 0
|
||||||
argNames <- forM args $ \ (Located asrc (ValIdent argName)) ->
|
argNames = map (\ (Located arsrc (ValIdent argName)) ->
|
||||||
registerName True asrc VarEnv argName
|
mkName argName VarEnv arsrc 0)
|
||||||
let builder = mkValueDecl name src Nothing . mkLambdaExp $2 argNames
|
args
|
||||||
return (builder, argNames)
|
return (mkValueDecl name src Nothing
|
||||||
|
(mkLambdaExp $2 argNames $3))
|
||||||
}
|
}
|
||||||
|
|
||||||
FixityDeclaration :: { () }
|
FixityDeclaration :: { () }
|
||||||
@@ -164,50 +154,38 @@ TypeDeclaration :: { Declaration }
|
|||||||
: ValIdent '::' Type
|
: ValIdent '::' Type
|
||||||
{%
|
{%
|
||||||
do let Located src (ValIdent rawName) = $1
|
do let Located src (ValIdent rawName) = $1
|
||||||
name <- registerName True src VarEnv rawName
|
name = mkName rawName VarEnv src 0
|
||||||
return (mkValueDecl name src (Just $3) emptyExpression) }
|
return (mkValueDecl name src (Just $3) emptyExpression) }
|
||||||
| 'type' TypeIdent '=' Type
|
| 'type' TypeIdent '=' Type
|
||||||
{%
|
{%
|
||||||
do let Located src (TypeIdent rawName) = $2
|
do let Located src (TypeIdent rawName) = $2
|
||||||
name <- registerName True src TypeEnv rawName
|
name = mkName rawName TypeEnv src 0
|
||||||
return (mkTypeDecl name src $4) }
|
return (mkTypeDecl name src $4) }
|
||||||
| 'primitive' 'type' TypeIdent '=' String
|
| 'primitive' 'type' TypeIdent '=' String
|
||||||
{%
|
{%
|
||||||
do let Located nsrc (TypeIdent rawName) = $3
|
do let Located nsrc (TypeIdent rawName) = $3
|
||||||
Located tsrc (StringTok rawText) = $5
|
Located tsrc (StringTok rawText) = $5
|
||||||
name <- registerName False nsrc TypeEnv rawName
|
name = mkName rawName TypeEnv nsrc 0
|
||||||
return (mkTypeDecl name $2 (mkPrimType tsrc rawText)) }
|
return (mkTypeDecl name $2 (mkPrimType tsrc rawText)) }
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
|
|
||||||
Type :: { Type }
|
Type :: { Type }
|
||||||
: RawType {%
|
: RawType { $1 }
|
||||||
do let (result, names) = $1
|
|
||||||
case names of
|
|
||||||
[] -> return result
|
|
||||||
xs ->
|
|
||||||
do unregisterNames TypeEnv xs
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
RawType :: { (Type, [Name]) }
|
RawType :: { Type }
|
||||||
: RawType '->' BaseType {%
|
: RawType '->' BaseType { mkFunType $2 [$1] $3 }
|
||||||
do let (p1, names1) = $1
|
| BaseType { $1 }
|
||||||
(p2, names2) = $3
|
|
||||||
return (mkFunType $2 [p1] p2, union names1 names2)
|
|
||||||
}
|
|
||||||
| BaseType { $1 }
|
|
||||||
|
|
||||||
BaseType :: { (Type, [Name]) }
|
BaseType :: { Type }
|
||||||
: TypeIdent {%
|
: TypeIdent {%
|
||||||
do let Located src (TypeIdent rawName) = $1
|
let Located src (TypeIdent rawName) = $1
|
||||||
name <- lookupName src TypeEnv rawName
|
name = mkName rawName TypeEnv src 0
|
||||||
return (mkTypeRef src Unknown name, []) }
|
in return (mkTypeRef src Unknown name) }
|
||||||
| ValIdent {%
|
| ValIdent {%
|
||||||
do let Located src (ValIdent rawName) = $1
|
let Located src (ValIdent rawName) = $1
|
||||||
name <- registerName True src TypeEnv rawName
|
name = mkName rawName TypeEnv src 0
|
||||||
return (mkTypeRef src Unknown name, [name])
|
in return (mkTypeRef src Unknown name) }
|
||||||
}
|
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -216,25 +194,21 @@ Expression :: { Expression }
|
|||||||
|
|
||||||
BaseExpression :: { Expression }
|
BaseExpression :: { Expression }
|
||||||
: OpIdent {%
|
: OpIdent {%
|
||||||
do let Located src (OpIdent _ rawName) = $1
|
let Located src (OpIdent _ rawName) = $1
|
||||||
name <- lookupName src VarEnv rawName
|
name = mkName rawName VarEnv src 0
|
||||||
return (mkRefExp src name) }
|
in return (mkRefExp src name) }
|
||||||
| ValIdent {%
|
| ValIdent {%
|
||||||
do let Located src (ValIdent rawName) = $1
|
let Located src (ValIdent rawName) = $1
|
||||||
name <- lookupName src VarEnv rawName
|
name = mkName rawName VarEnv src 0
|
||||||
return (mkRefExp src name) }
|
in return (mkRefExp src name) }
|
||||||
| Integer {%
|
| Integer { let Located src (IntTok base val) = $1
|
||||||
do let Located src (IntTok base val) = $1
|
in mkConstExp src (ConstantInt base val) }
|
||||||
return (mkConstExp src (ConstantInt base val)) }
|
| String { let Located src (StringTok val) = $1
|
||||||
| String {%
|
in mkConstExp src (ConstantString val) }
|
||||||
do let Located src (StringTok val) = $1
|
| Float { let Located src (FloatTok val) = $1
|
||||||
return (mkConstExp src (ConstantString val)) }
|
in mkConstExp src (ConstantFloat val) }
|
||||||
| Float {%
|
| Char { let Located src (CharTok val) = $1
|
||||||
do let Located src (FloatTok val) = $1
|
in mkConstExp src (ConstantChar val) }
|
||||||
return (mkConstExp src (ConstantFloat val)) }
|
|
||||||
| Char {%
|
|
||||||
do let Located src (CharTok val) = $1
|
|
||||||
return (mkConstExp src (ConstantChar val)) }
|
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -5,16 +5,12 @@ module Bang.Syntax.ParserMonad(
|
|||||||
, NameDatabase
|
, NameDatabase
|
||||||
, runParser
|
, runParser
|
||||||
, addFixities
|
, addFixities
|
||||||
, registerName
|
|
||||||
, unregisterNames
|
|
||||||
, lookupName
|
|
||||||
, parseError
|
, parseError
|
||||||
, runNextToken
|
, runNextToken
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
import Bang.AST.Name(Name, NameEnvironment(..), mkName,
|
import Bang.AST.Name(Name, NameEnvironment(..))
|
||||||
nameLocation, nameText)
|
|
||||||
import Bang.Monad(Compiler, err, runPass,
|
import Bang.Monad(Compiler, err, runPass,
|
||||||
getPassState, overPassState, viewPassState)
|
getPassState, overPassState, viewPassState)
|
||||||
import Bang.Syntax.Lexer(AlexReturn(..), AlexInput(..), alexScan)
|
import Bang.Syntax.Lexer(AlexReturn(..), AlexInput(..), alexScan)
|
||||||
@@ -37,7 +33,6 @@ type NameDatabase = Map (NameEnvironment, Text) Name
|
|||||||
data ParserState = ParserState {
|
data ParserState = ParserState {
|
||||||
_psPrecTable :: Map Text Fixity
|
_psPrecTable :: Map Text Fixity
|
||||||
, _psNameDatabase :: Map (NameEnvironment, Text) Name
|
, _psNameDatabase :: Map (NameEnvironment, Text) Name
|
||||||
, _psNextIdent :: Word
|
|
||||||
, _psOrigin :: Origin
|
, _psOrigin :: Origin
|
||||||
, _psLexerState :: AlexInput
|
, _psLexerState :: AlexInput
|
||||||
}
|
}
|
||||||
@@ -51,7 +46,7 @@ runParser origin stream action =
|
|||||||
over _1 (view psNameDatabase) `fmap` runPass pstate action
|
over _1 (view psNameDatabase) `fmap` runPass pstate action
|
||||||
where
|
where
|
||||||
initInput = AlexInput initialPosition stream
|
initInput = AlexInput initialPosition stream
|
||||||
pstate = ParserState Map.empty Map.empty 1 origin initInput
|
pstate = ParserState Map.empty Map.empty origin initInput
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -102,38 +97,6 @@ getFixities = viewPassState psPrecTable
|
|||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
|
|
||||||
registerName :: Bool -> Location -> NameEnvironment -> Text -> Parser Name
|
|
||||||
registerName redefOk loc env name =
|
|
||||||
do state <- getPassState
|
|
||||||
let key = (env, name)
|
|
||||||
case Map.lookup key (view psNameDatabase state) of
|
|
||||||
Nothing ->
|
|
||||||
do let res = mkName name env loc (view psNextIdent state)
|
|
||||||
overPassState (over psNameDatabase (Map.insert key res) .
|
|
||||||
over psNextIdent (+1))
|
|
||||||
return res
|
|
||||||
Just res | redefOk ->
|
|
||||||
return res
|
|
||||||
Just name' ->
|
|
||||||
err (RedefinitionError loc (view nameLocation name') name)
|
|
||||||
|
|
||||||
unregisterNames :: NameEnvironment -> [Name] -> Parser ()
|
|
||||||
unregisterNames env names =
|
|
||||||
do db <- viewPassState psNameDatabase
|
|
||||||
let db' = foldr (\ n m -> Map.delete (env, view nameText n) m) db names
|
|
||||||
overPassState (set psNameDatabase db')
|
|
||||||
|
|
||||||
lookupName :: Location -> NameEnvironment -> Text -> Parser Name
|
|
||||||
lookupName loc env name =
|
|
||||||
do state <- getPassState
|
|
||||||
case Map.lookup (env, name) (view psNameDatabase state) of
|
|
||||||
Nothing ->
|
|
||||||
err (UnboundVariable loc name)
|
|
||||||
Just realName ->
|
|
||||||
return realName
|
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
runNextToken :: (Located Token -> Parser a) ->
|
runNextToken :: (Located Token -> Parser a) ->
|
||||||
Parser a
|
Parser a
|
||||||
runNextToken parseAction = go =<< getLexerState
|
runNextToken parseAction = go =<< getLexerState
|
||||||
|
|||||||
@@ -1,28 +1,36 @@
|
|||||||
|
{-# LANGUAGE RankNTypes #-}
|
||||||
module Bang.Syntax.PostProcess(
|
module Bang.Syntax.PostProcess(
|
||||||
runPostProcessor
|
runPostProcessor
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
import Bang.AST(Name, Module, moduleDeclarations, ppName)
|
import Bang.AST(Name, Module, moduleDeclarations, ppName,
|
||||||
|
nameText, nameLocation, nameEnvironment)
|
||||||
import Bang.AST.Declaration(Declaration(..), declName,
|
import Bang.AST.Declaration(Declaration(..), declName,
|
||||||
ValueDeclaration,
|
tdName, tdType,
|
||||||
vdName, vdLocation, vdDeclaredType,
|
ValueDeclaration, vdName, vdLocation,
|
||||||
vdValue)
|
vdDeclaredType, vdValue)
|
||||||
import Bang.AST.Expression(isEmptyExpression)
|
import Bang.AST.Expression(Expression(..), isEmptyExpression, refName,
|
||||||
import Bang.AST.Type(Type)
|
lambdaArgumentNames, lambdaBody,
|
||||||
import Bang.Monad(Compiler, BangError(..), err)
|
isEmptyExpression)
|
||||||
|
import Bang.AST.Type(Type(..), rtName, ftArgumentTypes, ftResultType,
|
||||||
|
taLeftType, taRightType)
|
||||||
|
import Bang.Monad(Compiler, BangError(..), err, err', registerName)
|
||||||
import Bang.Syntax.Location(Location, ppLocation)
|
import Bang.Syntax.Location(Location, ppLocation)
|
||||||
import Bang.Utils.FreeVars(CanHaveFreeVars(..))
|
import Bang.Utils.FreeVars(CanHaveFreeVars(..))
|
||||||
import Bang.Utils.Pretty(BangDoc)
|
import Bang.Utils.Pretty(BangDoc, text')
|
||||||
import Control.Lens(view, set)
|
import Control.Lens(Lens', view, set)
|
||||||
import Control.Monad(foldM)
|
import Control.Monad(foldM)
|
||||||
|
import Data.Char(isLower)
|
||||||
import Data.Graph(SCC(..))
|
import Data.Graph(SCC(..))
|
||||||
import Data.Graph.SCC(stronglyConnComp)
|
import Data.Graph.SCC(stronglyConnComp)
|
||||||
import Data.Map.Strict(Map)
|
import Data.Map.Strict(Map)
|
||||||
import qualified Data.Map.Strict as Map
|
import qualified Data.Map.Strict as Map
|
||||||
import Text.PrettyPrint.Annotated(text, ($+$), (<+>), nest)
|
import Data.Text.Lazy(uncons)
|
||||||
|
import Text.PrettyPrint.Annotated(text, ($+$), (<+>), nest, quotes)
|
||||||
|
|
||||||
data PostProcessError = InternalError Name
|
data PostProcessError = InternalError Name
|
||||||
|
| UndefinedVariable Name
|
||||||
| RedefinitionError Name Location Location
|
| RedefinitionError Name Location Location
|
||||||
| TypeDeclWithoutValue Name Location
|
| TypeDeclWithoutValue Name Location
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
@@ -35,6 +43,8 @@ prettyError e =
|
|||||||
case e of
|
case e of
|
||||||
InternalError n ->
|
InternalError n ->
|
||||||
(Nothing, text "Serious post-processing error w.r.t. " <+> ppName n)
|
(Nothing, text "Serious post-processing error w.r.t. " <+> ppName n)
|
||||||
|
UndefinedVariable n ->
|
||||||
|
(Just (view nameLocation n), text "Undefined variable " <+> quotes (text' (view nameText n)))
|
||||||
RedefinitionError n l1 l2 ->
|
RedefinitionError n l1 l2 ->
|
||||||
(Just l1, text "Name" <+> ppName n <+> text "redefined." $+$
|
(Just l1, text "Name" <+> ppName n <+> text "redefined." $+$
|
||||||
nest 2 (text "original definiton at " <+> ppLocation l2))
|
nest 2 (text "original definiton at " <+> ppLocation l2))
|
||||||
@@ -44,13 +54,99 @@ prettyError e =
|
|||||||
|
|
||||||
runPostProcessor :: Module -> Compiler ps Module
|
runPostProcessor :: Module -> Compiler ps Module
|
||||||
runPostProcessor mdl =
|
runPostProcessor mdl =
|
||||||
do let decls = concat (view moduleDeclarations mdl)
|
do let baseDecls = concat (view moduleDeclarations mdl)
|
||||||
|
decls <- linkNames baseDecls
|
||||||
declTable <- makeDeclarationTable decls
|
declTable <- makeDeclarationTable decls
|
||||||
decls' <- combineTypeValueDeclarations declTable decls
|
decls' <- combineTypeValueDeclarations declTable decls
|
||||||
return (set moduleDeclarations (orderDecls decls') mdl)
|
return (set moduleDeclarations (orderDecls decls') mdl)
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
linkNames :: [Declaration] -> Compiler ps [Declaration]
|
||||||
|
linkNames decls =
|
||||||
|
do declaredNames <- foldM addNewNames Map.empty (map (view declName) decls)
|
||||||
|
mapM (linkDecls declaredNames) decls
|
||||||
|
where
|
||||||
|
addNewNames t n =
|
||||||
|
do n' <- registerName n
|
||||||
|
let key = (view nameText n, view nameEnvironment n)
|
||||||
|
return (Map.insert key n' t)
|
||||||
|
--
|
||||||
|
replaceName nameMap name =
|
||||||
|
do let key = (view nameText name, view nameEnvironment name)
|
||||||
|
case Map.lookup key nameMap of
|
||||||
|
Nothing -> err' (UndefinedVariable name) >> return name
|
||||||
|
Just name' -> return name'
|
||||||
|
--
|
||||||
|
addOrReplaceName nameMap name =
|
||||||
|
do let key = (view nameText name, view nameEnvironment name)
|
||||||
|
case Map.lookup key nameMap of
|
||||||
|
Nothing | couldBeTypeVariable name ->
|
||||||
|
do name' <- registerName name
|
||||||
|
return (name', Map.insert key name' nameMap)
|
||||||
|
Nothing ->
|
||||||
|
err' (UndefinedVariable name) >> return (name, nameMap)
|
||||||
|
Just name' ->
|
||||||
|
return (name', nameMap)
|
||||||
|
--
|
||||||
|
couldBeTypeVariable n =
|
||||||
|
case uncons (view nameText n) of
|
||||||
|
Nothing ->
|
||||||
|
error "Empty variable name?"
|
||||||
|
Just (x,_) ->
|
||||||
|
isLower x
|
||||||
|
--
|
||||||
|
linkDecls nameMap (DeclType td) =
|
||||||
|
do td' <- overM tdType (linkType' nameMap) td
|
||||||
|
td'' <- overM tdName (replaceName nameMap) td'
|
||||||
|
return (DeclType td'')
|
||||||
|
linkDecls nameMap (DeclVal vd) =
|
||||||
|
do vd' <- overM vdDeclaredType (traverse (linkType' nameMap)) vd
|
||||||
|
vd'' <- overM vdValue (linkExpr nameMap) vd'
|
||||||
|
vd''' <- overM vdName (replaceName nameMap) vd''
|
||||||
|
return (DeclVal vd''')
|
||||||
|
--
|
||||||
|
linkType' nm t = fst `fmap` linkType nm t
|
||||||
|
--
|
||||||
|
linkType nameMap x@(TypeUnit _) = return (x, nameMap)
|
||||||
|
linkType nameMap x@(TypePrim _) = return (x, nameMap)
|
||||||
|
linkType nameMap (TypeRef t) =
|
||||||
|
do (name, nameMap') <- addOrReplaceName nameMap (view rtName t)
|
||||||
|
let t' = set rtName name t
|
||||||
|
return (TypeRef t', nameMap')
|
||||||
|
linkType nameMap (TypeFun t) =
|
||||||
|
do (argTypes, nameMap') <- foldM linkTypes ([], nameMap) (view ftArgumentTypes t)
|
||||||
|
(resType, nameMap'') <- linkType nameMap' (view ftResultType t)
|
||||||
|
return (TypeFun (set ftArgumentTypes argTypes $
|
||||||
|
set ftResultType resType t),
|
||||||
|
nameMap'')
|
||||||
|
linkType nameMap (TypeApp t) =
|
||||||
|
do (lt, nameMap') <- linkType nameMap (view taLeftType t)
|
||||||
|
(rt, nameMap'') <- linkType nameMap' (view taRightType t)
|
||||||
|
return (TypeApp (set taLeftType lt (set taRightType rt t)), nameMap'')
|
||||||
|
--
|
||||||
|
linkTypes (acc, nameMap) argType =
|
||||||
|
do (argType', nameMap') <- linkType nameMap argType
|
||||||
|
return (acc ++ [argType'], nameMap')
|
||||||
|
--
|
||||||
|
linkExpr _ x | isEmptyExpression x = return x
|
||||||
|
linkExpr _ x@(ConstExp _) = return x
|
||||||
|
linkExpr nameMap (RefExp e) =
|
||||||
|
RefExp `fmap` overM refName (replaceName nameMap) e
|
||||||
|
linkExpr nameMap (LambdaExp e) =
|
||||||
|
do let names = view lambdaArgumentNames e
|
||||||
|
nameMap' <- foldM addNewNames nameMap names
|
||||||
|
e' <- overM lambdaArgumentNames (mapM (replaceName nameMap')) e
|
||||||
|
e'' <- overM lambdaBody (linkExpr nameMap') e'
|
||||||
|
return (LambdaExp e'')
|
||||||
|
|
||||||
|
overM :: Monad m => Lens' s a -> (a -> m a) -> s -> m s
|
||||||
|
overM field action input =
|
||||||
|
do newval <- action (view field input)
|
||||||
|
return (set field newval input)
|
||||||
|
|
||||||
|
-- -----------------------------------------------------------------------------
|
||||||
|
|
||||||
type DeclarationTable = Map Name (Maybe (Type, Location), Maybe ValueDeclaration)
|
type DeclarationTable = Map Name (Maybe (Type, Location), Maybe ValueDeclaration)
|
||||||
|
|
||||||
makeDeclarationTable :: [Declaration] -> Compiler ps DeclarationTable
|
makeDeclarationTable :: [Declaration] -> Compiler ps DeclarationTable
|
||||||
|
|||||||
Reference in New Issue
Block a user