📄 type.c
字号:
/* * JOOS is Copyright (C) 1997 Laurie Hendren & Michael I. Schwartzbach * * Reproduction of all or part of this software is permitted for * educational or research use on condition that this copyright notice is * included in any copy. This software comes with no warranty of any * kind. In no event will the authors be liable for any damages resulting from * use of this software. * * email: hendren@cs.mcgill.ca, mis@brics.dk */#include <stdio.h>#include <string.h>#include "memory.h"#include "error.h"#include "symbol.h"#include "type.h"extern char *currentfile;TYPE *polynullTYPE, *intTYPE, *boolTYPE, *charTYPE, *stringTYPE;TYPE *classTYPE(CLASS *c){ TYPE *t; t = NEW(TYPE); t->kind = refK; t->name = c->name; t->class = c; return t;}void initTypes(){ SYMBOL *s; polynullTYPE = NEW(TYPE); polynullTYPE->kind = polynullK; intTYPE = NEW(TYPE); intTYPE->kind = intK; boolTYPE = NEW(TYPE); boolTYPE->kind = boolK; charTYPE = NEW(TYPE); charTYPE->kind = charK; s = getSymbol(classlib,"String"); if (s==NULL) { reportGlobalError("class String not found"); noErrors(); } stringTYPE = NEW(TYPE); stringTYPE->kind = refK; stringTYPE->name = "String"; stringTYPE->class = s->val.classS;}int equalTYPE(TYPE *s, TYPE *t){ if (s->kind!=t->kind) return 0; if (s->kind==refK) { return strcmp(s->name,t->name)==0; } return 1;}int integerTYPE(TYPE *t){ return t->kind==intK || t->kind==charK;}int assignTYPE(TYPE *s, TYPE *t){ if (s->kind==refK && t->kind==polynullK) return 1; if (s->kind==intK && t->kind==charK) return 1; if (s->kind!=t->kind) return 0; if (s->kind==refK) return subClass(t->class,s->class); return 1;}int checkBOOL(TYPE *t, int lineno){ if (t->kind!=boolK) { reportError("boolean type expected",lineno); return 0; } return 1;}int checkCHAR(TYPE *t, int lineno){ if (t->kind!=charK) { reportError("char type expected",lineno); return 0; } return 1;}int checkINT(TYPE *t, int lineno){ if (t->kind!=intK && t->kind!=charK) { reportError("int type expected",lineno); return 0; } return 1;}int equalFORMAL(FORMAL *f, FORMAL *g){ if (f==NULL || g==NULL) return f==NULL && g==NULL; return equalTYPE(f->type,g->type) && equalFORMAL(f->next,g->next);}void typePROGRAM(PROGRAM *p){ initTypes(); typeHierarchyPROGRAM(p); typeImplementationPROGRAM(p);}void typeHierarchyPROGRAM(PROGRAM *p){ if (p!=NULL) { typeHierarchyPROGRAM(p->next); currentfile = p->name; typeHierarchyCLASSFILE(p->classfile); }}void typeHierarchyCLASSFILE(CLASSFILE *c){ if (c!=NULL) { typeHierarchyCLASSFILE(c->next); typeHierarchyCLASS(c->class); }}void typeHierarchyCLASS(CLASS *c){ if (subClass(c->parent,c)) { reportError("cyclic inheritance",c->lineno); } if (c->parent!=NULL) { if (c->parent->modifier==finalMod) { reportStrError("extension of final %s class",c->parentname,c->lineno); } } typeHierarchyFIELD(c->fields,c); typeHierarchyMETHOD(c->methods,c);}void typeHierarchyFIELD(FIELD *f, CLASS *this){ SYMBOL *s; if (f!=NULL) { typeHierarchyFIELD(f->next,this); s = lookupHierarchy(f->name,this->parent); if (s!=NULL) { reportStrError("illegal overriding of field %s",f->name,f->lineno); } }}void typeHierarchyMETHOD(METHOD *m, CLASS *this){ SYMBOL *s; if (m!=NULL) { typeHierarchyMETHOD(m->next,this); s = lookupHierarchy(m->name,this->parent); if (s!=NULL) { if (s->kind!=methodSym) { reportStrError("illegal overriding of method %s",m->name,m->lineno); } else { if (s->val.methodS->modifier==finalMod) { reportStrError("illegal overriding of final method %s", m->name,m->lineno); } else { if (!equalFORMAL(m->formals,s->val.methodS->formals) || !equalTYPE(m->returntype,s->val.methodS->returntype)) { reportStrError("overriden method %s must have same signature", m->name, m->lineno); } } } } }}void typeImplementationPROGRAM(PROGRAM *p){ if (p!=NULL) { typeImplementationPROGRAM(p->next); currentfile = p->name; typeImplementationCLASSFILE(p->classfile); }}void typeImplementationCLASSFILE(CLASSFILE *c){ if (c!=NULL) { typeImplementationCLASSFILE(c->next); typeImplementationCLASS(c->class); }}int memberCONSTRUCTOR(CONSTRUCTOR *c, CONSTRUCTOR *l){ if (l==NULL) return 0; if (equalFORMAL(c->formals,l->formals)) return 1; return memberCONSTRUCTOR(c,l->next);}void uniqueCONSTRUCTOR(CONSTRUCTOR *c){ if (c!=NULL) { uniqueCONSTRUCTOR(c->next); if (memberCONSTRUCTOR(c,c->next)) reportError("duplicate constructor",c->lineno); }}void typeImplementationCLASS(CLASS *c){ typeImplementationCONSTRUCTOR(c->constructors,c); uniqueCONSTRUCTOR(c->constructors); typeImplementationMETHOD(c->methods,c);}void typeImplementationCONSTRUCTOR(CONSTRUCTOR *c, CLASS *this){ if (c!=NULL) { typeImplementationCONSTRUCTOR(c->next,this); typeImplementationSTATEMENT(c->statements,this,makeTYPEvoid()); }}void typeImplementationMETHOD(METHOD *m, CLASS *this){ if (m!=NULL) { typeImplementationMETHOD(m->next,this); typeImplementationSTATEMENT(m->statements,this,m->returntype); }}TYPE *typePlus(EXP *left, EXP *right, int lineno){ if (integerTYPE(left->type) && integerTYPE(right->type)) { return intTYPE; } if (!equalTYPE(left->type,stringTYPE) && !equalTYPE(right->type,stringTYPE)) { reportError("arguments for + have wrong types",lineno); } left->tostring = 1; right->tostring = 1; return stringTYPE;}int applicableFORMALARGUMENT(FORMAL *f, ARGUMENT *a){ if (f==NULL || a==NULL) return (f==NULL && a==NULL); if (!assignTYPE(f->type,a->exp->type)) return 0; return applicableFORMALARGUMENT(f->next,a->next);}CONSTRUCTOR *applicableCONSTRUCTOR(CONSTRUCTOR *c, ARGUMENT *a){ if (c==NULL) return NULL; if (applicableFORMALARGUMENT(c->formals,a)) { return makeCONSTRUCTOR(c->name,c->formals,c->statements, applicableCONSTRUCTOR(c->next,a)); } else { return applicableCONSTRUCTOR(c->next,a); }}int morespecificFORMAL(FORMAL *f, FORMAL *g){ if (f==NULL || g==NULL) return (f==NULL && g==NULL); if (!assignTYPE(g->type,f->type)) return 0; return morespecificFORMAL(f->next,g->next);}int maxspecificFORMALCONSTRUCTOR(FORMAL *f, CONSTRUCTOR *d){ if (d==NULL) return 1; if (!morespecificFORMAL(f,d->formals)) return 0; return maxspecificFORMALCONSTRUCTOR(f,d->next);}CONSTRUCTOR *maxspecificCONSTRUCTOR(CONSTRUCTOR *c, CONSTRUCTOR *d){ if (c==NULL) return NULL; if (maxspecificFORMALCONSTRUCTOR(c->formals,d)) { return makeCONSTRUCTOR(c->name,c->formals,c->statements, maxspecificCONSTRUCTOR(c->next,d)); } else { return maxspecificCONSTRUCTOR(c->next,d); }}CONSTRUCTOR *selectCONSTRUCTOR(CONSTRUCTOR *c, ARGUMENT *a, int lineno){ CONSTRUCTOR *applicable; applicable = applicableCONSTRUCTOR(c,a); if (applicable==NULL) { reportError("no matching constructor",lineno); return NULL; } else { CONSTRUCTOR *maxspecific; maxspecific = maxspecificCONSTRUCTOR(applicable,applicable); if (maxspecific==NULL || maxspecific->next!=NULL) reportError("ambiguous constructor",lineno); return maxspecific; }}void typeImplementationSTATEMENT(STATEMENT *s, CLASS *this, TYPE *returntype){ if (s!=NULL) { switch (s->kind) { case skipK: break; case localK: break; case expK: typeImplementationEXP(s->val.expS,this); break; case returnK: if (s->val.returnS!=NULL) { typeImplementationEXP(s->val.returnS,this); } if (returntype->kind==voidK && s->val.returnS!=NULL) { reportError("return value not allowed",s->lineno); } if (returntype->kind!=voidK && s->val.returnS==NULL) { reportError("return value expected",s->lineno); } if (returntype->kind!=voidK && s->val.returnS!=NULL) { if (!assignTYPE(returntype,s->val.returnS->type)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -