![]() |
das2C
das core C utilities (v3)
|
What a variable's values (i.e. More...
#include <das3/value.h>#include <das3/units.h>#include <das3/datum.h>#include <das3/operator.h>#include <das3/property.h>#include <das3/generator.h>

Go to the source code of this file.
Data Structures | |
| struct | das_operand |
| The form layer's currency: a snapshot of the facts a formalism may need. More... | |
Macros | |
| #define | DasForm_kindStr(P) ((P)->pVTbl->sKind) |
| The wire kind= token this form answers to. | |
| #define | DasForm_isKind(P, VT) (((P) != NULL)&&((P)->pVTbl == (VT))) |
| Is this formalism of the given kind? | |
| #define | DAS_FORM_EXT (&das_form_generic_vtbl) |
| An extended formalism unknown to das2C. | |
Enumerations | |
| enum | das_binop_stat |
| Was this pairing claimed? More... | |
Functions | |
| DAS_API size_t | das_operand_elems (const das_operand *pThis) |
| Total elements in one item run, the product of the internal extents. | |
| DAS_API const DasForm_VTbl * | das_form_lookup (const char *sKind) |
| The vtable for a wire token, or NULL on a miss. | |
What a variable's values (i.e.
collections of elements) mean to arithmetic. Corresponds to <ops kind="thing" >
ls das3/form_*.c is the inventory of known formalisms. This file, form.c, provides no default formalism at all. Most interactions with formalisms are via virtual functions; in general, formalism specific functions are often not needed. Though if you are making your own formalisms, not just serializing from an input file, you need to know the concrete type at construction. Thus the general principle:
Construction needs the concrete type, interrogations should not
DasForm_isKind() and its type objects (DAS_FORM_VEC and friends) answer "which kind is this", and they have exactly two legitimate callers:
A client asking a question must not use them. Naming the forms that happen to answer today is a trait written out by enumeration, and it rots the day a new formalism answers too: the test returns false, which is indistinguishable from a legitimate "no", so nothing complains. Ask instead
DasForm_getParam(pForm, "frame", NULL) parameters, by name the vtable behavior, by dispatch
both of which a formalism written next year answers without the client being touched.
Constructing a formalism is the other half, and it does not reduce. A client emitting a position must call new_DasFormGeoLoc() and one emitting a free vector must call new_DasFormVector(); no parameter query distinguishes them, because the difference is the algebra and not the parameter set, which geoloc merely extends. So a writer names a concrete type once, at the site where it decides what it is making.
Understanding the roles of formalisms within variables can be summarized as:
Forms compute, variables walk
A form is handed values and hands back values. It never fetches. It has no generator, no array, no index and no loop, so there is exactly one piece of code that knows how to walk external indices and it lives at the variable layer. Everything else follows from this:
When non-local math arrives (interpolation, convolution, a point spread response) the answer is not to hand forms a generator. The recipe declares a stencil, the variable gathers that window and passes it in, and the walker is still the only thing that walks. A form says what it needs; it never goes and gets it.
A form may know a peer form. So for example code in:
form_rot.c
includes:
because a rotation is defined as a thing that acts on vectors, and so rotations have to know about vectors in order to provide useful operations. The arrow never reverses – form_vector.c need not know what a rotation is. That asymmetry is what binOpLeft and binOpRight are for. They are not a fallback mechanism; they are how the better-informed partner claims a pairing no matter which side it is standing on.
| #define DasForm_isKind | ( | P, | |
| VT | |||
| ) | (((P) != NULL)&&((P)->pVTbl == (VT))) |
Is this formalism of the given kind?
This macro compares formalism virtual table addresses directly, for speed. Each formalism defines a macro for its virtual table, use those here. For example
| #define DAS_FORM_EXT (&das_form_generic_vtbl) |
An extended formalism unknown to das2C.
Attributes are carried through but no binary operations are defined, though specific applications may know how to operate on these numeric collections.
| enum das_binop_stat |
Was this pairing claimed?
Three states, not two. A DECLINE is silent and means "not mine, ask the other operand"; a REFUSE means "this pairing is mine and it is illegal", and the refusing form has already said why in terms of the actual problem. Collapsing them would turn a frame mismatch into a generic "no rule for rotation * vector", which is a worse diagnostic and very nearly a lie.
| DAS_API size_t das_operand_elems | ( | const das_operand * | pThis | ) |
Total elements in one item run, the product of the internal extents.
| DAS_API const DasForm_VTbl * das_form_lookup | ( | const char * | sKind | ) |
The vtable for a wire token, or NULL on a miss.
For identity comparisons where a form object is not wanted.