Git Product home page Git Product logo

Comments (10)

sergei-mironov avatar sergei-mironov commented on September 24, 2024

Answering to my own question (from another account):
Ivory supports the following QQ syntax for declaring foreign structures

[ivory|
    abstract struct nk_message "nk/types.h"
    abstract struct nk_arena "nk/types.h"
    abstract struct nk_channel_state "nk/types.h"
    abstract struct nk_audit "nk/audit.h"
    abstract struct nk_subject "nk/security.h"
|]

nkModule = do
    defStruct (Proxy :: Proxy "nk_message")
    defStruct (Proxy :: Proxy "nk_arena")
    defStruct (Proxy :: Proxy  "nk_channel_state")
    defStruct (Proxy :: Proxy  "nk_audit")
    defStruct (Proxy :: Proxy  "nk_subject")


from ivory.

sergei-mironov avatar sergei-mironov commented on September 24, 2024

I still haven't found an easy way of importing foreign typedefs. As for now, Ivory doesn't allow to generate C code with user-defined type names.

from ivory.

leepike avatar leepike commented on September 24, 2024

Hi, can you give an example of what you would like? In particular, we need a way to bind imported typedefs to their associated Haskell types.

from ivory.

sergei-mironov avatar sergei-mironov commented on September 24, 2024

Basically, we have a set of aliases like the following:

/* nk/types.h */
typedef uint32_t nk_family_t;
typedef uint8_t nk_decision_t;
...

and so on. I'd like Ivory to generate code using this aliases. Unfortunately, as I wrote before, It seems Ivory don't support importing aliases. The closest method I know is to copy aliases in Haskell in the following manner:

type NkFamily = Uint32
type NkDecision = Uint8

Of cause, this would lead to code using uint8_t instead of nk_decision_t

from ivory.

leepike avatar leepike commented on September 24, 2024

Ok, I see. This would be quite hard to do, and I don't think there is a satisfying solution.

One solution is to do what you do, and make a Haskell type synonym. The upside is that you get Haskell type equality for free, but the downside is that the Ivory backend doesn't know about typedef string.

Another approach is for us to create a newtype that encodes the typedef as part of the type, analogous to structs. I.e., define something like

newtype TypeDef (sym :: Symbol) = TypeDef { getTypeDef :: AST.Expr }

and the appropriate instances. Now we have a string we can use in C code generation. Now the problem is that Haskell types won't match. For example, for a function foo

foo :: Def ('[TypeDef "a"] ':-> Uint8)
foo = proc "foo" $ \a -> body $ ret a

and TypeDef "a" that is a typedef for Uint8, we'll get a type error trying to return the argument, without having some sort of cast, since they are different Haskell types.

Does this make sense? Do you mind if we close this?

from ivory.

sergei-mironov avatar sergei-mironov commented on September 24, 2024

Thanks! The TypeDef (sym :: Symbol) looks like an acceptable solution, since we actually doesn't require compatibility between typedefed types and their synonyms. We would use newtype in C if we could.

Still there is a problem regarding this approach. I found that I don't know how to implement ivoryType function for IvoryType TypeDef instance. AFAIK, Ivory.Language.Syntax.Type type doesn't have a constructor to encode arbitrary type names in low-level AST. Is it possible to add such possibility (I have in mind strong guarantees regarding code generation, will this modification meet them)?

from ivory.

leepike avatar leepike commented on September 24, 2024

I think the way to do this is to have the quasiquoter generate the instances automatically, much like we do for structs. I can implement this, but it'll take me up to a week to get to it.

from ivory.

sergei-mironov avatar sergei-mironov commented on September 24, 2024

Nope, the absence of quasiquoter is not a problem. Let me re-formulate my thought. Recall the definition of IvoryType:

import qualified Ivory.Language.Syntax as AST

-- | The connection between Haskell and Ivory types.
class IvoryType t where
  ivoryType :: Proxy t -> AST.Type

Lets say we want to write an instance of IvoryType for TypeDef (sym :: Symbol) :

instance (ASymbol sym) => IvoryType (TypeDef sym) where
  ivoryType _ = AST.Ty???? (fromTypeSym (aSymbol :: SymbolType sym))

The only constructor of AST.Type accepting String is TyStruct. If I am correct, we have to add not only the quasiquoter, but completely new low-level constructor TyTypedef String in order to complete the code.

from ivory.

leepike avatar leepike commented on September 24, 2024

Something like the following should work: given (assuming a new constructor in the AST):

newtype NewType (sym :: Symbol) = NewType { getNewType :: AST.Expr }

mkNewType :: (ASymbol sym, IvoryType t) => Proxy t -> Proxy (sym :: Symbol) -> AST.Type
mkNewType t p = AST.TyNewType (fromTypeSym p) (ivoryType t)

You can define the following type and instances:

type YourType =  NewType "yourtype_t"

instance IvoryType YourType where
  ivoryType _ = mkNewType (Proxy :: Proxy Uint8) (Proxy :: Proxy "yourtype_t")

instance IvoryVar YourType where
  wrapVar    = wrapVarExpr
  unwrapExpr = getNewType

instance IvoryExpr YourType where
  wrapExpr = NewType

We'll want to use this as a number, so we also need

deriving instance Num YourType

And now, we can use it as an Ivory type.

bar :: Def ('[YourType, YourType] ':-> YourType)
bar = proc "bar" $ \a b -> body $ ret (a+b+3)

If that works, it seems we should be able to implement it quite easily. The backend would generate a typedef.

from ivory.

leepike avatar leepike commented on September 24, 2024

@grwlf I assume this issue is resolved. Let me know otherwise.

from ivory.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.