/*
 [The "BSD license"]
 Copyright (c) 2005-2006 Terence Parr
 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.
*/
/** Template subgroup to add template rewrite output
 *  If debugging, then you'll also get STDbg.stg loaded.
 */

@returnScopeInterface.memVars() ::= <<
<@super.memVars()>
/* ST returnInterface.memVars */
ST *st;
>>

@returnScopeInterface.properties() ::= <<
<@super.properties()>
/* ST returnScope.properties */
@property (retain, getter=getST, setter=setST:) ST *st;
>>

@returnScopeInterface.methodsDecl() ::= <<
<@super.methodsDecl()>
/* ST AST returnScopeInterface.methodsDecl */
- (id) getTemplate;
- (NSString *) toString;
- (NSString *) description;
>>

@returnScopeInterface() ::= <<
/* ST returnScopeInterface */
@interface <returnScopeInterface.name> : ANTLRReturnScope {
<returnScopeInterface.memVars()>
}
<returnScopeInterface.properties()>

<returnScopeInterface.methods()>
@end
>>

@returnScopeImplementation.synthesize() ::= <<
<@super.synthesize()>
/* ST returnScope.synthesize */
@synthesize st;
>>

@returnScopeImplementation.methods() ::= <<
<@super.methods()>
/* ST returnScope.methods */
- (id) getTemplate { return st; }
- (NSString *) toString { return st==nil?nil:[st toString]; }
- (NSString *) description { [self toString]; }
>>

@returnScopeImplementation() ::= <<
@implementation <returnScopeImplementation.name>
<returnScopeImplementation.synthesize()>

<returnScopeImplementation.methods()>
@end
>>

/** Add this to each rule's return value struct */
@returnScope.ruleReturnMembers() ::= <<
<@super.ruleReturnMembers()>
/* ST returnScope.ruleReturnMembers -- empty */
>>

@genericParserHeaderFile.memVars() ::= <<
<@super.memVars()>
/* ST genericParserHeaderFile.memVars -- empty now */
STGroup *templateLib; /* ST -- really a part of STAttrMap */
>>

@genericParserHeaderFile.properties() ::= <<
<@super.properties()>
/* ST genericParser.properties */
@property (retain, getter=getTemplateLib, setter=setTemplateLib:) STGroup *templateLib;
>>

@genericParserHeaderFile.methodsDecl() ::= <<
<@super.methodsDecl()>
/* ST genericParser.methodsDecl */
- init;
- (STGroup *) getTemplateLib;
- (void) setTemplateLib:(STGroup *)aTemplateLib;
@end
>>

@genericParser.synthesize() ::= <<
<@super.synthesize()>
/* ST genericParserImplementation.synthesize */
@synthesize templateLib;
>>

@genericParser.methods() ::= <<
<@super.methods()>
/* ST genericParser.methods */

- (STGroup *)getTemplateLib
{
    return templateLib;
}

- (void) setTemplateLib:(STGroup *)aTemplateLib
{
    templateLib = aTemplateLib;
}

>>

@genericParser.members() ::= <<
<@super.members()>
STGroup *templateLib = [STGroup  newSTGroup:@"<name>Templates"];

- (STGroup *) getTemplateLib
{
  return templateLib;
}

- (void) setTemplateLib:(STGroup *) templateLib
{
  this.templateLib = templateLib;
}

/** allows convenient multi-value initialization:
 *  "new STAttrMap().put(...).put(...)"
 */
/* REPLACE THIS STATIC CLASS
static class STAttrMap extends HashMap {
- (STAttrMap *) setObject:(id)aValue forKey:(NS*)String attrName
{
    [super setObject:value forKey:attrName];
    return self;
}
- (STAttrMap *) setObjectWithInt:(NSInteger)value forKey:(NSString *)attrName
{
    [super setObject:[NSNumber numberWithInteger:value] forKey:attrName];
    return self;
  }
}
*/
>>

@STAttrMap() ::= <<
/* -------- ST start STAttrMap ------------ */
<@STAttrMap.interface()>
<@STAttrMap.implementation()>
/* -------- ST end STAttrMap ------------ */
>>

@STAttrMap.interface() ::= <<
/* -------- ST start STAttrMap.interface ------------ */
@interface STAttrMap : ANTLRHashMap {
/*    <@STAttrMap.memVars()> */
    STGroup *templateLib;
}

/*    <@STAttrMap.properties()> */
@property (retain, getter=getTemplateLib, setter=setTemplateLib:) STGroup *templateLib;
/* <@STAttrMap.methodsDecl()> */
- (id) init;
- (STAttrMap *) setObject:(id)value forKey:(NSString *)attrName;
- (STAttrMap *) setObjectWithInt:(NSInteger)value forKey:(NSString *)attrName;
- (void) setTemplateLib:(STGroup *)aTemplateLib;
- (STGroup *) getTemplateLib;
@end
/* -------- ST end STAttrMap.interface ------------ */
>>

@STAttrMap.implementation() ::= <<
/* -------- ST start STAttrMap.implementation ------------ */
/** allows convenient multi-value initialization:
 *  "new STAttrMap().put(...).put(...)"
 */
@implementation STAttrMap
@synthesize templateLib;

<@STAttrMap.methods()>
@end
/* -------- ST end STAttrMap.implementation ------------ */
>>

@STAttrMap.memVars() ::= <<
/* -------- ST start STAttrMap.memVars ------------ */
    STGroup *templateLib;
/* -------- ST end STAttrMap.memVars ------------ */
>>

@STAttrMap.properties() ::= <<
/* -------- ST start STAttrMap.properties ------------ */
@property (retain, getter=getTemplateLib, setter=setTemplateLib:) STGroup *templateLib;
/* -------- ST end STAttrMap.properties ------------ */
>>

