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

Minor mitigating changes to typedef macro pragmas for now #427

Closed
metagn opened this issue Oct 9, 2021 · 1 comment
Closed

Minor mitigating changes to typedef macro pragmas for now #427

metagn opened this issue Oct 9, 2021 · 1 comment

Comments

@metagn
Copy link
Contributor

metagn commented Oct 9, 2021

This currently fails with "illformed AST":

import macros

macro test(s): untyped =
  newTree(nnkTypeSection, s)

type Foo {.test.} = object

You are supposed to return another nnkTypeDef. Before this is changed in favor of some new system, if ever, a small change in the meantime for convenience could be to accept a typesection from the macro and inject all the typedefs inside it into the original typesection where the typedef was (or behave as such).

import macros

macro test(s): untyped =
  let name = $s[0].basename
  result = newTree(nnkTypeSection,
    newTree(nnkTypeDef, ident(name & "1"), s[1], s[2]),
    newTree(nnkTypeDef, ident(name & "2"), s[1], s[2]))

type
  Foo = object
  Bar {.test.} = object
    x, y, z: int
  Baz = object

# becomes

type
  Foo = object
  Bar1 = object
    x, y, z: int
  Bar2 = object
    x, y, z: int
  Baz = object

Also maybe accept any expression from the macro if the typedef is the only one in its typesection (so cyclic references can be respected) and replace the entire typesection with that expression, but this might not be as easy.

import macros

macro test(s): untyped =
  let name = $s[0].basename
  result = newCall("echo", newLit("type name is " & name))

type Bar {.test.} = object
  x, y, z: int

# becomes

echo("type name is Bar")

# invalid:
type
  Foo = object
  Bar {.test.} = object
    x, y, z: int
type
  Bar {.test.} = object
    x, y, z: int
  Foo = object

Bonus: Maybe accept statement lists where the first statement is a typesection, inject that typesection, then add the remaining statements after the FULL original typesection. Not sure if this makes sense.

This should be completely non breaking, I don't think anyone relies on "illformed AST" errors.

Extras (not part of proposal):

  • The reason for basename in these examples is because typedef macros do not erase the remaining {..} like proc macro pragmas do, which maybe should be changed.
  • If you're wondering "why not make your own DSL for type construction like all the OOP libraries" it's because when and case in objects and postfixes are impossible to recreate without it looking very ugly. Enums also have their own unique syntax privileges. It sucks because type sections are also the least flexible syntax in the language (object does not even accept semicolons).
  • If you're wondering "wouldn't solving cyclic references make this a lot easier of a problem" yeah it would, but it doesn't really warrant the wait, it will only be satisfying to simplify it when we get there anyway. Plus macro pragmas for variables aren't even a proper feature yet and they're completely sequential.
@juancarlospaco
Copy link
Contributor

That kind of error messages need to be improved into something more useful and descriptive.

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

No branches or pull requests

2 participants