-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type signatures for nested parameterized rules #52
base: master
Are you sure you want to change the base?
Conversation
You may want to rebase against master and "git push -f". That will get these commits tested with the new .travis.yml file which does much more thorough testing than the old one. |
fc273c2
to
1f49d43
Compare
Very cool! I took the opportunity to clean up a little too. Should be good to go now. |
ece4987
to
a17f49f
Compare
I found an issue with Should happy parse the types and manipulate them as ASTs, something like this: module Main where
import Language.Haskell.Exts
import Data.Generics
normalizeType :: Data l
=> [(String, Type l)] -- type var env
-> Type l -- input type
-> ParseResult (Type l) -- normalized type in an error monad
normalizeType env = everywhereM $ mkM f where
f t = case t of
TyVar l (Ident _ s) -> -- substitute type variables
case lookup s env of
Nothing -> fail $ "Unknown type variable '" ++ s ++ "'"
Just t' -> return t'
TyParen _ t1 -> return t1 -- remove parens
_ -> return t -- preserve everything else
main :: IO ()
main =
let r = do { t <- parseType "[(Maybe a)]"
; a <- parseType "Token Int"
; normalizeType [("a", a)] t
}
in case r of
ParseFailed _ err -> putStrLn err
ParseOk t -> putStrLn $ prettyPrint t -- prints "[Maybe (Token Int)]" Unfortunately, this would make happy depend on haskell-src-exts (which depends on happy!) and syb... |
This pull request adds support for type signatures on nested parameterized rules.
Since type signatures can now depend on the types of other rules, it first builds an array of
ShowS
functions that generate typenames given an environment that maps names to types. The array is built in the M monad, so that errors can be reported. Then, a new array of actual type names is built by applying theShowS
functions to the array we are constructing (tying a knot)! The type dependencies should form a DAG, and not a general graph, so no cycles can occur, and the algorithm will terminate. The new array maps both terminals and non-terminals to their respective types; however, terminals are always mapped to the token type, so any token that uses a$$
will yield the wrong type.