View Single Post
Old 12-09-2010, 11:16 AM   #96
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 12,331
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Question for you template-language users ...

I have a partial implementation of an 'advanced' template language. Before I submit it to kovid for review, I want a sanity check. I might be making something that no one else can use.

The overarching goal is to make the template language into a 'real' programming language, at least up to a point. In the current language, all items are constants. For example, the replacement in a switch statement is a constant; you can't replace the source with something computed, such as another field.

Subgoals:
1) use as much of the existing template stuff as I can
2) make it easy to parse (efficiency)
3) support sequences of expressions (aka statements)

What I have is a language where everything is a function. A constant is a function that returns itself. A name not followed by a '(' is a reference to a local variable, otherwise it is a call of a function.

An example might make the above clearer. Consider the following (which actually works but is rather silly):
Code:
{#enum:0>15s:'
  assign(a, field('title'));
  assign(b, switch(a, '[DE]', lowercase(a), $));
  b
'}
The first line (line breaks are optional) is the same as today's language. It names the field that you are working with and defines the format to apply after the template function(s) are run. The difference is that the trailing colon is followed by a single quote. This tells the template processor that the 'new style' language is being used.

The second line assigns the value of the metadata field 'title' to the local variable 'a'.

The call to 'switch' in the third line shows one difference. The first variable in a function call specifies the value that the function is to operate upon. The special local variable '$' means the initial field, in this case #enum. The second parameter is the regexp that switch is to apply. The third parameter is the value that switch will return if the regexp matches. This third parameter is a call of the function lowercase(a). The default value of the switch (no regexps match) is $ (#enum). The result of the switch will be the lowercase value in the variable 'a' if it contains either a D or an E, otherwise the value in $ (#enum). The result of switch is assigned to the variable b.

The last line simply names 'b', so that is its value. As it is the last line in the program, that is also the value of the program. Had this line been left out, the value of the assign (value of b) would be the result of the template.

Note the trailing single quote before the } character. This quote is required as a check that the expression is in the new template language.

As you can see in the example, constant strings are entered in quotes. Either single or double quotes can be used. Constants can also be numbers.

In addition to the standard functions, the extended language has:
  • cmp(x, y, lt, eq, gt) -- treating x and y as numbers, if x < y then return lt else if x == y then return eq else return gt
  • concat(x, y) -- return a string x + y (x . y in PHP)
  • field(x) -- lookup x in metadata and return that value.
  • strcmp(x, y, lt, eq, gt) -- like cmp, only treat x and y as strings
  • substr(x, start, end) -- return the start'th through the end'th characters of x. If end == 0, then use length(x).

I know that I don't have looping constructs, but I don't see any need for them.

Have I missed something important? Any comments?
chaley is offline   Reply With Quote