/*
 [The "BSD license"]
 Copyright (c) 2007 Kay Roepke 2010 Alan Condit
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote products
    derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/** Templates for building ASTs during tree parsing.
 *
 *  Deal with many combinations.  Dimensions are:
 *  Auto build or rewrite
 *    no label, label, list label  (label/no-label handled together)
 *    child, root
 *    token, set, rule, wildcard
 *
 *  Each combination has its own template except that label/no label
 *  is combined into tokenRef, ruleRef, ...
 */

/* addition memVars for returnscopes */
@returnScopeInterface.memVars() ::= <<
/* ASTTreeParser returnScopeInterface.memVars */
<recognizer.ASTLabelType; null="ANTLRCommonTree"> *tree;
>>

/** the interface of returnScope methodsDecl */
@returnScopeInterface.methodsDecl() ::= <<
/* ASTTreeParser returnScopeInterface.methodsDecl */
- (<recognizer.ASTLabelType; null="ANTLRCommonTree"> *)getTree;
- (void) setTree:(<recognizer.ASTLabelType; null="ANTLRCommonTree"> *)aTree;<\n>
>>

/** the implementation of returnScope methods */
@returnScope.methods() ::= <<
/* ASTTreeParser returnScope.methods */
- (<ASTLabelType> *)getTree
{
    return tree;
}

- (void) setTree:(<ASTLabelType> *)aTree
{
    if (tree != aTree) {
        if ( tree ) [tree release];
        if ( aTree ) [aTree retain];
        tree = aTree;
    }
}

- (void) dealloc
{
    [self setTree:nil];
    [super dealloc];
}

@synthesize tree;
>>

@returnScopeProperties() ::= <<
@property (retain) <recognizer.ASTLabelType; null="ANTLRCommonTree"> *tree;
>>

/** Add a variable to track last element matched */
ruleDeclarations() ::= <<
/* ASTTreeParser ruleDeclarations */
<super.ruleDeclarations()>
<ASTLabelType> *_first_0 = nil;
<ASTLabelType> *_last = nil;<\n>
>>

/** What to emit when there is no rewrite rule.  For auto build
 *  mode, does nothing.
 */
noRewrite(rewriteBlockLevel, treeLevel) ::= <<
/* ASTTreeParser noRewrite */
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
<if(rewriteMode)>
retval.tree = (<ASTLabelType> *)_first_0;
if ( [treeAdaptor getParent:retval.tree] != nil && [treeAdaptor isNil:[treeAdaptor getParent:retval.tree]] ) )
    retval.tree = (<ASTLabelType> *)[treeAdaptor getParent:retval.tree];
<endif>
<if(backtracking)>}<endif>
>>

/** match ^(root children) in tree parser; override here to
 *  add tree construction actions.
 */
tree(root, actionsAfterRoot, children, nullableChildList,
     enclosingTreeLevel, treeLevel) ::= <<
/* ASTTreeParser tree */
_last = (<ASTLabelType> *)[input LT:1];
{
<ASTLabelType> *_save_last_<treeLevel> = _last;
<ASTLabelType> *_first_<treeLevel> = nil;
<if(!rewriteMode)>
<ASTLabelType> *root_<treeLevel> = [[[treeAdaptor class] newEmptyTree] retain];
<endif>
<root:element()>
<if(rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> )<endif>
<if(root.el.rule)>
if ( _first_<enclosingTreeLevel>==nil ) _first_<enclosingTreeLevel> = <root.el.label>.tree;
<else>
if ( _first_<enclosingTreeLevel>==nil ) _first_<enclosingTreeLevel> = <root.el.label>;
<endif>
<endif>
<actionsAfterRoot:element()>
<if(nullableChildList)>
if ( [input LA:1] == ANTLRTokenTypeDOWN ) {
    [self match:input TokenType:ANTLRTokenTypeDOWN Follow:nil]; <checkRuleBacktrackFailure()>
    <children:element()>
    [self match:input TokenType:ANTLRTokenTypeUP Follow:nil]; <checkRuleBacktrackFailure()>
}
<else>
[self match:input TokenType:ANTLRTokenTypeDOWN Follow:nil]; <checkRuleBacktrackFailure()>
<children:element()>
[self match:input TokenType:ANTLRTokenTypeUP Follow:nil]; <checkRuleBacktrackFailure()>
<endif>
<if(!rewriteMode)>
[treeAdaptor addChild:root_<treeLevel> toTree:root_<enclosingTreeLevel>];
<endif>
_last = _save_last_<treeLevel>;
}<\n>
>>

