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

Feature request: macros as variable declaration pragmas #6696

Closed
mratsim opened this issue Nov 5, 2017 · 9 comments · Fixed by #19406
Closed

Feature request: macros as variable declaration pragmas #6696

mratsim opened this issue Nov 5, 2017 · 9 comments · Fixed by #19406

Comments

@mratsim
Copy link
Collaborator

mratsim commented Nov 5, 2017

Forum thread link.

Example:

Being to do this with a user-defined macro

{.pragma: align64, codegenDecl: "$# $# __attribute__((aligned(64)))".}
var foo{.align64.} = [1, 2, 3, 4]
macro align64*(x: untyped): untyped =
  expectKind(x, nnkIdent)
  result = x
  when defined(js):
    return
  # codegenDecl code goes here


# This works
proc foo() {.align64.} =
  discard


# Get this to work
let bar {.align64.} = [1, 2, 3, 4]
@yglukhov
Copy link
Member

yglukhov commented Nov 5, 2017

And for types as well! =)

Question is to which AST macros should be applied though?

let bar {.foo.} = 123

Might be transformed to

foo(let bar = 123)

or

let foo(bar) = 123

or smth else? The first variant looks more useful and allows crazier things. However, what if the let section has more decls?

let
  bar {.foo.} = 123
  buz = 456

Should the let section be split now to the following?

foo(let bar = 123)
let buz = 456

@fredrikhr
Copy link
Contributor

Would also like this for Type declarations like:

import macros
macro myMagicTypeMacro(ast: untyped): untyped =
  result = ast

type MyMagicType {.myMagicTypeMacro.} = object of RootObj
  foo: int

@mratsim
Copy link
Collaborator Author

mratsim commented Nov 27, 2017

Related: #1930, #1930

@Skrylar
Copy link
Contributor

Skrylar commented Dec 20, 2017

In the case of Flatbuffers (and Capnproto, any serializer, etc) this would let you place format-specific tags on an object and avoid needing to take over the entire type section.

import macros

macro sporg(unused: untyped): untyped =
  discard

type
  thingdo = object
    foo {.sporg: true.}: int # something like this should work, as it does in C# (and Go, kind of)

macro cocainum(x: typedesc): untyped =
  let t = gettypeimpl(gettype(x)[1])
  echo lisprepr t

cocainum(thingdo)

@andreaferretti
Copy link
Collaborator

@Skrylar I tried to re-read your comment a few times but I could not parse it :-(

@Bulat-Ziganshin
Copy link

Bulat-Ziganshin commented Jul 15, 2018

@andreaferretti he meant that now we can apply macro to type in this way:

sporg true:
  type thingdo = object foo: int

and this feature will allow to add per-type pragmas right to the type definitions

@Skrylar
Copy link
Contributor

Skrylar commented Jul 17, 2018

We have these now in the form of custom pragmas, which I have (locally) tested and you can use them for ORMs/automatic serialization code. The API to use custom pragmas is a slight bit painful, but I'm not sure this ticket needs to be open anymore?

@metagn
Copy link
Collaborator

metagn commented Apr 30, 2020

This is now implemented, but without arguments like {.sporg: true.}, see https://nim-lang.org/docs/decls.html

@timotheecour
Copy link
Member

timotheecour commented May 7, 2020

the new design is being discussed here: nim-lang/RFCs#220, TLDR the syntax will likely change from (lhs,typ,rhs) params to a single AST param

metagn added a commit to metagn/Nim that referenced this issue Jan 17, 2022
fix nim-lang#15920, close nim-lang#18212, close nim-lang#14781, close nim-lang#6696,
close nim-lang/RFCs#220

Variable macro pragmas have been changed to
only take a unary section node.
They can now also be applied in sections with multiple variables,
as well as `const` sections. They also accept arguments.

Templates now support macro pragmas, mirroring other routine types.

Type and variable macro pragmas have been made experimental.
Symbols without parentheses instatiating nullary macros or templates
has also been documented in the experimental manual.

A check for a redefinition error based on the left hand side of variable
definitions when using variable macro pragmas was disabled.
This nerfs `byaddr` specifically, however this has been documented as
a consequence of the experimental features `byaddr` uses.

Given how simple these changes are I'm worried if I'm missing something.
Araq pushed a commit that referenced this issue Jan 20, 2022
* New/better macro pragmas, make some experimental

fix #15920, close #18212, close #14781, close #6696,
close nim-lang/RFCs#220

Variable macro pragmas have been changed to
only take a unary section node.
They can now also be applied in sections with multiple variables,
as well as `const` sections. They also accept arguments.

Templates now support macro pragmas, mirroring other routine types.

Type and variable macro pragmas have been made experimental.
Symbols without parentheses instatiating nullary macros or templates
has also been documented in the experimental manual.

A check for a redefinition error based on the left hand side of variable
definitions when using variable macro pragmas was disabled.
This nerfs `byaddr` specifically, however this has been documented as
a consequence of the experimental features `byaddr` uses.

Given how simple these changes are I'm worried if I'm missing something.

* accomodate compiler boot

* allow weird pragmas

* add test for #10994

* remove some control flow, try remove some logic
PMunch pushed a commit to PMunch/Nim that referenced this issue Mar 28, 2022
* New/better macro pragmas, make some experimental

fix nim-lang#15920, close nim-lang#18212, close nim-lang#14781, close nim-lang#6696,
close nim-lang/RFCs#220

Variable macro pragmas have been changed to
only take a unary section node.
They can now also be applied in sections with multiple variables,
as well as `const` sections. They also accept arguments.

Templates now support macro pragmas, mirroring other routine types.

Type and variable macro pragmas have been made experimental.
Symbols without parentheses instatiating nullary macros or templates
has also been documented in the experimental manual.

A check for a redefinition error based on the left hand side of variable
definitions when using variable macro pragmas was disabled.
This nerfs `byaddr` specifically, however this has been documented as
a consequence of the experimental features `byaddr` uses.

Given how simple these changes are I'm worried if I'm missing something.

* accomodate compiler boot

* allow weird pragmas

* add test for nim-lang#10994

* remove some control flow, try remove some logic
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants