/* Copyright Per Bothner 1987. Read the file Q-INFO */
#include <expression.h>
#if 0
#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
#include <obstack.h>
#endif
#define MAX_BLOCK_LEVEL 50
struct VarStateLink
  {
    struct VarStateLink *next; /* chain together in same level, VarStateList */
    struct Declaration *decl;
    struct VarStateLink *down; /* chain together for same Declaration */
    short saveFlags;
    short level;
  };

struct VarStateList
  {
    struct VarStateList *next, **prev;
    struct VarStateLink *first;
    short level;
  };

#define BindPass 1
#define OptPass 2

struct TraverseData {
    struct VarStateList *varStates;
    struct Location sourcePos;
    struct Identifier *(*notFoundId)(struct Identifier *,struct TraverseData*);
    struct Block *curBlock;
    struct ProcExpr *curProc;
    struct Module *curModule;
    char pass;
    char FILLER1; /* was: level */
    short flags;
    char errors;
    unsigned char displayMax;;
    short nesting;
    struct HashTable *symTab;
    struct LoopConsExpr *visibleLoopConsList;
    struct Identifier **identPtr; /* used when copying expressions */
    struct ProcExpr *pendingProcs;
    struct Block *(level2block[MAX_BLOCK_LEVEL]);
    struct CFile *compile_to; /* Destination used by Lisp compile-file. */
    struct LoopConsExpr *curLoopCons;
#ifdef __cplusplus
    TraverseData(struct Module *);
    ~TraverseData();
    void clear(struct Module *);
    int topLevel() { return curBlock->enclosing == NULL; }
#endif
};

struct NameDecl {Name name; struct Declaration *decl; };

/* values for flags */
#define TraverseInArgList 1
#define TraverseInQuote 2
#define TraverseInUnify 4 /* used by TraverseUnify and CheckFreeIdent */
#define TraverseLisp 8
#define TraverseScheme 16

extern Expr* ExprTraverse(Expr* p, struct TraverseData *data);
extern struct VarStateList * NewVarState(struct TraverseData *data);
extern void MergeVarState(struct VarStateList *, struct TraverseData *);
extern void SwapVarState(struct VarStateList *state, struct TraverseData *);
extern void TrError(struct TraverseData *data, char *format, ...);
extern void BlockScan(struct Block *block, struct TraverseData *data);
extern void BlockPopDecls(struct TraverseData *data, struct Block *block);
extern void BlockAssignFields(struct Block *block, struct TraverseData *data);
extern void PushDecl(struct TraverseData *data, struct Declaration *decl);
extern struct Block *
TraverseForEval(struct Block *block, struct TraverseData *data);
extern Expr *ExpandForms(Root *forms, TraverseData *, Block *block=NULL);
extern void ExpandLispBody(ProcExpr *proc, TraverseData *);
extern void PushPendingProc(Function *func, struct TraverseData *data);
extern void PopPendingProcs(TraverseData *data);
extern Type* ExprToType(Expr *expr, TraverseData *data);
