*) new style macros:
*) macros are generators for nodes (any kind)
*) type members are added to the enclosing type or module
*) expressions and statements are added to the enclosing block
example:
macro types:
for typeName in types.Arguments:
type = [|
class $typeName:
pass
|]
yield type
Description
*) new style macros:
*) macros are generators for nodes (any kind)
*) type members are added to the enclosing type or module
*) expressions and statements are added to the enclosing block
example:
macro types:
for typeName in types.Arguments:
type = [|
class $typeName:
pass
|]
yield type
Landed in rev. 3055.
Re-assigned it to me as I was very motivated to do it this morning to be able to use this awesomeness in a project I'm currently working on, I hope you do not mind
To be fully backward-compatible the new syntax does not replace completely the old one but is a additional possibility on top of the old one (which was/is just good enough if the consumer is not interested to generated classes/members/etc...)
For the sake of documenting this JIRA issue I post the testcases here :
"""
Foo says hello!
Bar says hello!
Zap says hello!
"""
import Boo.Lang.Compiler
macro helloClasses:
for typeName in helloClasses.Arguments:
yield [|
class $typeName:
override def ToString() as string:
return"${$typeName} says hello!"
|]
helloClasses Foo, Bar, Zap
print Foo()
print Bar()
print Zap()
"""
bonjour
quoi de neuf?
a bientot!
"""
import Boo.Lang.Compiler
macro speak:
for statement in speak.Block.Statements:
s = cast(Ast.ExpressionStatement, statement).Expression as Ast.StringLiteralExpression
if s.Value == "hello":
yield [| print "bonjour" |]
if s.Value == "whats up?":
yield [| print "quoi de neuf?" |]
yield [| print "a bientot!" |]
speak "french":
"hello""whats up?"
"""
DO>
<DO
Soviet Russia says hello to EnclosingClass+Foo!
Soviet Russia says hello to EnclosingClass+Bar!
Soviet Russia says hello to EnclosingClass+Zap!
Mission accomplished, nested classes, methods and fields are defeated!
"""
import Boo.Lang.Compilerimport Boo.Lang.Compiler.Ast
macro mixed:
yield cast(Field, [| (_i = 100) as int |])
#expression used to to disambiguate from BinaryExpression/assignment within block.
#another possibility: yield CodeBuilder.CreateField("_i", TypeSystemServices.IntType)
for typeName in mixed.Arguments:
yield [|
class $typeName:
_ec as EnclosingClass
def constructor(ec as EnclosingClass):
_ec = ec
override def ToString() as string:
_ec._i++
return"Soviet Russia says hello to ${$typeName}!"
|]
yield [|
def MissionAccomplished():
if _i == 103: #because must have started at 100 if above cast OK
print "Mission accomplished, nested classes, methods and fields are defeated!"
|]
class EnclosingClass:
def Do():
print "DO>"
mixed Foo, Bar, Zap
print "<DO"
ec = EnclosingClass()
ec.Do()
print EnclosingClass.Foo(ec)
print EnclosingClass.Bar(ec)
print EnclosingClass.Zap(ec)
ec.MissionAccomplished()
Cedric Vivier added a comment - 22/Oct/08 01:55 AM Landed in rev. 3055.
Re-assigned it to me as I was very motivated to do it this morning to be able to use this awesomeness in a project I'm currently working on, I hope you do not mind
To be fully backward-compatible the new syntax does not replace completely the old one but is a additional possibility on top of the old one (which was/is just good enough if the consumer is not interested to generated classes/members/etc...)
For the sake of documenting this JIRA issue I post the testcases here :
"""
Foo says hello!
Bar says hello!
Zap says hello!
"""
import Boo.Lang.Compiler
macro helloClasses:
for typeName in helloClasses.Arguments:
yield [|
class $typeName:
override def ToString() as string:
return"${$typeName} says hello!"
|]
helloClasses Foo, Bar, Zap
print Foo()
print Bar()
print Zap()
"""
bonjour
quoi de neuf?
a bientot!
"""
import Boo.Lang.Compiler
macro speak:
for statement in speak.Block.Statements:
s = cast(Ast.ExpressionStatement, statement).Expression as Ast.StringLiteralExpression
if s.Value == "hello":
yield [| print "bonjour" |]
if s.Value == "whats up?":
yield [| print "quoi de neuf?" |]
yield [| print "a bientot!" |]
speak "french":
"hello""whats up?"
"""
DO>
<DO
Soviet Russia says hello to EnclosingClass+Foo!
Soviet Russia says hello to EnclosingClass+Bar!
Soviet Russia says hello to EnclosingClass+Zap!
Mission accomplished, nested classes, methods and fields are defeated!
"""
import Boo.Lang.Compilerimport Boo.Lang.Compiler.Ast
macro mixed:
yield cast(Field, [| (_i = 100) as int |])
#expression used to to disambiguate from BinaryExpression/assignment within block.
#another possibility: yield CodeBuilder.CreateField("_i", TypeSystemServices.IntType)
for typeName in mixed.Arguments:
yield [|
class $typeName:
_ec as EnclosingClass
def constructor(ec as EnclosingClass):
_ec = ec
override def ToString() as string:
_ec._i++
return"Soviet Russia says hello to ${$typeName}!"
|]
yield [|
def MissionAccomplished():
if _i == 103: #because must have started at 100 if above cast OK
print "Mission accomplished, nested classes, methods and fields are defeated!"
|]
class EnclosingClass:
def Do():
print "DO>"
mixed Foo, Bar, Zap
print "<DO"
ec = EnclosingClass()
ec.Do()
print EnclosingClass.Foo(ec)
print EnclosingClass.Bar(ec)
print EnclosingClass.Zap(ec)
ec.MissionAccomplished()
Landed in rev. 3055.
Re-assigned it to me as I was very motivated to do it this morning to be able to use this awesomeness in a project I'm currently working on, I hope you do not mind
To be fully backward-compatible the new syntax does not replace completely the old one but is a additional possibility on top of the old one (which was/is just good enough if the consumer is not interested to generated classes/members/etc...)
For the sake of documenting this JIRA issue I post the testcases here :