⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 type.cpp

📁 c语言的简化编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        !stringType(s->val.setintS.modelname->type))
      reportError(s->lineno, "setint takes a type, a string and two integer arguments (type, modelname, nr, val)");
    
    break;
  case sleepK:
   typeEXP(s->val.sleepS.time);
   
   /* s->val.sleepS.time will be NULL if we use sleep without any params - ie. sleep(); */
   if (s->val.sleepS.time != NULL && !intType(s->val.sleepS.time->type))
     reportError(s->lineno, "sleep takes an integer argument (msec to sleep)");
    break;
  }
}


void typeEXP(EXP *e)
{
  struct TYPE *type;
  int argumentNo;
  struct DECL *currentFormal;
  struct EXP **currentArgument;
 
  if (e == NULL)
   return;	

   
  
  switch (e->kind) {
  case intconstK:
    e->type = intTYPE;
    break;
  case boolconstK:
    e->type = boolTYPE;
    break;
  case stringconstK:
    e->type = stringTYPE;
    break;
  case uminusK:
    typeEXP(e->val.uminusE);
    
    e->type = e->val.uminusE->type;
    if (!numericType(e->type)) {
      reportError(e->lineno, "int or float type expected with unary minus operator");
      e->type = undefinedTYPE;
    }
    break;
  case notK:
    typeEXP(e->val.notE.exp);

    if (!boolType(e->val.notE.exp->type))
      reportError(e->lineno, "bool type expected with '!' operator");
    e->type = boolTYPE;
    break;
  case lvalueK:
    typeLVALUE(e->val.lvalueE);
    e->type = e->val.lvalueE->type;
    break;
  case assignmentK:
    typeLVALUE(e->val.assignmentE.left);
    typeEXP(e->val.assignmentE.right);
   
    if (e->val.assignmentE.left->modifier == constMod)
      reportError(e->lineno, "Cannot assign to const variable '%s'", e->val.assignmentE.left->val.idL); /* (only normal variables can be const) */
    
    e->type = e->val.assignmentE.left->type;
    type = e->val.assignmentE.right->type;
    if (!assignable(e->type, type))
      reportError(e->lineno, "Cannot assign %s value to %s lvalue",
		  typeToString(type), 
		  typeToString(e->type));
    
    if (e->type != undefinedTYPE && type != undefinedTYPE) {
      /* make implicit casts explicit */
      if (type->kind != e->type->kind){
      	e->val.assignmentE.right = makeEXPcast(e->type, e->val.assignmentE.right);
	      e->val.assignmentE.right->type = e->type;
      }
    }
    break;
  case equalsK:
    typeEXP(e->val.equalsE.left);
    typeEXP(e->val.equalsE.right);
    
    e->type = greatestCommonType(e->val.equalsE.left->type, e->val.equalsE.right->type);
    
    if (e->type == undefinedTYPE) {
      if (e->val.equalsE.left->type != undefinedTYPE  && e->val.equalsE.right->type != undefinedTYPE) {
	        reportError(e->lineno, "Cannot compare expressions of types %s and %s", 
		                  typeToString(e->val.equalsE.left->type), 
		                  typeToString(e->val.equalsE.right->type));
          break;
      }
    }

    /* make implicit casts explicit */
    if (e->val.equalsE.left->type->kind != e->type->kind){
      e->val.equalsE.left = makeEXPcast(e->type, e->val.equalsE.left);
      e->val.equalsE.left->type = e->type;
    }
    if (e->val.equalsE.right->type->kind != e->type->kind){
      e->val.equalsE.right = makeEXPcast(e->type, e->val.equalsE.right);
      e->val.equalsE.right->type = e->type;
    }

    e->type = boolTYPE;
    break;
  case nequalsK:
    typeEXP(e->val.nequalsE.left);
    typeEXP(e->val.nequalsE.right);

    e->type = greatestCommonType(e->val.equalsE.left->type, e->val.equalsE.right->type);
    
    if (e->type == undefinedTYPE) {
      if (e->val.nequalsE.left->type != undefinedTYPE && e->val.nequalsE.right->type != undefinedTYPE) {
	      reportError(e->lineno, "Cannot compare expressions of types %s and %s", 
		                typeToString(e->val.nequalsE.left->type), 
		                typeToString(e->val.nequalsE.right->type));
		    break;            
      }
    }
    /* make implicit casts explicit */
    if (e->val.equalsE.left->type->kind != e->type->kind){
      e->val.nequalsE.left = makeEXPcast(e->type, e->val.nequalsE.left);
      e->val.nequalsE.left->type = e->type;
    }
    if (e->val.nequalsE.right->type->kind != e->type->kind){
      e->val.nequalsE.right = makeEXPcast(e->type, e->val.nequalsE.right);
      e->val.nequalsE.right->type = e->type;
    }

    e->type = boolTYPE;
    break;
  case lessK:
    typeEXP(e->val.lessE.left);
    typeEXP(e->val.lessE.right);

    if(!numericType(e->val.lessE.left->type) || !numericType(e->val.lessE.right->type)) 
      reportError(e->lineno, "Cannot compare %s with %s", 
		  typeToString(e->val.lessE.left->type), 
		  typeToString(e->val.lessE.right->type));

    /* make implicit casts explicit */
    type = greatestCommonType(e->val.lessE.left->type, e->val.lessE.right->type);

    if (e->type != undefinedTYPE){
      if (e->val.lessE.left->type->kind != type->kind){
	       e->val.lessE.left = makeEXPcast(type, e->val.lessE.left);
	       e->val.lessE.left->type = type;
      }
      if (e->val.lessE.right->type->kind != type->kind){
	       e->val.lessE.right = makeEXPcast(type, e->val.lessE.right);
	       e->val.lessE.right->type = type;
      }
    }

    e->type = boolTYPE;
    break;
  case greaterK:
    typeEXP(e->val.greaterE.left);
    typeEXP(e->val.greaterE.right);

    if(!numericType(e->val.greaterE.left->type) || !numericType(e->val.greaterE.right->type)) 
      reportError(e->lineno, "Cannot compare %s with %s", 
		  typeToString(e->val.greaterE.left->type), 
		  typeToString(e->val.greaterE.right->type));


    /* make implicit casts explicit */
    type = greatestCommonType(e->val.greaterE.left->type, e->val.greaterE.right->type);

    if (e->type != undefinedTYPE){
      if (e->val.greaterE.left->type->kind != type->kind){
	e->val.greaterE.left = makeEXPcast(type, e->val.greaterE.left);
	e->val.greaterE.left->type = type;
      }
      if (e->val.greaterE.right->type->kind != type->kind){
	e->val.greaterE.right = makeEXPcast(type, e->val.greaterE.right);
	e->val.greaterE.right->type = type;
      }
    }
    e->type = boolTYPE;
    break;
  case lequalsK:
    typeEXP(e->val.lequalsE.left);
    typeEXP(e->val.lequalsE.right);

    if(!numericType(e->val.lequalsE.left->type) || !numericType(e->val.lequalsE.right->type)) 
      reportError(e->lineno, "Cannot compare %s with %s", 
		  typeToString(e->val.lequalsE.left->type), 
		  typeToString(e->val.lequalsE.right->type));
    /* make implicit casts explicit */
    type = greatestCommonType(e->val.lequalsE.left->type, e->val.lequalsE.right->type);

    if (e->type != undefinedTYPE){
      if (e->val.lequalsE.left->type->kind != type->kind){
	e->val.lequalsE.left = makeEXPcast(type, e->val.lequalsE.left);
	e->val.lequalsE.left->type = type;
      }
      if (e->val.lequalsE.right->type->kind != type->kind){
	e->val.lequalsE.right = makeEXPcast(type, e->val.lequalsE.right);
	e->val.lequalsE.right->type = type;
      }
    }
    e->type = boolTYPE;
    break;
  case gequalsK:
    typeEXP(e->val.gequalsE.left);
    typeEXP(e->val.gequalsE.right);

    if(!numericType(e->val.gequalsE.left->type) || !numericType(e->val.gequalsE.right->type) ) 
      reportError(e->lineno, "Cannot compare %s with %s", 
		  typeToString(e->val.gequalsE.left->type), 
		  typeToString(e->val.gequalsE.right->type));

    /* make implicit casts explicit */
    type = greatestCommonType(e->val.gequalsE.left->type, e->val.gequalsE.right->type);

    if (e->type != undefinedTYPE){
      if (e->val.gequalsE.left->type->kind != type->kind){
	e->val.gequalsE.left = makeEXPcast(type, e->val.gequalsE.left);
	e->val.gequalsE.left->type = type;
      }
      if (e->val.gequalsE.right->type->kind != type->kind){
	e->val.gequalsE.right = makeEXPcast(type, e->val.gequalsE.right);
	e->val.gequalsE.right->type = type;
      }
    }
    e->type = boolTYPE;
    break;
  case plusK:
    printf("left exp kind: %i\n", e->val.plusE.left->kind);
    printf("right exp kind: %i\n", e->val.plusE.right->kind);
    
    typeEXP(e->val.plusE.left);
    typeEXP(e->val.plusE.right);
    
    e->type = greatestCommonType(e->val.plusE.left->type, e->val.plusE.right->type);
    
    if (e->type == undefinedTYPE) {
      if (e->val.plusE.left->type != undefinedTYPE 
	  && e->val.plusE.right->type != undefinedTYPE) {
	reportError(e->lineno, "Cannot add expressions of types %s and %s", 
		    typeToString(e->val.plusE.left->type), 
		    typeToString(e->val.plusE.right->type));
	e->type = undefinedTYPE;
      }
    }
    
    /* make implicit casts explicit */
    if (e->type != undefinedTYPE){
      if (e->val.equalsE.left->type->kind != e->type->kind){
	e->val.equalsE.left = makeEXPcast(e->type, e->val.equalsE.left);
	e->val.equalsE.left->type = e->type;
      }
      if (e->val.equalsE.right->type->kind != e->type->kind){
	e->val.equalsE.right = makeEXPcast(e->type, e->val.equalsE.right);
	e->val.equalsE.right->type = e->type;
      }
    }
    break;
  case minusK:
    typeEXP(e->val.minusE.left);
    typeEXP(e->val.minusE.right);

    e->type = greatestCommonType(e->val.minusE.left->type, e->val.minusE.right->type);
    
    if (e->type == undefinedTYPE || !numericType(e->type)) {
      if (e->val.minusE.left->type != undefinedTYPE 
	  && e->val.minusE.right->type != undefinedTYPE) {
	reportError(e->lineno, "Cannot subtract expressions of types %s and %s", 
		    typeToString(e->val.minusE.left->type), 
		    typeToString(e->val.minusE.right->type));
	e->type = undefinedTYPE;
      }
    }
    /* make implicit casts explicit */
    if (e->type != undefinedTYPE){
      if (e->val.minusE.left->type->kind != e->type->kind){
	e->val.minusE.left = makeEXPcast(e->type, e->val.minusE.left);
	e->val.minusE.left->type = e->type;
      }
      if (e->val.minusE.right->type->kind != e->type->kind){
	e->val.minusE.right = makeEXPcast(e->type, e->val.minusE.right);
	e->val.minusE.right->type = e->type;
      }
    }
    break;
  case multK:
    typeEXP(e->val.multE.left);
    typeEXP(e->val.multE.right);

    e->type = greatestCommonType(e->val.multE.left->type, e->val.multE.right->type);
    
    if (e->type == undefinedTYPE || !numericType(e->type)) {
      if (e->val.multE.left->type != undefinedTYPE 
	  && e->val.multE.right->type != undefinedTYPE) {
	reportError(e->lineno, "Cannot multiply expressions of types %s and %s", 
		    typeToString(e->val.multE.left->type), 
		    typeToString(e->val.multE.right->type));
	e->type = undefinedTYPE;
      }
    }
    /* make implicit casts explicit */
    if (e->type != undefinedTYPE){
      if (e->val.multE.left->type->kind != e->type->kind){
	e->val.multE.left = makeEXPcast(e->type, e->val.multE.left);
	e->val.multE.left->type = e->type;
      }
      if (e->val.multE.right->type->kind != e->type->kind){
	e->val.multE.right = makeEXPcast(e->type, e->val.multE.right);
	e->val.multE.right->type = e->type;
      }
    }
    break;
  case divK:
    typeEXP(e->val.divE.left);
    typeEXP(e->val.divE.right);
    
    e->type = greatestCommonType(e->val.divE.left->type, e->val.divE.right->type);
    
    if (e->type == undefinedTYPE || !numericType(e->type)) {
      if (e->val.divE.left->type != undefinedTYPE 
	  && e->val.divE.right->type != undefinedTYPE) {
	reportError(e->lineno, "Cannot divide expressions of types %s and %s", 
		    typeToString(e->val.divE.left->type), 
		    typeToString(e->val.divE.right->type));
	e->type = undefinedTYPE;
      }
    }

    /* make implicit casts explicit */
    if (e->type != undefinedTYPE){
      if (e->val.divE.left->type->kind != e->type->kind){
	e->val.divE.left = makeEXPcast(e->type, e->val.divE.left);
	e->val.divE.left->type = e->type;
      }
      if (e->val.divE.right->type->kind != e->type->kind){
	e->val.divE.right = makeEXPcast(e->type, e->val.divE.right);
	e->val.divE.right->type = e->type;
      }
    }
    break;
  case moduloK:
    typeEXP(e->val.moduloE.left);
    typeEXP(e->val.moduloE.right);

    if (!intType(e->val.moduloE.left->type) || !intType(e->val.moduloE.right->type))
      reportError(e->lineno, "int types expected for '%%' operator");

    e->type = intTYPE;
    break;
  case andK:
    typeEXP(e->val.andE.left);
    typeEXP(e->val.andE.right);

    if(!boolType(e->val.andE.left->type) || !boolType(e->val.andE.right->type))
      reportError(e->lineno, "bool types expected for '&&' operator");

    e->type = boolTYPE;
    break;
  case orK:
    typeEXP(e->val.orE.left);
    typeEXP(e->val.orE.right);

    if(!boolType(e->val.orE.left->type) || !boolType(e->val.orE.right->type))
      reportError(e->lineno, "bool types expected for '||' operator");

    e->type = boolTYPE;
    break;
  case callK:
   
    if (e->val.callE.arguments != NULL)
      typeEXP(e->val.callE.arguments);
   
    if (e->val.callE.symbol->kind == functionSym) {
      /* It is a function */
      
      /* Check argument types against formal types: */
      argumentNo=1;
      currentFormal = e->val.callE.symbol->val.functionS->formals;
      currentArgument = &(e->val.callE.arguments);
      
      while (currentFormal != NULL && (*currentArgument) != NULL) {
	/* Test if current argument is assignable to current formal */
	if(!assignable(currentFormal->type, (*currentArgument)->type)) {
	  reportError(e->lineno,
		      "Argument %d cannot be assigned to formal %d in function '%s'",
		      argumentNo,
		      argumentNo,
		      functionToSignatureString(e->val.callE.symbol->val.functionS));

	}

	// make implicit casts explicit 
	type = greaterType(currentFormal->type, (*currentArgument)->type);
	if (type == undefinedTYPE) // if no greater type we know there has been an error and bails
	  break;
	
	
	if ((*currentArgument)->type->kind != type->kind){
	  *currentArgument = makeEXPcast(currentFormal->type, *currentArgument);
	  (*currentArgument)->type = currentFormal->type;
	}
	// Next: 
	argumentNo++;
	currentFormal = currentFormal->next;
	currentArgument = &((*currentArgument)->next);
      }
      
      // Report argument count errors: 
      if (currentFormal != NULL && (*currentArgument) == NULL)
	reportError(e->lineno, "Too few arguments to function '%s'",
		    functionToSignatureString(e->val.callE.symbol->val.functionS));
      else if (currentFormal == NULL && (*currentArgument) != NULL)
	reportError(e->lineno, "Too many arguments to function '%s'",
		    functionToSignatureString(e->val.callE.symbol->val.functionS));
    } else {
      // It is a program 
      reportError(e->lineno, "Programs cannot be called");
    }
    
    // Set expression's type to the returntype of the function: 
    e->type = symbolType(e->val.callE.symbol);
    break;
  case castK:
    typeEXP(e->val.castE.exp);
   
    if (e->val.castE.exp->type == undefinedTYPE || e->val.castE.type == undefinedTYPE)
      break;
   
    if (validCast(e->val.castE.exp->type, e->val.castE.type) == false)
      reportError(e->lineno, "cannot cast expression of type %s to type %s",
		  typeToString(e->val.castE.exp->type), typeToString(e->val.castE.type));
    else { 
      e->type = e->val.castE.type;
    }
    break;
 
  } // end switch 
 
  
  if(e->next != NULL)
    typeEXP(e->next);
    
}



void typeLVALUE(LVALUE *l)
{
  
  switch(l->kind){
  case idK:
    l->type = symbolType(l->symbol);
  break;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -