/*************************************************
 **                                             **
 **     HAPPy Pascal Compiler                   **
 **        共通ヘッダ                           **
 **                                             **
 **         Copyright (c) H.Asano 1992,1993     **
 **                                             **
 *************************************************/

/***************************************/
/* HAPPyの制限事項となっている定数     */
/***************************************/
#define  Displimit        20            /* displayの配列数            */
#define  Maxlevel         10            /* 関数･手続きの最大ネスト数  */
#define  Maxstrlng       256            /* 最大文字列長               */
#define  Maxdiglng        15            /* 最大実数型文字長           */
#define  MaxIDlng         32            /* 名前の最大識別可能文字数   */
#define  setlow            0            /* 集合の要素の最低値         */
#define  sethigh          31            /* 集合の要素の最大値         */
#define  Maxaddr       32767            /* 最大アドレス(型の大きさ)   */
#define  Cixmax         1000            /* case文選択肢定数の範囲     */
#define  Maxfileno         8            /* 外部ファイル数             */

/***************************************/
/*          その他の定数               */
/***************************************/
#define  Maxint    2147483647 /* 整数の最大値                   */
#define  ordminchar  0        /* 最小文字コード                 */
#define  ordmaxchar  255      /* 最大文字コード                 */

#define  intsize    1         /* integer型のサイズ              */
#define  realsize   1         /* real型のサイズ                 */
#define  charsize   1         /* char型のサイズ                 */
#define  boolsize   1         /* boolean型のサイズ              */
#define  ptrsize    1         /* pointer型のサイズ              */
#define  setsize    1         /* 集合型のサイズ                 */
#define  stackelsize 1        /* スタックの1要素サイズ          */
#define  parmsize stackelsize /* 手続き･関数の引数のサイズ      */
#define  maxstack   1         /* stackの1要素の最大サイズ       */
#define  charmax    1         /*    */
#define  nil        0         /* pascal の nil と 同じ          */

#define  lcaftermarkstack 5   /* mst命令実行後のlcの値          */
#define  inputadr  lcaftermarkstack    /* input  buffer address */
#define  outputadr inputadr + charmax  /* output buffer address */

#define  intal         1      /* integer型の境界     */
#define  realal        1      /* real   型の境界     */
#define  charal        1      /* char   型の境界     */
#define  boolal        1      /* boolean型の境界     */
#define  adral         1      /* pointer型の境界     */
#define  fileal     charal    /* file   型の境界     */
#define  setal         1      /* set    型の境界     */
#define  stackal       1      /*  */
#define  parmal    stackal    /* パラメータの境界    */
#define  recal         1      /* record    の境界    */


/***********************************/
/*      boolean型の定義            */
/***********************************/
typedef enum bool  {false = 0,          /* 偽 */
		    true  = 1           /* 真 */
		   }
             boolean ;

/***********************************/
/* set operation マクロ の定義     */
/***********************************/

/* addset(S,pos) ･･･ Sに要素posを加える                 */
/* inset (S,pos) ･･･ Sに要素posが含まれているか判定する */

#define addset(S,pos)     \
	(*(((pos)>31) ? &(S.H) : &(S.L)) |= ((long)1 << ((pos)&0x1F)))

#define inset(S,pos)      \
        (( (((pos)>31) ? (S.H) : (S.L)) >> ((pos)&0x1f) )&0x1)

typedef struct {
	   unsigned long H;   /* 32-63までの要素に対するエリア */
	   unsigned long L;   /*  0-31までの要素に対するエリア */
	 } Set ;


/***********************************/
/*         型のtypedef             */
/***********************************/
typedef struct Constant    csp ;  /* 定数  の構造体 */
typedef struct Structure   stp ;  /* 構造  の構造体 */
typedef struct Identifier  ctp ;  /* 名前  の構造体 */
typedef struct labl        lbp ;  /* ラベルの構造体 */

