safety commit, newer version
authorceriel <none@none>
Thu, 27 Mar 1986 17:37:41 +0000 (17:37 +0000)
committerceriel <none@none>
Thu, 27 Mar 1986 17:37:41 +0000 (17:37 +0000)
15 files changed:
lang/m2/comp/Makefile
lang/m2/comp/declar.g
lang/m2/comp/def.H
lang/m2/comp/def.c
lang/m2/comp/enter.c
lang/m2/comp/error.c
lang/m2/comp/expression.g
lang/m2/comp/main.c
lang/m2/comp/misc.H
lang/m2/comp/program.g
lang/m2/comp/scope.C
lang/m2/comp/scope.h
lang/m2/comp/tokenname.c
lang/m2/comp/type.H
lang/m2/comp/type.c

index 653a2fa..d8a5804 100644 (file)
@@ -76,12 +76,12 @@ idf.o: idf.h
 input.o: f_info.h input.h
 type.o: Lpars.h def.h def_sizes.h idf.h type.h
 def.o: Lpars.h debug.h def.h idf.h main.h scope.h
-scope.o: debug.h scope.h
+scope.o: LLlex.h debug.h def.h idf.h scope.h type.h
 misc.o: LLlex.h f_info.h idf.h misc.h
 enter.o: def.h idf.h misc.h scope.h type.h
 tokenfile.o: Lpars.h
 program.o: LLlex.h Lpars.h def.h idf.h main.h misc.h scope.h type.h
 declar.o: LLlex.h Lpars.h def.h idf.h misc.h scope.h type.h
-expression.o: Lpars.h
+expression.o: LLlex.h Lpars.h def.h idf.h scope.h
 statement.o: Lpars.h
 Lpars.o: Lpars.h
index e88573d..3989bb6 100644 (file)
@@ -27,15 +27,17 @@ ProcedureDeclaration
 
 ProcedureHeading(struct def **pdf; int type;)
 {
+       struct type *tp;
+       struct paramlist *params = 0;
 } :
        PROCEDURE IDENT
                        { assert(type == D_PROCEDURE || type == D_PROCHEAD);
-                         *pdf = define(dot.TOK_IDF, CurrentScope, D_PROCHEAD);
+                         *pdf = define(dot.TOK_IDF, CurrentScope, type);
                          if (type == D_PROCEDURE) {
                                open_scope(OPENSCOPE, 0);
                          }
                        }
-       FormalParameters(type, &((*pdf)->df_type))?
+       FormalParameters(type, &params, &tp)?
 ;
 
 block:
@@ -54,15 +56,31 @@ declaration:
        ModuleDeclaration ';'
 ;
 
-FormalParameters(int doparams; struct type **tp;) :
-       '(' [ FPSection(doparams) [ ';' FPSection(doparams)]* ]? ')'
-       [ ':' qualident
+FormalParameters(int doparams; struct paramlist **pr; struct type **tp;)
+{
+       struct def *df;
+       register struct paramlist *pr1;
+} :
+       '('
+       [
+               FPSection(doparams, pr)
+               [
+                       { for (pr1 = *pr; pr1->next; pr1 = pr1->next) ; }
+                       ';' FPSection(doparams, &(pr1->next))
+               ]*
+       ]?
+       ')'
+                       { *tp = 0; }
+       [ ':' qualident(D_TYPE | D_HTYPE, &df, "type")
+                       { /* ???? *tp = df->df_type; */ }
        ]?
 ;
 
-FPSection(int doparams;)
+FPSection(int doparams; struct paramlist **ppr;)
 {
        struct id_list *FPList;
+       register struct id_list *pid;
+       register struct paramlist *pr = 0;
        int VARflag = 0;
 } :
        [
@@ -74,70 +92,88 @@ FPSection(int doparams;)
                                EnterIdList(FPList,
                                            D_VARIABLE,
                                            VARflag,
-                                           (struct type *) 0   /* ???? */
+                                           (struct type *) 0   /* ???? */,
+                                           CurrentScope
                                );
                          }
+                         *ppr = pr = new_paramlist();
+                         pr->par_type = 0;     /* ??? */
+                         pr->par_var = VARflag;
+                         for (pid = FPList->next; pid; pid = pid->next) {
+                               pr->next = new_paramlist();
+                               pr = pr->next;
+                               pr->par_type = 0;       /* ??? */
+                               pr->par_var = VARflag;
+                         }
+                         pr->next = 0;
                          FreeIdList(FPList);
                        }
 ;
 
