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

feat: allow C types to satisfy all type constraints #1306

Merged
merged 1 commit into from
Sep 4, 2021

Conversation

scolsen
Copy link
Contributor

@scolsen scolsen commented Aug 27, 2021

This commit builds on the emit-c feature by permitting C typed values to
be used anywhere in Carp code.

For example, if one wants to use the literal C macro EDOM:

(register EDOM C "EDOM")

(Int.+ 1 EDOM)
=> 34

when compiled, this will produce the call:

Int__PLUS(1, EDOM)

So it provides a quite flexible means of using C macros directly. It is,
of course, also radically unsafe. Anyone registering and using values of
the C type better be cautious.

One can get pretty crazy with this feature:

(register comment-it C "// commented out;")

(Int.+ 1 comment-it)
=> int _11 = Int__PLUS_(1, // commented out;)
   int* _12 = &_11; // ref
   String _13 = IntRef_str(_12);

This commit builds on the emit-c feature by permitting C typed values to
be used anywhere in Carp code.

For example, if one wants to use the literal C macro `EDOM`:

```clojure
(register EDOM C "EDOM")

(Int.+ 1 EDOM)
=> 34
```

when compiled, this will produce the call:

```c
Int__PLUS(1, EDOM)
```

So it provides a quite flexible means of using C macros directly. It is,
of course, also radically unsafe. Anyone registering and using values of
the C type better be cautious.

One can get pretty crazy with this feature:

```clojure
(register comment-it C "// commented out;")

(Int.+ 1 comment-it)
=> int _11 = Int__PLUS_(1, // commented out;)
   int* _12 = &_11; // ref
   String _13 = IntRef_str(_12);
```
@scolsen
Copy link
Contributor Author

scolsen commented Aug 27, 2021

I'm iffy on this one. It's incredibly unsafe and not really blocked by much. To make it a bit more obvious how unsafe this is we could tuck registration of C literals behind a separate register style command.

Also note that this mostly just saves wrapper boilerplate since once could always do:

int my_edom() {
  return EDOM;
}

To make some macro value accessible in carp.

@scolsen scolsen requested a review from a team August 27, 2021 18:31
@hellerve
Copy link
Member

It’s terrible, I love it! Not sure whether my excitement should count as a positive review, though :)

@TimDeve
Copy link
Contributor

TimDeve commented Aug 27, 2021

Yeah it definitely feels iffy to me.
For the specific example you are using (C macros that stand for value) you can register it directly as a value/variable:

(register EDOM Int "EDOM")

My gut says there should be time where that doesn't work but I've never hit a problem with it. Obviously you lose the "it can be any type represented by the literal" thing.

@scolsen
Copy link
Contributor Author

scolsen commented Aug 27, 2021

Yeah it definitely feels iffy to me.
For the specific example you are using (C macros that stand for value) you can register it directly as a value/variable:

(register EDOM Int "EDOM")

My gut says there should be time where that doesn't work but I've never hit a problem with it. Obviously you lose the "it can be any type represented by the literal" thing.

Indeed! but when I did it this way I got the following problem when evaling in the repl:

LibC.EDOM
out/main.c:10508:15: error: cannot take the address of an rvalue of type 'int'
    int* _9 = &EDOM; // ref
              ^~~~~

but may the PR then should somehow fix emit to not produce the invalid ref

@eriksvedang
Copy link
Collaborator

This change to the type checker makes sense to me, if you have arbitrary C code you want to be able to use it wherever (and be prepared to face the consequences.)

But I think the particular situation would be better suited by making the current code do the right thing (since what you have is clearly an integer, and you should be able to type it as such.) Not sure how hard the fix is though.

@TimDeve
Copy link
Contributor

TimDeve commented Aug 30, 2021

@scolsen You're right, I thought for sure I had tried to take a ref and it worked anyway. The alternative is to do something like this but you certainly lose some of the flexibility of the original macro:

(deftemplate domain-error Int "static int $NAME=EDOM" ""))

@eriksvedang eriksvedang merged commit 4630e0e into carp-lang:master Sep 4, 2021
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.

4 participants