// TOKEN AST STUFF

/** ID! and output=AST (same as plain tokenRef) 'cept add
 *  setting of _last
 */
tokenRefBang(token,label,elementIndex,terminalOptions) ::= <<
/* ASTTreeParser tokenRefBang */
_last = (<ASTLabelType> *)[input LT:1];
<super.tokenRef(...)>
>>

/** ID auto construct */
tokenRef(token,label,elementIndex,terminalOptions) ::= <<
/* ASTTreeParser tokenRef */
_last = (<ASTLabelType> *)[input LT:1];
<super.tokenRef(...)>
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
<if(terminalOptions.node)>
    <label>_tree = [ANTLR<terminalOptions.node> newANTLR<terminalOptions.node>:<label>];
<else>
    <label>_tree = (<ASTLabelType> *)[treeAdaptor dupNode:<label>];
<endif><\n>
    [treeAdaptor addChild:<label>_tree toTree:root_<treeLevel>];
<if(backtracking)>}<endif>
<else> <! rewrite mode !>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> )<endif>
if ( _first_<treeLevel>==nil ) _first_<treeLevel> = <label>;
<endif>
>>

/** label+=TOKEN auto construct */
tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
/* ASTTreeParser tokenRefAndListLabel */
<tokenRef(...)>
<listLabel(elem=label,...)>
>>

/** ^(ID ...) auto construct */
tokenRefRuleRoot(token,label,elementIndex) ::= <<
/* ASTTreeParser tokenRefRuleRoot */
_last = (<ASTLabelType> *)[input LT:1];
<super.tokenRef(...)>
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
<if(terminalOptions.node)>
<label>_tree = [ANTLR<terminalOptions.node> newANTLR<terminalOptions.node>:<label>];
<else>
<label>_tree = (<ASTLabelType> *)[treeAdaptor dupNode:<label>];
<endif><\n>
root_<treeLevel> = (<ASTLabelType> *)[treeAdaptor becomeRoot:<label>_tree old:root_<treeLevel>];
<if(backtracking)>}<endif>
<endif>
>>

/** Match ^(label+=TOKEN ...) auto construct */
tokenRefRuleRootAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
/* ASTTreeParser tokenRefRuleRootAndListLabel */
<tokenRefRuleRoot(...)>
<listLabel(elem=label,...)>
>>

/** Match . wildcard and auto dup the node/subtree */
wildcard(token,label,elementIndex,terminalOptions) ::= <<
/* ASTTreeParser wildcard */
_last = (<ASTLabelType> *)[input LT:1];
<super.wildcard(...)>
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
<label>_tree = (<ASTLabelType> *)[adaptor dupTree:<label>];
[adaptor addChild:<label>_tree toTree:root_<treeLevel>];
<if(backtracking)>}<endif>
<else> <! rewrite mode !>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> )<endif>
if ( _first_<treeLevel> == nil ) _first_<treeLevel> = <label>;
<endif>
>>

// SET AST

matchSet(s,label,terminalOptions,elementIndex,postmatchCode) ::= <<
/* ASTTreeParser matchSet */
_last = (<ASTLabelType> *)[input LT:1];
<super.matchSet(postmatchCode={
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
<if(terminalOptions.node)>
<label>_tree = [ANTLR<terminalOptions.node> newANTLR<terminalOptions.node>:<label>];
<else>
<label>_tree = (<ASTLabelType> *)[adaptor dupNode:<label>];
<endif><\n>
[adaptor addChild:<label>_tree toTree:root_<treeLevel>];
<if(backtracking)>\}<endif>
<endif>
}, ...
)>
>>

