E, 这个算术节点指的是 ArithmaticNode.
由于之前已经测试了ArithmaticNode 全部可能的子节点项目, 因此这次要测试的非常简单, 只需要查看运算指令执行完毕后, 弹栈弹出的大小是不是期望的那么多. 所以, 直接上测试例子了
struct List* ins; struct List* subIns; struct ArithmaticNode* a; struct IntegerNode* i = newIntegerNode(14); a = newArithmaticNode((struct AbstractValueNode*)i); subIns = i->createInstruction(i); ins = a->createInstruction(a); assert(1 + subIns->count(subIns) == ins->count(ins)); while (0 != subIns->count(subIns)) { assertInsEqual_Del(ins->popElementAt(ins, 0), subIns->popElementAt(subIns, 0)); } assert(POP == ((struct AbstractInstruction*) (ins->elementAt(ins, 0)))->code); assert(INT_SIZE == ((struct IntParamInstruction*) (ins->elementAt(ins, 0)))->param); revert(ins->popElementAt(ins, 0)); ins->finalize(ins); subIns->finalize(subIns); a->delNode(a);
对于子节点的指令, 仍然是产生相同的节点指令再一一匹配. 下面就轮到声明语句了.
声明语句除了产生指令之外, 还会注册符号. 不过, 注册符号的具体细节在符号表模块已经完成了测试, 现在只是进行一点点简单的验证工作, 看看指定的变量是否被注册了. 比如这样
struct { char* ident; AcceptType type; int nrDim; int offsets[MAX_ARRAY_SIZE]; int size; int base; } data[NR_TEST_CASE] = { { "testee", INTEGER }, { "tom", INTEGER }, { "jerry", REAL }, { "mANDg", REAL } }; char* ident = "param"; char* ident1 = "param1"; struct DeclarationNode* dec; struct List* ins; initialSymTabManager(); dec = newDeclarationNode(INTEGER_TYPE); dec->vars->enqueue(dec->vars, newVariableNode(ident)); dec->initVals->enqueue(dec->initVals, NULL); dec->vars->enqueue(dec->vars, newVariableNode(ident1)); dec->initVals->enqueue(dec->initVals, NULL); ins = dec->createInstruction(dec); // 类型验证 assert(INTEGER == typeOf(dec->vars->peekAt(dec->vars, 0))); assert(INTEGER == typeOf(dec->vars->peekAt(dec->vars, 1))); assert(0 == ins->count(ins)); ins->finalize(ins); dec->delNode(dec); finalizeSymTabManager();
当然, 由于没有赋初值的动作, 因此没有任何指令产生. 对于有赋初始值的声明语句才需要测试其生成的指令, 而这些指令与一个算术节点非常类似
struct DeclarationNode* dec; struct VariableNode* var1; struct List* ins,* subIns1; initialSymTabManager(); dec = newDeclarationNode(REAL_TYPE); dec->vars->enqueue(dec->vars, newVariableNode(ident1)); dec->initVals->enqueue(dec->initVals, newVariableNode(ident)); var1 = newVariableNode(ident1); ins = dec->createInstruction(dec); assert(REAL == typeOf(var1)); subIns1 = var1->addressOf(var1); assert(ins->count(ins) - 2 == subIns0->count(subIns0) + subIns1->count(subIns1)); while (0 != subIns1->count(subIns1)) { assertInsEqual_Del(ins->popElementAt(ins, 0), subIns1->popElementAt(subIns1, 0)); } assert(REAL_ASSIGN == ((struct AbstractInstruction*) (ins->elementAt(ins, 0)))->code); revert(ins->popElementAt(ins, 0)); assert(POP == ((struct AbstractInstruction*) (ins->elementAt(ins, 0)))->code); assert(REAL_SIZE == ((struct IntParamInstruction*) (ins->elementAt(ins, 0)))->param); revert(ins->popElementAt(ins, 0)); finalizeSymTabManager();
这两类节点的指令生成测试大致就是这样了. 请 svn update 一下 Jerry 目录吧.