|
A small, polymorphic datatype that acts like a pointer.
Author: Matthew Hoosier
The Wrapper extension creates a simple container type that can
be used whenever indirection is needed in a BIR model. The polymorphic
type declared here can be used to contain a single element of any
(fixed) type. The wrapper itself (regardless of whether it contains a
reference or primitive type) is heap-allocated so that the object can
be passed between functions. C programmers may feel comfortable
likening a wrapper to a pointer parameter passed into a function with
the expectation of being filled. The C function signature void foo(int *fillme) would become
the BIR function function
foo(Wrapper.type<int> fillme) { ... }.
extension Wrapper for edu.ksu.cis.projects.bogor.module.wrapper.WrapperModule { // The type itself typedef type<'a>;
// Constructor. Always returns a non-null value expdef Wrapper.type<'a> create<'a>('a element);
// Accessor. Return the contained element (possibly null if 'a is // a heap type) or throws a BIR NullPointerException expdef 'a get<'a>(Wrapper.type<'a> wrapper);
// Mutator. Installs a new elements into the the given wrapper. // Raises a BIR NullPointerException if the wrapper is null. actiondef set<'a>(Wrapper.type<'a> wrapper, 'a elem); }
The following example uses a wrapper to get the return value
from a function in an indirect way:
system Test { extension Wrapper for edu.ksu.cis.projects.bogor.module.wrapper.WrapperModule { ... }
const CONSTANTS { INITIAL_VAL = -1; RESULT_VAL = 101; }
main thread MAIN() { // declare variable (initial value is null) Wrapper.type<int> container;
// allocate new wrapper instance on heap container := Wrapper.create(CONSTANTS.INITIAL_VAL);
// fill in value assert Wrapper.get(container) != CONSTANTS.RESULT_VAL; fillContainer(container); assert Wrapper.get(container) == CONSTANTS.RESULT_VAL; }
function fillContainer(Wrapper.type<int> container) { Wrapper.set(container, CONSTANTS.RESULT_VAL); } }
|