Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ctype.h>

#pragma lib     "../cc/cc.a$O"

#ifndef EXTERN
#define EXTERN  extern
#endif

typedef struct  Node    Node;
typedef struct  Sym     Sym;
typedef struct  Type    Type;
typedef struct  Funct   Funct;
typedef struct  Decl    Decl;
typedef struct  Io      Io;
typedef struct  Hist    Hist;
typedef struct  Term    Term;
typedef struct  Init    Init;
typedef struct  Bits    Bits;

typedef Rune    TRune;  /* target system type */

#define NHUNK           50000L
#define BUFSIZ          8192
#define NSYMB           1500
#define NHASH           1024
#define STRINGSZ        200
#define HISTSZ          20
#define YYMAXDEPTH      1500
#define NTERM           10
#define MAXALIGN        7

#define SIGN(n)         (1ULL<<(n-1))
#define MASK(n)         (SIGN(n)|(SIGN(n)-1))

#define BITS    5
#define NVAR    (BITS*sizeof(ulong)*8)
struct  Bits
{
        ulong   b[BITS];
};

struct  Node
{
        Node*   left;
        Node*   right;
        void*   label;
        long    pc;
        int     reg;
        long    xoffset;
        double  fconst;         /* fp constant */
        vlong   vconst;         /* non fp const */
        char*   cstring;        /* character string */
        TRune*  rstring;        /* rune string */

        Sym*    sym;
        Type*   type;
        long    lineno;
        char    op;
        char    oldop;
        char xcast;
        char    class;
        char    etype;
        char    complex;
        char    addable;
        char    scale;
        char    garb;
};
#define Z       ((Node*)0)

struct  Sym
{
        Sym*    link;
        Type*   type;
        Type*   suetag;
        Type*   tenum;
        char*   macro;
        long    varlineno;
        long    offset;
        vlong   vconst;
        double  fconst;
        Node*   label;
        ushort  lexical;
        char    *name;
        ushort  block;
        ushort  sueblock;
        char    class;
        char    sym;
        char    aused;
        char    sig;
};
#define S       ((Sym*)0)

enum{
        SIGNONE = 0,
        SIGDONE = 1,
        SIGINTERN = 2,

        SIGNINTERN = 1729*325*1729,
};

struct  Decl
{
        Decl*   link;
        Sym*    sym;
        Type*   type;
        long    varlineno;
        long    offset;
        short   val;
        ushort  block;
        char    class;
        char    aused;
};
#define D       ((Decl*)0)

struct  Type
{
        Sym*    sym;
        Sym*    tag;
        Funct*  funct;
        Type*   link;
        Type*   down;
        long    width;
        long    offset;
        long    lineno;
        schar   shift;
        char    nbits;
        char    etype;
        char    garb;
};

#define T       ((Type*)0)
#define NODECL  ((void(*)(int, Type*, Sym*))0)

struct  Init                    /* general purpose initialization */
{
        int     code;
        ulong   value;
        char*   s;
};

EXTERN struct
{
        char*   p;
        int     c;
} fi;

struct  Io
{
        Io*     link;
        char*   p;
        char    b[BUFSIZ];
        short   c;
        short   f;
};
#define I       ((Io*)0)

struct  Hist
{
        Hist*   link;
        char*   name;
        long    line;
        long    offset;
};
#define H       ((Hist*)0)
EXTERN Hist*    hist;

struct  Term
{
        vlong   mult;
        Node    *node;
};

enum
{
        Axxx,
        Ael1,
        Ael2,
        Asu2,
        Aarg0,
        Aarg1,
        Aarg2,
        Aaut3,
        NALIGN,
};

enum                            /* also in ../{8a,0a}.h */
{
        Plan9   = 1<<0,
        Unix    = 1<<1,
        Windows = 1<<2,
};

