-- @atlcompiler atl2006 module APascal2RSL; create OUT : RSL from IN : APascal; helper context String def: startsWith(s : String) : Boolean = s.size() <= self.size() and self.substring(1, s.size()) = s; helper context String def: endsWith(s : String) : Boolean = let start : Integer = self.size() - s.size() + 1 in start > 0 and self.substring(start, self.size()) = s; rule APascal2RSL { from s: APascal!APascal to t: RSL!RSL ( domain <- s.domain, rslelems <- Sequence { s.advice, thisModule.PointCutExprToInitExpr(s.pointcut->first().pctexpr->first()), thisModule.PointCutExprToExitExpr(s.pointcut->first().pctexpr->first()), thisModule.PointCutExprToWithinCode(s.pointcut->first().pctexpr->last()), s.pointcut->collect(e | thisModule.PointCutToExternalPattern(e)), s.pointcut->collect(e | thisModule.PointCutToRule(e)) }, ruleset <- rs ), rs : RSL!RuleSet ( rsname <- s.name, rname <- s.pointcut->collect(e|e.name) ) } rule ApDomain2RSLDomain { from s : APascal!Domain to t : RSL!Domain ( dname <- s.name ) } rule BeforeAdvice2Pattern { from s : APascal!BeforeAdvice to t : RSL!Pattern ( phead <- ph, ptoken <- 'statement_list', ptext <- spt ), ph : RSL!PatternHead ( name <- 'before_advice_stmt' ), spt : RSL!SimplePatternText ( ptext <- s.advStmt->iterate(e; acc : String = '' | acc + if acc = '' then '' else '\r\n\t' endif + e.stmt) ) } rule GenerateAfterAdviceDummy extends BeforeAdvice2Pattern { from s : APascal!BeforeAdvice ( not s.aspect.advice->exists(e | e.oclIsKindOf(APascal!AfterAdvice)) ) to t : RSL!Pattern, at : RSL!Pattern ( rsl <- s.aspect, phead <- aph, ptoken <- 'statement_list', ptext <- aspt ), aph : RSL!PatternHead ( name <- 'after_advice_stmt' ), aspt : RSL!SimplePatternText ( ptext <- '' ) } rule AfterAdvice2Pattern { from s : APascal!AfterAdvice to t : RSL!Pattern ( phead <- ph, ptoken <- 'statement_list', ptext <- spt ), ph : RSL!PatternHead ( name <- 'after_advice_stmt' ), spt : RSL!SimplePatternText ( ptext <- s.advStmt->iterate(e; acc : String = '' | acc + if acc = '' then '' else '\r\n\t' endif + e.stmt) ) } rule GenerateBeforeAdviceDummy extends AfterAdvice2Pattern{ from s : APascal!AfterAdvice ( not s.aspect.advice->exists(e | e.oclIsKindOf(APascal!BeforeAdvice)) ) to t : RSL!Pattern, bt: RSL!Pattern ( rsl <- s.aspect, phead <- bph, ptoken <- 'statement_list', ptext <- bspt ), bph : RSL!PatternHead ( name <- 'before_advice_stmt' ), bspt : RSL!SimplePatternText ( ptext <- '' ) } lazy rule PointCutExprToInitExpr { from s : APascal!Expression to t : RSL!Pattern ( ptext <- spt, ptoken <- 'NATURAL_NUMBER', phead <- ph ), ph : RSL!PatternHead ( name <- 'init' ), spt : RSL!SimplePatternText ( ptext <- if s.loopStmt.loopInitCondition.condition.toString() = '*' then '123456789' else s.loopStmt.loopInitCondition.condition.toString() endif ) } lazy rule PointCutExprToExitExpr { from s : APascal!Expression to t : RSL!Pattern ( ptext <- spt, ptoken <- 'NATURAL_NUMBER', phead <- ph ), ph : RSL!PatternHead ( name <- 'exit' ), spt : RSL!SimplePatternText ( ptext <- if s.loopStmt.loopExitCondition.condition.toString() = '*' then '123456789' else s.loopStmt.loopExitCondition.condition.toString() endif ) } lazy rule PointCutExprToWithinCode { from s : APascal!Expression to t : RSL!Pattern ( ptext <- spt , ptoken <- 'IDENTIFIER', phead <- ph ), ph : RSL!PatternHead ( name <- 'within_code' ), spt : RSL!SimplePatternText ( ptext <- if s.pointcut.pctexpr.size() > 1 then ' '+ s.funcOrProcSig.name else ' ' + 'wc_' endif ) } lazy rule PointCutToExternalPattern { from s : APascal!Pointcut to t : RSL!ExternalPattern ( dname <- 'ObjectPascal', eptext <- 'around_advice_for', ptoken <- 'ObjectPascal', phead <- ph ), ph : RSL!PatternHead ( name <- 'around_advice_for', params <- Sequence {pp1,pp2,pp3,pp4,pp5,pp6} ), pp1 : RSL!PatternParameter ( name <- 'program', referTo <- 'ObjectPascal' ), pp2 : RSL!PatternParameter ( name <- 'proceed_bef', referTo <- 'statement_list' ), pp3 : RSL!PatternParameter ( name <- 'proceed_after', referTo <- 'statement_list' ), pp4 : RSL!PatternParameter ( name <- 'withincode', referTo <- 'IDENTIFIER' ), pp5 : RSL!PatternParameter ( name <- 'init', referTo <- 'NATURAL_NUMBER' ), pp6 : RSL!PatternParameter ( name <- 'exit', referTo <- 'NATURAL_NUMBER' ) } lazy rule PointCutToRule { from s : APascal!Pointcut to t : RSL!Rule ( rname <- s.name, type <- 'ObjectPascal', params <- Sequence {rp1}, r_lhs_pattern <- rlhsp, r_rhs_pattern <- rrhsp ), rp1: RSL!RuleParameter ( name <- 'program', referTo <- 'ObjectPascal' ), rlhsp : RSL!RuleLHS ( ruletext <- irt -- IDRuleText ), irt : RSL!IDRuleText ( text <- 'program' ), rrhsp : RSL!RuleRHS ( ruletext <- crt, -- ComplexRuleText condition <- Sequence {rcon} ), crt : RSL!ComplexRuleText ( pref <- rule_rhs_pattern ), rule_rhs_pattern : RSL!PatternRef ( name <- 'around_advice_for', params <- Sequence {param1,param2,param3,param4,param5,param6} ), param1 : RSL!RealParameter ( name <- 'program' ), param2 : RSL!PatternRef ( name <- 'before_advice_stmt' ), param3 : RSL!PatternRef ( name <- 'after_advice_stmt' ), param4 : RSL!PatternRef ( name <- 'within_code' ), param5 : RSL!PatternRef ( name <- 'init' ), param6 : RSL!PatternRef ( name <- 'exit' ), rcon : RSL!RuleNotEqCondition ( lhs <- 'program', pref <- rule_rhs_cond ), rule_rhs_cond : RSL!PatternRef ( name <- 'around_advice_for', params <- Sequence {p1,p2,p3,p4,p5,p6} ), p1 : RSL!RealParameter ( name <- 'program' ), p2 : RSL!PatternRef ( name <- 'before_advice_stmt' ), p3 : RSL!PatternRef ( name <- 'after_advice_stmt' ), p4 : RSL!PatternRef ( name <- 'within_code' ), p5 : RSL!PatternRef ( name <- 'init' ), p6 : RSL!PatternRef ( name <- 'exit' ) }