Skip to content

Support identifiers for namespace/template of C++ #83

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

Closed
wants to merge 10 commits into from

Conversation

junjihashimoto
Copy link
Collaborator

@junjihashimoto junjihashimoto commented Feb 3, 2019

This PR supports identifiers for namespace/template of C++.
We want to use libtorch library which uses various Tensor classes(at::Tensor, torch::Tensor, caffe2::Tensor and so on).

I think cIdentLetter should support c types only and this modification is hackey.
But the implementation of identifier is not pluggable.

Could you merge this PR?

@junjihashimoto junjihashimoto force-pushed the dev branch 2 times, most recently from 43525c9 to a492ef5 Compare February 13, 2019 03:37
@junjihashimoto
Copy link
Collaborator Author

Though cIdent parser of first commit is hackey, cppIdentParser and its test are added on last commit.
cppIdentParser checks the correspondence of template-parentheses.
cpp-parser has little influence on c-parser.

@cblp
Copy link

cblp commented Apr 12, 2019

I really want this, too!

Could you please retry Travis tests? It seems to be a temporary network problem.

@junjihashimoto
Copy link
Collaborator Author

ok、I try rebuild.

@junjihashimoto
Copy link
Collaborator Author

Travis tests have been passed.

Copy link
Collaborator

@bitonic bitonic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the contribution! i'll take a closer look today

@bitonic bitonic dismissed their stale review April 27, 2019 13:16

missed the tests

Copy link
Collaborator

@bitonic bitonic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that parsing template applications into single identifiers is a good idea -- apart from being pretty opaque, it currently doesn't support anything but other identifiers as parameters.

There's also the problem that this addition is now present for all uses of inline-c, although I'm a bit less bothered by that.

I'd be happier with extending data Type i with a CppTemplate P.CIdentifier [Type i], and then implementing the proper C++ grammar for template applications.

What do you think?

@junjihashimoto
Copy link
Collaborator Author

junjihashimoto commented Apr 28, 2019

Thank you for your reply. I appreciate your reviewing.

There's also the problem that this addition is now present for all uses of inline-c, although I'm a bit less bothered by that.

I think so. I'm sorry to trouble you.
But I do not have good idea how to separate c-parser and c++-parser.
How about putting a flag changing the parsers somewhere?
Do you have any suggestions?

I'd be happier with extending data Type i with a CppTemplate P.CIdentifier [Type i], and then implementing the proper C++ grammar for template applications.

This is good. I will try it.
But c++-template arguments support just number, e.g. std::array<bool,4>.
The "4" is not "data Type i" probably.

@bitonic
Copy link
Collaborator

bitonic commented Apr 29, 2019

@junjihashimoto oh, nothing to be sorry about! I think it's a very nice feature to add, we just need to add it right.

And sorry about how long it took me to review this.

But c++-template arguments support just number, e.g. std::array<bool,4>.
The "4" is not "data Type i" probably.

Yes, we have to extend our types a bit. I'd be pretty conservative, probably adding only numeric literals, since those are very useful in C++.

@cblp
Copy link

cblp commented May 6, 2019

Is something bad in adding something that can be a type in C++ but not in C?

@bitonic
Copy link
Collaborator

bitonic commented May 6, 2019

@cblp no, but the way it is added in the current pr is extremely ad-hoc -- only identifiers can be arguments of templates, and that property is not even checked.

@junjihashimoto
Copy link
Collaborator Author

junjihashimoto commented Aug 5, 2019

@bitonic long time no see.

I have extended data TypeSpecifier instead of data Type i.
Because template-type is a bit similar to struct-type in data TypeSpecifier, and we can reduce the code to parse it.
Then the parser generates CppTemplate Ary '(CInt,10)-type from array<int,10> of c++-type.
How about this PR?

data TypeSpecifier
  = Void
  | Bool
  | Char (Maybe Sign)
  | Short Sign
  | Int Sign
  | Long Sign
  | LLong Sign
  | Float
  | Double
  | LDouble
  | TypeName P.CIdentifier
  | Struct P.CIdentifier
  | Enum P.CIdentifier
  | Template P.CIdentifier [TypeSpecifier]
  | TemplateConst String
  deriving (Typeable, Show, Eq, Ord)

@junjihashimoto
Copy link
Collaborator Author

Current implementation improves mapping of template-type.
e.g. std::array<int,4> of C++'s template-type is mapped to Array '(Int,4).
And it has a switch to use c-parser or c++-parser.

@bitonic
Copy link
Collaborator

bitonic commented Aug 13, 2019

@junjihashimoto thanks! I'll take a look.

@bitonic
Copy link
Collaborator

bitonic commented Aug 13, 2019

@junjihashimoto First of all, the branch in this PR seems to contain a lot of unrelated changes. Could you isolate the changes related to the template arguments, or at the very least have them so that I can easily review commit-by-commit? Thanks!

@junjihashimoto
Copy link
Collaborator Author

@bitonic
Sorry for including the changes and thank you for reading it.
I have isolated the commit related to the template argument.

@junjihashimoto
Copy link
Collaborator Author

This pr includes following items.

  • Support for namespace/template of C++
  • Fix deprecated warning of TH
  • Fix return-value of exception to reduce compiler-warning
  • Fix the test of exception to catch exception on MACOS(https://gitlab.haskell.org/ghc/ghc/issues/11829)
  • Add bool type

@@ -87,7 +87,50 @@ catchBlock = QuasiQuoter
, quoteDec = unsupported
} where
unsupported _ = fail "Unsupported quasiquotation."


