Pristine Ack-5.5
[Ack-5.5.git] / lang / pc / comp / scope.c
1 /* S C O P E   M E C H A N I S M */
2
3 #include        "debug.h"
4
5 #include        <alloc.h>
6 #include        <assert.h>
7 #include        <em_arith.h>
8 #include        <em_label.h>
9
10 #include        "LLlex.h"
11 #include        "def.h"
12 #include        "idf.h"
13 #include        "misc.h"
14 #include        "node.h"
15 #include        "scope.h"
16 #include        "type.h"
17
18 struct scope *GlobalScope, *PervasiveScope, *BlockScope;
19 struct scopelist *CurrVis;
20 extern int proclevel;                   /* declared in declar.g */
21 static int sccount;
22
23 InitScope()
24 {
25         register struct scope *sc = new_scope();
26         register struct scopelist *ls = new_scopelist();
27
28         sc->sc_level = proclevel;
29         PervasiveScope = sc;
30         ls->sc_scope = PervasiveScope;
31         ls->sc_count = ++sccount;
32         CurrVis = ls;
33 }
34
35 open_scope()
36 {
37         register struct scope *sc = new_scope();
38         register struct scopelist *ls = new_scopelist();
39
40         sc->sc_level = proclevel;
41         ls->sc_scope = sc;
42         ls->next = CurrVis;
43         ls->sc_count = ++sccount;
44         CurrVis = ls;
45 }
46
47 close_scope(doclean)
48 {
49         /* When this procedure is called, the next visible scope is equal to
50            the statically enclosing scope
51         */
52         register struct def *df;
53
54         assert(CurrentScope != 0);
55         df = CurrentScope->sc_def;
56         if (doclean) while (df) {
57                 struct def *next = df->df_nextinscope;
58                 if (! (df->df_flags & (D_VARPAR|D_VALPAR))) remove_def(df);
59                 df = next;
60         }
61         CurrVis = CurrVis->next;
62 }
63
64 Forward(nd, tp)
65         register struct node *nd;
66         register struct type *tp;
67 {
68         /* Enter a forward reference into the current scope. This is
69          * used in pointertypes.
70          */
71         register struct def *df = define(nd->nd_IDF, CurrentScope, D_FORWTYPE);
72         register struct forwtype *fw_type = new_forwtype();
73
74         fw_type->f_next = df->df_fortype;
75         df->df_fortype = fw_type;
76
77         fw_type->f_node = nd;
78         fw_type->f_type = tp;
79 }
80
81 chk_prog_params()
82 {
83         /* the program parameters must be global variables of some file type */
84         register struct def *df = CurrentScope->sc_def;
85
86         while( df )     {
87             if( df->df_kind & D_PARAMETER )     {
88                 if( !is_anon_idf(df->df_idf) )  {
89                     if( df->df_type == error_type )
90                          error("program parameter \"%s\" must be a global variable",
91                                                         df->df_idf->id_text);
92                     else if( df->df_type->tp_fund != T_FILE )
93                         error("program parameter \"%s\" must have a file type",
94                                                         df->df_idf->id_text);
95
96                     df->df_kind = D_VARIABLE;
97                 }
98                 else df->df_kind = D_ERROR;
99             }
100             df = df->df_nextinscope;
101         }
102 }
103
104 chk_directives()
105 {
106         /* check if all forward declarations are defined */
107         register struct def *df = CurrentScope->sc_def;
108
109         while( df )     {
110                 if( df->df_kind == D_FWPROCEDURE )
111                      error("procedure \"%s\" not defined", df->df_idf->id_text);
112                 else if( df->df_kind == D_FWFUNCTION )
113                       error("function \"%s\" not defined", df->df_idf->id_text);
114
115                 df = df->df_nextinscope;
116         }
117 }