BARfly Help - BAR Implementation File Reference - Common Declarations

  Common Declarations

Many declarations in implementation files have consistent styles, regardless of the scope in which the declaration appears.  These common declarations are constants, type specifications, variable declarations, function declarations, construct declaration keywords, and conditional expressions.

Constants

EnumeratedConstant ::= IdentifierName
EnumeratedConstantBlockName ::= IdentifierName
Constant ::= EnumeratedConstant | Number | ShortString | BooleanValueKeyword

A constant evaluates to an unchanging load at compile-time.  This can be an enumerated constant, a number, a short string, or the Boolean keywords ‘true’ or ‘false’.

Enumerated constant names must be declared in an enumerated constant block prior to their usage if they are to be interpreted as constants during compilation.

Type Specifications

EndianTypeModifier ::= ('bigendian' | 'littleendian')?
SignAndEndianTypeModifiers ::= (('signed' | 'unsigned')? ('bigendian' | 'littleendian')?) | (('bigendian' | 'littleendian')? ('signed' | 'unsigned')?)
SimpleType ::= (SignAndEndianTypeModifiers? SimpleIntegralTypeName) | (EndianTypeModifier? SimpleFloatingTypeName)
DataStructureType ::= SimpleType | IdentifierName

When specifying a simple type or structured type, as used with variable types, function return types, unorganized block unit types, and other contexts like typecasts and memory allocation, either SimpleType or DataStructureType can be used.

Simple types can make use of type qualifiers:  ‘littleendian’ and ‘bigendian’ for all simple types, and ‘signed’ and ‘unsigned’ for integral types.  The SignAndEndianTypeModifier expression demonstrates that keyword ordering is not important if there is a need to introduce both byte order qualifications and sign qualifications to a simple type.

A structured type must be defined in a structure definition prior to usage as a valid DataStructureType.

Variable Declarations

VariableDeclaration ::= (‘*’)? S? IdentifierName S? ('[' S? Constant? S? ']' S? ('[' S? Constant S? ']')?)? (S? '=' S? Initializer)?

Most variable declarations allow for optional pointer qualification (asterisk), optional one-dimensional array qualification, optional two-dimensional array qualification, and optional initializer.

BitFieldVariableDeclaration ::= IdentifierName S? ‘:’ S? Constant (S? '=' S? Initializer)?

Bit field variable declarations lack pointer or array qualification.  Instead, bit fields require a colon and a sizing constant, which specifies the number of bits occupied by the bit field.  A bit field has an optional initializer.

ParameterVariableDeclaration ::= (‘*’)? S? IdentifierName

Parameter variables, used in function declarations, differ from VariableDeclaration in that array qualification and initializer cannot appear.

LocalVariableDeclaration ::= (‘*’)? S? IdentifierName (S? '=' S? Expression)?

Local variables, used in function bodies, differ from VariableDeclaration in that array qualification cannot appear, and optional initializer is replaced by an optional assigned expression.  The expression, if it appears, makes the local variable declaration serve a dual purpose:  variable declaration and variable assignment at run-time.

If there is no assigned expression, the variable defaults to zero (for scalar contents) or null (for pointer contents).

Function Declarations

FunctionDeclaration ::= (DataStructureType | ‘void’) S (‘*’)? S? IdentifierName S? ‘(‘ S? ParameterList S? ‘)’ S? ‘{‘ S? FunctionBodyDefinition S? ‘}’ S? ‘;’

Function declarations, for both global and member functions, always assume a common template, FunctionDeclaration.  It is never necessary to qualify namespaces for member functions, since member functions must always be declared and defined inside a construct definition.

The asterisk is optional; it identifies the return type as a pointer to the given type.

The function return type is either a keyword representing one of the built-in simple types (void, char, short, long, longlong, float, or double) or an identifier for a data structure name.  If a data structure name is used, an asterisk is required.

ParameterList ::= ((DataStructureType | ‘void’) S ParameterVariableDeclaration) (S? ‘,’ S? (DataStructureType | ‘void’) S ParameterVariableDeclaration)*)?

Parameter lists can contain as many as 255 parameters, and as few as none.

Variable types identify the base type of parameters.  The type is either a keyword representing one of the built-in simple types (void, char, short, long, longlong, float, or double) or an identifier for a data structure name.  If the void type or a structured type is used, an asterisk is required to qualify the type as a pointer (cannot have void parameter type or whole structured type passed by value).

Variable names uniquely identify parameters.  The name is an identifier that has not appeared earlier in the file as a construct name, an enumerated constant block name, an enumerated constant name, or in the parameter list as another parameter variable name.

The function body must always be defined at time of function declaration; no “prototyping” is allowed.

Construct Declaration Keywords

StructKeyword ::= 'struct' | 'class'

Structure declarations can use ‘struct’ or ‘class’ interchangeably; there is no fundamental difference (all structure members are public).

BlockKeyword ::= 'block' | 'fileformatframework'

Block declarations use ‘block’ in all cases except where declaring the top-level construct, in which case, ‘fileformatframework’ should be used.

BlockTypeOrganized ::= 'organized' (S 'bitscan')?
BlockTypeUnorganized ::= 'unorganized' (S 'textual')?
BlockType ::= BlockTypeOrganized | BlockTypeUnorganized

When declaring a block, it must be immediately classified as a specific construct:  either organized block (using the 'organized' keyword) or unorganized block (using the 'unorganized' keyword).

Optionally, an organized block can be further refined into a bitscan block with the ‘bitscan’ attribute, while an unorganized block can be further refined into a text block with the ‘textual’ attribute.

Conditional Expressions

ConditionalExpression ::= ‘(‘ S? Expression S? ‘)’

A conditional expression, enclosed within parentheses, appears in various function statements.  The result of the expression must be either a scalar or pointer value; it cannot be void.

BAR does not perform short-circuit evaluation in conditional expressions.  Assume that every load in a conditional expression will be evaluated.


  See also:  [Deserialization: Critical steps] [Serialization: Critical steps] [Fundamental components]
[Common declarations] [File scope] [Structure scope] [Block scope]
[Node list scope] [Decision list scope] [Function scope] [Expressions]
[Compiler errors] [Compiler warnings]


BARfly Help Copyright © 2009 Christopher Allen