[svn] r7802: nemerle/trunk/snippets/aop/src: ftests/param_polym/backtracking_in_args_matching_positive.n h...

Luntain svnadmin at nemerle.org
Sat Oct 6 22:51:45 CEST 2007


Log:
=== AOP ===

- restore subtyping graph on backtracking while matching parameters patterns
- clean up modifiers in Parse.n

Author: Luntain
Date: Sat Oct  6 22:51:38 2007
New Revision: 7802

Added:
   nemerle/trunk/snippets/aop/src/ftests/param_polym/backtracking_in_args_matching_positive.n
Modified:
   nemerle/trunk/snippets/aop/src/helper/GapMatching.n
   nemerle/trunk/snippets/aop/src/helper/Parameters.n
   nemerle/trunk/snippets/aop/src/helper/Parse.n
   nemerle/trunk/snippets/aop/src/macros/macros.n
   nemerle/trunk/snippets/aop/src/utests/gap_matching.n

Added: nemerle/trunk/snippets/aop/src/ftests/param_polym/backtracking_in_args_matching_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/param_polym/backtracking_in_args_matching_positive.n	Sat Oct  6 22:51:38 2007
@@ -0,0 +1,30 @@
+// the ellipsis operator inside args() will cause backtracking 
+// implementation should handle this
+#pragma indent
+using Nemerle.IO
+using Nemerle.Aop
+
+public class A {}
+public class B: A {}
+
+public class C
+
+    public M(_: int, _: B): void
+        print("M\n")
+
+
+    public static Main(): void
+        C().M(1, B())
+
+[aspect] public class Aspekt {
+    after(_arg: A+): execution(C.?(..): ?) && args(.., _arg) {
+        print("advice\n")
+    }
+}
+
+/*
+BEGIN-OUTPUT
+M
+advice
+END-OUTPUT
+*/

Modified: nemerle/trunk/snippets/aop/src/helper/GapMatching.n
==============================================================================
--- nemerle/trunk/snippets/aop/src/helper/GapMatching.n	(original)
+++ nemerle/trunk/snippets/aop/src/helper/GapMatching.n	Sat Oct  6 22:51:38 2007
@@ -12,24 +12,40 @@
 
     public module GapMatching
         