matchRuleBlockSet(s,label,terminalOptions,elementIndex,postmatchCode,treeLevel="0") ::= <<
/* ASTTreeParser matchRuleBlockSet */
<matchSet(...)>
<noRewrite(...)> <! set return tree !>
>>

matchSetBang(s,label,terminalOptions,elementIndex,postmatchCode) ::= <<
/* ASTTreeParser matchSetBang */
_last = (<ASTLabelType> *)[input LT:1];
<super.matchSet(...)>
>>

matchSetRuleRoot(s,label,terminalOptions,elementIndex,debug) ::= <<
/* ASTTreeParser matchSetRuleRoot */
<super.matchSet(postmatchCode={
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
<if(terminalOptions.node)>
<label>_tree = [ANTLR<terminalOptions.node> newANTLR<terminalOptions.node>:<label>];
<else>
<label>_tree = (<ASTLabelType> *)[adaptor dupNode:<label>];
<endif><\n>
root_<treeLevel> = (<ASTLabelType> *)[adaptor becomeRoot:<label>_tree old:root_<treeLevel>];
<if(backtracking)>\}<endif>
<endif>
}, ...
)>
>>

// RULE REF AST

/** rule auto construct */
ruleRef(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRef */
_last = (<ASTLabelType> *)[input LT:1];
<super.ruleRef(...)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) <endif>
<if(!rewriteMode)>
    [treeAdaptor addChild:<label>.tree toTree:root_<treeLevel>];
<else> <! rewrite mode !>
if ( _first_<treeLevel> == nil ) _first_<treeLevel> = <label>.tree;
<endif>
>>

/** x+=rule auto construct */
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefAndListLabel */
<ruleRef(...)>
<! <listLabel(elem = "["+label+" getTree]",...)> !>
<listLabel(elem = {[<label> getTree]},...)>
>>

/** ^(rule ...) auto construct */
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefRuleRoot */
_last = (<ASTLabelType> *)[input LT:1];
<super.ruleRef(...)>
<if(!rewriteMode)>
<if(backtracking)>if ( state.backtracking == 0 ) <endif>
root_<treeLevel> = (<ASTLabelType> *)[treeAdaptor becomeRoot:<label>.tree old:root_<treeLevel>];
<endif>
>>

/** ^(x+=rule ...) auto construct */
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefRuleRootAndListLabel */
<ruleRefRuleRoot(...)>
<listLabel(elem = {[<label> getTree]},...)>
>>

/** rule when output=AST and tracking for rewrite */
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefTrack */
_last = (<ASTLabelType> *)[input LT:1];
<super.ruleRefTrack(...)>
>>

/** x+=rule when output=AST and tracking for rewrite */
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefTrackAndListLabel */
_last = (<ASTLabelType> *)[input LT:1];
<super.ruleRefTrackAndListLabel(...)>
>>

/** ^(rule ...) rewrite */
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefRuleRootTrack */
_last = (<ASTLabelType> *)[input LT:1];
<super.ruleRefRootTrack(...)>
>>

/** ^(x+=rule ...) rewrite */
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefRuleRootTrackAndListLabel */
_last = (<ASTLabelType> *)[input LT:1];
<super.ruleRefRuleRootTrackAndListLabel(...)>
>>

/** Streams for token refs are tree nodes now; override to
 *  change nextToken to nextNode.
 */
createRewriteNodeFromElement(token,terminalOptions,scope) ::= <<
/* ASTTreeParser createRewriteNodeFromElement */
<if(terminalOptions.node)>
<! new <terminalOptions.node>(stream_<token>.nextNode()) !>
[[[ANTLR<terminalOptions.node>(stream_<token> alloc] init] nextNode];
<else>
<! stream_<token>.nextNode() !>
[stream_<token> nextNode]
<endif>
>>

ruleCleanUp() ::= <<
/* ASTTreeParser ruleCleanUp */
<super.ruleCleanUp()>
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<\n><endif>
retval.tree = (<ASTLabelType> *)[treeAdaptor rulePostProcessing:root_0];
<if(backtracking)>}<endif>
<endif>
>>
