Skip to content
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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

PhilThomas
Copy link
Contributor

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 the ShowS 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.

@erikd
Copy link
Member

erikd commented Sep 1, 2016

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.

@PhilThomas PhilThomas force-pushed the master branch 4 times, most recently from fc273c2 to 1f49d43 Compare September 4, 2016 02:28
@PhilThomas
Copy link
Contributor Author

Very cool! I took the opportunity to clean up a little too. Should be good to go now.

@PhilThomas PhilThomas force-pushed the master branch 2 times, most recently from ece4987 to a17f49f Compare September 4, 2016 06:14
@PhilThomas
Copy link
Contributor Author

PhilThomas commented Sep 4, 2016

I found an issue with ProduceGLRCode.mkDecodeUtils. The types of two elements in seminfo may appear to be different when compared as strings, even though they may be equivalent to Haskell. For instance [Maybe (Token)] and [Maybe Token] are not equal strings, but they do represent equivalent types. Having different string representations of the same type causes mkDecodeUtils to create separate instances of TreeDecode for equivalent types, making ghc very unhappy. I suppose that this was always a potential problem, but previously, the user was in complete control of the String form of all types, and could be counted upon to make sure that equivalent types had the same representation. However, when types are generated for parameterized rules, unnecessary parentheses are added in case they are needed, causing the string representations to mismatch (unless the user also adds parentheses to match).

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...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants