|
|
1.1 root 1: /*
2: * File: lrec.c
3: * Contents: field, mkrec
4: */
5:
6: #include "../h/rt.h"
7:
8: /*
9: * x.y - access field y of record x.
10: */
11:
12: LibDcl(field,2,".")
13: {
14: register word fnum;
15: register struct b_record *rp;
16: register struct descrip *dp;
17: extern word *ftab, *records;
18:
19: DeRef(Arg1);
20: /*
21: * x must be a record and y must be a field number.
22: */
23: if (Qual(Arg1) || Arg1.dword != D_Record)
24: runerr(107, &Arg1);
25:
26: /*
27: * Map the field number into a field number for the record x.
28: */
29: rp = (struct b_record *) BlkLoc(Arg1);
30: fnum = ftab[IntVal(Arg2) * *records + BlkLoc(rp->recdesc)->proc.recnum - 1];
31: /*
32: * If fnum < 0, x doesn't contain the specified field.
33: */
34: if (fnum < 0)
35: runerr(207, &Arg1);
36:
37: /*
38: * Return a pointer to the descriptor for the appropriate field.
39: */
40: dp = &rp->fields[fnum];
41: Arg0.dword = D_Var + ((word *)dp - (word *)rp);
42: BlkLoc(Arg0) = (union block *) dp;
43: Return;
44: }
45:
46:
47: /*
48: * mkrec - create a record.
49: */
50:
51: LibDcl(mkrec,-1,"mkrec")
52: {
53: register int i;
54: register struct b_proc *bp;
55: register struct b_record *rp;
56: extern struct b_record *alcrecd();
57:
58: /*
59: * Be sure that call is from a procedure.
60: */
61:
62: /*
63: * Ensure space for the record to be created.
64: */
65: blkreq((uword)sizeof(struct b_record) +
66: BlkLoc(Arg(0))->proc.nfields*sizeof(struct descrip));
67:
68: /*
69: * Get a pointer to the record constructor procedure and allocate
70: * a record with the appropriate number of fields.
71: */
72: bp = (struct b_proc *) BlkLoc(Arg(0));
73: rp = alcrecd((int)bp->nfields, (struct descrip *)bp);
74:
75: /*
76: * Set all fields in the new record to null value.
77: */
78: for (i = bp->nfields; i > nargs; i--)
79: rp->fields[i-1] = nulldesc;
80:
81: /*
82: * Assign each argument value to a record element and dereference it.
83: */
84: for ( ; i > 0; i--) {
85: rp->fields[i-1] = Arg(i);
86: DeRef(rp->fields[i-1]);
87: }
88:
89: ArgType(0) = D_Record;
90: Arg(0).vword.bptr = (union block *)rp;
91: Return;
92: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.