📄 type.c
字号:
reportError("illegal type of expression",s->lineno); } } break; case sequenceK: typeImplementationSTATEMENT(s->val.sequenceS.first,this,returntype); typeImplementationSTATEMENT(s->val.sequenceS.second,this,returntype); break; case ifK: typeImplementationEXP(s->val.ifS.condition,this); checkBOOL(s->val.ifS.condition->type,s->lineno); typeImplementationSTATEMENT(s->val.ifS.body,this,returntype); break; case ifelseK: typeImplementationEXP(s->val.ifelseS.condition,this); checkBOOL(s->val.ifelseS.condition->type,s->lineno); typeImplementationSTATEMENT(s->val.ifelseS.thenpart,this,returntype); typeImplementationSTATEMENT(s->val.ifelseS.elsepart,this,returntype); break; case whileK: typeImplementationEXP(s->val.whileS.condition,this); checkBOOL(s->val.whileS.condition->type,s->lineno); typeImplementationSTATEMENT(s->val.whileS.body,this,returntype); break; case blockK: typeImplementationSTATEMENT(s->val.blockS.body,this,returntype); break; case superconsK: typeImplementationARGUMENT(s->val.superconsS.args,this); s->val.superconsS.constructor = selectCONSTRUCTOR(this->parent->constructors, s->val.superconsS.args, s->lineno); break; } }}TYPE *typeVar(SYMBOL *s){ switch(s->kind) { case fieldSym: return s->val.fieldS->type; break; case formalSym: return s->val.formalS->type; break; case localSym: return s->val.localS->type; break; case classSym: case methodSym: break; } return NULL;}void typeImplementationEXP(EXP *e, CLASS *this){ SYMBOL *s; TYPE *t; switch (e->kind) { case idK: e->type = typeVar(e->val.idE.idsym); break; case assignK: e->type = typeVar(e->val.assignE.leftsym); typeImplementationEXP(e->val.assignE.right,this); if (!assignTYPE(e->type,e->val.assignE.right->type)) { reportError("illegal assignment",e->lineno); } break; case orK: typeImplementationEXP(e->val.orE.left,this); typeImplementationEXP(e->val.orE.right,this); checkBOOL(e->val.orE.left->type,e->lineno); checkBOOL(e->val.orE.right->type,e->lineno); e->type = boolTYPE; break; case andK: typeImplementationEXP(e->val.andE.left,this); typeImplementationEXP(e->val.andE.right,this); checkBOOL(e->val.andE.left->type,e->lineno); checkBOOL(e->val.andE.right->type,e->lineno); e->type = boolTYPE; break; case eqK: typeImplementationEXP(e->val.eqE.left,this); typeImplementationEXP(e->val.eqE.right,this); if (!assignTYPE(e->val.eqE.left->type,e->val.eqE.right->type) && !assignTYPE(e->val.eqE.right->type,e->val.eqE.left->type)) { reportError("arguments for = have wrong types",e->lineno); } e->type = boolTYPE; break; case ltK: typeImplementationEXP(e->val.ltE.left,this); typeImplementationEXP(e->val.ltE.right,this); checkINT(e->val.ltE.left->type,e->lineno); checkINT(e->val.ltE.right->type,e->lineno); e->type = boolTYPE; break; case gtK: typeImplementationEXP(e->val.gtE.left,this); typeImplementationEXP(e->val.gtE.right,this); checkINT(e->val.gtE.left->type,e->lineno); checkINT(e->val.gtE.right->type,e->lineno); e->type = boolTYPE; break; case leqK: typeImplementationEXP(e->val.leqE.left,this); typeImplementationEXP(e->val.leqE.right,this); checkINT(e->val.leqE.left->type,e->lineno); checkINT(e->val.leqE.right->type,e->lineno); e->type = boolTYPE; break; case geqK: typeImplementationEXP(e->val.geqE.left,this); typeImplementationEXP(e->val.geqE.right,this); checkINT(e->val.geqE.left->type,e->lineno); checkINT(e->val.geqE.right->type,e->lineno); e->type = boolTYPE; break; case neqK: typeImplementationEXP(e->val.neqE.left,this); typeImplementationEXP(e->val.neqE.right,this); if (!assignTYPE(e->val.neqE.left->type,e->val.neqE.right->type) && !assignTYPE(e->val.neqE.right->type,e->val.neqE.left->type)) { reportError("arguments for != have wrong types",e->lineno); } e->type = boolTYPE; break; case instanceofK: typeImplementationEXP(e->val.instanceofE.left,this); if (e->val.instanceofE.left->type->kind!=refK) { reportError("class reference expected",e->lineno); } if (!subClass(e->val.instanceofE.left->type->class, e->val.instanceofE.class) && !subClass(e->val.instanceofE.class, e->val.instanceofE.left->type->class)) { reportError("instanceof will always fail",e->lineno); } e->type = boolTYPE; break; case plusK: typeImplementationEXP(e->val.plusE.left,this); typeImplementationEXP(e->val.plusE.right,this); e->type = typePlus(e->val.plusE.left,e->val.plusE.right,e->lineno); break; case minusK: typeImplementationEXP(e->val.minusE.left,this); typeImplementationEXP(e->val.minusE.right,this); checkINT(e->val.minusE.left->type,e->lineno); checkINT(e->val.minusE.right->type,e->lineno); e->type = intTYPE; break; case timesK: typeImplementationEXP(e->val.timesE.left,this); typeImplementationEXP(e->val.timesE.right,this); checkINT(e->val.timesE.left->type,e->lineno); checkINT(e->val.timesE.right->type,e->lineno); e->type = intTYPE; break; case divK: typeImplementationEXP(e->val.divE.left,this); typeImplementationEXP(e->val.divE.right,this); checkINT(e->val.divE.left->type,e->lineno); checkINT(e->val.divE.right->type,e->lineno); e->type = intTYPE; break; case modK: typeImplementationEXP(e->val.modE.left,this); typeImplementationEXP(e->val.modE.right,this); checkINT(e->val.modE.left->type,e->lineno); checkINT(e->val.modE.right->type,e->lineno); e->type = intTYPE; break; case notK: typeImplementationEXP(e->val.notE.not,this); checkBOOL(e->val.notE.not->type,e->lineno); e->type = boolTYPE; break; case uminusK: typeImplementationEXP(e->val.uminusE,this); checkINT(e->val.uminusE->type,e->lineno); e->type = intTYPE; break; case thisK: if (this==NULL) { reportError("'this' not allowed here",e->lineno); } e->type = classTYPE(this); break; case newK: if (e->val.newE.class->modifier==abstractMod) { reportStrError("illegal abstract constructor %s", e->val.newE.class->name,e->lineno); } typeImplementationARGUMENT(e->val.newE.args,this); e->val.newE.constructor = selectCONSTRUCTOR(e->val.newE.class->constructors, e->val.newE.args, e->lineno); e->type = classTYPE(e->val.newE.class); break; case invokeK: t = typeImplementationRECEIVER(e->val.invokeE.receiver,this); typeImplementationARGUMENT(e->val.invokeE.args,this); if (t->kind!=refK) { reportError("receiver must be an object",e->lineno); e->type = polynullTYPE; } else { s = lookupHierarchy(e->val.invokeE.name,t->class); if (s==NULL || s->kind!=methodSym) { reportStrError("no such method called %s", e->val.invokeE.name,e->lineno); e->type = polynullTYPE; } else { e->val.invokeE.method = s->val.methodS; if (s->val.methodS->modifier==staticMod) { reportStrError("static method %s may not be invoked", e->val.invokeE.name,e->lineno); } typeImplementationFORMALARGUMENT(s->val.methodS->formals, e->val.invokeE.args, e->lineno); e->type = s->val.methodS->returntype; } } break; case intconstK: e->type = intTYPE; break; case boolconstK: e->type = boolTYPE; break; case charconstK: e->type = charTYPE; break; case stringconstK: e->type = stringTYPE; break; case nullK: e->type = polynullTYPE; break; case castK: typeImplementationEXP(e->val.castE.right,this); e->type = makeTYPEextref(e->val.castE.left,e->val.castE.class); if (e->val.castE.right->type->kind!=refK && e->val.castE.right->type->kind!=polynullK) { reportError("class reference expected",e->lineno); } else { if (e->val.castE.right->type->kind==refK && !subClass(e->val.castE.class, e->val.castE.right->type->class) && !subClass(e->val.castE.right->type->class, e->val.castE.class)) { reportError("cast will always fail",e->lineno); } } break; case charcastK: typeImplementationEXP(e->val.charcastE,this); checkINT(e->val.charcastE->type,e->lineno); e->type = charTYPE; break; }}void typeImplementationARGUMENT(ARGUMENT *a, CLASS *this){ if (a!=NULL) { typeImplementationARGUMENT(a->next,this); typeImplementationEXP(a->exp,this); }}TYPE *typeImplementationRECEIVER(RECEIVER *r, CLASS *this){ switch(r->kind) { case objectK: typeImplementationEXP(r->objectR,this); return r->objectR->type; break; case superK: if (this->parent==NULL) { reportError("super not allowed here",r->lineno); } return classTYPE(this->parent); break; } return NULL;}void typeImplementationFORMALARGUMENT(FORMAL *f, ARGUMENT *a, int lineno){ if (f==NULL && a!=NULL) { reportError("too many arguments",a->exp->lineno); return; } if (f!=NULL && a==NULL) { reportError("too few arguments",lineno); return; } if (f!=NULL && a!=NULL) { typeImplementationFORMALARGUMENT(f->next,a->next,lineno); if (!assignTYPE(f->type,a->exp->type)) { reportError("argument has wrong type",a->exp->lineno); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -