Translating Blech variable names to C

This explains the how Blech variable names and memory accesses are rendered as C code.

Possibilities in Blech

Variable names appear in different syntactic contexts (expressions):

  1. current / previous access
  2. lhs / rhs value (in assignment)
  3. lhs / rhs reference (in procedure call)

Variable names appear in different declaration contexts:

  1. Parameter input / output
  2. Global constant
  3. Activity- / function-local Blech variable
  4. Activity-local external C-variable
  5. Auxiliary variable introduced by the compiler

Variable names may represent various kinds of data types:

  1. Simple (atomic)
  2. Structures
  3. Arrays

Not all combinations are possible. Below is an overview of what is possible in Blech and what the corresponding generated C code must look like.

Translation workflow

Translating any access to data runs through several stages:

Given a typed memory location foo[0].bar(Remark: prev foo[0].bar binds as (prev foo)[0].bar).

  1. For the QNamePrefix part foo, determine a name scheme (depending on declaration context)
    1. Static name blc_<longId>_foo or blc_<moduleName>_<longId>_foo
    2. Parameter name blc_foo
    3. Auto name blc_foo
    4. Context element blc_blech_ctx->blc_foo
    5. Auxiliary name aux_blc_foo
    6. prev of Blech var prev_blc_foo
    7. prev of extern var blc_blech_ctx->prev_blc_foo
  2. Ensure the name <name> generated above represents the memory blob itself, not a pointer to it
    1. if foo is a simple type or struct parameter rewrite name from above to *<name>
    2. Nothing to do for arrays as the name (pointer to the first element) already represents the whole array blob.
  3. Append all field / cell access to this name <name>[0].bar
  4. Depending on usage context and type (of bar) determine whether to use the path as is or construct a reference from it
simple struct array
lhs assign as-is as-is as-is
rhs assign as-is as-is as-is
output arg & & as-is
input arg as-is & as-is

Possibly reduce trivial combinations like &(*<name>) to <name>. This will happen for e.g. simple typed output parameters passed on as an output argument.

Remarks and after thoughts:

The blc_ prefix is used to make sure we never overwrite global variables with the same name (that might appear in C sources outside the scope of the generated Blech code). Of course, we assume that the blc_ prefix is reserved and not used by sources not generated by the Blech compiler.

However previous variables use the scheme prev_blc_ making prev_ yet another exclusive prefix. We cannot simply generate blc_prev_<id> for prev <id> as this would clash with a regular Blech variable called prev_id.

We also use blc_ for naming fields in the activity context. This ensure we rule out clashes between normal and prev’ed external variables in the activity context.

Auxiliary variables use yet another prefix aux_blc_. This ensures they do not shadow a global C variable with the same name (assuming that the environment never uses names starting with aux_blc_). This is basically the same reasoning as with auto variables. However we need the extra aux_ to prevent a clash with an actual Blech variable.

Last modified May 4, 2021: drafting the module chapter (fa3db01)