/[ascend]/trunk/base/generic/compiler/typelint.c
ViewVC logotype

Contents of /trunk/base/generic/compiler/typelint.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 222 - (show annotations) (download) (as text)
Fri Jan 27 04:23:20 2006 UTC (14 years, 10 months ago) by johnpye
File MIME type: text/x-csrc
File size: 29044 byte(s)
Updating for Jerry's new error_reporter syntax, bug #179
1 /*
2 * Type definition lint module
3 * by Ben Allan
4 * Created: 9/16/96
5 * Version: $Revision: 1.48 $
6 * Version control file: $RCSfile: typelint.c,v $
7 * Date last modified: $Date: 1998/07/23 13:57:59 $
8 * Last modified by: $Author: ballan $
9 *
10 * This file is part of the Ascend Language Interpreter.
11 *
12 * Copyright (C) 1996 Benjamin Andrew Allan
13 *
14 * The Ascend Language Interpreter is free software; you can redistribute
15 * it and/or modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * The Ascend Language Interpreter is distributed in hope that it will be
20 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with the program; if not, write to the Free Software Foundation,
26 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
27 * COPYING.
28 */
29
30 #include <math.h>
31 #include <ctype.h>
32 #include "utilities/ascConfig.h"
33 #include "general/list.h"
34 #include "general/dstring.h"
35 #include "compiler/compiler.h"
36 #include "compiler/fractions.h"
37 #include "compiler/dimen.h"
38 #include "compiler/functype.h"
39 #include "compiler/types.h"
40 #include "compiler/stattypes.h"
41 #include "compiler/statement.h"
42 #include "compiler/slist.h"
43 #include "compiler/statio.h"
44 #include "compiler/symtab.h"
45 #include "compiler/module.h"
46 #include "compiler/library.h"
47 #include "compiler/child.h"
48 #include "compiler/vlist.h"
49 #include "compiler/vlistio.h"
50 #include "compiler/name.h"
51 #include "compiler/nameio.h"
52 #include "compiler/when.h"
53 #include "compiler/select.h"
54 #include "compiler/switch.h"
55 #include "compiler/sets.h"
56 #include "compiler/exprs.h"
57 #include "compiler/forvars.h"
58 #include "compiler/bit.h"
59 #include "compiler/syntax.h"
60 #include "compiler/setinstval.h"
61 #include "compiler/childinfo.h"
62 #include "compiler/instance.h"
63 #include "compiler/evaluate.h"
64 #include "compiler/proc.h"
65 #include "compiler/type_desc.h"
66 #include "compiler/typedef.h"
67 #include "compiler/typelint.h"
68
69 #ifndef lint
70 static CONST char TypeLintRCSid[] ="$Id: typelint.c,v 1.48 1998/07/23 13:57:59 ballan Exp $";
71 #endif
72
73 struct errormessage {
74 const char *str;
75 int level;
76 };
77
78 /*
79 * Messages with a level < g_parser_warnings do not get printed.
80 * g_parser_warnings ==
81 * 2 => suppress style warnings.
82 * 3 => suppress warnings
83 * 4 => suppress errors
84 * 5 => suppress fatality explanations.
85 * The effect is obviously cumulative.
86 */
87 int g_parser_warnings = 0;
88
89 static struct errormessage g_DefinitionErrorMessages[] = {
90 /*0*/{"No error",0},
91 {"Name of a part has been reused (failure)",3},
92 {"Name of a part has incorrect structure (failure)",3},
93 {"Name of a part/variable that does not exist",3},
94 {"Name of undefined function (failure)",3},
95 /*5*/{"Illegal right hand side type in ALIASES",3},
96 {"Illegal expression encountered (parser, lint or memory error, failure)",3},
97 {"Illegal parameter type for WILL_BE (failure)",3},
98 {"Statement not allowed in context (failure)",3},
99 {"Illegal parameter (more than 1 name per IS_A/WILL_BE - failure)",3},
100 /*10*/{"Illegal parameter reduction (LHS not defined by ancestral IS_A)",3},
101 {"Illegal parameter reduction (reassigning part - failure)",3},
102 {"Illegal parameter type for IS_A (punting). Try WILL_BE?",3},
103 {"Unverifiable name or illegal type in a relation",2},
104 {"Unverifiable name or illegal type in RHS of :==",2},
105 /*15*/{"Incorrect number of arguments passed to parameterized type. (failure)",3},
106 {"Incorrect argument passed to parameterized type. (failure)",3},
107 {"Statement possibly modifies type of parameter. (failure)",3},
108 {"Unverifiable LHS of :==, possibly undefined part or non-constant type",2},
109 {"Unverifiable LHS of :=, possibly undefined part or non-variable type",2},
110 /*20*/{"Illegal type or undefined name in RHS of := (failure)",3},
111 {"Object with incompatible type specified in refinement",3},
112 {"FOR loop index shadows previous declaration (failure)",3},
113 {"Unverifiable name or illegal type in ARE_ALIKE",2},
114 {"Illegal parameterized type in ARE_ALIKE",3},
115 /*25*/{"Illegal set of array elements in ARE_ALIKE",3},
116 {"WILL(_NOT)_BE_THE_SAME contains incorrect names.",3},
117 {"WILL_BE in WHERE clause not yet implemented.",3},
118 {"Mismatched alias array subscript and set name in ALIASES-ISA.",3},
119 {"Unverifiable FOR loop set, possibly undefined part or non-constant type", 2},
120 /*30*/{"SELECT statements are not allowed inside a FOR loop",3},
121 {"Illegal relation -- too many relational operators (<,>,=,<=,>=,<>)",3},
122 {"Illegal logical relation -- too many equality operators (!=,==)",3},
123 {"Illegal USE found outside WHEN statement",3},
124 {"Illegal FOR used in a method must be FOR/DO",3},
125 /*35*/{"Illegal FOR used in body must be FOR/CREATE",3},
126 {"Illegal ATOM attribute or relation type in ARE_THE_SAME",3},
127 {":= used outside METHOD makes models hard to debug or reuse",1},
128 {"Illegal BREAK used outside loop or SWITCH.",3},
129 {"Illegal CONTINUE used outside loop.",3},
130 /*40*/{"Illegal FALL_THROUGH used outside SWITCH.",3},
131 {"Incorrect nested argument definition for MODEL. (failure)",3},
132 {"Indexed relation has incorrect subscripts. (failure)",3},
133 {"Illegal FOR used in WHERE statements must be FOR/CHECK",3},
134 {"Illegal FOR used in parameter definitions must be FOR/EXPECT",3},
135 /*45*/{"Miscellaneous style",1},
136 {"Miscellaneous warning",2},
137 {"Miscellaneous error",3},
138 {"Unknown error encountered in statement",5}
139 };
140
141 void TypeLintErrorAuxillary(FILE *f, char *str, enum typelinterr err,
142 int uselabel)
143 {
144 assert(f!=NULL);
145 assert(str!=NULL);
146 if (g_DefinitionErrorMessages[err].level < g_parser_warnings) {
147 /* no element of gDEM should have .level == 0 */
148 return;
149 }
150 if (uselabel) {
151 FPRINTF(f,"%s%s",StatioLabel(g_DefinitionErrorMessages[err].level),str);
152 } else {
153 FPRINTF(f,"%s",str);
154 }
155 }
156
157 void TypeLintError(FILE *f, CONST struct Statement *stat,enum typelinterr err)
158 {
159 assert(f!=NULL);
160 assert(stat!=NULL);
161 if (g_DefinitionErrorMessages[err].level < g_parser_warnings) {
162 /* no element of gDEM should have .level == 0 */
163 return;
164 }
165 WSSM(f,stat,g_DefinitionErrorMessages[err].str,
166 g_DefinitionErrorMessages[err].level);
167 }
168
169 void TypeLintName(FILE *f, CONST struct Name *n, char *m)
170 {
171 TypeLintNameMsg(f,n,m,0);
172 }
173
174 void TypeLintNameMsg(FILE *f, CONST struct Name *n, char *m,int level)
175 {
176 assert(f!=NULL);
177 assert(n!=NULL);
178 assert(m!=NULL);
179 if (level > 0 && level < g_parser_warnings) {
180 return;
181 }
182 switch(level){
183 case 2:
184 ERROR_REPORTER_START_NOLINE(ASC_PROG_WARNING);
185 break;
186 case 3:
187 ERROR_REPORTER_START_NOLINE(ASC_PROG_ERROR);
188 break;
189 case 4:
190 ERROR_REPORTER_START_NOLINE(ASC_PROG_FATAL);
191 break;
192 default:
193 ERROR_REPORTER_START_NOLINE(ASC_PROG_NOTE);
194 }
195 FPRINTF(f," %s",m);
196 WriteName(f,n);
197 FPRINTF(f,"\n");
198 error_reporter_end_flush();
199 }
200
201 void TypeLintNameNode(FILE *f, CONST struct Name *n, char *m)
202 {
203 assert(f!=NULL);
204 assert(n!=NULL);
205 assert(m!=NULL);
206 FPRINTF(f,"%s",m);
207 WriteNameNode(f,n);
208 FPRINTF(f,"\n");
209 }
210
211 void TypeLintNameNodeMsg(FILE*f, CONST struct Name *n, char *m,int level)
212 {
213 assert(f!=NULL);
214 assert(n!=NULL);
215 assert(m!=NULL);
216 if (level > 0 && level < g_parser_warnings) {
217 return;
218 }
219 if (level >0 && level <5) {
220 FPRINTF(f,"%s",StatioLabel(level));
221 }
222 FPRINTF(f," %s",m);
223 WriteNameNode(f,n);
224 FPRINTF(f,"\n");
225 }
226
227 /*
228 * Returns position of first compound name in list
229 * if a CompoundName (e.g. a.b) is found in the
230 * list. Array names are simple e.g. a[i][j],
231 * but compound names include names like a[i][j].b.
232 * Returns -1 OTHERWISE.
233 */
234 static
235 int CompoundNameInList(CONST struct VariableList *vl)
236 {
237 int rval = 0;
238 while (vl != NULL) {
239 if (NameCompound(NamePointer(vl))) {
240 return rval;
241 }
242 vl = NextVariableNode(vl);
243 rval++;
244 }
245 return -1;
246 }
247
248 /*
249 * pulls the single name element out of the last set name (subscript)
250 * in the alias array name of the ALIASES-IS_A statement.
251 */
252 static
253 CONST struct Name *ExtractARRName(CONST struct Statement *s)
254 {
255 CONST struct Name *n;
256 CONST struct Set *sn;
257 CONST struct Expr *ex;
258 int len;
259
260 assert(s!=NULL);
261 assert(StatementType(s)==ARR);
262
263 /* get name from var. */
264 n = NamePointer(ArrayStatAvlNames(s));
265 len = NameLength(n);
266 if (len < 2) {
267 return NULL;
268 }
269 /* get last subscript in name */
270 while (len > 1) {
271 len--;
272 n = NextName(n);
273 }
274 /* must be subscript */
275 if (NameId(n)!=0) {
276 return NULL;
277 }
278 sn = NameSetPtr(n);
279 /* must be single set, not range */
280 if (SetType(sn)!=0) {
281 return NULL;
282 }
283 ex = GetSingleExpr(sn);
284 /* must be name of var we're to IS_A elsewhere */
285 if (ExprListLength(ex) != 1 || ExprType(ex) !=e_var) {
286 return NULL;
287 }
288 return ExprName(ex);
289 }
290
291 static int g_tlibs_depth=0;
292 /* counter to avoid redundant spew */
293 enum typelinterr TypeLintIllegalBodyStats(FILE *fp,
294 symchar *name,
295 CONST struct StatementList *sl,
296 unsigned int context)
297 {
298 unsigned long c,len;
299 struct gl_list_t *gl;
300 struct Statement *s;
301 struct TypeDescription *d;
302 enum typelinterr rval = DEF_OKAY, tmperr;
303 struct SelectList *selcase;
304 struct WhenList *wcase;
305 struct StatementList *slint;
306
307 g_tlibs_depth++;
308 assert(name !=NULL);
309 len = StatementListLength(sl);
310 if (len == 0L) {
311 g_tlibs_depth--;
312 return rval;
313 }
314 gl = GetList(sl);
315 for(c=1; c<=len; c++) {
316 s = (struct Statement *)gl_fetch(gl,c);
317 switch(StatementType(s)) {
318 case ISA:
319 d = FindType(GetStatType(s));
320 if (GetBaseType(d)== model_type || GetBaseType(d) == patch_type) {
321 /* check arg list length. can't do types until after. */
322 if (GetModelParameterCount(d) != SetLength(GetStatTypeArgs(s))) {
323 if (TLINT_ERROR) {
324 FPRINTF(fp,"%sType %s needs %u arguments. Got %lu.\n",
325 StatioLabel(3),
326 SCP(GetStatType(s)),
327 GetModelParameterCount(d),
328 SetLength(GetStatTypeArgs(s)));
329 }
330 rval = DEF_ARGNUM_INCORRECT;
331 TypeLintError(fp,s,rval);
332 break;
333 }
334 }
335 /* fall through */
336 case ALIASES:
337 /* check simple name */
338 if (CompoundNameInList(GetStatVarList(s)) != -1) {
339 if (TLINT_ERROR) {
340 FPRINTF(fp,
341 "%sCannot create parts in another object with IS_A/ALIASES.\n",
342 StatioLabel(3));
343 FPRINTF(fp,"%sName %d is incorrect.\n",
344 StatioLabel(3),
345 CompoundNameInList(GetStatVarList(s)));
346 }
347 rval = DEF_NAME_INCORRECT;
348 TypeLintError(fp,s,rval);
349 }
350 break;
351 case ARR:
352 /* like ALIASES, only different. */
353 /* assumptions about the parser: the avlname and setname varlists
354 * will only have 1 name pointer in them, as the parser stops
355 * longer lists.
356 */
357 /* check simple names */
358 if (CompoundNameInList(ArrayStatAvlNames(s)) != -1) {
359 if (TLINT_ERROR) {
360 FPRINTF(fp,"%sCannot create parts in another object with ALIASES.\n",
361 StatioLabel(3));
362 }
363 rval = DEF_NAME_INCORRECT;
364 TypeLintError(fp,s,rval);
365 }
366 if (CompoundNameInList(ArrayStatSetName(s)) != -1) {
367 if (TLINT_ERROR) {
368 FPRINTF(fp,"%sCannot create parts in another object with IS_A.\n",
369 StatioLabel(3));
370 }
371 rval = DEF_NAME_INCORRECT;
372 TypeLintError(fp,s,rval);
373 }
374 if (CompareNames(NamePointer(ArrayStatSetName(s)),ExtractARRName(s))) {
375 if (TLINT_ERROR) {
376 FPRINTF(fp,"%sName of set defined with IS_A ",StatioLabel(3));
377 WriteVariableList(fp,ArrayStatSetName(s));
378 FPRINTF(fp,"\n must match last subscript of ALIASES-ISA LHS.\n");
379 }
380 rval = DEF_ARR_INCORRECT;
381 TypeLintError(fp,s,rval);
382 }
383 break;
384 case REL:
385 /* check simple name */
386 if (NameCompound(RelationStatName(s)) != 0) {
387 if (TLINT_ERROR) {
388 FPRINTF(fp,"%sCannot create relations in another object.\n",
389 StatioLabel(3));
390 }
391 rval = DEF_NAME_INCORRECT;
392 TypeLintError(fp,s,rval);
393 }
394 if (NumberOfRelOps(RelationStatExpr(s)) > 1) {
395 rval = DEF_TOOMANY_RELOP;
396 TypeLintError(fp,s,rval);
397 }
398 break;
399 case LOGREL:
400 /* check simple name */
401 if (NameCompound(LogicalRelStatName(s)) != 0) {
402 if (TLINT_ERROR) {
403 FPRINTF(fp,"%sCannot create logical relations in another object.\n",
404 StatioLabel(3));
405 }
406 rval = DEF_NAME_INCORRECT;
407 TypeLintError(fp,s,rval);
408 }
409 if (NumberOfRelOps(LogicalRelStatExpr(s)) > 1) {
410 rval = DEF_TOOMANY_LOGOP;
411 TypeLintError(fp,s,rval);
412 }
413 break;
414 case IRT:
415 d = FindType(GetStatType(s));
416 if (GetBaseType(d)== model_type || GetBaseType(d) == patch_type) {
417 /* check arg list length. can't do types until after. */
418 if (GetModelParameterCount(d) != SetLength(GetStatTypeArgs(s))) {
419 if (TLINT_ERROR) {
420 FPRINTF(fp,"%sType %s needs %u arguments. Got %lu.\n",
421 StatioLabel(3),
422 SCP(GetStatType(s)),
423 GetModelParameterCount(d),
424 SetLength(GetStatTypeArgs(s)));
425 }
426 rval = DEF_ARGNUM_INCORRECT;
427 TypeLintError(fp,s,rval);
428 break;
429 }
430 }
431 break;
432 case ATS:
433 break;
434 case AA:
435 if (TLINT_STYLE) {
436 FPRINTF(fp,"%sType \"%s\" contains AA:\n",
437 StatioLabel(1),SCP(name));
438 WriteStatement(fp,s,2);
439 }
440 break;
441 case FOR:
442 if (ForContainsSelect(s)) {
443 rval = DEF_ILLEGAL_SELECT;
444 TypeLintError(fp,s,rval);
445 }
446 if (ForLoopKind(s) != fk_create) {
447 rval = DEF_FOR_NOTBODY; /* err fatal to type */
448 TypeLintError(fp,s,rval);
449 } else {
450 tmperr = TypeLintIllegalBodyStats(fp,name,ForStatStmts(s),
451 (context | context_FOR));
452 if (tmperr != DEF_OKAY) {
453 /* don't want DEF_OKAY to wipe out rval if badness already found.
454 */
455 rval = tmperr;
456 }
457 }
458 break;
459 case ASGN:
460 TypeLintError(fp,s,DEF_STAT_BODYASGN);
461 TypeLintErrorAuxillary(fp,
462 " Move default assignments to METHOD default_self.\n",
463 DEF_STAT_BODYASGN,FALSE);
464 break;
465 case CASGN:
466 break;
467 case FNAME:
468 if ((context & context_WHEN) == 0) {
469 rval = DEF_USE_NOTWHEN;
470 TypeLintError(fp,s,rval);
471 if ((context & context_SELECT) != 0) {
472 FPRINTF(fp," Perhaps the surrounding SELECT should be WHEN?\n");
473 }
474 }
475 break;
476 case WHEN:
477 /* check simple name */
478 /* vicente, what's up with this? we can name whens? */
479 if (NameCompound(WhenStatName(s)) != 0) {
480 FPRINTF(fp," Cannot create whens in another object.\n");
481 rval = DEF_NAME_INCORRECT;
482 TypeLintError(fp,s,rval);
483 }
484 wcase = WhenStatCases(s);
485 while ( wcase!=NULL ) {
486 slint = WhenStatementList(wcase);
487 tmperr = TypeLintIllegalBodyStats(fp,name,slint,
488 (context | context_WHEN));
489 if (tmperr != DEF_OKAY) {
490 rval = tmperr;
491 }
492 wcase = NextWhenCase(wcase);
493 }
494 break;
495 case SELECT:
496 selcase = SelectStatCases(s);
497 while ( selcase!=NULL ) {
498 slint = SelectStatementList(selcase);
499 tmperr = TypeLintIllegalBodyStats(fp,name,slint,
500 (context | context_SELECT));
501 if (tmperr != DEF_OKAY) {
502 rval = tmperr;
503 }
504 selcase = NextSelectCase(selcase);
505 }
506 break;
507 case EXT:
508 if (ExternalStatMode(s) == 0) {
509 Asc_StatErrMsg_NotAllowedDeclarative(fp,s);
510 rval = DEF_STAT_MISLOCATED;
511 }
512 break;
513 case REF:
514 break;
515 case COND:
516 tmperr = TypeLintIllegalBodyStats(fp,name,CondStatList(s),
517 (context | context_COND));
518 if (tmperr != DEF_OKAY) {
519 rval = tmperr;
520 }
521 break;
522 /* Stuff illegal in body */
523 case SWITCH:
524 TypeLintError(fp,s,DEF_STAT_MISLOCATED);
525 rval = DEF_STAT_MISLOCATED;
526 FPRINTF(fp," Perhaps SWITCH should be WHEN or SELECT?\n");
527 break;
528 case FLOW: /* fallthrough */
529 case WHILE:
530 TypeLintError(fp,s,DEF_STAT_MISLOCATED);
531 rval = DEF_STAT_MISLOCATED;
532 FPRINTF(fp," Flow controls are allowed only in methods.\n");
533 break;
534 case IF:
535 TypeLintError(fp,s,DEF_STAT_MISLOCATED);
536 rval = DEF_STAT_MISLOCATED;
537 FPRINTF(fp," Perhaps IF should be WHEN or SELECT?\n");
538 break;
539 case RUN:
540 case CALL:
541 case WILLBE:
542 case WBTS:
543 case WNBTS:
544 default:
545 TypeLintError(fp,s,DEF_STAT_MISLOCATED);
546 rval = DEF_STAT_MISLOCATED;
547 }
548 }
549 if (rval != DEF_OKAY && g_tlibs_depth < 2 /* at top */) {
550 FPRINTF(fp," Errors detected in body statements of %s\n",
551 SCP(name));
552 }
553 g_tlibs_depth--;
554 return rval;
555 }
556
557 enum typelinterr TypeLintIllegalParamStats(FILE * fp,
558 symchar *name,
559 CONST struct StatementList *sl)
560 {
561 unsigned long c,len;
562 struct gl_list_t *gl;
563 struct Statement *s;
564 enum typelinterr rval = DEF_OKAY;
565 symchar *tid;
566 CONST struct TypeDescription *t;
567
568 assert(name !=NULL);
569 len = StatementListLength(sl);
570 if (len == 0L) {
571 return rval;
572 }
573 gl = GetList(sl);
574 for(c=1; c<=len;c++) {
575 s = (struct Statement *)gl_fetch(gl,c);
576 switch(StatementType(s)) {
577 case WILLBE:
578 /* check rhs for bad type here */
579 tid = GetStatType(s);
580 t = FindType(tid);
581 switch (GetBaseType(t)) {
582 case relation_type:
583 case logrel_type:
584 case when_type:
585 rval = DEF_ILLEGAL_PARAM;
586 TypeLintError(fp,s,rval);
587 break;
588 case model_type:
589 case patch_type:
590 /* check arg list length. can't do types until after. */
591 if ( SetLength(GetStatTypeArgs(s)) != 0L) {
592 if (TLINT_ERROR) {
593 FPRINTF(fp,
594 "%sArguments defined with WILL_BE cannot " /* no comma */
595 "have arguments. Got %lu.\n",
596 StatioLabel(3),
597 SetLength(GetStatTypeArgs(s)));
598 FPRINTF(fp, "%sYou may want to use WILL_BE_THE_SAME instead.\n",
599 StatioLabel(2));
600 }
601 rval = DEF_ARGDEF_INCORRECT;
602 TypeLintError(fp,s,rval);
603 }
604 break;
605 default:
606 break;
607 }
608 if (VariableListLength(GetStatVarList(s)) > 1L) {
609 rval = DEF_MULTI_PARAM;
610 TypeLintError(fp,s,rval);
611 break; /* no point complaining twice */
612 }
613 /* check simple names */
614 if (CompoundNameInList(GetStatVarList(s)) != -1) {
615 if (TLINT_ERROR) {
616 FPRINTF(fp,"%sCannot use . in defining MODEL arguments.\n",
617 StatioLabel(3));
618 }
619 rval = DEF_NAME_INCORRECT;
620 TypeLintError(fp,s,rval);
621 }
622 break;
623 case ISA:
624 /* check rhs for bad type here */
625 tid = GetStatType(s);
626 t = FindType(tid);
627 if (BaseTypeIsSet(t)==0 && BaseTypeIsConstant(t)==0) {
628 rval = DEF_ILLEGAL_VALPAR;
629 TypeLintError(fp,s,rval);
630 break; /* no point complaining twice */
631 }
632 if (VariableListLength(GetStatVarList(s)) > 1L) {
633 rval = DEF_MULTI_PARAM;
634 TypeLintError(fp,s,rval);
635 break; /* no point complaining twice */
636 }
637 if (CompoundNameInList(GetStatVarList(s)) != -1) {
638 if (TLINT_ERROR) {
639 FPRINTF(fp,"%sCannot create parts in another object with IS_A.\n",
640 StatioLabel(3));
641 FPRINTF(fp," Name %d is incorrect.\n",
642 CompoundNameInList(GetStatVarList(s)));
643 }
644 rval = DEF_NAME_INCORRECT;
645 TypeLintError(fp,s,rval);
646 }
647 break;
648 case ALIASES: /* huge fallthrough */
649 case ARR:
650 case IRT:
651 case ATS:
652 case WBTS:
653 case WNBTS:
654 case AA:
655 case FOR: /* eventually for legal and fk_expect required */
656 case REL:
657 case LOGREL:
658 case ASGN:
659 case CASGN:
660 case WHEN:
661 case FNAME:
662 case SELECT:
663 case SWITCH:
664 case EXT:
665 case REF:
666 case COND:
667 case RUN:
668 case CALL:
669 case FLOW:
670 case WHILE:
671 case IF:
672 default:
673 TypeLintError(fp,s,DEF_STAT_MISLOCATED);
674 rval = DEF_STAT_MISLOCATED;
675 }
676 }
677 if (rval != DEF_OKAY) {
678 FPRINTF(fp," Errors detected in argument definitions of %s\n",SCP(name));
679 }
680 return rval;
681 }
682
683 /* could stand to be a lot more rigorous */
684 enum typelinterr
685 TypeLintIllegalWhereStats(FILE * fp,
686 symchar *name,
687 CONST struct StatementList *sl)
688 {
689 unsigned long c,len;
690 struct gl_list_t *gl;
691 struct Statement *s;
692 enum typelinterr rval = DEF_OKAY, tmperr;
693
694 assert(name !=NULL);
695 len = StatementListLength(sl);
696 if (len == 0L) {
697 return rval;
698 }
699 gl = GetList(sl);
700 for(c=1; c<=len;c++) {
701 s = (struct Statement *)gl_fetch(gl,c);
702 switch(StatementType(s)) {
703 case FOR:
704 if (ForLoopKind(s) != fk_check) {
705 rval = DEF_FOR_NOTCHECK;
706 TypeLintError(fp,s,rval);
707 } else {
708 tmperr = TypeLintIllegalWhereStats(fp,name,ForStatStmts(s));
709 if (tmperr != DEF_OKAY) {
710 rval = tmperr;
711 }
712 }
713 break;
714 case WBTS:
715 case WNBTS:
716 case LOGREL:
717 case REL:
718 break;
719 case CASGN:
720 case ALIASES:
721 case ARR:
722 case ISA:
723 case IRT:
724 case ATS:
725 case AA:
726 case ASGN:
727 case WHEN:
728 case FNAME:
729 case SELECT:
730 case SWITCH:
731 case EXT:
732 case REF:
733 case COND:
734 case RUN:
735 case CALL:
736 case IF:
737 case FLOW:
738 case WHILE:
739 case WILLBE:
740 default:
741 TypeLintError(fp,s,DEF_STAT_MISLOCATED);
742 rval = DEF_STAT_MISLOCATED;
743 }
744 }
745 if (rval != DEF_OKAY) {
746 FPRINTF(fp," Errors detected in WHERE statements of %s\n",SCP(name));
747 }
748 return rval;
749 }
750
751 enum typelinterr
752 TypeLintIllegalReductionStats(FILE * fp,
753 symchar *name,
754 CONST struct StatementList *sl)
755 {
756 unsigned long c,len;
757 struct gl_list_t *gl;
758 struct Statement *s;
759 enum typelinterr rval = DEF_OKAY;
760
761 assert(name !=NULL);
762 len = StatementListLength(sl);
763 if (len == 0L) {
764 return rval;
765 }
766 gl = GetList(sl);
767 for(c=1; c<=len;c++) {
768 s = (struct Statement *)gl_fetch(gl,c);
769 switch(StatementType(s)) {
770 case CASGN:
771 if (NameCompound(AssignStatVar(s)) != 0) {
772 if (TLINT_ERROR) {
773 FPRINTF(fp,"%sCannot assign parts in an object being passed in.\n",
774 StatioLabel(3));
775 }
776 rval = DEF_NAME_INCORRECT;
777 TypeLintError(fp,s,rval);
778 }
779 break;
780 case ALIASES:
781 case ARR:
782 case ISA:
783 case IRT:
784 case ATS:
785 case WBTS:
786 case WNBTS:
787 case AA:
788 case FOR: /* probably should be legal now and require fk_create */
789 case REL:
790 case LOGREL:
791 case ASGN:
792 case WHEN:
793 case FNAME:
794 case SELECT:
795 case SWITCH:
796 case EXT:
797 case REF:
798 case COND:
799 case RUN:
800 case CALL:
801 case IF:
802 case FLOW:
803 case WHILE:
804 case WILLBE:
805 default:
806 TypeLintError(fp,s,DEF_STAT_MISLOCATED);
807 rval = DEF_STAT_MISLOCATED;
808 }
809 }
810 if (rval != DEF_OKAY) {
811 FPRINTF(fp," Errors detected in parameter assignments of %s\n",SCP(name));
812 }
813 return rval;
814 }
815
816 static
817 enum typelinterr
818 TypeLintIllegalMethodStatList(FILE *fp,
819 symchar *name, symchar *pname,
820 struct StatementList *sl,
821 unsigned int context)
822 {
823 unsigned long c,len;
824 struct gl_list_t *gl;
825 struct Statement *s;
826 struct SwitchList *sw;
827 struct StatementList *sublist;
828 enum typelinterr rval = DEF_OKAY, tmperr;
829
830 if (sl == NULL) {
831 return rval;
832 }
833 len = StatementListLength(sl);
834 gl = GetList(sl);
835 for(c=1; c<=len;c++) {
836 s = (struct Statement *)gl_fetch(gl,c);
837 switch(StatementType(s)) {
838 case CASGN:
839 case ALIASES:
840 case ARR:
841 case ISA:
842 case IRT:
843 case ATS:
844 case WBTS:
845 case WNBTS:
846 case AA:
847 case REF:
848 case COND:
849 case WILLBE:
850 case FNAME:
851 Asc_StatErrMsg_NotAllowedMethod(fp,s);
852 rval = DEF_STAT_MISLOCATED;
853 break;
854 case REL:
855 case LOGREL:
856 Asc_StatErrMsg_NotAllowedMethod(fp,s);
857 rval = DEF_STAT_MISLOCATED;
858 FPRINTF(stderr," Perhaps = or == should be := ?\n");
859 break;
860 case WHEN:
861 Asc_StatErrMsg_NotAllowedMethod(fp,s);
862 rval = DEF_STAT_MISLOCATED;
863 FPRINTF(stderr," Perhaps WHEN should be SWITCH?\n");
864 break;
865 case SELECT:
866 Asc_StatErrMsg_NotAllowedMethod(fp,s);
867 rval = DEF_STAT_MISLOCATED;
868 FPRINTF(stderr," Perhaps SELECT should be SWITCH?\n");
869 break;
870 case FOR:
871 if (ForLoopKind(s) != fk_do) {
872 rval = DEF_FOR_NOTMETH;
873 TypeLintError(fp,s,rval);
874 } else {
875 tmperr = TypeLintIllegalMethodStatList(fp,name,pname,ForStatStmts(s),
876 (context | context_FOR));
877 if (tmperr != DEF_OKAY) {
878 rval = tmperr;
879 }
880 }
881 break;
882 case EXT:
883 if (ExternalStatMode(s) != 0) {
884 Asc_StatErrMsg_NotAllowedMethod(fp,s);
885 rval = DEF_STAT_MISLOCATED;
886 }
887 break;
888 case ASGN:
889 case RUN:
890 case FIX:
891 case CALL:
892 break;
893 case WHILE:
894 if (WhileStatBlock(s) != NULL) {
895 tmperr = TypeLintIllegalMethodStatList(fp,name,pname,WhileStatBlock(s),
896 (context | context_WHILE));
897 if (tmperr != DEF_OKAY) {
898 rval = tmperr;
899 break;
900 }
901 }
902 break;
903 case ASSERT:
904 /* no sublists for TEST */
905 break;
906
907 case IF:
908 if (IfStatThen(s) != NULL) {
909 tmperr = TypeLintIllegalMethodStatList(fp,name,pname,IfStatThen(s),
910 (context | context_IF));
911 if (tmperr != DEF_OKAY) {
912 rval = tmperr;
913 break;
914 }
915 }
916 if (IfStatElse(s) != NULL){
917 tmperr = TypeLintIllegalMethodStatList(fp,name,pname,IfStatElse(s),
918 (context | context_IF));
919 if (tmperr != DEF_OKAY) {
920 rval = tmperr;
921 }
922 }
923 break;
924 case SWITCH:
925 sw = SwitchStatCases(s);
926 while (sw!=NULL) {
927 sublist = SwitchStatementList(sw);
928 if (sublist!=NULL) {
929 tmperr = TypeLintIllegalMethodStatList(fp,name,pname,sublist,
930 (context | context_SWITCH));
931 if (tmperr != DEF_OKAY) {
932 rval = tmperr;
933 break;
934 }
935 }
936 sw = NextSwitchCase(sw);
937 }
938 break;
939 case FLOW:
940 switch (FlowStatControl(s)) {
941 case fc_break:
942 if ((context & (context_FOR | context_SWITCH | context_WHILE))==0) {
943 rval = DEF_ILLEGAL_BREAK;
944 TypeLintError(fp,s,rval);
945 }
946 break;
947 case fc_continue:
948 if ((context & (context_FOR | context_WHILE))==0) {
949 rval = DEF_ILLEGAL_CONTINUE;
950 TypeLintError(fp,s,rval);
951 }
952 break;
953 case fc_fallthru:
954 if ((context & context_SWITCH)==0) {
955 rval = DEF_ILLEGAL_FALLTHRU;
956 TypeLintError(fp,s,rval);
957 }
958 break;
959 case fc_return:
960 case fc_stop:
961 break;
962 }
963 break;
964 default:
965 rval = DEF_UNKNOWN_ERR;
966 TypeLintError(fp,s,rval);
967 break;
968 }
969 }
970 if (rval != DEF_OKAY) {
971 FPRINTF(fp," Errors detected in METHOD %s of %s\n",SCP(pname),SCP(name));
972 }
973 return rval;
974 }
975
976 enum typelinterr TypeLintIllegalMethodStats(FILE * fp,
977 symchar *name,
978 struct gl_list_t *pl,
979 unsigned int context)
980 {
981 unsigned long pc,plen;
982 struct StatementList *sl;
983 symchar *pname;
984 enum typelinterr rval = DEF_OKAY, tmperr;
985
986 assert(name != NULL);
987 if (pl == NULL) {
988 return rval;
989 }
990 plen = gl_length(pl);
991 for (pc=1; pc <= plen; pc++) {
992 sl = ProcStatementList((struct InitProcedure *)gl_fetch(pl,pc));
993 pname= ProcName((struct InitProcedure *)gl_fetch(pl,pc));
994 tmperr = TypeLintIllegalMethodStatList(fp,name,pname,sl,context);
995 if (tmperr != DEF_OKAY) {
996 rval = tmperr;
997 }
998 }
999 return rval;
1000 }

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22