/* record-ops.c
*
* COPYRIGHT (c) 1998 Bell Labs, Lucent Technologies.
*
* Some (type unsafe) operations on records.
*/
#include "ml-base.h"
#include "ml-values.h"
#include "ml-state.h"
#include "ml-objects.h"
#include "arena-id.h"
#include "gc.h"
/* GetLen:
*
* Check that we really have a record object, and return its length.
*/
PVT int GetLen (ml_val_t r)
{
ml_val_t d;
int t;
if (! isBOXED(r))
return -1;
switch (EXTRACT_OBJC(ADDR_TO_PAGEID(BIBOP, r))) {
case OBJC_new:
d = OBJ_DESC(r);
t = GET_TAG(d);
if (t == DTAG_record)
return GET_LEN(d);
else
return -1;
case OBJC_pair: return 2;
case OBJC_record:
d = OBJ_DESC(r);
t = GET_TAG(d);
if (t == DTAG_record)
return GET_LEN(d);
else
return -1;
default:
return -1;
}
}
/* RecordConcat:
*
* Concatenate two records; returns unit if either argument is not
* a record of length at least one.
*/
ml_val_t RecordConcat (ml_state_t *msp, ml_val_t r1, ml_val_t r2)
{
int l1 = GetLen(r1);
int l2 = GetLen(r2);
if ((l1 > 0) && (l2 > 0)) {
int n = l1+l2;
int i, j;
ml_val_t *p, res;
ML_AllocWrite (msp, 0, MAKE_DESC(n, DTAG_record));
j = 1;
for (i = 0, p = PTR_MLtoC(ml_val_t, r1); i < l1; i++, j++) {
ML_AllocWrite (msp, j, p[i]);
}
for (i = 0, p = PTR_MLtoC(ml_val_t, r2); i < l2; i++, j++) {
ML_AllocWrite (msp, j, p[i]);
}
res = ML_Alloc(msp, n);
return res;
}
else {
return ML_unit;
}
} /* end of RecordConcat */
syntax highlighted by Code2HTML, v. 0.9.1