@STAttrMap.methodsDecl() ::= <<
/* -------- ST start STAttrMap.methodsDecl ------------ */
- (id) init;
- (STAttrMap *) setObject:(id)value forKey:(NSString *)attrName;
- (STAttrMap *) setObjectWithInt:(NSInteger)value forKey:(NSString *)attrName;
- (void) setTemplateLib:(STGroup *)aTemplateLib;
- (STGroup *) getTemplateLib;
/* -------- ST end STAttrMap.methodsDecl ------------ */
>>

@STAttrMap.methods() ::= <<
/* -------- ST start STAttrMap.methods ------------ */
- (id) init
{
    self = [super initWithLen:16];
    if ( self != nil ) {
        templateLib = [STGroup newSTGroup:"<name>Templates"];
    }
    return self;
}

- (STAttrMap *) setObject:(id)aValue forKey:(NSString *)aAttrName
{
    [super setObject:aValue forKey:aAttrName];
    return self;
}

- (STAttrMap *) setObjectWithInt:(NSInteger)aValue forKey:(NSString *)aAttrName
{
    [super setObject:[NSNumber numberWithInteger:aValue] forKey:aAttrName];
    return self;
}
- (void) setTemplateLib:(STGroup *)aTemplateLib
{
    templateLib = aTemplateLib;
}

- (STGroup *)getTemplateLib
{
    return templateLib;
}
/* -------- ST end STAttrMap.methods ------------ */
>>

/** x+=rule when output=template */
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
/* ST ruleRefAndListLable */
<ruleRef(...)>
<listLabel(elem=[label getTemplate,...]>
>>

rewriteTemplate(alts) ::= <<
/* -------- ST start rewriteTemplate ------------ */
// TEMPLATE REWRITE
<if(backtracking)>
if ( <actions.(actionScope).synpredgate> ) {
    <alts:rewriteTemplateAlt(); separator="else ">
    <if(rewriteMode)><replaceTextInLine()><endif>
}
<else>
<alts:rewriteTemplateAlt(); separator="else ">
<if(rewriteMode)><replaceTextInLine()><endif>
<endif>
/* -------- ST end rewriteTemplate ------------ */
>>

replaceTextInLine() ::= <<
/* -------- ST start replaceTextInLine ------------ */
<if(TREE_PARSER)>
[[(ANTLRTokenRewriteStream *)input getTokenStream]
    replaceFromIndex:[[input getTreeAdaptor] getTokenStartIndex:retval.start]
             ToIndex:[[input getTreeAdaptor] getTokenStopIndex:retval.start]
                Text:retval.st];
<else>
[(ANTLRTokenRewriteStream *)input)
        replaceFromIndex:[((ANTLRCommonToken *)retval.start) getTokenIndex]
                 ToIndex:[[input LT:-1] getTokenIndex]
                    Text:retval.st];
<endif>
/* -------- ST end replaceTextInLine ------------ */
>>

rewriteTemplateAlt() ::= <<
/* -------- ST start rewriteTemplateAlt ------------ */
/* ST <it.description> */
<if(it.pred)>
if (<it.pred>) {
    retval.st = <it.alt>;
}<\n>
<else>
{
    retval.st = <it.alt>;
}<\n>
<endif>
/* -------- ST end rewriteTemplateAlt ------------ */
>>

rewriteEmptyTemplate(alts) ::= <<
nil;
>>

/** Invoke a template with a set of attribute name/value pairs.
 *  Set the value of the rule's template *after* having set
 *  the attributes because the rule's template might be used as
 *  an attribute to build a bigger template; you get a self-embedded
 *  template.
 */
rewriteExternalTemplate(name,args) ::= <<
/* -------- ST start rewriteExternalTemplate ------------ */
[templateLib getInstanceOf:@"<name>"
<if(args)>[[STAttrMap newSTAttrMap] <args:{a | setObject:<a.value> forKey:@"<a.name>"]}><endif>]
/* -------- ST end rewriteExternalTemplate ------------ */
>>

/** expr is a string expression that says what template to load */
rewriteIndirectTemplate(expr,args) ::= <<
/* -------- ST start rewriteIndirectTemplate ------------ */
[templateLib getInstanceOf:<expr>
<if(args)> [[STAttrMap newSTAttrMap]<args:{a | setObject:<a.value> forKey:@"<a.name>"]}>]
<else>]<endif>
/* -------- ST end rewriteIndirectTemplate ------------ */
>>

/** Invoke an inline template with a set of attribute name/value pairs */
rewriteInlineTemplate(args, template) ::= <<
/* -------- ST start rewriteInlineTemplate ------------ */
STGroup *templateLib;
templateLib.templates = [STAttrMap newSTAttrMap];
<if(args)> [templateLib.templates <args:{a | setObject:<a.value> forKey:@"<a.name>"];}><endif>
[ST newST:templateLib template:@"<template>"];
/* -------- ST end rewriteInlineTemplate ------------ */
>>

/** plain -> {foo} action */
rewriteAction(action) ::= <<
/* -------- ST start rewriteAction ------------ */
<action>
/* -------- ST end rewriteAction ------------ */
>>

/** An action has %st.attrName=expr; or %{st}.attrName=expr; */
actionSetAttribute(st,attrName,expr) ::= <<
/* -------- ST start actionSetAttribute ------------ */
[[ST attributes] setObject:<expr> forKey:@"<attrName>"];
<![<st> setAttribute:<expr> name:@"<attrName>"];!>
/* -------- ST end actionSetAttribute ------------ */
>>

/** Translate %{stringExpr} */
actionStringConstructor(stringExpr) ::= <<
/* -------- ST start actionStringConstructor ------------ */
[ST newSTWithTemplate:<stringExpr>]
/* -------- ST end actionStringConstructor ------------ */
>>
