/* * File: lrec.c * Contents: field, mkrec */ #include "..\h\config.h" #include "..\h\rt.h" #include "rproto.h" /* * x.y - access field y of record x. */ LibDcl(field,2,".") { register word fnum; register struct b_record *rp; register dptr dp; extern word *ftabp, *records; #if MACINTOSH #if MPW /* #pragma unused(nargs) */ #endif /* MPW */ #endif /* MACINTOSH */ if (DeRef(Arg1) == Error) RunErr(0, NULL); /* * Arg1 must be a record and Arg2 must be a field number. */ if (Arg1.dword != D_Record) RunErr(107, &Arg1); /* * Map the field number into a field number for the record x. */ rp = (struct b_record *) BlkLoc(Arg1); fnum = ftabp[IntVal(Arg2) * *records + rp->recdesc->proc.recnum - 1]; /* * If fnum < 0, x doesn't contain the specified field. */ if (fnum < 0) RunErr(207, &Arg1); /* * Return a pointer to the descriptor for the appropriate field. */ dp = &rp->fields[fnum]; Arg0.dword = D_Var + ((word *)dp - (word *)rp); VarLoc(Arg0) = (dptr)rp; Return; } /* * mkrec - create a record. */ LibDcl(mkrec,-1,"mkrec") { register int i; register struct b_proc *bp; register struct b_record *rp; /* * Be sure that call is from a procedure. */ /* * Ensure space for the record to be created. */ if (blkreq((uword)sizeof(struct b_record) + BlkLoc(Arg(0))->proc.nfields*sizeof(struct descrip)) == Error) RunErr(0, NULL); /* * Get a pointer to the record constructor procedure and allocate * a record with the appropriate number of fields. */ bp = (struct b_proc *) BlkLoc(Arg(0)); rp = alcrecd((int)bp->nfields, (union block **)bp); rp->id = (bp->recid)++; /* * Set all fields in the new record to null value. */ for (i = (int)bp->nfields; i > nargs; i--) rp->fields[i-1] = nulldesc; /* * Assign each argument value to a record element and dereference it. */ for ( ; i > 0; i--) { rp->fields[i-1] = Arg(i); if (DeRef(rp->fields[i-1]) == Error) RunErr(0, NULL); } ArgType(0) = D_Record; Arg(0).vword.bptr = (union block *)rp; Return; }