/***************************************/
/* pascal source の symbolの種類定義   */
/***************************************/
enum symbol   { ident,                  /* 名前                       */
                intconst,               /* 整数定数                   */
                realconst,              /* 実数定数                   */
                stringconst,            /* 2文字以上の文字列          */
                notsy,                  /* not                        */
                mulop,                  /* * / div mod and            */
                addop,                  /* + - or                     */
                relop,                  /* = <> < <= > >= in          */
                lparent,                /* (                          */
		rparent,                /* )                          */
		lbrack,                 /* [                          */
                rbrack,                 /* ]                          */
                comma,                  /* ,                          */
                semicolon,              /* ;                          */
                period,                 /* .                          */
                period2,                /* ..                         */
                arrow,                  /* ^                          */
                colon,                  /* :                          */
                becomes,                /* :=                         */
                labelsy,                /* label                      */
                constsy,                /* const                      */
                typesy,                 /* type                       */
                varsy,                  /* var                        */
                funcsy,                 /* func                       */
                progsy,                 /* program                    */
                procsy,                 /* procedure                  */
                setsy,                  /* set                        */
                packedsy,               /* packed                     */
                arraysy,                /* array                      */
                recordsy,               /* record                     */
                filesy,                 /* file                       */
                beginsy,                /* begin                      */
                ifsy,                   /* if                         */
                casesy,                 /* case                       */
                repeatsy,               /* repeat                     */
                whilesy,                /* while                      */
                forsy,                  /* for                        */
                withsy,                 /* with                       */
                gotosy,                 /* goto                       */
                endsy,                  /* end                        */
                elsesy,                 /* else                       */
                untilsy,                /* until                      */
                ofsy,                   /* of                         */
                dosy,                   /* do                         */
                tosy,                   /* to                         */
                downtosy,               /* downto                     */
                thensy,                 /* then                       */
                nilsy,                  /* nil                        */
                othersy                 /* その他の記号               */
             }  ;

/***************************************/
/* pascal の演算子の種類               */
/***************************************/
enum operator   {mul,                   /*    *                       */
                 rdiv,                  /*    /                       */
                 andop,                 /*    and                     */
                 idiv,                  /*    div                     */
                 imod,                  /*    mod                     */
                 plus,                  /*    +                       */
                 minus,                 /*    -                       */
                 orop,                  /*    or                      */
                 ltop,                  /*    <                       */
                 leop,                  /*    <=                      */
                 geop,                  /*    >=                      */
                 gtop,                  /*    >                       */
                 neop,                  /*    <>                      */
                 eqop,                  /*    =                       */
                 inop,                  /*    in                      */
                 noop                   /*    演算子でないもの        */
              } ;

/**********************************************************************/
/****       プログラムパラメータ(ファイル名) に関する型定義        ****/
/**********************************************************************/

typedef struct filerec  extfilep ;

struct filerec {
   char      filename[MaxIDlng+1] ;     /* ファイル名                 */
   extfilep  *nextfile            ;     /* 次へのポインタ             */
} ;

/*********************************************************************/
/****               label に関する型定義                          ****/
/*********************************************************************/

struct labl {
   lbp         *nextlab           ;     /* 次のlablアドレス           */
   boolean     defined            ;     /* 定義フラグ　               */
   int         labval             ;     /* pascalソース上のラベル値   */
   int         labname            ;     /* P-codeソース上のラベル値   */
}  ;

/*********************************************************************/
/****             constant(定数)に関する型定義                    ****/
/*********************************************************************/

enum cstclass { real,                   /* 実数型                     */
                pset,                   /* 集合型                     */
                strg } ;                /* 文字列型                   */

struct Constant {
   enum cstclass   cclass    ;          /* 定数の種別                 */
   union {
      char         *rval         ;      /* 実数の定数を格納           */
      Set          pval          ;      /* 集合値を格納               */
      char         *sval         ;      /* 文字列定数を格納           */
   }  c  ;
}  ;

union valu {
   long    ival   ;                     /* 整数､文字(1文字)           */
   csp     *valp  ;                     /* 上記以外はcspへのポインタ  */
} ;

