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

📄 type.cpp

📁 c语言的简化编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* u1comp type.c
 *
 * History:
 * 04.11.2000 - created
 */
#include "stdafx.h"

#include "type.h"
#include "error.h"
#include "symbol.h"
#include "memory.h"
#include <string.h>
#include "tree.h"
#include "typedef.h"

TYPE *undefinedTYPE;
static TYPE *voidTYPE, *boolTYPE, *intTYPE, *stringTYPE;

void initTypes()
{
  undefinedTYPE = NULL;
  
  voidTYPE = makeTYPEvoid();
  boolTYPE = makeTYPEbool();
  intTYPE = makeTYPEint();
  stringTYPE = makeTYPEstring();
}

char *typeToString(TYPE *t)
{
  switch(t->kind) {
  case boolK:
    return "bool";
  case intK:
    return "int";
  case stringK:
    return "string";
  case voidK:
    return "void";
  }
  
  return "N/A";
}


/* Create a string with the function signature - ie. 'int myfunc(int a, int b)'   */
char *functionToSignatureString(FUNCTION *f)
{
  DECL *formal;
  int stringLength=1;
  char *signature;
  
  /* Count length of formal types: */
  formal = f->formals;
  while (formal != NULL) {
    stringLength += strlen(typeToString(formal->type));
    
    /* Possibly add length of separating comma and space: */
    if (formal->next != NULL)
      stringLength += 2;
    
    formal = formal->next;
  }
  
  /* Add length of return type, function name and parantheses: */
  stringLength += strlen(typeToString(f->type)) + 1 + strlen(f->name) + 2;
  
  /* Construct string: */
  signature = (char*)Malloc(stringLength);
  signature[0] = 0; /* make empty string */
  
  strcat(signature, typeToString(f->type));
  strcat(signature, " ");
  strcat(signature, f->name);
  strcat(signature, "(");
  
  formal = f->formals;
  while (formal != NULL) {
    strcat(signature, typeToString(formal->type));
    
    /* Possibly add separating comma and space: */
    if (formal->next != NULL)
      strcat(signature, ", ");
    
    formal = formal->next;
  }
  
  strcat(signature, ")");
  
  return signature;
}



/* The 'greatest' type of the two */
TYPE *greaterType(TYPE *l, TYPE *r)
{
  
  /* Pass on undefinedTYPE: */
  if (l == undefinedTYPE || r == undefinedTYPE)
    return undefinedTYPE;
  
  /*bool*/
  if(l->kind == boolK && r->kind == boolK)
    return boolTYPE;
  /*int*/
  if(l->kind == intK && r->kind == intK)
    return intTYPE;
  /*string*/
  if(l->kind == stringK && ( r->kind == stringK || r->kind == intK || r->kind == boolK))
    return stringTYPE;
  
  /* l is not greater than or equal to r */
  return undefinedTYPE;
}



TYPE *greatestCommonType(TYPE *t1, TYPE *t2)
{
  TYPE *type;

  if((type = greaterType(t1,t2)) != undefinedTYPE)
    return type;
  else if((type = greaterType(t2,t1)) != undefinedTYPE)
    return type;

  return undefinedTYPE;
}



/* Can we assign right type to left? */
bool assignable(TYPE *left, TYPE *right)
{
  /* undefinedTYPE always yields success: */
  if (left == undefinedTYPE || right == undefinedTYPE)
    return true;
  
  if (greaterType(left, right) != undefinedTYPE)
    return true;
  else
    return false;
}


/* Small function to retrieve the type of a given symbol (from the symbol check phase)*/
TYPE *symbolType(SYMBOL *symbol)
{
  switch(symbol->kind) {
  case functionSym:
    return symbol->val.functionS->type;
  case programSym:
    return voidTYPE;
  case declSym:
    return symbol->val.declS->type;
  }
  
  /* Should not be possible: */
  return undefinedTYPE;
}


/* Is the given type a void type? */
bool voidType(TYPE *type)
{
  /* undefinedTYPE always yields success: */
  if (type == undefinedTYPE)
    return true;
  
  if (type->kind == voidK)
    return true;
  
  return false;
}

