[符号表]関数の実装


シンボル表の実現方法は様々ですが、テストに合格すれば大丈夫です.ここでは一つの参照的実現を示した.
    まず、符号表に関する構造体です.これはdatastruct.hの中に置いたほうがいいです.
/*     ,              */
struct VarCell {
    char* ident;        //    
    int addr;           //    
    AcceptType type;    //   
    int nrDim;          //   
    int* dims;          //      
};

/*
 * varList:        ,         VarCell*
 *
 * baseAddr:             
 *
 * used:            
 */
struct SymbolTable {
    struct LinkedList varList;
    int baseAddr;
    int used;
};
    そして関数の実装
#include<string.h>

struct SymbolTable* newSymbolTable(int base)
{
    struct SymbolTable* table = (struct SymbolTable*)
                                allocate(sizeof(struct SymbolTable));
    table->baseAddr = base;
    table->used = 0;
    initLinkedList(&(table->varList));
    return table;
}

void finalizeSymbolTable(struct SymbolTable* table)
{
    struct Iterator* i;
    struct VarCell* v;
    //         
    for_each (i, &(table->varList)) {
        v = (struct VarCell*)(i->current(i));
        revert(v->ident);
        if (0 != v->nrDim) {
            revert(v->dims);
        }
        revert(v);
    }
    table->varList.finalize(&(table->varList));
    revert(table);
}

SymbolTableError regVar(struct SymbolTable* table, char* ident,
                        AcceptType type, int nrDim, int* dims)
{
    struct Iterator* i;
    struct VarCell* v;
    //                  
    for_each (i, &(table->varList)) {
        v = (struct VarCell*)(i->current(i));
        if (0 == strcmp(v->ident, ident)) {
            i->terminate(i);
            return SymTab_MultiDef;
        }
    }

    struct VarCell* toAdd = (struct VarCell*)allocate(sizeof(struct VarCell));
    toAdd->addr = table->baseAddr + table->used;
    toAdd->type = type;
    int varSize = INTEGER == type ? INT_SIZE : REAL_SIZE, used = varSize;
    // INT_SIZE   REAL_SIZE              ,           sizeof(int)   sizeof(double)
    toAdd->nrDim = nrDim;
    if (0 != toAdd->nrDim) {
        toAdd->dims = (int*)allocate(sizeof(int) * nrDim);
        int j, k,* ptr;
        //     dims       ,             
        for (j = 0; j < toAdd->nrDim; ++j) {
            toAdd->dims[j] = varSize;
            used *= dims[j];
            for (k = 0; k < j; ++k) {
                toAdd->dims[j] *= dims[k];
            }
        }
    } else {
        toAdd->dims = NULL;
    }

    toAdd->ident = (char*)allocate(sizeof(char) * (1 + strlen(ident)));
    strcpy(toAdd->ident, ident);

    //      ,            
    table->varList.add(&(table->varList), toAdd);
    table->used += used;
    // MAX_VAR_IN_STACK                 
    if (MAX_VAR_IN_STACK <= table->used + table->baseAddr) {
        table->used -= varSize;
        int j;
        for (j = 0; j < toAdd->nrDim; ++j) {
            toAdd->dims[j] = 1;
        }
        return SymTab_SizeExceeded;
    }
    return SymTab_OK;
}

SymbolTableError getVarType(struct SymbolTable* table,
                            char* ident, AcceptType* ret)
{
    struct Iterator* i;
    struct VarCell* v;
    for_each (i, &(table->varList)) {
        v = (struct VarCell*)(i->current(i));
        if (0 == strcmp(v->ident, ident)) {
            *ret = v->type;
            i->terminate(i);
            return SymTab_OK;
        }
    }
    return SymTab_NotDef;
}

SymbolTableError getVarAddr(struct SymbolTable* table, char* ident, int* ret)
{
    struct Iterator* i;
    struct VarCell* v;
    for_each (i, &(table->varList)) {
        v = (struct VarCell*)(i->current(i));
        if (0 == strcmp(v->ident, ident)) {
            *ret = v->addr;
            i->terminate(i);
            return SymTab_OK;
        }
    }
    return SymTab_NotDef;
}

SymbolTableError getVarNrDim(struct SymbolTable* table, char* ident, int* ret)
{
    struct Iterator* i;
    struct VarCell* v;
    for_each (i, &(table->varList)) {
        v = (struct VarCell*)(i->current(i));
        if (0 == strcmp(v->ident, ident)) {
            *ret = v->nrDim;
            i->terminate(i);
            return SymTab_OK;
        }
    }
    return SymTab_NotDef;
}

SymbolTableError getVarDimSize(struct SymbolTable* table,
                               char* ident, int* ret, int index)
{
    struct Iterator* i;
    struct VarCell* v;
    for_each (i, &(table->varList)) {
        v = (struct VarCell*)(i->current(i));
        if (0 == strcmp(v->ident, ident)) {
            i->terminate(i);
            if (0 <= index && index < v->nrDim) {
                *ret = v->dims[index];
                return SymTab_OK;
            } else {
                *ret = -1;
                return SymTab_ArrDimOutOfRange;
            }
        }
    }
    return SymTab_NotDef;
}
MAX_VER_IN_STACKはマクロとして設計できます.const.hの中に置いて、あまり小さくしないでください.Jerryはデータの段がないので、すべての声明の変数はすべて倉庫の中で、MAX_VER_IN_STACK この値は宣言できる変数の数を直接決定(制限)します.