/*********************************************************************/
/****         identifiler(名前) に関する型定義                    ****/
/*********************************************************************/

enum idclass {  types,                  /*  型                        */
                konst,                  /*  定数                      */
                vars,                   /*  変数                      */
                field,                  /*  レコードの欄              */
                proc,                   /*  手続き                    */
                func  };                /*  関数                      */

enum idkind   { actual,                 /*  実                        */
                formal }  ;             /*  仮                        */

enum declkind { standard,               /*  標準宣言                  */
                declared };             /*  ユーザ定義のもの          */

enum where       /****** displayで使い､この水準がどこの定義かを示す****/
              { blck  ,                 /* block で定義されている     */
                crec  ,                 /* constant record            */
                vrec  ,                 /* variable record            */
                rec    }  ;             /* record                     */

struct Identifier {
  char         name[MaxIDlng+1] ;  /* 名前                            */
  char         linkno           ;  /* 引数の名前並び番号(引数のみ有効)*/
  ctp          *llink           ;  /* 左へのポインタ                  */
  ctp          *rlink           ;  /* 右へのポインタ                  */
  stp          *idtype          ;  /* 名前の型                        */
  ctp          *next            ;  /* 順序がある場合次へのポインタ    */
  enum idclass klass            ;  /* 名前の種別                      */
  union  { /*n*/
    union valu values           ;  /* 定数 (konst)                    */
    struct  { /*v*/                /* 変数 (vars)                     */
      enum idkind vkind         ;  /*   変数の種別                    */
      int         vlev          ;  /*   定義された水準                */
      int         vaddr         ;  /*   変数の割りつけ開始アドレス    */
    } v                         ;
    int      fldaddr            ;  /* レコードの欄 (field)            */
    struct  { /*pf*/               /* 手続き、関数 (proc,func)        */
      enum declkind pfdeckind   ;  /*   宣言の種別 (standard/declared)*/
      union   { /*sd*/
        int   key               ;  /*[standard]  その識別数           */
        struct { /*d*/             /*[declared]                       */
          enum idkind pfkind    ;  /*     actual / formal             */
          int pflev             ;  /*     定義された水準              */
          union { /*af*/
            struct { /*a*/         /*[actual]                         */
              int pfname        ;  /*   p-codeラベル名                */
              boolean forwdecl  ;  /*   前方宣言                      */
	      ctp *fwdptr       ;  /*   前方宣言リスト                */
	    } a                 ;
	    struct { /*f*/         /*[formal]                         */
	      int levadr        ;  /*   水準の格納アドレス            */
	      int adradr        ;  /*   実行開始アドレスの格納アドレス*/
	      ctp *prm          ;  /*   仮引数へのポインタ            */
	    } f                 ;
	  } af                  ;
        } d                     ;
      } sd                      ;
    } pf                        ;
  } n                           ;
}                               ;

/*********************************************************************/
/****             data structure  に関する型定義                  ****/
/*********************************************************************/

enum structform {  scalar  ,    /* スカラー型 */
                   subrange,    /* 範囲型     */
                   pointer ,    /* ポインタ型 */
                   power   ,    /*            */
                   arrays  ,    /* 配列型     */
                   records ,    /* レコード型 */
                   files   ,    /* ファイル型 */
                   tagfld  ,    /* ﾀｸﾞﾌｨｰﾙﾄﾞ  */ /* not structure */
		   variant } ;  /* 変数型     */ /* not structure */

typedef enum packedkind         /* 集合型の詰めあり/なし型の種別      */
                 { unpacked,    /* 詰めなし (値0)････ falseと同じ     */
                   packed  ,    /* 詰めなし (値1)････ true と同じ     */
                   both    }    /* どちらでもない (集合構成子の場合)  */
        packedkind          ;