enum
{
        DMARK,
        DAUTO,
        DSUE,
        DLABEL,
};
enum
{
        OXXX,
        OADD,
        OADDR,
        OAND,
        OANDAND,
        OARRAY,
        OAS,
        OASI,
        OASADD,
        OASAND,
        OASASHL,
        OASASHR,
        OASDIV,
        OASHL,
        OASHR,
        OASLDIV,
        OASLMOD,
        OASLMUL,
        OASLSHR,
        OASMOD,
        OASMUL,
        OASOR,
        OASSUB,
        OASXOR,
        OBIT,
        OBREAK,
        OCASE,
        OCAST,
        OCOMMA,
        OCOND,
        OCONST,
        OCONTINUE,
        ODIV,
        ODOT,
        ODOTDOT,
        ODWHILE,
        OENUM,
        OEQ,
        OFOR,
        OFUNC,
        OGE,
        OGOTO,
        OGT,
        OHI,
        OHS,
        OIF,
        OIND,
        OINDREG,
        OINIT,
        OLABEL,
        OLDIV,
        OLE,
        OLIST,
        OLMOD,
        OLMUL,
        OLO,
        OLS,
        OLSHR,
        OLT,
        OMOD,
        OMUL,
        ONAME,
        ONE,
        ONOT,
        OOR,
        OOROR,
        OPOSTDEC,
        OPOSTINC,
        OPREDEC,
        OPREINC,
        OPROTO,
        OREGISTER,
        ORETURN,
        OSET,
        OSIGN,
        OSIZE,
        OSTRING,
        OLSTRING,
        OSTRUCT,
        OSUB,
        OSWITCH,
        OUNION,
        OUSED,
        OWHILE,
        OXOR,
        ONEG,
        OCOM,
        OPOS,
        OELEM,

        OTST,           /* used in some compilers */
        OINDEX,
        OFAS,
        OREGPAIR,
        OEXREG,

        OEND
};
enum
{
        TXXX,
        TCHAR,
        TUCHAR,
        TSHORT,
        TUSHORT,
        TINT,
        TUINT,
        TLONG,
        TULONG,
        TVLONG,
        TUVLONG,
        TFLOAT,
        TDOUBLE,
        TIND,
        TFUNC,
        TARRAY,
        TVOID,
        TSTRUCT,
        TUNION,
        TENUM,
        TDOT,
        NTYPE,

        TAUTO   = NTYPE,
        TEXTERN,
        TSTATIC,
        TTYPEDEF,
        TTYPESTR,
        TREGISTER,
        TCONSTNT,
        TVOLATILE,
        TUNSIGNED,
        TSIGNED,
        TFILE,
        TOLD,
        NALLTYPES,

        /* adapt size of Rune to target system's size */
        TRUNE = sizeof(TRune)==4? TUINT: TUSHORT,
};
enum
{
        CXXX,
        CAUTO,
        CEXTERN,
        CGLOBL,
        CSTATIC,
        CLOCAL,
        CTYPEDEF,
        CTYPESTR,
        CPARAM,
        CSELEM,
        CLABEL,
        CEXREG,
        NCTYPES,
};
enum
{
        GXXX            = 0,
        GCONSTNT        = 1<<0,
        GVOLATILE       = 1<<1,
        NGTYPES         = 1<<2,

        GINCOMPLETE     = 1<<2,
};
enum
{
        BCHAR           = 1L<<TCHAR,
        BUCHAR          = 1L<<TUCHAR,
        BSHORT          = 1L<<TSHORT,
        BUSHORT         = 1L<<TUSHORT,
        BINT            = 1L<<TINT,
        BUINT           = 1L<<TUINT,
        BLONG           = 1L<<TLONG,
        BULONG          = 1L<<TULONG,
        BVLONG          = 1L<<TVLONG,
        BUVLONG         = 1L<<TUVLONG,
        BFLOAT          = 1L<<TFLOAT,
        BDOUBLE         = 1L<<TDOUBLE,
        BIND            = 1L<<TIND,
        BFUNC           = 1L<<TFUNC,
        BARRAY          = 1L<<TARRAY,
        BVOID           = 1L<<TVOID,
        BSTRUCT         = 1L<<TSTRUCT,
        BUNION          = 1L<<TUNION,
        BENUM           = 1L<<TENUM,
        BFILE           = 1L<<TFILE,
        BDOT            = 1L<<TDOT,
        BCONSTNT        = 1L<<TCONSTNT,
        BVOLATILE       = 1L<<TVOLATILE,
        BUNSIGNED       = 1L<<TUNSIGNED,
        BSIGNED         = 1L<<TSIGNED,
        BAUTO           = 1L<<TAUTO,
        BEXTERN         = 1L<<TEXTERN,
        BSTATIC         = 1L<<TSTATIC,
        BTYPEDEF        = 1L<<TTYPEDEF,
        BTYPESTR        = 1L<<TTYPESTR,
        BREGISTER       = 1L<<TREGISTER,

