Issue Details (XML | Word | Printable)

Key: BOO-1077
Type: Improvement Improvement
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Cedric Vivier
Reporter: Rodrigo B. de Oliveira
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Boo

New style generator macros

Created: 29/Jul/08 06:19 AM   Updated: 12/Jan/09 03:04 PM   Resolved: 22/Oct/08 01:55 AM
Return to search
Component/s: None
Affects Version/s: 0.8.2
Fix Version/s: 0.9

Time Tracking:
Not Specified

Testcase included: yes


 Description  « Hide

*) 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


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.Compiler
import 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()

Rodrigo B. de Oliveira added a comment - 12/Jan/09 03:04 PM

AWESOME!