[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