#ifndef NCTREF_VARTABLE_H #define NCTREF_VARTABLE_H #include"types.h" #include struct Token; union AST; typedef enum { VARTABLEENTRY_SYMBOL, VARTABLEENTRY_VAR, VARTABLEENTRY_TYPE, VARTABLEENTRY_CEXPR } VarTableEntryKind; union AST; typedef struct UseDef { union AST *def; // assign stmt union AST *use; // corresponding AST_EXPR_VAR union AST *stmt; // whole using stmt struct UseDef *next; } UseDef; // Stack, necessary for "possible reaching defs" such as from if statements typedef struct ReachingDefs { size_t defCount; union AST **defs; int excludeParent; struct ReachingDefs *parent; } ReachingDefs; struct ReachingDefs *reachingdefs_push(struct ReachingDefs*); struct ReachingDefs *reachingdefs_coalesce(struct ReachingDefs*); void reachingdefs_set(struct ReachingDefs*, union AST*); struct VarTable; typedef struct VarTableEntry { Type *type; struct VarTable *owner; VarTableEntryKind kind; struct { union { struct { char isLocal; char isExternal; const char *name; struct { struct Token *rangeTokens; size_t startTokI; size_t endTokI; } genfunc; } symbol; struct { // For debugging const char *name; // Register allocation // vars in loops have higher priority // a more advanced approach would be to use weights for different colors (e.g. multipliers "should" be in eax) uint8_t priority; int16_t color, degree; bool precolored; // Used during parsing ReachingDefs *reachingDefs; // Optimizations UseDef *usedefFirst; UseDef *usedefLast; } var; struct { Type *ptr; } type; struct { // cexpr is used for expression parametization as opposed to type parametrization // I don't like the idea of having a special VarTableEntry kind for these, but all other places were worse const char *paramName; size_t paramIdx; // If the cexpr has been parametrized (as opposed to just being a symbol), this field will be non-NULL union AST *concrete; } cexpr; }; } data; } VarTableEntry; typedef struct VarTable { struct VarTable *parent; size_t count; const char **names; VarTableEntry **data; } VarTable; VarTable *vartable_new(VarTable*); VarTableEntry *vartable_get(VarTable*, const char*); VarTableEntry *vartable_find(VarTable*, const char*); VarTableEntry *vartable_set(VarTable*, const char*, VarTableEntry*); VarTable *vartable_merge(VarTable *child); //void vartable_new_reachingdefs_for_all_vars(VarTable*); //void vartable_coalesce_reachingdefs_for_all_vars(VarTable*); void vte_precolor(VarTableEntry *vte, int color); #endif