/* Is the given type a boolean type? */
bool boolType(TYPE *type)
{
  /* undefinedTYPE always yields success: */
  if (type == undefinedTYPE)
    return true;
  
  if (type->kind == boolK)
    return true;
  
  return false;
}


/* Is the given type a numeric type? (note: in pxdscript this means int) */
bool numericType(TYPE *type)
{
  /* undefinedTYPE always yields success: */
  if (type == undefinedTYPE)
    return true;
  
  if (type->kind == intK)
    return true;
  
  return false;
}

/* Is the given type a int type? */
bool intType(TYPE *type)
{
  /* undefinedTYPE always yields success: */
  if (type == undefinedTYPE)
    return true;
  
  if (type->kind == intK)
    return true;
  
  return false;
}

/* Is the given type a string type? */
bool stringType(TYPE *type)
{
  /* undefinedTYPE always yields success: */
  if (type == undefinedTYPE)
    return true;
  
  if (type->kind == stringK)
    return true;
  
  return false;
}


/* Here you define the casting rules of your language. 
   Remember that what you deside here you have to pay for later
   by coding the code needed to maintain these rules ;) */
bool validCast(TYPE *source, TYPE *dest) {

  /* rules for cast int -> ?? */
  if (source->kind == intK)
    if (dest->kind == stringK || dest->kind == intK)
      return true;
  
   /* rules for cast string -> ?? */
  if (source->kind == stringK)
    if (dest->kind == intK || dest->kind == stringK )
      return true;
  
   /* rules for cast bool -> ?? */
  if (source->kind == boolK)
    if (dest->kind == stringK || dest->kind == boolK)
      return true;

  return false;
}




void typeSCRIPTCOLLECTION(SCRIPTCOLLECTION *s)
{
  /* Initialize the type structures we'll use to compare with in this phase */
  initTypes();
  
  /* Check all toplevels */
  if(s->toplevels != NULL)
    typeTOPLEVEL(s->toplevels);
}

void typeTOPLEVEL(TOPLEVEL *t)
{
  /* Which kind of toplevel? */
  switch(t->kind){
  case functionK:
    typeFUNCTION(t->val.functionT);
    break;
  case programK:
    typePROGRAM(t->val.programT);
    break;
  case simpledeclK:                              /* chenhongyu, 2004-9-17. */
    typeSIMPLEDECL(t->val.decl);
	break;
  }

  if(t->next != NULL)
    typeTOPLEVEL(t->next);
}

void typeFUNCTION(FUNCTION *f)
{
  if(f->formals != NULL)
    typeDECL(f->formals);

  if(f->stms != NULL)
    typeSTM(f->stms, f->type);
}

void typePROGRAM(PROGRAM *s)
{
  if(s->stms != NULL)
    typeSTM(s->stms, voidTYPE);
}

/* chenhongyu, 2004-9-17. */
void typeSIMPLEDECL(DECL *d)
{
  if(d->val.simplevarD.initialization != NULL) {
      typeEXP(d->val.simplevarD.initialization);
      
      if (!assignable(d->type, d->val.simplevarD.initialization->type))
        reportError(d->lineno, "Cannot assign %s value to %s lvalue",
		  typeToString(d->val.simplevarD.initialization->type), 
		  typeToString(d->type));

      if (d->type != undefinedTYPE && d->val.simplevarD.initialization->type != undefinedTYPE) {
        /* make implicit casts explicit */
        if (d->val.simplevarD.initialization->type->kind != d->type->kind){
      	   d->val.simplevarD.initialization = makeEXPcast(d->type, d->val.simplevarD.initialization);
	   d->val.simplevarD.initialization->type = d->type;
        }
      }
     }
}


/* Note that at this point the two variable types are treated identically. Originally the differences were
   that the simplevar could not have any modifiers (const) and you could not declare a list of variables
   (int x,t,b;). 
   The 'const' issue is not to be checked here (in the initialization) and in the weeding phase we translated
   a declaration like above into a bunch of single declarations... */
