From: Michael Andreen Date: Sat, 11 Mar 2006 13:08:01 +0000 (+0000) Subject: typechecker compiles and is compatible with old programs while using the new state... X-Git-Url: https://ruin.nu/git/?p=proglang.git;a=commitdiff_plain;h=ff80cbdaf843e2745f59e6f5d3c8670cadbf68b2 typechecker compiles and is compatible with old programs while using the new state, still doesn't check functions though --- diff --git a/Makefile b/Makefile index e065a1a..e52bbb4 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -all: Testsyntax +all: Testsyntax Typechecker doc: Docsyntax.dvi diff --git a/Typecheck.hs b/Typecheck.hs index 70aad70..29008bd 100644 --- a/Typecheck.hs +++ b/Typecheck.hs @@ -1,12 +1,16 @@ -module Typecheck (typeCheckExp, typeCheckStm, typeCheckVar) where +module Typecheck where -- (typeCheckExp, typeCheckStm, typeCheckVar, State) where import Abssyntax -import Control.Monad.State +import Control.Monad.State hiding (State) import Data.Map as Map import Prelude hiding (lookup) type Types = [Map Ident Type] +type Function = (Type, [Type]) + +data State = State {variables::Types,functions::[Map Ident Function],function::Ident} + inList :: Eq a => a -> [a] -> Bool inList _ [] = False @@ -16,7 +20,7 @@ assert :: Monad m => Bool -> String -> m () assert True _ = return () assert False s = fail s -typeCheckExp :: (MonadState Types m) => Exp -> m Type +typeCheckExp :: (MonadState State m) => Exp -> m Type typeCheckExp (BiOpExp e o e') = do t1 <- typeCheckExp e t2 <- typeCheckExp e' @@ -47,22 +51,22 @@ typeCheckExp (ENot e) = do TBool <- typeCheckExp e return TBool -typeCheckVar :: (MonadState Types m) => Ident -> m Type +typeCheckVar :: (MonadState State m) => Ident -> m Type typeCheckVar i = do - ms <- get - findVariable i ms + s <- get + findVariable i $ variables s -findVariable :: (MonadState Types m) => Ident -> Types -> m Type +findVariable :: (MonadState State m) => Ident -> Types -> m Type findVariable i [] = fail $ "Variable "++show i++" not found in any scope." findVariable i (m:ms) = if member i m then lookup i m else findVariable i ms -pushAndPop :: (MonadState Types m) => m a -> m () +pushAndPop :: (MonadState State m) => m a -> m () pushAndPop s = do - modify (empty:) + modify (\s -> s { variables = empty:variables s}) s - modify tail + modify (\s -> s { variables = tail $ variables s}) -typeCheckStm :: (MonadState Types m) => Stm -> m () +typeCheckStm :: (MonadState State m) => Stm -> m () typeCheckStm SNoop = return () typeCheckStm (SExp e) = do typeCheckExp e @@ -84,9 +88,9 @@ typeCheckStm (SPrint e) = do typeCheckExp e return () -addVariable :: (MonadState Types m) => Ident -> Type -> m () +addVariable :: (MonadState State m) => Ident -> Type -> m () addVariable i t = do - (m:ms) <- get - case insertLookupWithKey (\k a1 a2 -> a1) i t m of - (Nothing,m') -> put (m':ms) + s <- get + let (m:ms) = variables s in case insertLookupWithKey (\k a1 a2 -> a1) i t m of + (Nothing,m') -> modify (\s -> s{ variables = m':ms}) _ -> fail $ "Duplicate variable declaration: "++show i diff --git a/Typechecker.hs b/Typechecker.hs index d9b1e10..8828fbe 100644 --- a/Typechecker.hs +++ b/Typechecker.hs @@ -11,9 +11,9 @@ import Skelsyntax import Printsyntax import Abssyntax -import Typecheck -import Control.Monad.State +import Control.Monad.State hiding (State) import Data.Map as Map hiding (showTree) +import Typecheck import ErrM @@ -23,23 +23,29 @@ myLLexer = myLexer type Verbosity = Int + +splitFunStm :: [FuncStm] -> ([Func],[Stm]) +splitFunStm [] = ([],[]) +splitFunStm ((F f):fss) = let (fs,ss) = splitFunStm fss in (f:fs,ss) +splitFunStm ((S s):fss) = let (fs,ss) = splitFunStm fss in (fs,s:ss) + putStrV :: Verbosity -> String -> IO () putStrV v s = if v > 1 then putStrLn s else return () -runFile :: Verbosity -> ParseFun Stms -> FilePath -> IO () +runFile :: Verbosity -> ParseFun Program -> FilePath -> IO () runFile v p f = putStrLn f >> readFile f >>= run v p -run :: Verbosity -> ParseFun Stms -> String -> IO () +run :: Verbosity -> ParseFun Program -> String -> IO () run v p s = let ts = myLLexer s in case p ts of Bad s -> do putStrLn "\nParse Failed...\n" putStrV v "Tokens:" putStrV v $ show ts putStrLn s - Ok (Program s) -> do + Ok (Program s) -> let (fun,st) = splitFunStm (s) in do putStrLn "\nParse Successful!" showTree v (Program s) - runStateT (mapM typeCheckStm s) [empty] + runStateT (mapM typeCheckStm st) State{variables=[empty], functions=[empty], function=(Ident "")} print "The program is type-correct!!" return () @@ -52,9 +58,9 @@ showTree v tree main :: IO () main = do args <- getArgs case args of - [] -> hGetContents stdin >>= run 2 pStms - "-s":fs -> mapM_ (runFile 0 pStms) fs - fs -> mapM_ (runFile 2 pStms) fs + [] -> hGetContents stdin >>= run 2 pProgram + "-s":fs -> mapM_ (runFile 0 pProgram) fs + fs -> mapM_ (runFile 2 pProgram) fs