1 /* Loglan82 Compiler&Interpreter
2 Copyright (C) 1981-1993 Institute of Informatics, University of Warsaw
3 Copyright (C) 1993, 1994 LITA, Pau
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 contacts: Andrzej.Salwicki@univ-pau.fr
22 LITA Departement d'Informatique
24 Avenue de l'Universite
26 tel. ++33 59923154 fax. ++33 59841696
28 =======================================================================
39 * @brief Type checking routines
43 static bool pref(word, word);
44 static bool typep0(word, word, bool, word *, word *);
45 static bool prefh(word, word);
46 static bool typef(word, word, word, word);
54 /** Determine if prot occurs in the prefix sequence of object am */
55 static bool pref(word am, word prot)
61 if (t1 != AINT && t1 != AVIRT && t1 != AREAL && t1 != FILEOBJECT) {
62 /* neither array nor file */
65 t2 = t1 + ptr->lthpreflist;
75 /** Validate qualification of object */
76 void qua(virtaddr *virt, word tp)
78 if (virt->mark != M[virt->addr + 1])
80 if (M[tp] != CLASSTYPE)
82 if (!pref(M[virt->addr], M[tp + 1]))
86 /** Determine if A in B */
87 bool inl(virtaddr *virt, word tp)
89 /* none is in everything */
90 if (virt->mark != M[virt->addr + 1])
92 else if (M[tp] != CLASSTYPE)
95 return pref(M[virt->addr], M[tp + 1]);
98 /** Determine if A is B */
99 bool is(virtaddr *virt, word tp)
101 if (virt->mark != M[virt->addr + 1] || M[tp] != CLASSTYPE)
104 return (M[M[virt->addr] + PROTNUM] == M[tp + 1]);
109 * Check correctness of an especially clumsy assignment statement
111 void typref(virtaddr *virt, word tp)
116 /* none always allowed */
117 if (virt->mark == M[virt->addr + 1]) {
118 /* am of right hand side */
120 t1 = M[t3 + PROTNUM];
121 if (t1 == AINT || t1 == AREAL || t1 == AVIRT)
123 /* right hand side type */
125 if (t2 == FILETYPE) {
126 if (t1 != FILEOBJECT)
129 else if (t2 == PURECOROUTINE || t2 == PUREPROCESS) {
130 if (t2 == PURECOROUTINE)
135 if (prototype[t1]->kind != knd)
140 if (!pref(t3, M[tp + 1]))
148 * Check correctness of a dynamic assignment
150 void typed(word ldim, word lt, word rdim, word rt, virtaddr *virt)
162 * Search the SL chain of object am to find the nearest Y such that Y in A.
163 * prot = prototype number of A
165 word loadt(word am, word prot)
169 while(!pref(am, prot)) {
170 t1 = am + M[am] + SL;
171 /* try next object in chain */
184 * Compute type of a formal parameter - see also typep (below).
186 static bool typep0(word am, word pdaddr, bool protp, word *dim, word *tp)
191 /* prototype number on input */
193 ptr = prototype[pdaddr];
195 *tp = ptr->finaltype;
197 /* type address on input */
198 *dim = M[pdaddr + 1];
201 if (M[*tp] != FORMTYPE)
204 /* SL prototype number */
210 *tp = loadt(am, t1) + M[*tp + 2];
221 * Compute type of formal parameter
223 void typep(word am, word nr, word *dim, word *tp)
225 if (!typep0(am, M[prototype[M[am + PROTNUM]]->pfdescr + nr], FALSE, dim,
232 /* Auxiliary function for heads, almost the same as pref.
235 static bool prefh(word tp, word prot)
240 ptr = prototype[M[tp + 1]];
242 t1 = t2 + ptr->lthpreflist - 1;
254 * Check compatibility of generalized types, used by heads only.
256 static bool typef(word dima, word ta, word dimb, word tb)
261 /* incompatible headers */
265 /* types different somehow */
267 /* dim must be 0 now */
274 if (t1 == PRIMITIVETYPE || t1 == FILETYPE)
277 if (t2 == PRIMITIVETYPE || t2 == FILETYPE)
280 if (t1 != PURECOROUTINE && t1 != PUREPROCESS) {
281 if (t2 == PURECOROUTINE || t2 == PUREPROCESS)
284 if (!prefh(ta, M[tb + 1])) {
285 if (!prefh(tb, M[ta + 1]))
295 /* AIL: t1 below replaced with t2, 1989.02.02 */
296 /* if (t1 == PURECOROUTINE || t1 == PUREPROCESS) */
297 if (t2 == PURECOROUTINE || t2 == PUREPROCESS) {
302 knd = prototype[M[tb + 1]]->kind;
304 if ((t1 == PURECOROUTINE && knd != COROUTINE) ||
305 (t1 == PUREPROCESS && knd != PROCESS)) {
307 if ((t1 != PURECOROUTINE) ||
309 t2 != PUREPROCESS)) {
322 * Verify the compatibility of formal/actual procedure (function) heads.
324 void heads(virtaddr *virt, word nr)
326 word i, j, fp, gp, oba, g, slen, dim, t1, t2, tp, ftv;
329 word x[MAXHDLEN + 1], y[MAXHDLEN + 1];
330 /* The two arrays declared above may be dynamically generated as objects */
331 /* upon entry to heads. In fact heads was implemented this way in the */
332 /* original LOGLAN running system on MERA-400 */
335 ptr = prototype[M[oba + PROTNUM]];
336 /* parameter description pointer */
337 fp = M[ptr->pfdescr + nr];
338 /* length of its desclist */
342 /* type value pointer */
343 ftv = oba + M[ptr->parlist + nr];
346 if (M[ftv + 1] == M[g + 1 ]) {
351 /* SL chain cut off */
354 /* prototype number of g */
359 if (ptr->kind == FUNCTION) {
363 junk = typep0(g, gp, TRUE, &dim, &tp);
364 junk = typep0(oba, fp + 2, FALSE, &t1, &t2);
366 if (typef(dim, tp, t1, t2))
369 else if (t2 != FORMPROC)
372 /* incompatible lengths */
373 if (slen != ptr->lthparlist)
376 /* oba descriptlist */
379 t2 = ptr->pfdescr - 1;
380 /* verify second order lists */
381 for (i = 1; i <= slen; i++ ) {
382 /* mark entry as empty */
386 /* first type pointer */
388 /* second type pointer */
390 /* first type ordinal */
395 if (tp == FORMTYPE) {
396 /* save pointers to formal types */
400 if (tp == PARIN || tp == PAROUT || tp == PARINOUT) {
402 /* if (typep0(oba, fp, FALSE, &dim, &tp)) */
403 if (! typep0(oba, fp, FALSE, &dim, &tp)) {
405 /* search preceding formals */
406 for (j = 1; j <= i; j++)
407 if (x[j] == M[fp + 2])
411 if (y[j] != M[gp + 2])
414 /* already defined */
416 for (j = 1; j <= i; j++ )
417 if (y [j] == M[gp + 2])
420 junk = typep0(g, gp, FALSE, &j, &ftv);
421 junk = typef(dim, tp, j, ftv);