Prokee Module: bmc

From prokee
Revision as of 00:24, 1 May 2019 by Andy (talk | contribs)
Jump to navigation Jump to search

The program bmc is small tool which allows the automated generation of files which are compiled by concatenating predefined blocks of code or text.

Bmc contains an experimental parser for a small subset of the Universal Prokee Language (UPL). It may be used to execute search queries within hierarchical structures written in #Block Syntax. The search results are then concatenated and can be written to a file.

F.e. bmc can be used to generate a series of personalized letters. In this case, the predefined blocks of code could be the names of customers, and some text-blocks, which should or should not appear on the letter depending on some properties of the customer. The output of bmc are then the individual letters.

By constructing complex searches and concatenation patterns, bmc can be seen as a "compiler" which extracts information (lots of tiny fragments of code) from an hierarchical structure (the input) and compiles it to another language by concatenating the extracted fragments. By doing so, the semantics of a program can be included in the source code itself in form of the tiny (atomic) fragments of code and the rules and meaning of their concatenation defined as named blocks.

Block Syntax

The concept of Named Blocks is taken from UPL. An named block is given by its name followed by the blocks contents within curly braces. Empty named blocks are called Words.

Words are Literals which are defined by just stating them, followed by either the empty block {} or a semicolon. To define the Word "Vienna" we can write Vienna; or Vienna{}.

Blocks allow the definition of additional named blocks (or words) within the block.

F.e. the following example lists some districts of Vienna.

Vienna
{
    Kagran;
    Brigittenau;
    Leopoldstadt;
    ...
}

Such blocks can be nested to model more complex structures.

Additionally each block may contain one or more values. The only type of supported values are strings. The following example shows a definition of a rectangle, where the dimensions are given as the values of the blocks Width and Height.

Rectangle
{
    Width
    {
        "10 cm"
    }
    Height
    {
        "7 cm"
    }
}

To reduce typing a bit, bmc allows to compact the example above to a more natural looking equivalent variation.

Rectangle
{
    Width="10 cm";
    Height="7 cm";
}

Inheritance

Blocks may inherit properties from other blocks. Inheritance is established by the ':' operator.

To illustrate this, the next example shows the definition of an point and a rectangle, which inherits its position from the point.

Point
{
    Horizontal-Position="10 cm";
    Vertical-Position="10 cm";
}
Rectangle:Point
{
    Width="10 cm";
    Height="7 cm";
}

The DEF keyword is used to overwrite inherited properties.

In the following example Rectangle has the dimensions 10 x 7 cm.

StandardRectangle
{
    Width="10 cm";
    Height="10 cm";
}
Rectangle:StandardRectangle
{
    DEF Height="7 cm";
}

To refer to an element within a block, the '.' operator can be used similar to most object oriented languages.

F.e. if we want to know the height of the rectangle above, we could write Rectangle.Height.

String Concatenation

We can ask bmc for values of blocks. Such questions start with a '@'. F.e. "@Rectangle.Height" would be answered with "7 cm". By concatenating more of such questions, which may refer to additional questions, all the resulting answers will be concatenated to one single output string. bmc does nothing more, than a lookup within a given block structure and then printing all the values of the found blocks.

A hello world program would be as simple as the following

SAY_HELLO="Hello World!";
@SAY_HELLO

How can you do arithmetic operations with concatenation?

Well, you can't.

  • You may define the result:
 1+1="2";
 @1+1     //will output "2"
  • Or you may do some ugly tricks:
1="x";
2="xx";
3="xxx";

x="1";
xx="2";
xxx="3";

+="";

//calculate 1+1
@1@+@1     //will output "xx"

//calculate 1+2
@1@+@2     //will output "xxx"

//calculate 1+2
//use the result for another query
@<@1@+@2>  // Step 1:
           //   evaluation within <...>
           //   "@1@+@2" will evaluate to "xxx"
           // Step 2:
           //   "@xxx" will then output "3"

But this is not what bmc is intended for. The only purpose in bmc is in doing concatenation of predefined block-values. Basically a real compiler, which outputs machine code, does also concatenate single machine code commands into an executable file. By putting all those commands into a giant block structure, you could build a compiler for any language by using bmc. But your sourcecode would completely unreadable.