void typeDECL(DECL *d)
{
   
  switch(d->kind){
  case formalK:
    break;
  case variableK:
    if(d->val.variableD.initialization != NULL){
      typeEXP(d->val.variableD.initialization);
        
      if (!assignable(d->type, d->val.variableD.initialization->type))
        reportError(d->lineno, "Cannot assign %s value to %s lvalue",
		  typeToString(d->val.variableD.initialization->type), 
		  typeToString(d->type));
    
      if (d->type != undefinedTYPE && d->val.variableD.initialization->type != undefinedTYPE) {
        /* make implicit casts explicit */
        if (d->val.variableD.initialization->type->kind != d->type->kind){
      	   d->val.variableD.initialization = makeEXPcast(d->type, d->val.variableD.initialization);
	   d->val.variableD.initialization->type = d->type;
        }
      } 
    }
    break;
  case simplevarK:
    if(d->val.simplevarD.initialization != NULL) {
      typeEXP(d->val.simplevarD.initialization);
      
      if (!assignable(d->type, d->val.simplevarD.initialization->type))
        reportError(d->lineno, "Cannot assign %s value to %s lvalue",
		  typeToString(d->val.simplevarD.initialization->type), 
		  typeToString(d->type));

      if (d->type != undefinedTYPE && d->val.simplevarD.initialization->type != undefinedTYPE) {
        /* make implicit casts explicit */
        if (d->val.simplevarD.initialization->type->kind != d->type->kind){
      	   d->val.simplevarD.initialization = makeEXPcast(d->type, d->val.simplevarD.initialization);
	   d->val.simplevarD.initialization->type = d->type;
        }
      }
    }        
    break;
  }
  
  if(d->next != NULL)
    typeDECL(d->next);
    
   
}

void typeFORINIT(FORINIT *f)
{
  switch(f->kind){
  case declforinitK:
    typeDECL(f->val.declforinitF);
    break;
  case expforinitK:
    typeEXP(f->val.expforinitF);
    break;
  }

  if(f->next != NULL)
    typeFORINIT(f->next);
}



void typeSTM(STM *s, TYPE *returnType)
{
  switch(s->kind){
  case skipK:
    break;
  case expK:
    typeEXP(s->val.expS);
    break;
  case declstmK:
    typeDECL(s->val.declstmS);
    break;
  case returnK:
    if(s->val.returnS.exp != NULL){
      typeEXP(s->val.returnS.exp);
      if(!assignable(returnType, s->val.returnS.exp->type))
	reportError(s->lineno, "Function must return expression of type %s", 
		    typeToString(returnType));
    }
    else if(!voidType(returnType))
      reportError(s->lineno, "Function must return expression of type %s", 
		  typeToString(returnType));
    break;
  case ifK:
    typeEXP(s->val.ifS.condition);
    typeSTM(s->val.ifS.body, returnType);
    
    if (!boolType(s->val.ifS.condition->type))
      reportError(s->lineno, "Condition in if statement must be of type bool");
    break;
  case ifelseK:
    typeEXP(s->val.ifelseS.condition);
    typeSTM(s->val.ifelseS.thenpart, returnType);
    typeSTM(s->val.ifelseS.elsepart, returnType);
    
    if (!boolType(s->val.ifelseS.condition->type))
      reportError(s->lineno, "Condition in if statement must be of type bool");
    break;
  case whileK:
    typeEXP(s->val.whileS.condition);
    typeSTM(s->val.whileS.body, returnType);
    
    if (!boolType(s->val.whileS.condition->type))
      reportError(s->lineno, "Condition in while statement must be of type bool");
    break;
  case forK:
    typeFORINIT(s->val.forS.inits);
    typeEXP(s->val.forS.condition);
    typeEXP(s->val.forS.updates);
    typeSTM(s->val.forS.body, returnType);
    
    if (!boolType(s->val.forS.condition->type))
      reportError(s->lineno, "Condition in for statement must be of type bool");
    break;
  case sequenceK:
    typeSTM(s->val.sequenceS.first, returnType);
    typeSTM(s->val.sequenceS.second, returnType);
    break;
  case scopeK:
    typeSTM(s->val.scopeS.stm, returnType);
    break;
  case setintK:  
    typeEXP(s->val.setintS.modelname);
    typeEXP(s->val.setintS.nr);
    typeEXP(s->val.setintS.val);
    
    if (!intType(s->val.setintS.nr->type) || !intType(s->val.setintS.val->type) ||

⌨️ 快捷键说明

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