struct Structure {
   int              size           ;    /* その型のサイズ             */
   enum structform  form           ;    /* 型の種別                   */
   boolean          assignflag     ;    /* 代入可能な型の時  真       */
   union {
      struct {                          /*[scalar]                    */
         enum declkind scalkind    ;    /*  standard/declared         */
	 ctp           *fconst     ;    /*  declared時 next欄で       */
	                                /*    つながれる最後尾        */
      } sc                         ;
      struct {                          /*[subrange]                  */
	 stp           *rangetype  ;    /*  範囲の元となる型          */
         long          min         ;    /*  最小値                    */
         long          max         ;    /*  最大値                    */
      } su                         ;
      struct {                          /*[pointer]                   */
	 stp           *eltype     ;    /*  指し示すものの型          */
      } pt                         ;
      struct {                          /*[power]                     */
         packedkind    packed      ;    /*  詰めあり/なし/両方        */
	 stp           *elset      ;    /*  要素の型                  */
	 int           elmin       ;    /*  要素の最小値              */
	 int           elmax       ;    /*  要素の最大値              */
      } pw                         ;
      struct {                          /*[arrays]                    */
         boolean       packed      ;    /*  packed表示                */
	 stp           *aeltype    ;    /*  要素の型                  */
	 stp           *inxtype    ;    /*  添え字の型                */
      } ar                         ;
      struct {                          /*[records]                   */
         boolean       packed      ;    /*  packed表示                */
	 ctp           *fstfld     ;    /*  レコードの最初の欄        */
	 stp           *recvar     ;    /*  可変部のtagfldをもつstp   */
      } re                         ;
      struct {                          /*[files]                     */
         boolean       packed      ;    /*  packed表示                */
         boolean       texttype    ;    /*  text型の時 真             */
	 stp           *filtype    ;    /*  ファイルの要素の型        */
      } fi                         ;
      struct {                          /*[tagfld] 可変要素選択子     */
	 ctp           *tagfieldp  ;    /*  タグ欄の名前              */
	 stp           *tagtype    ;    /*  タグ型                    */
	 stp           *fstvar     ;    /*  可変要素へのポインタ      */
      } tg                         ;
      struct {                          /*[variant] 可変要素          */
	 stp           *nextvr     ;    /*  次の可変要素              */
	 stp           *subvar     ;    /*  配下の可変部              */
         long          varval      ;    /*  選択定数の値              */
      } vr                         ;
   } sf                            ;
}                                  ;

/*********************************************************************/
/****                     式  に関する型定義                      ****/
/*********************************************************************/

enum attrkind {
                cst ,                   /* 定数                       */
                varbl,                  /* 変数                       */
                expr  };                /* 式                         */

enum vaccess {
                drct   ,                /* 直接                       */
                indrct                  /* 間接                       */
             }         ;

typedef struct attr {
   stp             *typtr ;             /* 型へのアドレス             */
   enum attrkind   kind   ;             /* cst/varbl/expr             */
  /*** kind=cst の 場合 ***/
   union valu      cval   ;             /*[cst]  定数の値             */
  /*** kind=varbl  の場合 ***/
   enum  vaccess   access ;             /* drct/indrct                */
   int   vlevel           ;             /*[drct] 定義された水準       */
   int   dplmt            ;             /*[drct] 割りつけ開始番地     */
   int   idplmt           ;             /*[indrct]                    */
} attr ;

/*********************************************************************/
/****             共通変数                                        ****/
/*********************************************************************/

/**** display *****/

typedef struct Aplist aplist ;
struct Aplist {                 /* 同一水準で参照された名前リスト   */
   ctp        *name      ;
   aplist     *next      ;
}                        ;

EXTERN int top           ;      /* display の 現在のトップを示すもの*/
EXTERN int level         ;      /* 現在の水準                       */
EXTERN int disx          ;      /* searchidで見つかった水準         */
                                /*  共通変数になっているのはよくない*/
EXTERN int mainlabel     ;      /* メインブロックのP-codeラベル値   */