        BINTEGER        = BCHAR|BUCHAR|BSHORT|BUSHORT|BINT|BUINT|
                                BLONG|BULONG|BVLONG|BUVLONG,
        BNUMBER         = BINTEGER|BFLOAT|BDOUBLE,

/* these can be overloaded with complex types */

        BCLASS          = BAUTO|BEXTERN|BSTATIC|BTYPEDEF|BTYPESTR|BREGISTER,
        BGARB           = BCONSTNT|BVOLATILE,
};

struct  Funct
{
        Sym*    sym[OEND];
        Sym*    castto[NTYPE];
        Sym*    castfr[NTYPE];
};

EXTERN struct
{
        Type*   tenum;          /* type of entire enum */
        Type*   cenum;          /* type of current enum run */
        vlong   lastenum;       /* value of current enum */
        double  floatenum;      /* value of current enum */
} en;

EXTERN  int     autobn;
EXTERN  long    autoffset;
EXTERN  int     blockno;
EXTERN  Decl*   dclstack;
EXTERN  char    debug[256];
EXTERN  Hist*   ehist;
EXTERN  long    firstbit;
EXTERN  Sym*    firstarg;
EXTERN  Type*   firstargtype;
EXTERN  Decl*   firstdcl;
EXTERN  int     fperror;
EXTERN  Sym*    hash[NHASH];
EXTERN  int     hasdoubled;
EXTERN  char*   hunk;
EXTERN  char**  include;
EXTERN  Io*     iofree;
EXTERN  Io*     ionext;
EXTERN  Io*     iostack;
EXTERN  long    lastbit;
EXTERN  char    lastclass;
EXTERN  Type*   lastdcl;
EXTERN  long    lastfield;
EXTERN  Type*   lasttype;
EXTERN  long    lineno;
EXTERN  long    nearln;
EXTERN  int     maxinclude;
EXTERN  int     nerrors;
EXTERN  int     newflag;
EXTERN  long    nhunk;
EXTERN  int     ninclude;
EXTERN  Node*   nodproto;
EXTERN  Node*   nodcast;
EXTERN  Biobuf  outbuf;
EXTERN  Biobuf  diagbuf;
EXTERN  char*   outfile;
EXTERN  char*   pathname;
EXTERN  int     peekc;
EXTERN  long    stkoff;
EXTERN  Type*   strf;
EXTERN  Type*   strl;
EXTERN  char    symb[NSYMB];
EXTERN  Sym*    symstring;
EXTERN  int     taggen;
EXTERN  Type*   tfield;
EXTERN  Type*   tufield;
EXTERN  int     thechar;
EXTERN  char*   thestring;
EXTERN  Type*   thisfn;
EXTERN  long    thunk;
EXTERN  Type*   types[NTYPE];
EXTERN  Type*   fntypes[NTYPE];
EXTERN  Node*   initlist;
EXTERN  Term    term[NTERM];
EXTERN  int     nterm;
EXTERN  int     packflg;
EXTERN  int     fproundflg;
EXTERN  int     profileflg;
EXTERN  int     ncontin;
EXTERN  int     newvlongcode;
EXTERN  int     canreach;
EXTERN  int     warnreach;
EXTERN  Bits    zbits;

