code after compilation, or using Template Haskell to inspect parts of the
code you have written). This allows the full power of Haskell for generating
a circuit. However it also creates severe limitations in the use of the
- language (you can't use case statements in Lava, since they would be
+ language (you can't use case expressions in Lava, since they would be
executed only once during circuit generation) and extra notational overhead.
We will now have a look at the existing hardware description languages,
possible in a completely reliable way yet. \cite[gill09]
\item Some things are verbose to express. Especially ForSyDe suffers
from a lot of notational overhead due to the Template Haskell approach
- used. Since conditional statements are not supported, a lot of Haskell's
+ used. Since conditional expressions are not supported, a lot of Haskell's
syntax sugar (if expressions, pattern matching, guards) cannot be used
either, leading to more verbose notation as well.
\item Polymorphism and higher order values are not supported within the
stateful functions at a time, the final state consists of nested two-tuples.
The final \hs{()} in the state originates from the fact that the \hs{return}
function has no real state, but is part of the composition. We could have left
-out the return statement (and the \hs{outb <-} part) to make \hs{foo}'s return
+out the return expression (and the \hs{outb <-} part) to make \hs{foo}'s return
value equal to \hs{funcb}'s, but this approach makes it clearer what is
happening.
is calculated as well, but only saved when the right clock has an up
transition.
-As you can see, there is some code duplication in the case statement that
+As you can see, there is some code duplication in the case expression that
selects the right clock. One of the advantages of an explicit approach like
this, is that some of this duplication can be extracted away into helper
functions. For example, we could imagine a \hs{select_clock} function, which
This is of course a very intrusive solution. Every type must become member
of this typeclass, and there is now some member in every type that is a
special don't care value. Guaranteeing the obvious don't care semantics
- also becomes harder, since every pattern match or case statement must now
+ also becomes harder, since every pattern match or case expressions must now
also take care of the don't care value (this might actually be an
advantage, since it forces designers to specify how to handle don't care
for different operations).
\stoplambda
Again, the transformation does not apply to this lambda abstraction, so we
- look at its body. For brevity, we'll put the case statement on one line from
+ look at its body. For brevity, we'll put the case expression on one line from
now on.
\startlambda
\stoptrans
\todo{Check the subscripts of this transformation}
- Note that this transformation applies to case statements with any
+ Note that this transformation applies to case expressions with any
scrutinee. If the scrutinee is a complex expression, this might result
in duplicate hardware. An extra condition to only apply this
transformation when the scrutinee is already simple (effectively
\in{section}[sec:transformation:caseremoval].
\subsubsection[sec:transformation:caseremoval]{Case removal}
- This transform removes any case statements with a single alternative and
+ This transform removes any case expression with a single alternative and
only wild binders.
- These "useless" case statements are usually leftovers from case simplification
+ These "useless" case expressions are usually leftovers from case simplification
on extractor case (see the previous example).
\starttrans
binder, even when strictness was involved. Nonetheless, the prototype
handles this binder as expected.
- Note that these case statements are less powerful than the full Haskell
- case statements. In particular, they do not support complex patterns like
+ Note that these case expressions are less powerful than the full Haskell
+ case expressions. In particular, they do not support complex patterns like
in Haskell. Only the constructor of an expression can be matched,
complex patterns are implemented using multiple nested case expressions.
- Case statements are also used for unpacking of algebraic datatypes, even
+ Case expressions are also used for unpacking of algebraic datatypes, even
when there is only a single constructor. For examples, to add the elements
of a tuple, the following Core is generated:
\emph{one} application, no more and no less.
The function result should contain exactly one state variable, which
- can be extracted using (multiple) case statements. The extracted
+ can be extracted using (multiple) case expressions. The extracted
state variable is referred to the \emph{output substate}
The type of this output substate must be identical to the type of
TODO: State & pattern matches
TODO: Separate compilation / Prelude
TODO: Add case binder removal transformation
-TODO: Remove all "statement"s
TODO: User-defined type classes (future work?)
TODO: Entity / Architecture / Component vs Function?
TODO: Expand on "representable"