EXTERN struct {
   ctp         *fname    ;      /* その水準で定義した名前リスト     */
   lbp         *flabel   ;      /* その水準のラベルリスト           */
   ctp         *funcname ;      /* その水準の関数名                 */
   aplist      *aname    ;      /* その水準での引用名リスト         */
   boolean     funcassign;      /* その水準の関数名への代入表示     */
   enum where  occur     ;      /* その水準の定義される場所を示す   */
   int         clev      ;      /*[occur=crec]*/
   int         cdspl     ;      /*[occur=crec]*/
   int         vdspl     ;      /*[occur=vrec]*/
} display[Displimit+1]   ;

/**** symbol set *****/
EXTERN Set constbegsys   ;      /* constant begin symbol set    */
EXTERN Set simptypebegsys;      /* simple type begin symbol set */
EXTERN Set typebegsys    ;      /* type begin symbol set        */
EXTERN Set blockbegsys   ;      /* block begin symbol set       */
EXTERN Set selectsys     ;      /* selector symbol set          */
EXTERN Set facbegsys     ;      /* factor begin symbol set      */
EXTERN Set statbegsys    ;      /* statement begin symbol set   */
EXTERN Set statfolsys    ;      /* statement follow symbol set  */
EXTERN Set typedels      ;      /* typed element symbol set     */

/**** returned by insymbol() *****/

EXTERN enum symbol   sy ;       /* 要素のsymbol  */
EXTERN enum operator op ;       /* 演算子        */
EXTERN char id[MaxIDlng+1] ;    /* identifier    */
EXTERN int  ch ;                /* 読込文字      */
EXTERN int           lgth  ;    /* 文字列等の長さ*/
EXTERN union valu    val   ;    /* 値            */

/**** pointers ****/

EXTERN extfilep  *fextfilep ;           /* ﾌﾟﾛｸﾞﾗﾑ引数(ﾌｧｲﾙ名)ﾎﾟｲﾝﾀ */

EXTERN stp *parmptr ;
EXTERN stp *intptr  ;
EXTERN stp *realptr ;
EXTERN stp *charptr ;
EXTERN stp *boolptr ;
EXTERN stp *nilptr  ;
EXTERN stp *textptr ;

EXTERN ctp *fwptr   ;    /* ポインタ型の前方参照のものをつないでおく  */

EXTERN ctp *utypptr ;    /* 型名が未定義の時に返却する名前ポインタ    */
EXTERN ctp *ucstptr ;    /* 定数名が未定義の時に返却する名前ポインタ  */
EXTERN ctp *uvarptr ;    /* 変数名が未定義の時に返却する名前ポインタ  */
EXTERN ctp *ufldptr ;    /* フィールド名が未定義の時に返却する名前ポインタ*/
EXTERN ctp *uprcptr ;    /* 手続き名が未定義の時に返却する名前ポインタ*/
EXTERN ctp *ufctptr ;    /* 関数名が未定義の時に返却する名前ポインタ  */


/**** flags ****/

EXTERN boolean defineinput ;     /* input ファイル定義あり の時 真    */
EXTERN boolean defineoutput;     /* outputファイル定義あり の時 真    */
EXTERN boolean pcode ;           /* Pコードの出力要否                 */
EXTERN boolean debug ;           /* デバッグコンパイル指定            */
EXTERN boolean pcdinf;           /* Pコードの情報出力要否             */
EXTERN boolean typevar;          /* 型定義部での型の処理を行う時true
                                   変数定義部での型の処理を行う時false
                              (ポインタ型前方参照チェックのために使用 */

/**** Pcode 関連 ****/
EXTERN int topnew    ;        /* その命令を実行した時のスタックの先頭 */
EXTERN int topmax    ;        /* 最も大きくなる場合のスタックの先頭   */
EXTERN int ic        ;        /* instruction counter                  */
EXTERN int lc        ;        /* location   counter (変数の割当番地)  */

/**** list 関係 ****/
EXTERN int   lineno;                    /* ソースの行番号             */
EXTERN char  *passname;                 /* Pascal source file name    */
EXTERN int   errorcount  ;              /* 発見したエラー数           */

/**** 式のコンパイル時に使用する属性エリア ****/
EXTERN attr gattr           ;
