Recursive Macros

View: New views
10 Messages — Rating Filter:   Alert me  

Recursive Macros

by Mad-12 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Hi folkz,
i want to write a macro, which works on every statement returning a
string and could handle controlfunctions as for or if.


SQLExecuteMacro con:
     command1
     command 2
     if  exp1:
          command3
     else:
          command4
should be evaluatet to

con.lock()
con.command = command1
con.execute()
con.command = command2
con.execute()
if exp1:
     con.command = command3
     con.execute()
else:
     con.command = command4
     con.execute()
con.unlock()
i got it working for a block of statements returning a string, but i
dont know how to do for if/unless/for/try and so on.

greatz
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Boo Programming Language" group.
To post to this group, send email to boolang@...
To unsubscribe from this group, send email to boolang+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/boolang?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Recursive Macros

by Rodrigo B. de Oliveira :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Thu, Sep 24, 2009 at 8:29 AM, Mad <dajo.mail@...> wrote:
>
> Hi folkz,
> i want to write a macro, which works on every statement returning a
> string and could handle controlfunctions as for or if.
> ...
> i got it working for a block of statements returning a string, but i
> dont know how to do for if/unless/for/try and so on.
>

Transformations of that kind are usually more easily handled by
visitors/transformers:

    namespace SQLMacros

    import Boo.Lang.PatternMatching
    import Boo.Lang.Compiler
    import Boo.Lang.Compiler.Ast
    import Boo.Lang.Compiler.MetaProgramming
    import System.Reflection

    class CommandTransformer(DepthFirstTransformer):
    """
    Transforms standalone string literals into command execution
    blocks.
    """
        _con as Expression

        def constructor(con as Expression):
            _con = con

        override def LeaveExpressionStatement(node as ExpressionStatement):
            if node.Expression isa StringLiteralExpression:
                code = [|
                    body:
                        $_con.command = $(node.Expression)
                        $_con.execute()
                |].Body
                ReplaceCurrentNode(code)

    macro SQLExecuteMacro(con as Expression):
        SQLExecuteMacro.Body.Accept(CommandTransformer(con))

        yield [| $con.lock() |]
        yield SQLExecuteMacro.Body
        yield [| $con.unlock |]


    example = [|
        import SQLMacros

        SQLExecuteMacro myConnection:
            "UPDATE FOO"
            "UPDATE BAR"
            if true:
                 "UPDATE BAZ"
            else:
                 "UPDATE GAZOONG"
    |]

    print compile_(example,
Assembly.GetExecutingAssembly()).CompileUnit.ToCodeString()

Best wishes,
Rodrigo

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Boo Programming Language" group.
To post to this group, send email to boolang@...
To unsubscribe from this group, send email to boolang+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/boolang?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Recursive Macros

by Mad-12 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


perfect, the hits the point what i was looking for
thanks a lot.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Boo Programming Language" group.
To post to this group, send email to boolang@...
To unsubscribe from this group, send email to boolang+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/boolang?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Recursive Macros

by Mad-12 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


i've one more question,
the total result should look like this:

try:
    con.lock()
    con.startTransaction()
    con.command = "foo"
    con.execute()
    ...
    con.commit()
except:
    con.rollback()
ensure:
    con.unlock()

i tried this by extending "yield [| $con.lock()|] to
yield [| try:
    con.lock()
|]
and so on, but i get a "unexpected token 'try'" error.

it works if i dont want to put it in a try-block, just like
con.lock()
con.startTransaction()
con.command = "foo"
con.execute()
...
con.commit()
con.unlock()

but thats not exactly what im looking for.

greatz
On 24 Sep., 14:34, Mad <dajo.m...@...> wrote:
> perfect, the hits the point what i was looking for
> thanks a lot.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Boo Programming Language" group.
To post to this group, send email to boolang@...
To unsubscribe from this group, send email to boolang+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/boolang?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Recursive Macros

by Rodrigo B. de Oliveira :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Thu, Sep 24, 2009 at 9:51 AM, Mad <dajo.mail@...> wrote:

