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 目录吧.
本文通过具体的代码示例,介绍了如何测试算术节点和声明语句节点生成的指令,确保指令正确并能实现预期的功能。
3万+

被折叠的 条评论
为什么被折叠?