-FormalType:
-       [ ARRAY OF ]? qualident
+FormalType
+{
+       struct def *df;
+       int ARRAYflag = 0;
+} :
+       [ ARRAY OF      { ARRAYflag = 1; }
+       ]?
+       qualident(D_TYPE | D_HTYPE, &df, "type")
 ;
 
 TypeDeclaration
 {
        struct def *df;
-       struct idf *id;
+       struct type *tp;
 }:
-       IDENT           { id = dot.TOK_IDF; }
-       '=' type        { df = define(id, CurrentScope, D_TYPE);
-                         /* ???? */
+       IDENT           { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
+       '=' type(&tp)
+                       { df->df_type = tp;
                        }
 ;
 
-type:
-       SimpleType
+type(struct type **ptp;):
+       SimpleType(ptp)
 |
-       ArrayType
+       ArrayType(ptp)
 |
-       RecordType
+       RecordType(ptp)
 |
-       SetType
+       SetType(ptp)
 |
-       PointerType
+       PointerType(ptp)
 |
-       ProcedureType
+       ProcedureType(ptp)
 ;
 
-SimpleType:
-       qualident
+SimpleType(struct type **ptp;)
+{
+       struct def *df;
+} :
+       qualident(D_TYPE | D_HTYPE, &df, "type")
        [
 
        |
-               SubrangeType
+               SubrangeType(ptp)
                /*
                 * The subrange type is given a base type by the
                 * qualident (this is new modula-2).
                 */
+                       { /* ???? (*ptp)->next = df->df_type; */ }
        ]
 |
-       enumeration
+       enumeration(ptp)
 |
-       SubrangeType
+       SubrangeType(ptp)
 ;
 
-enumeration
+enumeration(struct type **ptp;)
 {
        struct id_list *EnumList;
 } :
        '(' IdentList(&EnumList) ')'
                        {
-                         EnterIdList(EnumList,
-                                     D_ENUM,
-                                     0,
-                                     (struct type *) 0 /* ???? */
-                         );
+                         *ptp = standard_type(ENUMERATION,int_align,int_size);
+                         EnterIdList(EnumList, D_ENUM, 0, *ptp, CurrentScope);
                          FreeIdList(EnumList);
                        }
 
@@ -157,43 +193,102 @@ IdentList(struct id_list **p;)
                                { q->next = 0; }
 ;
 
-SubrangeType:
+SubrangeType(struct type **ptp;)
+{
+       struct type *tp;
+}:
        /*
           This is not exactly the rule in the new report, but see
           the rule for "SimpleType".
        */
-       '[' ConstExpression UPTO ConstExpression ']'
+       '[' ConstExpression
+       UPTO ConstExpression
+       ']'
+       /*
+          Evaluate the expressions. Check that they are indeed constant.
+          ???
+          Leave the basetype of the subrange in tp;
+       */
+                       {
+                         /* For the time being: */
+                         tp = int_type;
+                         tp = construct_type(SUBRANGE, tp, (arith) 0);
+                         *ptp = tp;
+                       }
 ;
 
-ArrayType:
-       ARRAY SimpleType [ ',' SimpleType ]* OF type
+ArrayType(struct type **ptp;)
+{
+       struct type *tp;
+       register struct type *tp2;
+} :
+       ARRAY SimpleType(&tp)
+                       {
+                         *ptp = tp2 = construct_type(ARRAY, tp);
+                       }
+       [
+               ',' SimpleType(&tp)
+                       { tp2 = tp2->tp_value.tp_arr.ar_elem = 
+                               construct_type(ARRAY, tp);
+                       }
+       ]* OF type(&tp)
+                       { tp2->tp_value.tp_arr.ar_elem = tp; }
 ;
 
-RecordType:
-       RECORD FieldListSequence END
+RecordType(struct type **ptp;)
+{
+       int scopenr;
+}
+:
+       RECORD
+                       { scopenr = uniq_scope(); }
+       FieldListSequence(scopenr)
+                       {
+                         *ptp = standard_type(RECORD, record_align, (arith) 0 /* ???? */);
+                         (*ptp)->tp_value.tp_record.rc_scopenr = scopenr;
+                       }
+       END
 ;
 
-FieldListSequence:
-       FieldList [ ';' FieldList ]*
+FieldListSequence(int scopenr;):
+       FieldList(scopenr)
+       [
+               ';' FieldList(scopenr)
+       ]*
 ;
 
-FieldList
+FieldList(int scopenr;)
 {
        struct id_list *FldList;
+       struct idf *id;
+       struct def *df, *df1;
+       struct type *tp;
 } :
 [
-       IdentList(&FldList) ':' type
+       IdentList(&FldList) ':' type(&tp)
 |
-       CASE IDENT?                     /* Changed rule in new modula-2 */
-       ':' qualident
-       OF variant [ '|' variant ]*
-       [ ELSE FieldListSequence ]?
+       CASE
+       [
+               IDENT           { id = dot.TOK_IDF; }
+       |
+                               { id = gen_anon_idf(); }
+       ]                       /* Changed rule in new modula-2 */
+       ':' qualident(D_TYPE|D_HTYPE, &df, "type")
+                               { df1 = define(id, scopenr, D_FIELD);
+                                 df1->df_type = df->df_type;
+                               }
+       OF variant(scopenr)
+       [
+               '|' variant(scopenr)
+       ]*
+       [ ELSE FieldListSequence(scopenr)
+       ]?
        END
 ]?
 ;
 
-variant:
-       [ CaseLabelList ':' FieldListSequence ]?
+variant(int scopenr;):
+       [ CaseLabelList ':' FieldListSequence(scopenr) ]?
                                        /* Changed rule in new modula-2 */
 ;
 
@@ -205,21 +300,59 @@ CaseLabels:
        ConstExpression [ UPTO ConstExpression ]?
 ;
 
-SetType:
-       SET OF SimpleType
+SetType(struct type **ptp;)
+{
+       struct type *tp;
+} :
+       SET OF SimpleType(&tp)
+                       {
+                         *ptp = construct_type(SET, tp, (arith) 0 /* ???? */);
+                       }
 ;
 
-PointerType:
-       POINTER TO type
+PointerType(struct type **ptp;)
+{
+       struct type *tp;
+       register struct def *df;
+       struct def *lookfor();
+} :
+       POINTER TO
+       [ %if ( (df = lookup(dot.TOK_IDF, CurrentScope)))
+               IDENT
+                               {
+                                 if (!(df->df_kind & (D_TYPE | D_HTYPE))) {
+                                       error("\"%s\" is not a type identifier",
+                                               df->df_idf->id_text);
+                                 }
+                                 if (!df->df_type) {
+                                       error("type \"%s\" not declared",
+                                               df->df_idf->id_text);
+                                 }
+                                 *ptp = df->df_type;
+                               }
+       | %if (df = lookfor(dot.TOK_IDF, 0), df->df_kind == D_MODULE)
+               type(&tp)
+                               { *ptp = construct_type(POINTER, tp); }
+       |
+               IDENT
+                               { *ptp = construct_type(POINTER, NULLTYPE);
+                                 Forward(&dot, &((*ptp)->next));
+                               }
+       ]
 ;
 
-ProcedureType:
+ProcedureType(struct type **ptp;):
        PROCEDURE FormalTypeList?
+                       { *ptp = 0; }
 ;
 
-FormalTypeList:
+FormalTypeList
+{
+       struct def *df;
+} :
        '(' [ VAR? FormalType [ ',' VAR? FormalType ]* ]? ')'
-       [ ':' qualident ]?
+       [ ':' qualident(1, &df, "type")
+       ]?
 ;
 
 ConstantDeclaration
@@ -236,17 +369,14 @@ ConstantDeclaration
 VariableDeclaration
 {
        struct id_list *VarList;
+       struct type *tp;
 } :
        IdentList(&VarList)
        [
                ConstExpression
        ]?
-       ':' type
-                       { EnterIdList(VarList,
-                                     D_VARIABLE,
-                                     0,
-                                     (struct type *) 0 /* ???? */
-                                    );
+       ':' type(&tp)
+                       { EnterIdList(VarList, D_VARIABLE, 0, tp, CurrentScope);
                          FreeIdList(VarList);
                        }
 ;
index ba3604d..24abd79 100644 (file)
@@ -38,21 +38,24 @@ struct def  {               /* list of definitions for a name */
        struct def *next;
        struct idf *df_idf;     /* link back to the name */
        int df_scope;           /* Scope in which this definition resides */
-       char df_kind;           /* The kind of this definition: */
-#define D_MODULE       0x00
-#define D_PROCEDURE    0x01
-#define D_VARIABLE     0x02
-#define D_FIELD                0x03
-#define D_TYPE         0x04
-#define D_ENUM         0x05
-#define D_CONST                0x06
-#define D_IMPORT       0x07
-#define D_PROCHEAD     0x08    /* A procedure heading in a definition module */
-#define D_HIDDEN       0x09    /* A hidden type */
-#define D_HTYPE                0x0A    /* Definition of a hidden type seen */
-#define D_STDPROC      0x0B    /* A standard procedure */
-#define D_STDFUNC      0x0C    /* A standard function */
-#define D_ISEXPORTED   0xFF    /* Not yet defined */
+       short df_kind;          /* The kind of this definition: */
+#define D_MODULE       0x0001
+#define D_PROCEDURE    0x0002
+#define D_VARIABLE     0x0004
+#define D_FIELD                0x0008
+#define D_TYPE         0x0010
+#define D_ENUM         0x0020
+#define D_CONST                0x0040
+#define D_IMPORT       0x0080
+#define D_PROCHEAD     0x0100  /* A procedure heading in a definition module */
+#define D_HIDDEN       0x0200  /* A hidden type */
+#define D_HTYPE                0x0400  /* Definition of a hidden type seen */
+#define D_STDPROC      0x0800  /* A standard procedure */
+#define D_STDFUNC      0x1000  /* A standard function */
+#define D_ERROR                0x2000  /* A compiler generated definition for an
+                                  undefined variable
+                               */
+#define D_ISEXPORTED   0x4000  /* Not yet defined */
        char df_flags;
 #define D_ADDRESS      0x01    /* Set if address was taken */
 #define D_USED         0x02    /* Set if used */
@@ -74,6 +77,9 @@ struct def    {               /* list of definitions for a name */
 
 /* ALLOCDEF "def" */
 
-struct def
+extern struct def
        *define(),
-       *lookup();
+       *lookup(),
+       *ill_df;
+
+#define NULLDEF ((struct def *) 0)
index 53e69b9..5a815e9 100644 (file)
@@ -14,21 +14,30 @@ static char *RcsId = "$Header$";
 
 struct def *h_def;             /* Pointer to free list of def structures */
 
+static struct def illegal_def =
+       {0, 0, -20 /* Illegal scope */, D_ERROR};
+
+struct def *ill_df = &illegal_def;
+
 struct def *
 define(id, scope, kind)
        register struct idf *id;
-       register struct scope *scope;
 {
        /*      Declare an identifier in a scope, but first check if it
                already has been defined. If so, error message.
        */
-       register struct def *df = lookup(id, scope->sc_scope);
+       register struct def *df;
 
-       DO_DEBUG(debug(3,"Defining identifier %s in scope %d", id->id_text, scope->sc_scope));
+       DO_DEBUG(debug(4,"Defining identifier %s in scope %d", id->id_text, scope));
+       df = lookup(id, scope);
        if (    /* Already in this scope */
                df
           ||   /* A closed scope, and id defined in the pervasive scope */
-               (scopeclosed(scope) && (df = lookup(id, 0)))
+               ( CurrentScope == scope 
+               &&
+                 scopeclosed(currscope)
+               &&
+                 (df = lookup(id, 0)))
           ) {
                switch(df->df_kind) {
                case D_PROCHEAD:
@@ -43,17 +52,17 @@ define(id, scope, kind)
                                return df;
                        }
                        break;
+               case D_ERROR:
                case D_ISEXPORTED:
                        df->df_kind = kind;
                        return df;
-                       break;
                }
-               error("Identifier \"%s\" already declared", id->id_text);
+               error("identifier \"%s\" already declared", id->id_text);
                return df;
        }
        df = new_def();
        df->df_idf = id;
-       df->df_scope = scope->sc_scope;
+       df->df_scope = scope;
        df->df_kind = kind;
        df->next = id->id_def;
        id->id_def = df;
@@ -73,7 +82,7 @@ lookup(id, scope)
 
        df1 = 0;
        df = id->id_def;
-       DO_DEBUG(debug(3,"Looking for identifier %s in scope %d", id->id_text, scope));
+       DO_DEBUG(debug(4,"Looking for identifier %s in scope %d", id->id_text, scope));
        while (df) {
                if (df->df_scope == scope) {
                        if (df1) {
index 6dcc048..d5c1322 100644 (file)
@@ -32,24 +32,50 @@ Enter(name, kind, type, pnam)
        return df;
 }
 
-EnterIdList(idlist, kind, flags, type)
+EnterIdList(idlist, kind, flags, type, scope)
        register struct id_list *idlist;
        struct type *type;
 {
        register struct def *df;
-       struct def *last = 0;
+       struct def *first = 0, *last = 0;
        int assval = 0;
 
        while (idlist) {
-               df = define(idlist->id_ptr, CurrentScope, kind);
+               df = define(idlist->id_ptr, scope, kind);
                df->df_type = type;
                df->df_flags = flags;
                if (kind == D_ENUM) {
+                       if (!first) first = df;
                        df->df_value.df_enum.en_val = assval++;
                        if (last) last->df_value.df_enum.en_next = df;
                        last = df;
                }
                idlist = idlist->next;
        }
-       if (last) last->df_value.df_enum.en_next = 0;
+       if (last) {
+               /* Also meaning : enumeration */
+               last->df_value.df_enum.en_next = 0;
+               type->tp_value.tp_enum.en_enums = first;
+               type->tp_value.tp_enum.en_ncst = assval;
+       }
+}
+
+/*     Look for an identifier in the current visibility range.
+       If it is not defined, give an error message, and
+       create a dummy definition.
+*/
+struct def *
+lookfor(id, give_error)
+       struct idf *id;
+{
+       register struct scope *sc = currscope;
+       struct def *df;
+
+       while (sc) {
+               df = lookup(id, sc->sc_scope);
+               if (df) return df;
+               sc = nextvisible(sc);
+       }
+       if (give_error) error("Identifier \"%s\" not declared", id->id_text);
+       return define(id, CurrentScope, D_ERROR);
 }
index 278a39d..1a769bc 100644 (file)
@@ -132,7 +132,7 @@ _error(class, expr, fmt, argv)
        case LEXERROR:
        case CRASH:
        case FATAL:
-               /*
+               /* ????
                if (C_busy())
                        C_ms_err();
                */
@@ -164,7 +164,7 @@ _error(class, expr, fmt, argv)
        switch (class)  {       
        case WARNING:
        case ERROR:
-               ln = /* expr ? expr->ex_line : */ dot.tk_lineno;
+               ln = /* ???? expr ? expr->ex_line : */ dot.tk_lineno;
                break;
        case LEXWARNING:
        case LEXERROR:
index c56441f..38c08a7 100644 (file)
@@ -1,5 +1,15 @@
+/* E X P R E S S I O N S */
+
 {
 static char *RcsId = "$Header$";
+
+#include       <alloc.h>
+#include       <em_arith.h>
+#include       <em_label.h>
+#include       "LLlex.h"
+#include       "idf.h"
+#include       "def.h"
+#include       "scope.h"
 }
 
 number:
@@ -8,8 +18,44 @@ number:
        REAL
 ;
 
-qualident:
-       IDENT selector*
+qualident(int types; struct def **pdf; char *str;)
+{
+       int scope;
+       register struct def *df;
+       struct def *lookfor();
+} :
+       IDENT           { if (types) {
+                               df = lookfor(dot.TOK_IDF, 1);
+                               if (df->df_kind == D_ERROR) {
+                                       *pdf = df;
+                                       types = 0;
+                               }
+                         }
+                       }
+       [
+                       { if (types &&!(scope = has_selectors(df))) {
+                               types = 0;
+                               *pdf = ill_df;
+                         }
+                       }
+               /* selector */
+               '.' IDENT
+                       { if (types) {
+                               df = lookup(dot.TOK_IDF, scope);
+                               if (!df) {
+                                       error("identifier \"%s\" not declared",
+                                             dot.TOK_IDF->id_text);
+                                       types = 0;
+                                       df = ill_df;
+                               }
+                         }
+                       }
+       ]*
+                       { if (types && !(types & df->df_kind)) {
+                               error("identifier \"%s\" is not a %s",
+                                       dot.TOK_IDF, str);
+                         }
+                       }
 ;
 
 selector:
@@ -52,8 +98,11 @@ MulOperator:
        '*' | '/' | DIV | MOD | AND | '&'
 ;
 
-factor:
-       qualident
+factor
+{
+       struct def *df;
+} :
+       qualident(0, &df, (char *) 0)
        [
                designator_tail? ActualParameters?
        |
@@ -83,15 +132,25 @@ element:
        expression [ UPTO expression ]?
 ;
 
-designator:
-       qualident designator_tail?
+designator
+{
+       struct def *df;
+} :
+       qualident(0, &df, (char *) 0)
+       designator_tail?
 ;
 
 designator_tail:
        visible_designator_tail
-       [ selector | visible_designator_tail ]*
+       [
+               selector
+       |
+               visible_designator_tail
+       ]*
 ;
 
 visible_designator_tail:
-       '[' ExpList ']' | '^'
+       '[' ExpList ']'
+|
+       '^'
 ;
index b245420..7ff75ed 100644 (file)
@@ -121,8 +121,6 @@ Option(str)
        options[str[1]]++;      /* switch option on     */
 }
 
-#define NULLTYPE       ((struct type *) 0)
-
 add_standards()
 {
        register struct def *df;
@@ -157,15 +155,13 @@ add_standards()
        (void) Enter("NIL", D_CONST, nil_type, 0);
        (void) Enter("PROC",
                     D_TYPE,
-                    construct_type(PROCEDURE, NULLTYPE, (arith) 0),
+                    construct_type(PROCEDURE, NULLTYPE),
                     0);
-       tp = construct_type(SUBRANGE, int_type, (arith) 0);
+       tp = construct_type(SUBRANGE, int_type);
        tp->tp_value.tp_subrange.su_lb = 0;
        tp->tp_value.tp_subrange.su_ub = wrd_size * 8 - 1;
-       (void) Enter("BITSET",
-                    D_TYPE,
-                    construct_type(SET, tp, wrd_size),
-                    0);
+       df = Enter("BITSET", D_TYPE, construct_type(SET, tp), 0);
+       df->df_type->tp_size = wrd_size;
        df = Enter("FALSE", D_ENUM, bool_type, 0);
        df->df_value.df_enum.en_val = 0;
        df->df_value.df_enum.en_next = Enter("TRUE", D_ENUM, bool_type, 0);
index 82deee3..ef9a781 100644 (file)
@@ -12,3 +12,6 @@ struct id_list {
 /* ALLOCDEF "id_list" */
 
 #define is_anon_idf(x) ((x)->id_text[0] == '#')
+
+extern struct idf
+       *gen_anon_idf();
index 32e888f..77751d7 100644 (file)
@@ -83,7 +83,7 @@ DefinitionModule
        MODULE IDENT    { 
                          df = define(dot.TOK_IDF, CurrentScope, D_MODULE);
                          open_scope(CLOSEDSCOPE, 0);
-                         df->df_value.df_module.mo_scope = CurrentScope->sc_scope;
+                         df->df_value.df_module.mo_scope = CurrentScope;
                        }
        ';'
        import(0)* 
@@ -98,12 +98,13 @@ DefinitionModule
 definition
 {
        struct def *df;
+       struct type *tp;
 } :
        CONST [ ConstantDeclaration ';' ]*
 |
        TYPE
        [ IDENT 
-         [ '=' type 
+         [ '=' type(&tp)
          | /* empty */
            /*
               Here, the exported type has a hidden implementation.
index f46f3cf..6eafc23 100644 (file)
@@ -4,12 +4,18 @@ static char *RcsId = "$Header$";
 
 #include       <assert.h>
 #include       <alloc.h>
+#include       <em_arith.h>
+#include       <em_label.h>
+#include       "LLlex.h"
+#include       "idf.h"
 #include       "scope.h"
+#include       "type.h"
+#include       "def.h"
 #include       "debug.h"
 
 static int maxscope;           /* maximum assigned scope number */
 
-struct scope *CurrentScope;
+struct scope *currscope;
 
 /* STATICALLOCDEF "scope" */
 
@@ -29,29 +35,32 @@ open_scope(scopetype, scopenr)
        sc->sc_scope = scopenr == 0 ? ++maxscope : scopenr;
        assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE);
        DO_DEBUG(debug(1, "Opening a %s scope", scopetype == OPENSCOPE ? "open" : "closed"));
-       sc1 = CurrentScope;
+       sc1 = currscope;
        if (scopetype == CLOSEDSCOPE) {
                sc1 = new_scope();
-               sc1->sc_scope = 0;                      /* Pervasive scope nr */
-               sc1->next = CurrentScope;
+               sc1->sc_scope = 0;              /* Pervasive scope nr */
+               sc1->next = currscope;
        }
        sc->next = sc1;
-       CurrentScope = sc;
+       currscope = sc;
 }
 
+static rem_forwards();
+
 close_scope()
 {
-       register struct scope *sc = CurrentScope;
+       register struct scope *sc = currscope;
 
        assert(sc != 0);
        DO_DEBUG(debug(1, "Closing a scope"));
+       if (sc->sc_forw) rem_forwards(sc->sc_forw);
        if (sc->next && (sc->next->sc_scope == 0)) {
                struct scope *sc1 = sc;
 
                sc = sc->next;
                free_scope(sc1);
        }
-       CurrentScope = sc->next;
+       currscope = sc->next;
        free_scope(sc);
 }
 
@@ -61,5 +70,61 @@ init_scope()
 
        sc->sc_scope = 0;
        sc->next = 0;
-       CurrentScope = sc;
+       currscope = sc;
+}
+
+int
+uniq_scope()
+{
+       return ++maxscope;
+}
+
+struct forwards {
+       struct forwards *next;
+       struct token fo_tok;
+       struct type **fo_ptyp;
+};
+
+/* STATICALLOCDEF "forwards" */
+
+/*     Enter a forward reference into a list belonging to the
+       current scope. This is used for POINTER declarations, which
+       may have forward references that must howewer be declared in the
+       same scope.
+*/
+Forward(tk, ptp)
+       struct token *tk;
+       struct type **ptp;
+{
+       register struct forwards *f = new_forwards();
+
+       f->fo_tok = *tk;
+       f->fo_ptyp = ptp;
+       f->next = currscope->sc_forw;
+       currscope->sc_forw = f;
+}
+
+/*     When closing a scope, all forward references must be resolved
+*/
+static
+rem_forwards(fo)
+       struct forwards *fo;
+{
+       register struct forwards *f;
+       struct token savetok;
+       register struct def *df;
+       struct def *lookfor();
+
+       savetok = dot;
+       while (f = fo) {
+               dot = f->fo_tok;
+               df = lookfor(dot.TOK_IDF, 1);
+               if (!(df->df_kind & (D_TYPE | D_HTYPE | D_ERROR))) {
+                       error("identifier \"%s\" not a type", df->df_idf->id_text);
+               }
+               *(f->fo_ptyp) = df->df_type;
+               fo = f->next;
+               free_forwards(f);
+       }
+       dot = savetok;
 }
index 20e72ad..f924b6b 100644 (file)
@@ -7,6 +7,7 @@
 
 struct scope {
        struct scope *next;
+       struct forwards *sc_forw;
        int sc_scope;           /* The scope number. Scope number 0 indicates
                                   both the pervasive scope and the end of a
                                   visibility range
@@ -14,7 +15,9 @@ struct scope {
 };
 
 extern struct scope
-       *CurrentScope;
+       *currscope;
 
 #define nextvisible(x) ((x)->sc_scope ? (x)->next : (struct scope *) 0)
 #define scopeclosed(x) ((x)->next->sc_scope == 0)
+#define enclosing(x)   ((x)->next->scope != 0 ? (struct scope *) 0 : (x)->next->next)
+#define CurrentScope   (currscope->sc_scope)
index 97020e0..6d16fe3 100644 (file)
@@ -86,6 +86,7 @@ struct tokenname tkstandard[] =       {       /* standard identifiers */
        {CARDINAL, ""},
        {LONGREAL, ""},
        {SUBRANGE, ""},
+       {ENUMERATION, ""},
        {ERRONEOUS, ""},
        {0, ""}
 };
index ca59a1f..942fcbf 100644 (file)
@@ -22,7 +22,7 @@ struct subrange {
 };
 
 struct array {
-       struct type *ar_index;  /* Type of index */
+       struct type *ar_elem;   /* Type of elements */
        arith ar_lb, ar_ub;     /* Lower bound and upper bound */
        label ar_descr;         /* Label of array descriptor */
 };
@@ -90,3 +90,5 @@ struct type
        *create_type(),
        *construct_type(),
        *standard_type();
+
+#define NULLTYPE ((struct type *) 0)
index 37fb537..a8eb556 100644 (file)
@@ -64,9 +64,8 @@ create_type(fund)
 }
 
 struct type *
-construct_type(fund, tp, count)
+construct_type(fund, tp)
        struct type *tp;
-       arith count;
 {
        /*      fund must be a type constructor.
                The pointer to the constructed type is returned.
@@ -82,13 +81,10 @@ construct_type(fund, tp, count)
                break;
        case SET:
                dtp->tp_align = wrd_align;
-               dtp->tp_size = align((count + 7) / 8, wrd_align);
                dtp->next = tp;
                break;
        case ARRAY:
                dtp->tp_align = tp->tp_align;
-               if (tp->tp_size < 0) dtp->tp_size = -1;
-               else dtp->tp_size = count * tp->tp_size;
                dtp->next = tp;
                break;
        case SUBRANGE:
@@ -134,3 +130,24 @@ init_types()
        nil_type = standard_type(POINTER, ptr_align, ptr_size);
        error_type = standard_type(ERRONEOUS, 1, (arith) 1);
 }
+
+int
+has_selectors(df)
+       register struct def *df;
+{
+
+       switch(df->df_kind) {
+       case D_MODULE:
+               return df->df_value.df_module.mo_scope;
+       case D_VARIABLE: {      
+               register struct type *tp = df->df_type;
+
+               if (tp->tp_fund == RECORD) {
+                       return tp->tp_value.tp_record.rc_scopenr;
+               }
+               break;
+               }
+       }
+       error("no selectors for \"%s\"", df->df_idf->id_text);
+       return 0;
+}