BH (Bluespec Haskell/Classic) is a language for hardware design. The language borrows its notation, type and package system from an existing general-purpose functional programming language called Haskell [@haskell12] where those constructs have been well tested for over a decade. Unlike Haskell, BH is meant solely for hardware design--- a BH program represents a circuit. The abstract model for these circuits is a Term Rewriting System (TRS); details about using TRSs for describing circuits, and compiling these descriptions to real hardware, may be found in James Hoe's thesis [@jhoe]. BH has several restrictions and extensions relative to Haskell, arising out of this hardware focus.
This document is not meant as a tutorial on BH (separate documents exist for that purpose). Nevertheless, this document has numerous small examples to explicate BH notation.
The grammar rules in the presentation below mostly follow the usual EBNF (Extended BNF) structure. Grammar alternatives are separated by "$\mid$". Items enclosed in [ ] are optional. Items enclosed in { } can be repeated zero or more times. The last piece of notation is used sloppily; sometimes there must be at least one item, and also, the last terminal inside the { } is sometimes a separator rather than terminator.
An identifier in BH consists of a letter followed by zero or more
letters, digits, underscores and single quotes. Identifiers are case
sensitive: glurph
, gluRph
and Glurph
are three distinct
identifiers.
The case of the first letter in an identifier is very important. If the first letter is lower case, the identifier is a "variable identifier", referred to in the grammar rules as a varId. If the first letter is upper case, the identifier is a "constructor identifier", referred to in the grammar rules as a conId.
In BH, package names (packageId), type names (tycon) and value constructor names are all constructor identifiers. (Ordinary) variables, field names and type variables are all variable identifiers.
A lone underscore, "
", is treated as a special identifier--- it is
used as a "don't care" pattern or expression (more details in Sections
5.10 and
6.1).
The Standard Prelude is a predefined package that is imported implicitly into every BH package. It contains a number of useful predefined entities (types, values/functions, classes, instances, etc.). It is somewhat analogous to the combination of various ".h" files and standard libraries in C, except that in BH no special action is needed to import the prelude or to link it in. We will refer to the prelude periodically in the following sections, and there are more details in appendix 15.
In BH, there are various syntactic constructs that involve zero or more items enclosed in braces and separated by semicolons: These braces and semicolons can be omitted entirely if the components are laid out with proper indentation.
Suppose the parser discovers a missing open brace (e.g., after the
keywords where
, let
, do
and of
). Then, the indentation of the
next lexical element is remembered (and the missing open brace is
implicitly inserted before it). For each subsequent line, if it contains
only whitespace or is indented more, then it is treated as a
continuation of the current item. If it is indented the same amount, it
is treated as the beginning of the next item (i.e., a semicolon is
inserted implicitly before the item). If it is indented less, then the
list of items is considered to be complete (i.e., a closing brace is
implicitly inserted). An explicit brace is never matched against an
implicit one. Thus, while using the layout rule, if the parser
encounters an explicit open brace, then it does not resume using the
layout rule for this list of items until it has "emerged" past the
explicit corresponding closing brace (a construct nested inside this
list of items may still use the layout rule).
In a BH program, a comment is legal as whitespace, and may be
introduced in two ways. An ordinary comment is introduced by a lexical
token consisting of two or more consecutive dashes followed by a
non-symbol, and extends up to and including the end of the line. (See
Section
[sec-infix-applications] for the list of symbols.) Note: the
lexical token β>
is a legal token in BH, and since it contains three
consecutive dashes followed by a symbol, it does not begin a comment.
A nested comment is introduced by the lexeme "{-
" and extends until
the next matching "-}
", possibly spanning multiple lines. A nested
comment can itself contain another nested comment; this nesting can be
repeated to any depth.
In an ordinary comment, the character sequences "{-
" and "-}
" have
no special significance, and, in a nested comment, a sequence of dashes
has no special significance.
A concept that is pervasive in BH is the notion of a type. Every value expression in BH, even a basic value identifier, has a type, and the compiler does extensive static type checking to rule out absurd use of values (such as taking the square root of an IP address). Types are discussed in section 2.
A BH program consists of one or more packages. These outermost constructs are described in section 3. As explained later, a BH package is a linguistic namespace-management mechanism and does not have any direct correlation with any hardware module being described by the program. Hardware modules correspond to modules, a particular type of value in BH.
Within each package is a collection of top-level definitions. These are described in section 4.
Amongst the top-level definitions are value definitions (section 4.7), which constitute the actual meat of the code. Value definitions are built around expressions, which are described in section 5.