exceptionalValue :: String -> String
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please comment on what warning this avoids and how you generated this list.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the comment.

@@ -22,6 +26,7 @@ cppCtx :: Context
cppCtx = baseCtx <> mempty
{ ctxForeignSrcLang = Just TH.LangCxx
, ctxOutput = Just $ \s -> "extern \"C\" {\n" ++ s ++ "\n}"
, ctxEnableCpp = True
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? Can't we just use LangCxx to generate this boolean?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is okay. use langCxx

@@ -100,6 +103,8 @@ data TypeSpecifier
| TypeName P.CIdentifier
| Struct P.CIdentifier
| Enum P.CIdentifier
| Template P.CIdentifier [TypeSpecifier]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please prefix these two cases with Cxx.

@@ -1,18 +1,48 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE CPP #-}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pleaste add some tests where the context contains a mapping from a templated type to a haskell type. E.g. * vector<A, B> to something in Haskell.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mapping of std::vector<Test::Test> is included in the file.

@@ -1,18 +1,48 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are all these extensions really needed? At the very least remove the dangerous ones, such as UndecidableInstances.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. So I am going to reduce the extensions.

@@ -484,6 +509,8 @@ instance PP.Pretty TypeSpecifier where
TypeName s -> PP.pretty s
Struct s -> "struct" <+> PP.pretty s
Enum s -> "enum" <+> PP.pretty s
Template s args -> PP.pretty s <+> "<" <+> mconcat (intersperse "," (map PP.pretty args)) <+> ">"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd do " >" so that this will work even without C++11.

@@ -212,13 +215,14 @@ quickCParser typeNames s p = case runCParser typeNames "quickCParser" s p of
-- | Like 'quickCParser', but uses @'cCParserContext' ('const' 'False')@ as
-- 'CParserContext'.
quickCParser_
:: String
:: Bool
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things:

  • To parse namespaces, just change the definition of cpcParseIdent for C++, and export cxxidentifier_no_lex
  • For templates, put a Bool (say cpcParseCxxTemplates) in the CParserContext.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cCParserContext has The Bool to change the parser for C++.
cxxidentifier_no_lex is not exported, because identifier_no_lex reads and uses CParserContext' value to change the parser.

@@ -293,11 +298,14 @@ data TypeSpecifier
| Struct CIdentifier
| Enum CIdentifier
| TypeName CIdentifier
| Template CIdentifier [TypeSpecifier]
| TemplateConst String
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now this seems to only parse integral const expressions. That's OK, but can you document this, linking to some documentation on what is the full range of const template argument that you can have?

templateParser s = parse'
where
parse' = do
id' <- cidentParserWithNamespace
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this rather than just using cpcParseIdent? That should include namespaces now, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should include namespaces to parse the format like "std::vector".

try (concat <$> sequence [cidentParser, (string "::"), cidentParserWithNamespace]) <|>
cidentParser
templateArgType = try type_specifier <|> (TemplateConst <$> (many $ oneOf ['0'..'9']))
templateArgParser' = do
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use sepBy templateArgType (symbol ",") or similar.

@bitonic
Copy link
Collaborator

bitonic commented Aug 13, 2019

@junjihashimoto did a first review pass. Overall the approach looks good, thanks a lot for the contribution!

@junjihashimoto
Copy link
Collaborator Author

@bitonic Thank you for reviewing and good advice. I am going to update the pr soon.

@junjihashimoto
Copy link
Collaborator Author

I think the modification is done and there may be some differences from your expectations.

@bitonic
Copy link
Collaborator

bitonic commented Aug 17, 2019

@junjihashimoto just wanted to let you know that I have not forgotten about this -- but I've been a bit busy and I'm not entirely sure that the template parsing is safe. Specifically I'm not sure whether we need to store the C++ type names too. I'll try to check and merge this soon.

@junjihashimoto
Copy link
Collaborator Author

I can wait.

@junjihashimoto
Copy link
Collaborator Author

junjihashimoto commented Nov 22, 2019

@bitonic
Hi, long time no see.
Please review before the new year, if you can do it.
Because we want to release hasktorch and upload it before the new year.
🙇
I will fix CI-error on the weekend.
If you think we should fork this pr or do other thing to support c++, let me know.

@bitonic
Copy link
Collaborator

bitonic commented Nov 22, 2019

@junjihashimoto I'm very sorry about the delay, I'll try to review it in the next few days.

@junjihashimoto
Copy link
Collaborator Author

I'm happy to hear that.

@junjihashimoto
Copy link
Collaborator Author

My modification is done.
This PR works on both linux and macos.
hasktorch/hasktorch#249

@bitonic
Copy link
Collaborator

bitonic commented Nov 25, 2019

@junjihashimoto I have rebased and merged your PR. Again, deep apologies about the delay, I got really busy and this slipped off my radar. Moreover, it wasn't an obvious merge -- I'm still not totally convinced about the new grammar. But it's a useful feature, and I think it's better to have it.

Thank you so much for the change and the patience.

@bitonic bitonic closed this Nov 25, 2019
@bitonic
Copy link
Collaborator

bitonic commented Nov 25, 2019

Released now as inline-c 0.9.0.0 and inline-c-cpp 0.3.1.0.

@junjihashimoto
Copy link
Collaborator Author

@bitonic
Thank you for your supporting and comments.
If this pr is not obvious for you, so other person thinks so too.
I should improve documentions and add examples.

@junjihashimoto
Copy link
Collaborator Author

junjihashimoto commented Nov 26, 2019

@bitonic
Current hackage's inline-c works .
hasktorch/hasktorch#252

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.

3 participants