[svn] r7472: nemerle/trunk/ncc: parsing/AST.n parsing/MainParser-Extensions.n parsing/MainParser.n testsui...

Luntain svnadmin at nemerle.org
Fri Feb 23 16:28:46 CET 2007


Log:
added new feature: macro to define a new kind of member, does not support modifiers and custom attributes yet

Author: Luntain
Date: Fri Feb 23 16:28:45 2007
New Revision: 7472

Added:
   nemerle/trunk/ncc/testsuite/positive/syntax_extension_custom_members.n
Modified:
   nemerle/trunk/ncc/parsing/AST.n
   nemerle/trunk/ncc/parsing/MainParser-Extensions.n
   nemerle/trunk/ncc/parsing/MainParser.n
   nemerle/trunk/ncc/testsuite/positive/macrolib.n

Modified: nemerle/trunk/ncc/parsing/AST.n
==============================================================================
--- nemerle/trunk/ncc/parsing/AST.n	(original)
+++ nemerle/trunk/ncc/parsing/AST.n	Fri Feb 23 16:28:45 2007
@@ -528,6 +528,8 @@
       this.macro_attrs = [];
     }
 
+    public this() { this(NemerleAttributes.None,[]) }
+
     public static this ()
     {
       Empty = Modifiers (NemerleAttributes.None, []);

Modified: nemerle/trunk/ncc/parsing/MainParser-Extensions.n
==============================================================================
--- nemerle/trunk/ncc/parsing/MainParser-Extensions.n	(original)
+++ nemerle/trunk/ncc/parsing/MainParser-Extensions.n	Fri Feb 23 16:28:45 2007
@@ -339,7 +339,7 @@
     parse_grammar_rule (tree : GrammarElement, stop : TokenStoppers, target : MacroTargets)
       : GrammarElement * list [SyntaxElement]
     {
-      // Message.Debug (tree.ToStringWhole ());
+//      Message.Debug (tree.ToStringWhole ());
       def expect_semicolon () {
         if (stream == null)
           jump_to_sibling ();

Modified: nemerle/trunk/ncc/parsing/MainParser.n
==============================================================================
--- nemerle/trunk/ncc/parsing/MainParser.n	(original)
+++ nemerle/trunk/ncc/parsing/MainParser.n	Fri Feb 23 16:28:45 2007
@@ -667,7 +667,7 @@
                         | _ =>
                           pop_stream ();
                           when (key == "variant") in_variant = true;
-                          members = process_groups (children, "type member", ParseClassMember);
+                          members = process_groups (children, "type member", fun() {ParseClassMember(mods)}); 
                           when (members.Exists (_ is ClassMember.TypeDeclaration (TopDeclaration.Delegate (null))))
                             members = members.Filter (m => !(m 
                               is ClassMember.TypeDeclaration (TopDeclaration.Delegate (null))));
@@ -748,7 +748,14 @@
     }
 
     
-    ParseClassMember () : ClassMember
+    ParseClassMember(): ClassMember
+    {
+        ParseClassMember(null)
+    }
+    
+    // class_modifiers might be null. It is used only in case of "custom" member parsed.
+    // Custom member is added as a custom attribute to parent class.
+    ParseClassMember (class_modifiers: Modifiers) : ClassMember
     {
       def start_tok = get_token ();
       match (start_tok) {
@@ -757,8 +764,33 @@
           mutable customs = get_customs ();
           def mods = Modifiers (get_modifiers (), []);
 
-          parse_top_extensions (mods, MacroTargets.All & ~MacroTargets.Parameter);
+          mutable parsed_custom_member = false;
+          when (class_modifiers != null) {
+            def collect_type_macro_inv = Modifiers();
+            parse_top_extensions (collect_type_macro_inv, MacroTargets.Class);
+            if (!collect_type_macro_inv.IsEmpty && stream == null) {
+                // End of the current "member" loose group; there is nothing left 
+                // to be parsed as a regular member, so we threat it as a macro invocation with special syntax.
+                parsed_custom_member = true;
+                foreach (type_macro_attr in collect_type_macro_inv.GetCustomAttributes()) {
+                    class_modifiers.AddCustomAttribute(type_macro_attr)
+                }
+            }
+            else {
+                // There is sth more in this loose group. Even if a class targeted macro was parsed, this
+                // does not mean it is a custom member. It could be a macro targeted at a nested class.
+                foreach (type_macro_attr in collect_type_macro_inv.GetCustomAttributes()) {
+                    mods.AddCustomAttribute(type_macro_attr)
+                }
+            }
+          }
 
+          if (parsed_custom_member) {
+            pop_stream();
+            null
+          }
+          else {
+          parse_top_extensions (mods, MacroTargets.All & ~MacroTargets.Parameter);
           def tok = peek_token ();
           def result = 
             match (tok) {
@@ -838,6 +870,7 @@
             }
           pop_stream ("class member");
           result
+          }
             
         | _ => null
       }

Modified: nemerle/trunk/ncc/testsuite/positive/macrolib.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/positive/macrolib.n	(original)
+++ nemerle/trunk/ncc/testsuite/positive/macrolib.n	Fri Feb 23 16:28:45 2007
@@ -6,6 +6,7 @@
 using System;
 using System.Xml;
 
+
 public interface IFoo
 {
   Foo () : void;
@@ -444,3 +445,25 @@
       <[ () ]>
     }
 }
+
+
+// for syntax_extension_custom_members.n
+[Nemerle.MacroUsage(Nemerle.MacroPhase.BeforeInheritance, Nemerle.MacroTargets.Class)]
+macro abrakadabra( type_builder: TypeBuilder, _loose_group: Token)
+syntax("abrakadabra", _loose_group) {
+
+    def field_for_instance = <[ decl: static mutable field_for_instance: $(type_builder.ParsedName: name); ]>;
+        type_builder.Define(field_for_instance);
+
+    def lazy_accessor = <[ 
+        decl:
+        public static $("Instance": dyn): $( type_builder.ParsedName: name) {
+            get {
+                when (field_for_instance == null)
+                    field_for_instance = $(type_builder.ParsedName: name)();
+                field_for_instance
+            }
+        }
+    ]>;
+    type_builder.Define(lazy_accessor);
+}

Added: nemerle/trunk/ncc/testsuite/positive/syntax_extension_custom_members.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/ncc/testsuite/positive/syntax_extension_custom_members.n	Fri Feb 23 16:28:45 2007
@@ -0,0 +1,23 @@
+// REFERENCE: macrolib.dll
+using Nemerle.IO;
+
+public class Foo {
+
+    public MethodOfFoo(): void {
+		print("hello there\n");
+	}
+
+    abrakadabra {  // custom member, creates static instance property, macro is defined in macrolib.n
+        "asdf" 
+    }
+
+	public static Main(): void {
+		Foo.Instance.MethodOfFoo(); // note Instance property, it should be created by abrakadabra macro 
+	}
+}
+
+/*
+BEGIN-OUTPUT
+hello there
+END-OUTPUT
+*/



More information about the svn mailing list