#ifndef MODILES_H
#define MODULES_H
#define ModuleLabelFormat "%s_MODULE_"
#include "symbol.h"

struct ModuleList
  { /* each module maintains a list(s) of modules it references */
    struct ModuleList *next;
    struct Module *module;
    char included; /* 1 if *: LOAD module */
    char isPrivate;
    char *name;	/* file name used to load module */
/* char implicit; * generated transitively - or perhaps maintain two lists?*/
  };

#define ModuleError 1
struct Module : public Package
  {
    struct ModuleList *imported;
    struct ModuleList **lastMod;
    RootPtr temp; /* kind==1: expression; kind==2: struct bfile_data * */
    struct Block *block; /* points to "self" if kind != 1 */
    struct TraverseData *tr_data;
    char kind; /* 0 = unknown; 1 = Src; 2 = Bin; 4 = loaded; 8 = syms */
    char flags;
    struct HashTable *modsIncluded; /* used by ModPutModule */
    Module *nextToCompile;
    struct MacroTable *parseTable;
    Symbol * file_name;
    struct Declaration *lookupDecls;
    Module(Symbol *n);
//    Name name;
#if 0
    struct HashTable *syms; /* internally visible symbols */
    struct ModuleList *requiredModules; /* list of:: id: LOAD module */
/* need list of all directly required modules, for Qx file and linker
   for compiling other modules, need:
   a: list of all (directly) exported declarations
   b: list of all (transitively) non-private included modules
   c: ditto non-transitive (direct) list.
   a and c can be in Qx file, and b can be generated from c.
   When compiling, need symbol table for each module
   - map identifier to (list of) global declarations
   This can be generated from:
   - list of all globals for this module (private and public)
   - list of all included modules (direct list=>transitive one)
 */
    struct ModuleList *exportedModules; /* list of:: *: LOAD module */
    struct ModuleList *internalModules; /* list of:: PRIVATE *: module */
/* also need transitive closure of the two?one latter */
/* list of global declarations for this module; some PRIVATE */
#endif
  };
extern struct Module *ModulesToCompile; //list of modules to be saved on finish

enum Language {
    UnknownLanguage,
    QLanguage,
    LispLanguage,
    SchemeLanguage
};
extern Language DefaultLanguage;

extern struct Module * LookupModule(Symbol* module_name);
EXTERN struct ModuleList * ReadModule(char *file_name, struct Module *into);
extern struct Module * CheckModule(char *file_name);
extern Root* EvalModule(struct Module *module);
extern void PreEvalModule(struct Module *module);
extern void SaveModule(struct Module *module, int compiling);
extern struct Module *DefaultModule;
extern struct lsymbol_table *GlobalLabels;
extern int *global_label_hashtab;
extern int GetDirectoryPrefixLength(char *name);
#endif /* MODULES_H */
