migration macro syntax

7 views
Skip to first unread message

Andrew Davey

unread,
Jun 11, 2009, 5:27:32 PM6/11/09
to Nemerle Forum
Can Nemerle macro syntax support this:

migration (1, "Add customer table") {
up {
}
down {
}
}

?

Ķaмĭļ ๏ Şκaļşκĭ

unread,
Jun 11, 2009, 5:35:57 PM6/11/09
to nemer...@googlegroups.com
Yes, sure.
You must create three macros:

macro m (x : int, y : string, body : PExpr)
syntax ("migration" , "(", x, y, ")", body) {
}

macro u(b)
syntax ("up", b) { }

macro d(b) syntax ("down", b) {}
--
Kamil Skalski
http://kamil-skalski.pl

Andrew Davey

unread,
Jun 12, 2009, 7:26:55 AM6/12/09
to Nemerle Forum
Thanks. I went for this in the end (bit simpler)

public macro MigrationMacro(up, down) syntax ("migration", "up",
up, "down", down)
{
def ctx = Nemerle.Macros.ImplicitCTX();
when (ctx.IsMainPass) {
MigrationHelpers.Create(ctx, up, down);
}
<[]>
}

Any tips on why the macro causes VS to display errors, but still
compiles just fine?!

module MigrationHelpers
{

public Create(ctx : Typer, up : PExpr, down : PExpr) : void
{
def up = (up :> PExpr.Sequence).body;
def down = (down :> PExpr.Sequence).body;

def parts = ctx.CurrentType.ParsedName.Id.Split('_');
def version = long.Parse(parts[0]);

def mods = Modifiers(NemerleAttributes.Public, [ <
[ MigrationAttribute( $(PExpr.Literal(Literal.FromLong(version))) ) ]
> ]);
def m = ctx.CurrentType.DefineNestedType(<[ decl:
..$mods class Migration : Migrator.Framework.Migration
{
public override Up() : void {..$up}
public override Down() : void {..$down}
}
]>);
m.Compile();
}

}

Thanks :D

On Jun 11, 10:35 pm, Ķaмĭļ ๏ Şκaļşκĭ <kamil.skal...@gmail.com> wrote:
> Yes, sure.
> You must create three macros:
>
> macro m (x : int, y : string, body : PExpr)
> syntax ("migration" , "(", x, y, ")", body) {
>
> }
>
> macro u(b)
> syntax ("up", b) {  }
>
> macro d(b) syntax ("down", b) {}
>

ReverseBlade

unread,
Jun 13, 2009, 4:11:13 AM6/13/09
to Nemerle Forum
Another way to do this is to make one big macro rather than inner
macros.

In this case the syntax turns into the following:


migration (1, "Add customer table"): {
up: {
}
down: {
}

}


Notice the ":" this is necessary since nemerle compiler requires a
valid keyword for matching xx { } for a reason I don't know.



If these are migrations you may want to put this into an assembly
level macro so the syntax would resemble to a true DSL like

[assembly:
// Macro starts

migration (1, Add customer table): {
up: {
}
down: {
}

//macro ends
}

]


How you will match parse above syntax should be easy

no need to use syntax option

macro (migration,body)
{

....

match (body)
{
| <[ ($id, $label): { ..$statments } ]> => // do smt with it and
label

foreach (statements)
{
| <[ ("up":dyn) : { .. $upstatments }=> //...
| <[ ("down":dyn) : { .. $downstatments }=> //...
}
}



this might not be the best way. I also haven't tried it exactly but it
should work.

Andrew Davey

unread,
Jun 13, 2009, 6:18:32 AM6/13/09
to Nemerle Forum
Thanks for these ideas - very useful.

Do you know why VS reports errors that the compiler does not?
e.g.
parse error near keyword 'migration': expecting type declaration

I could use assembly macros, but the syntax looks a bit noisy.
I'd really like to use my originally proposed migration syntax and put
this directly into a .n file with no other noise.
Whilst it does compile, the VS false error reporting is very annoying!

catbert

unread,
Jun 14, 2009, 6:16:00 AM6/14/09
to Nemerle Forum
It is a known problem that VS integration often reports errors that do
not exist.

Try entering some code outside the class declaration, this will cause
entire file to be reparsed and can make those errors go away.

VladD2

unread,
Jun 15, 2009, 7:59:53 AM6/15/09
to nemer...@googlegroups.com
2009/6/12 Andrew Davey <a.j....@gmail.com>:

> Any tips on why the macro causes VS to display errors, but still
> compiles just fine?!

The expression level macros typed many time on VS Integration. Don't
use expression level macros to define types.

The best place to define types is macro-attribute (assembly level or
type level).

PS

Andrew, you speak Russian?

Andrew Davey

unread,
Jun 15, 2009, 8:13:45 AM6/15/09
to Nemerle Forum
That limits DSL possibilities somewhat. I guess I can live with it.. :
(

- Sorry I don't speak Russian.

On Jun 15, 12:59 pm, VladD2 <v...@rsdn.ru> wrote:
> 2009/6/12 Andrew Davey <a.j.da...@gmail.com>:

VladD2

unread,
Jun 15, 2009, 10:12:32 AM6/15/09
to nemer...@googlegroups.com
2009/6/15 Andrew Davey <a.j....@gmail.com>:

>
> That limits DSL possibilities somewhat. I guess I can live with it.. :
> (

Use assembly (or class) level macro to define class which you need. In
this case in expression level macro you should lookup it type and set
bodies of it methods.

If you define types in expression level macro you should try lookup it
before. But I advise use assembly level macro. For example:
[Migration(Version=1)] // This is a macro which define nested type
class A
{
public Methid1() : void
{

Reply all
Reply to author
Forward
0 new messages