Search code examples
stringtemplatestringtemplate-4

How to insert a string template into another string template ST 4.0


Im just starting to learn string template and ive come across the example shown here:

group simple;
vardef(type,name) ::= "<type> <name>;"

method(type,name,args) ::= <<
  <type> <name>(<args; separator=",">) {
      <statements; separator="\n">
  }
>>

What I want to do is pass in a stringtemplate as an argument to the method stringtemplate as follows:

statements(function, arguments) ::= <<
    <function>(<arguments; separator=",">);
>>

 method(type,name,args, <statements> ) ::= <<
     <type> <name>(<args; separator=",">) {
     <statements; separator="\n">
  }
>>

However that didnt work out so im guessing its not possible to pass stringtemplates to stringtemplates? Then how does statements get populated?

I get the following error when I attempt this:

mytemplate.stg 14:26: invalid character '<'
mytemplate.stg 14:36: invalid character '>'

Solution

  • I'm using stringtemplate 4 with C# and I ran into the same issue when creating a generic "Delimit" template which would accept as parameters a collection, a map operation (anonymous template) over each item, and a delimiter (also an anonymous template). The template params work but I couldn't get the parameter passing mechanism to work; instead I had to rely on dynamic scoping and a variable named item existing in the caller's context.

    NormalGet(schema, table) ::= <<
    CREATE PROCEDURE [<schema.Name>].[Get<table.Name>] 
        <Delimit(items = table.Cols, itemTransformer = {@<item.Name> <item.ListType> readonly},     delimiter = ",\n")>
    AS
    BEGIN
    END
    >>
    

    and Delimit:

    Delimit(items, itemTransformer, delimiter) ::= <<
    <trunc(items): { item | <itemTransformer><delimiter>} ><last(items): { item |<itemTransformer> } >
    >>
    

    gives me something like:

    CREATE PROCEDURE [data].[GetCluster] 
        @idCluster common.intList readonly,
        @Name common.varcharList readonly,
        @Category common.varcharList readonly,
        @DisplayOrder common.intList readonly,
        @IsEditable common.bitList readonly 
    AS
    BEGIN
    END
    

    what I would like to do is replace my call to Delimit with something like this:

        <Delimit(items = table.Cols, itemTransformer = {col | @<col.Name> <col.ListType> readonly},     delimiter = ",\n")>
    

    but I can't work out the syntax for that or if it's even possible.