Details

    • Type: Improvement Improvement
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 0.8.2
    • Fix Version/s: 0.9
    • Component/s: None
    • Labels:
      None
    • Testcase included:
      yes
    • Number of attachments :
      0

      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
              

        Activity

        Cedric Vivier made changes -
        Field Original Value New Value
        Assignee Rodrigo B. de Oliveira [ bamboo ] Cedric Vivier [ cedricv ]
        Hide
        Cedric Vivier added a comment -

        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()
        
        Show
        Cedric Vivier added a comment - 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()
        Cedric Vivier made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Cedric Vivier made changes -
        Testcase included yes
        Summary New style macros New style enumerable macros
        Cedric Vivier made changes -
        Summary New style enumerable macros New style generator macros
        Hide
        Rodrigo B. de Oliveira added a comment -

        AWESOME!

        Show
        Rodrigo B. de Oliveira added a comment - AWESOME!

          People

          • Assignee:
            Cedric Vivier
            Reporter:
            Rodrigo B. de Oliveira
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: