/[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 615 - (show annotations) (download) (as text)
Wed May 17 06:29:40 2006 UTC (13 years, 6 months ago) by johnpye
File MIME type: text/x-csrc
File size: 28708 byte(s)
Forced pygtk to share major env vars with base library.
Modified 'can't use this here' error messages.
Added notification when colour codes are being disabled.
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.h"
36 #include "fractions.h"
37 #include "dimen.h"
38 #include "functype.h"
39 #include "types.h"
40 #include "stattypes.h"
41 #include "statement.h"
42 #include "slist.h"
43 #include "statio.h"
44 #include "symtab.h"
45 #include "module.h"
46 #include "library.h"
47 #include "child.h"
48 #include "vlist.h"
49 #include "vlistio.h"
50 #include "name.h"
51 #include "nameio.h"
52 #include "when.h"
53 #include "select.h"
54 #include "switch.h"
55 #include "sets.h"
56 #include "exprs.h"
57 #include "forvars.h"
58 #include "bit.h"
59 #include "syntax.h"
60 #include "setinstval.h"
61 #include "childinfo.h"
62 #include "instance.h"
63 #include "evaluate.h"
64 #include "proc.h"
65 #include "type_desc.h"
66 #include "typedef.h"
67 #include "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) == ek_method) {
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,"Perhaps '=' or '==' should be ':='?");
857 rval = DEF_STAT_MISLOCATED;
858 break;
859 case WHEN:
860 Asc_StatErrMsg_NotAllowedMethod(fp,s,"Perhaps WHEN should be SWITCH?");
861 rval = DEF_STAT_MISLOCATED;
862 break;
863 case SELECT:
864 Asc_StatErrMsg_NotAllowedMethod(fp,s,"Perhaps SELECT should be SWITCH?");
865 rval = DEF_STAT_MISLOCATED;
866 break;
867 case FOR:
868 if (ForLoopKind(s) != fk_do) {
869 rval = DEF_FOR_NOTMETH;
870 TypeLintError(fp,s,rval);
871 } else {
872 tmperr = TypeLintIllegalMethodStatList(fp,name,pname,ForStatStmts(s),
873 (context | context_FOR));
874 if (tmperr != DEF_OKAY) {
875 rval = tmperr;
876 }
877 }
878 break;
879 case EXT:
880 if (ExternalStatMode(s) != ek_method) {
881 Asc_StatErrMsg_NotAllowedMethod(fp,s,"");
882 rval = DEF_STAT_MISLOCATED;
883 }
884 break;
885 case ASGN:
886 case RUN:
887 case FIX:
888 case FREE:
889 case CALL:
890 break;
891 case WHILE:
892 if (WhileStatBlock(s) != NULL) {
893 tmperr = TypeLintIllegalMethodStatList(fp,name,pname,WhileStatBlock(s),
894 (context | context_WHILE));
895 if (tmperr != DEF_OKAY) {
896 rval = tmperr;
897 break;
898 }
899 }
900 break;
901 case ASSERT:
902 /* no sublists for TEST */
903 break;
904
905 case IF:
906 if (IfStatThen(s) != NULL) {
907 tmperr = TypeLintIllegalMethodStatList(fp,name,pname,IfStatThen(s),
908 (context | context_IF));
909 if (tmperr != DEF_OKAY) {
910 rval = tmperr;
911 break;
912 }
913 }
914 if (IfStatElse(s) != NULL){
915 tmperr = TypeLintIllegalMethodStatList(fp,name,pname,IfStatElse(s),
916 (context | context_IF));
917 if (tmperr != DEF_OKAY) {
918 rval = tmperr;
919 }
920 }
921 break;
922 case SWITCH:
923 sw = SwitchStatCases(s);
924 while (sw!=NULL) {
925 sublist = SwitchStatementList(sw);
926 if (sublist!=NULL) {
927 tmperr = TypeLintIllegalMethodStatList(fp,name,pname,sublist,
928 (context | context_SWITCH));
929 if (tmperr != DEF_OKAY) {
930 rval = tmperr;
931 break;
932 }
933 }
934 sw = NextSwitchCase(sw);
935 }
936 break;
937 case FLOW:
938 switch (FlowStatControl(s)) {
939 case fc_break:
940 if ((context & (context_FOR | context_SWITCH | context_WHILE))==0) {
941 rval = DEF_ILLEGAL_BREAK;
942 TypeLintError(fp,s,rval);
943 }
944 break;
945 case fc_continue:
946 if ((context & (context_FOR | context_WHILE))==0) {
947 rval = DEF_ILLEGAL_CONTINUE;
948 TypeLintError(fp,s,rval);
949 }
950 break;
951 case fc_fallthru:
952 if ((context & context_SWITCH)==0) {
953 rval = DEF_ILLEGAL_FALLTHRU;
954 TypeLintError(fp,s,rval);
955 }
956 break;
957 case fc_return:
958 case fc_stop:
959 break;
960 }
961 break;
962 default:
963 rval = DEF_UNKNOWN_ERR;
964 TypeLintError(fp,s,rval);
965 break;
966 }
967 }
968 if (rval != DEF_OKAY) {
969 FPRINTF(fp," Errors detected in METHOD %s of %s\n",SCP(pname),SCP(name));
970 }
971 return rval;
972 }
973
974 enum typelinterr TypeLintIllegalMethodStats(FILE * fp,
975 symchar *name,
976 struct gl_list_t *pl,
977 unsigned int context)
978 {
979 unsigned long pc,plen;
980 struct StatementList *sl;
981 symchar *pname;
982 enum typelinterr rval = DEF_OKAY, tmperr;
983
984 assert(name != NULL);
985 if (pl == NULL) {
986 return rval;
987 }
988 plen = gl_length(pl);
989 for (pc=1; pc <= plen; pc++) {
990 sl = ProcStatementList((struct InitProcedure *)gl_fetch(pl,pc));
991 pname= ProcName((struct InitProcedure *)gl_fetch(pl,pc));
992 tmperr = TypeLintIllegalMethodStatList(fp,name,pname,sl,context);
993 if (tmperr != DEF_OKAY) {
994 rval = tmperr;
995 }
996 }
997 return rval;
998 }

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