extern  char    *onames[], *tnames[], *gnames[];
extern  char    *cnames[], *qnames[], *bnames[];
extern  char    tab[NTYPE][NTYPE];
extern  char    comrel[], invrel[], logrel[];
extern  long    ncast[], tadd[], tand[];
extern  long    targ[], tasadd[], tasign[], tcast[];
extern  long    tdot[], tfunct[], tindir[], tmul[];
extern  long    tnot[], trel[], tsub[];

extern  char    typeaf[];
extern  char    typefd[];
extern  char    typei[];
extern  char    typesu[];
extern  char    typesuv[];
extern  char    typeu[];
extern  char    typev[];
extern  char    typec[];
extern  char    typeh[];
extern  char    typeil[];
extern  char    typeilp[];
extern  char    typechl[];
extern  char    typechlv[];
extern  char    typechlvp[];
extern  char    typechlp[];
extern  char    typechlpfd[];

EXTERN  char*   typeswitch;
EXTERN  char*   typeword;
EXTERN  char*   typecmplx;

extern  ulong   thash1;
extern  ulong   thash2;
extern  ulong   thash3;
extern  ulong   thash[];

/*
 *      compat.c/unix.c/windows.c
 */
int     mywait(int*);
int     mycreat(char*, int);
int     systemtype(int);
int     pathchar(void);
int     myaccess(char*);
char*   mygetwd(char*, int);
int     myexec(char*, char*[]);
int     mydup(int, int);
int     myfork(void);
int     mypipe(int*);
void*   mysbrk(ulong);

/*
 *      parser
 */
int     yyparse(void);
int     mpatov(char*, vlong*);

/*
 *      lex.c
 */
void*   allocn(void*, long, long);
void*   alloc(long);
void    cinit(void);
int     compile(char*, char**, int);
void    errorexit(void);
int     filbuf(void);
int     getc(void);
long    getr(void);
int     getnsc(void);
Sym*    lookup(void);
void    main(int, char*[]);
void    newfile(char*, int);
void    newio(void);
void    pushio(void);
long    escchar(long, int, int);
Sym*    slookup(char*);
void    syminit(Sym*);
void    unget(int);
long    yylex(void);
int     Lconv(Fmt*);
int     Tconv(Fmt*);
int     FNconv(Fmt*);
int     Oconv(Fmt*);
int     Qconv(Fmt*);
int     VBconv(Fmt*);
void    setinclude(char*);

/*
 * mac.c
 */
void    dodefine(char*);
void    domacro(void);
Sym*    getsym(void);
long    getnsn(void);
void    linehist(char*, int);
void    macdef(void);
void    macprag(void);
void    macend(void);
void    macexpand(Sym*, char*);
void    macif(int);
void    macinc(void);
void    maclin(void);
void    macund(void);

/*
 * dcl.c
 */
Node*   doinit(Sym*, Type*, long, Node*);
Type*   tcopy(Type*);
Node*   init1(Sym*, Type*, long, int);
Node*   newlist(Node*, Node*);
void    adecl(int, Type*, Sym*);
int     anyproto(Node*);
void    argmark(Node*, int);
void    dbgdecl(Sym*);
Node*   dcllabel(Sym*, int);
Node*   dodecl(void(*)(int, Type*, Sym*), int, Type*, Node*);
Sym*    mkstatic(Sym*);
void    doenum(Sym*, Node*);
void    snap(Type*);
Type*   dotag(Sym*, int, int);
void    edecl(int, Type*, Sym*);
Type*   fnproto(Node*);
Type*   fnproto1(Node*);
void    markdcl(void);
Type*   paramconv(Type*, int);
void    pdecl(int, Type*, Sym*);
Decl*   push(void);
Decl*   push1(Sym*);
Node*   revertdcl(void);
long    round(long, int);
int     rsametype(Type*, Type*, int, int);
int     sametype(Type*, Type*);
ulong   sign(Sym*);
ulong   signature(Type*);
void    sualign(Type*);
void    tmerge(Type*, Sym*);
void    walkparam(Node*, int);
void    xdecl(int, Type*, Sym*);
Node*   contig(Sym*, Node*, long);