-        public Match['a,'b](pattern: list[PatternFragment['a]], word: LazyList['b], f: 'a * 'b -> bool): bool
-            Match'(pattern,word,fun(x,(y,_)) {(f(x,y),None())}).IsSome
+        public Match['a,'b](
+                        pattern: list[PatternFragment['a]],
+                        word: LazyList['b],
+                        f: 'a * 'b -> bool): bool
+            Match'(pattern,word,fun(x,(y,_)) {(f(x,y),None())}, fun() {0}, fun(_){}).IsSome
 
-        public Match' ['a,'b,'c](pattern: list[PatternFragment['a]], word: LazyList['b], f: 'a * ('b * int) -> bool*option['c]): option[list['c]]
-            Match''(pattern,LazyList.Zip(word,LazyList.IntStream(1)),f)
+        public Match' ['a,'b,'c](
+                        pattern: list[PatternFragment['a]], 
+                        word: LazyList['b],
+                        f: 'a * ('b * int) -> bool*option['c],
+                        saveState: void->int,
+                        restoreState: int->void): option[list['c]]
+            Match''(pattern,LazyList.Zip(word,LazyList.IntStream(1)),f, saveState, restoreState)
 
-        private Match'' ['a,'b,'c](pattern: list[PatternFragment['a]], word: LazyList['b*int], f: 'a * ('b * int) -> bool*option['c]): option[list['c]]
+        private Match'' ['a,'b,'c](
+                        pattern: list[PatternFragment['a]],
+                        word: LazyList['b*int],
+                        f: 'a * ('b * int) -> bool*option['c],
+                        saveState: void->int, 
+                        restoreState: int->void): option[list['c]]
             match(pattern,word)
                 | ([],Nil) => Some([])
                 | ([Gap],_) => Some([]) //must be for the sake of Nil
                 | (Gap::tail as gpattern,Cons(_,ltail) as word) =>
-                    match(Match''(tail,word,f))
+                    def snapshot = saveState()
+                    match(Match''(tail,word,f,saveState,restoreState))
                         | Some as res => res
-                        | None => Match''(gpattern,ltail,f)
+                        | None => 
+                            restoreState(snapshot) //backtracking
+                            Match''(gpattern,ltail,f,saveState,restoreState)
                 | (Fragment(pattern)::rest, Cons(elem,word_rest)) =>
                     match(f(pattern,elem))
                         | (true,x) =>
-                            match (Match''(rest,word_rest,f))
+                            match (Match''(rest,word_rest,f,saveState,restoreState))
                                 | Some(xs) => Some(x.Map(_::xs).WithDefault(xs))
                                 | None() => None()
                         | (false,_) =>

Modified: nemerle/trunk/snippets/aop/src/helper/Parameters.n
==============================================================================
--- nemerle/trunk/snippets/aop/src/helper/Parameters.n	(original)
+++ nemerle/trunk/snippets/aop/src/helper/Parameters.n	Sat Oct  6 22:51:38 2007
@@ -36,7 +36,7 @@
                     | (Param.FormalParamRef(tp,num_in_advice),(parm_type,i)) =>
                         (tp.Matches(parm_type),Some(VariableBinding.Parameter(i,num_in_advice))) 
 
-                GapMatching.Match'(parameter_pattern,LazyList.FromList(actual_params),ismatch)
+                GapMatching.Match'(parameter_pattern,LazyList.FromList(actual_params),ismatch, TypePattern.PushState, TypePattern.PopState)
 
             match(method.GetMemType()) 
                 | MType.Fun(from,_) =>

Modified: nemerle/trunk/snippets/aop/src/helper/Parse.n
==============================================================================
--- nemerle/trunk/snippets/aop/src/helper/Parse.n	(original)
+++ nemerle/trunk/snippets/aop/src/helper/Parse.n	Sat Oct  6 22:51:38 2007
@@ -16,7 +16,7 @@
       | Both = 3
   }
 
-  static public pointcut( 
+  internal static pointcut( 
               tokens: list[Token], 
               params_dict: Hashtable[string,AdviceParameter],
               env: GlobalEnv): PResult[Pointcut] {
@@ -139,7 +139,7 @@
   }
 
 
-  public static type_pattern(tokens: list[Token], env: GlobalEnv): PResult[TypePattern] {
+  static type_pattern(tokens: list[Token], env: GlobalEnv): PResult[TypePattern] {
       def parse = type_pattern'(_,env,MTypePattern()) <@ mtypepattern => TypePattern.Make(mtypepattern); 
       parse(tokens)
   }
@@ -150,7 +150,7 @@
     parse(tokens)
   }
 
-  internal static type_pattern' ['a](tokens: list[Token], env: GlobalEnv, factory: TypePatternFactory['a]): PResult['a] {
+  static type_pattern' ['a](tokens: list[Token], env: GlobalEnv, factory: TypePatternFactory['a]): PResult['a] {
 
    def parse_typepattern = reversed {
        parse_arrow ;
@@ -204,7 +204,7 @@
    parse_typepattern(tokens)
   }
 
-  public static id_pattern(tokens: list[Token]): PResult[IdPattern]
+  static id_pattern(tokens: list[Token]): PResult[IdPattern]
    def parse = reversed {
        exact <|> blank;
        def blank = operator("?") <@ _=> IdPattern.Blank();

Modified: nemerle/trunk/snippets/aop/src/macros/macros.n
==============================================================================
--- nemerle/trunk/snippets/aop/src/macros/macros.n	(original)
+++ nemerle/trunk/snippets/aop/src/macros/macros.n	Sat Oct  6 22:51:38 2007
@@ -107,9 +107,10 @@
             check_if_within_aspect(type_builder)
             def lexer = Lexer.WithoutFixing(tail)
             def tyvars = maybe_parse_tyvars(lexer,type_builder.GlobalEnv) 
-            def (parameters,artificialtyvars,constraints) = parse_parms(lexer.Pop():> Token.RoundGroup,type_builder.GlobalEnv)
+            def (parameters,artificialtyvars,constraints) = parse_parms(
+                                    lexer.Pop():> Token.RoundGroup, type_builder.GlobalEnv)
             lexer.DropOperator(":")
-            def (pointcut_toks,beyond_pointcut_toks) = split_tokens(lexer);
+            def (pointcut_toks, beyond_pointcut_toks) = split_tokens(lexer);
             def typarms = MainParser.ParseWhereConstraints(type_builder.GlobalEnv,beyond_pointcut_toks.Head,tyvars)
             def typarms = Typarms(typarms.tyvars+artificialtyvars,typarms.constraints+constraints) 
             def(advice_name,header) = make_header(tail.Location, parameters, meth, PExpr.Void(), typarms)

Modified: nemerle/trunk/snippets/aop/src/utests/gap_matching.n
==============================================================================
--- nemerle/trunk/snippets/aop/src/utests/gap_matching.n	(original)
+++ nemerle/trunk/snippets/aop/src/utests/gap_matching.n	Sat Oct  6 22:51:38 2007
@@ -30,11 +30,30 @@
     assert !Match([PatternFragment.Fragment(2)],lazy_list([1]), f)
     assert !Match([PatternFragment.Fragment(2)],lazy_list([2,1]), f)
 
-test "matching that returns result"
+test "matching that returns result / no match"
     def g = fun(a,(b,i)) {(f(a,b),Some(i))}
-    def result = Match'([PatternFragment.Fragment(123)],lazy_list([43,44,45]),g)
+    def saveState = fun(){0}
+    def restoreState = fun(_) {}
+    def result = Match'([PatternFragment.Fragment(123)], lazy_list([43,44,45]), g, saveState, restoreState)
     assert result.IsNone
-    def result = Match'([PatternFragment.Fragment(43),PatternFragment.Gap()],lazy_list([43,44,45]),g)
+
+test "matching that returns result / match"
+    def g = fun(a,(b,i)) {(f(a,b),Some(i))}
+    def saveState = fun(){0}
+    def restoreState = fun(_) {}
+    def result = Match'([PatternFragment.Fragment(43),PatternFragment.Gap()],lazy_list([43,44,45]),g, saveState, restoreState)
     assert result.UnSome() == [1] 
-    def result = Match'([PatternFragment.Gap(),PatternFragment.Fragment(44),PatternFragment.Fragment(45)],lazy_list([43,44,45]),g)
+
+test "matching that returns result / two matched fragments"
+    def g = fun(a,(b,i)) {(f(a,b),Some(i))}
+    def saveState = fun(){0}
+    def restoreState = fun(_) {}
+    def result = Match'(
+                [PatternFragment.Gap(),
+                 PatternFragment.Fragment(44),
+                 PatternFragment.Fragment(45)],
+                lazy_list([43,44,45]),
+                g,
+                saveState,
+                restoreState)
     assert result.UnSome() == [2,3] 



More information about the svn mailing list