[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