/*
 * com.c
 */
void    ccom(Node*);
void    complex(Node*);
int     tcom(Node*);
int     tcoma(Node*, Node*, Type*, int);
int     tcomd(Node*);
int     tcomo(Node*, int);
int     tcomx(Node*);
int     tlvalue(Node*);
void    constas(Node*, Type*, Type*);
Node*   uncomma(Node*);
Node*   uncomargs(Node*);

/*
 * con.c
 */
void    acom(Node*);
void    acom1(vlong, Node*);
void    acom2(Node*, Type*);
int     acomcmp1(const void*, const void*);
int     acomcmp2(const void*, const void*);
int     addo(Node*);
void    evconst(Node*);

/*
 * funct.c
 */
int     isfunct(Node*);
void    dclfunct(Type*, Sym*);

/*
 * sub.c
 */
void    arith(Node*, int);
int     deadheads(Node*);
Type*   dotsearch(Sym*, Type*, Node*, long*);
long    dotoffset(Type*, Type*, Node*);
void    gethunk(void);
Node*   invert(Node*);
int     bitno(long);
void    makedot(Node*, Type*, long);
int     mixedasop(Type*, Type*);
Node*   new(int, Node*, Node*);
Node*   new1(int, Node*, Node*);
int     nilcast(Type*, Type*);
int     nocast(Type*, Type*);
void    prtree(Node*, char*);
void    prtree1(Node*, int, int);
void    relcon(Node*, Node*);
int     relindex(int);
int     simpleg(long);
Type*   garbt(Type*, long);
int     simplec(long);
Type*   simplet(long);
int     stcompat(Node*, Type*, Type*, long[]);
int     tcompat(Node*, Type*, Type*, long[]);
void    tinit(void);
Type*   typ(int, Type*);
Type*   copytyp(Type*);
void    typeext(Type*, Node*);
void    typeext1(Type*, Node*);
int     side(Node*);
int     vconst(Node*);
int     log2(uvlong);
int     vlog(Node*);
int     topbit(ulong);
void    simplifyshift(Node*);
long    typebitor(long, long);
void    diag(Node*, char*, ...);
void    warn(Node*, char*, ...);
void    yyerror(char*, ...);
void    fatal(Node*, char*, ...);

/*
 * acid.c
 */
void    acidtype(Type*);
void    acidvar(Sym*);

/*
 * pickle.c
 */
void    pickletype(Type*);

/*
 * bits.c
 */
Bits    bor(Bits, Bits);
Bits    band(Bits, Bits);
Bits    bnot(Bits);
int     bany(Bits*);
int     bnum(Bits);
Bits    blsh(uint);
int     beq(Bits, Bits);
int     bset(Bits, uint);

/*
 * dpchk.c
 */
void    dpcheck(Node*);
void    arginit(void);
void    pragvararg(void);
void    pragpack(void);
void    pragfpround(void);
void pragprofile(void);
void    pragincomplete(void);

/*
 * calls to machine depend part
 */
void    codgen(Node*, Node*);
void    gclean(void);
void    gextern(Sym*, Node*, long, long);
void    ginit(void);
long    outstring(char*, long);
long    outlstring(TRune*, long);
void    xcom(Node*);
long    exreg(Type*);
long    align(long, Type*, int);
long    maxround(long, long);

extern  schar   ewidth[];

/*
 * com64
 */
int     com64(Node*);
void    com64init(void);
void    bool64(Node*);
double  convvtof(vlong);
vlong   convftov(double);
double  convftox(double, int);
vlong   convvtox(vlong, int);

/*
 * machcap
 */
int     machcap(Node*);

#pragma varargck        argpos  warn    2
#pragma varargck        argpos  diag    2
#pragma varargck        argpos  yyerror 1

#pragma varargck        type    "F"     Node*
#pragma varargck        type    "L"     long
#pragma varargck        type    "Q"     long
#pragma varargck        type    "O"     int
#pragma varargck        type    "T"     Type*
#pragma varargck        type    "|"     int