>
> i've one more question,
> the total result should look like this:
>
> try:
>    con.lock()
>    con.startTransaction()
>    con.command = "foo"
>    con.execute()
>    ...
>    con.commit()
> except:
>    con.rollback()
> ensure:
>    con.unlock()
>
> i tried this by extending "yield [| $con.lock()|] to
> yield [| try:
>    con.lock()
> |]

The code inside [| |] must always be well formed (meaning complete
try/if/while forms).

Change the macro to deliver the complete try block as a single unit:

        macro SQLExecuteMacro(con as Expression):
        SQLExecuteMacro.Body.Accept(CommandTransformer(con))

        yield [|
            try:
                $con.lock()
                $(SQLExecuteMacro.Body)
                $con.commit()
            except x:
                $con.rollback()
            ensure:
                $con.unlock()
        |]

Best wishes,
Rodrigo

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Boo Programming Language" group.
To post to this group, send email to boolang@...
To unsubscribe from this group, send email to boolang+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/boolang?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Recursive Macros

by Mad-12 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


ok, i nearly got it working, except one little problem.

this does not work:
MySqlTransaction self.Con,tables,Ages.Tools.Net.Mysql.LockMode.Write:
                        for level as levels in [l  for l as levels in levels.GetValues
(levels) if l <= grenzeUnten and l >= grenzeOben]:
                                "delete from ${self.tables.tabelle[level]} where ${self.ids.ToMySql
()}"

but this does:
MySqlTransaction self.Con,tables,Ages.Tools.Net.Mysql.LockMode.Write:
                        for level as levels in [l  for l as levels in levels.GetValues
(levels) if l <= grenzeUnten and l >= grenzeOben]:
                                s = "delete from ${self.tables.tabelle[level]} where $
{self.ids.ToMySql()}"

in the first case, i get this error:
Expressions in statements must only be executed for their side-
effects. (BCE0034)
and father

MySqlTransaction self.Con,tables,Ages.Tools.Net.Mysql.LockMode.Write:
                        "Select something from somewhere"
works again.

greatz
On 24 Sep., 15:20, "Rodrigo B. de Oliveira" <rodrigobam...@...>
wrote:

> On Thu, Sep 24, 2009 at 9:51 AM, Mad <dajo.m...@...> wrote:
>
> > i've one more question,
> > the total result should look like this:
>
> > try:
> >    con.lock()
> >    con.startTransaction()
> >    con.command = "foo"
> >    con.execute()
> >    ...
> >    con.commit()
> > except:
> >    con.rollback()
> > ensure:
> >    con.unlock()
>
> > i tried this by extending "yield [| $con.lock()|] to
> > yield [| try:
> >    con.lock()
> > |]
>
> The code inside [| |] must always be well formed (meaning complete
> try/if/while forms).
>
> Change the macro to deliver the complete try block as a single unit:
>
>         macro SQLExecuteMacro(con as Expression):
>         SQLExecuteMacro.Body.Accept(CommandTransformer(con))
>
>         yield [|
>             try:
>                 $con.lock()
>                 $(SQLExecuteMacro.Body)
>                 $con.commit()
>             except x:
>                 $con.rollback()
>             ensure:
>                 $con.unlock()
>         |]
>
> Best wishes,
> Rodrigo
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Boo Programming Language" group.
To post to this group, send email to boolang@...
To unsubscribe from this group, send email to boolang+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/boolang?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Recursive Macros

by Rodrigo B. de Oliveira :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Thu, Sep 24, 2009 at 11:12 AM, Mad <dajo.mail@...> wrote:

>
> ok, i nearly got it working, except one little problem.
>
> this does not work:
> MySqlTransaction self.Con,tables,Ages.Tools.Net.Mysql.LockMode.Write:
>                        for level as levels in [l  for l as levels in levels.GetValues
> (levels) if l <= grenzeUnten and l >= grenzeOben]:
>                                "delete from ${self.tables.tabelle[level]} where ${self.ids.ToMySql
> ()}"
>

That's because "...${...}..." is not a StringLiteralExpression but a
ExpressionInterpolationExpression. You can find out what the node
types are by using booish like this:

