Ser2

ser2 was created between 2009 and 2012. Its name abbreviates "Search Entity and Replace", the "2" indicates the second attempt. ser2 is inspired by C++ template meta-programming. It is a minimalistic functional language with the initial and final state predefined and built-in i/o.

= Overview =

Relation to established languages
C++ template meta-programming is Turing-complete and in order to achieve this, only a tiny subset of the template engine is necessary. It boils down to partial specializations as in

template  struct object{ typedef new_object::result result; };

So that the result of  is the result of. ser2 basically strips this down to the essential content of such a specialization

!object--:fixed:#T: / new_object---:foo:#T:bar:

In fact, ser2 easily translates to a C++ template meta-program.

In a nutshell
In a nutshell, the language translates a (sub-)tree of objects to a new (sub-)tree of objects. In order to make the language easier readable, at the end of the object name the number of subobjects is indicated by a number of " "-signs. Wildcards start with a " ". The initial object is the object " " with a i/o object as subobject. At termination, it is this i/o subobject that must remain. The following shows "Hello world!":

!print--:#o:--:#c:#n: / wrote--:'@output--:#o:#c :#n: !print--:#o:    eol: / wrote- :'@output--:#o:&0a: !wrote--:'@iopair--:#o:#c:#n: / print--:#o:#n: !wrote- :'@iopair--:#o:#c:   / #o: !'@run-:#: / print--:#: --:'H:--:'e:--:'l:--:'l:--:'o:--:' :--:'w:--:'o:--:'r:--:'l:--:'d:--:'!:eol:

The " " object gets replaced by " ", repeating the subobjects of " ". Meanwhile the character that forms the second object gets printed.

= Language definition = The language purely consists of a set of rules. A rule consists of two parts, the pattern and the replacement. The pattern starts with a " " and the replacement by " ". The state of the program is a rooted tree of objects. If a pattern matches a subtree, then the subtree is replaced by the replacement. Smaller subtrees are treated first, following the eager evaluation scheme.

File format
The file is in 8-bit ASCII. Within a pattern or replacement, any character other than alphanumeric and " " is ignored, but the character following " ". Outside of a pattern or replacement, any character except " " is ignored.

Objects
Object names are alphanumeric + " " and are terminated by " ", for extended names involving " " see below. An object name may have in addition an arbitrary number " "s at the end, indicating the number of child objects. These child objects have to be listed after the object name. Example:

pair--:first:second:

denotes the object " " with two child objects, " " and " ". Arbitrary hierarchies are admissible, a typical example is

list--:s:list--:e:list--:r:list--:2:nil:

denoting the object tree

list--: / | s:  list--: / |    e:  list--: / |       r:  list--: / |          2:  nil:

Wildcards
A wildcard name is alphanumeric + " " and starts with a " " and ends with a " ". No " " are allowed. A wildcard matches and replaces a subtree. Example:


 * 1) wildcard:

Patterns
A pattern is like a tree of objects. It can have wildcards. Then

/list--:#cur:#next:

would match the object above with " " set to " " and " " set to " ". In a pattern, each wildcard must be unique. Implementations may refuse to allow a wildcard at the root object, since this always leads to a non-terminating program.

Replacements
A replacement is an object, where the wildcards are replaced by the subtree that was assigned while matching the pattern. In a replacement, each wildcard must occur at most once. Child objects are subject to a replacement prior to the parent object. Different child objects of the same parent object may be replaced in any order or even concurrently.

Resolution order
There may be ambiguous cases in pattern matching. The following rule is used: A pattern X matches at least as good as a pattern Y if, no matter what objects would be assigned to the wildcards, the resulting object always matches Y. If there exists a rule for which no other rule matches at least as well, this rule is applied. Otherwise undefined behaviour will occur.

Names with special characters
In the names of objects an " " may occur and than the following character is forced to be part of the object name, but the character has to be below 0xf0. Examples:

object's_name: arbitrary' chars' are' possible' e'.g'.' ':' or' '': name'1: name1:

Note in particular, that the latter two objects are different.

Instead of using " " it is also possible to use " " where xx is the hexadecimal 8-bit code (upper or lower case) for the character. Hence the following two objects are the same:

space' : space&20:

Special objects
Finally there are a few objects that have a special meaning. They define the initial condition, simple i/o routines and some optional convenience stuff. Each of those special objects is limited to appear either only in patterns or only in replacements. In detail we have:

Syntax characters
= Caveats =
 * There is no support for any number, strings, or similar things and in addition there is no inherent way to compare or copy objects. This may make it a bit difficult to write something useful…

Take C++, but remove everything except the bare minimum required for turing-complete template meta-programming. The keywords template, typedef, typename and struct should be enough. Could get rid of either struct or typename with some trivial changes from C++, but if you want to keep it compatible your options are more limited.
 * ser2 approaches an entry from the List of ideas:


 * When translating to C++, the order of the rules may play a role. An example is

!const-:x:/foo-:bar: !foo-:bar:/bar: !'@run-:#:/done--:#:const-:x: !done--:#:bar:/#:

Which would instantiate  before its specialization. This can be avoided by using a dummy template as in.