>>>import Boo.Lang.Compiler
>>>[| "" |].GetType()
Boo.Lang.Compiler.Ast.StringLiteralExpression
>>>[| "${42}" |].GetType()
Boo.Lang.Compiler.Ast.ExpressionInterpolationExpression
>>>


Just change the original LeaveExpressionStatement to take that
expression type into account:

    override def LeaveExpressionStatement(node as ExpressionStatement):
        if IsCommand(node.Expression):
            code = [|
                body:
                    $_con.command = $(node.Expression)
                    $_con.execute()
            |].Body
            ReplaceCurrentNode(code)

    def IsCommand(e as Expression):
        if e isa StringLiteralExpression: return true
        if e isa ExpressionInterpolationExpression: return true
        return false

Best wishes,
Rodrigo

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Boo Programming Language" group.
To post to this group, send email to boolang@...
To unsubscribe from this group, send email to boolang+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/boolang?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Recursive Macros

by Mad-12 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


thanx, not it works, seems to me like you did all of my coding job.
Mad

On 24 Sep., 18:43, "Rodrigo B. de Oliveira" <rodrigobam...@...>
wrote:

> On Thu, Sep 24, 2009 at 11:12 AM, Mad <dajo.m...@...> wrote:
>
> > ok, i nearly got it working, except one little problem.
>
> > this does not work:
> > MySqlTransaction self.Con,tables,Ages.Tools.Net.Mysql.LockMode.Write:
> >                        for level as levels in [l  for l as levels in levels.GetValues
> > (levels) if l <= grenzeUnten and l >= grenzeOben]:
> >                                "delete from ${self.tables.tabelle[level]} where ${self.ids.ToMySql
> > ()}"
>
> That's because "...${...}..." is not a StringLiteralExpression but a
> ExpressionInterpolationExpression. You can find out what the node
> types are by using booish like this:
>
> >>>import Boo.Lang.Compiler
> >>>[| "" |].GetType()
>
> Boo.Lang.Compiler.Ast.StringLiteralExpression>>>[| "${42}" |].GetType()
>
> Boo.Lang.Compiler.Ast.ExpressionInterpolationExpression
>
>
>
> Just change the original LeaveExpressionStatement to take that
> expression type into account:
>
>     override def LeaveExpressionStatement(node as ExpressionStatement):
>         if IsCommand(node.Expression):
>             code = [|
>                 body:
>                     $_con.command = $(node.Expression)
>                     $_con.execute()
>             |].Body
>             ReplaceCurrentNode(code)
>
>     def IsCommand(e as Expression):
>         if e isa StringLiteralExpression: return true
>         if e isa ExpressionInterpolationExpression: return true
>         return false
>
> Best wishes,
> Rodrigo
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Boo Programming Language" group.
To post to this group, send email to boolang@...
To unsubscribe from this group, send email to boolang+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/boolang?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Recursive Macros

by Rodrigo B. de Oliveira :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Fri, Sep 25, 2009 at 9:03 AM, Mad <dajo.mail@...> wrote:
>
> ... seems to me like you did all of my coding job.
>

I didn't mean to take the fun out of your hands. Hopefully the
insights will inspire you to take it further ;)

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Boo Programming Language" group.
To post to this group, send email to boolang@...
To unsubscribe from this group, send email to boolang+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/boolang?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Recursive Macros

by Mad-12 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


in the beginning i had no idea how to do, i tried something with a y-
combinator, you helped me very much.

On 25 Sep., 14:36, "Rodrigo B. de Oliveira" <rodrigobam...@...>
wrote:
> On Fri, Sep 25, 2009 at 9:03 AM, Mad <dajo.m...@...> wrote:
>
> > ... seems to me like you did all of my coding job.
>
> I didn't mean to take the fun out of your hands. Hopefully the
> insights will inspire you to take it further ;)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Boo Programming Language" group.
To post to this group, send email to boolang@...
To unsubscribe from this group, send email to boolang+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/boolang?hl=en
-~----------~----~----~----~------~----~------~--~---