Example #1
0
static int getNumOrSym(char **token, int sep, int kind, int *isAlpah)
{
    char    *cp;
    int     num;

    assert(token && *token);

    if (*token == 0) {
        return 0;
    }
    if (isalpha((uchar) **token)) {
        *isAlpah = 1;
        cp = strchr(*token, sep);
        if (cp) {
            *cp++ = '\0';
        }
        num = lookupSym(*token, kind);
        *token = cp;
        return num;
    }
    num = atoi(*token);
    *token = strchr(*token, sep);
    if (*token) {
        *token += 1;
    }
    *isAlpah = 0;
    return num;
}
Example #2
0
void checkCall(astree* curr) {
    if(lookup(curr->children[0]->lexinfo)) {
        symbol *fnSym = lookupSym(curr->children[0]->lexinfo);
        if(curr->children.size()-1!=fnSym->parameters->size()) {
            errprintf("%zu.%zu.%zu Parameters of defined function"
                      " do not match\n",
                      curr->children[0]->filenr,curr->children[0]->linenr,
                      curr->children[0]->offset);
        } else {
            for(size_t i = 0; i<fnSym->parameters->size(); i++) {
                int paramType = getIdentReturn(fnSym->parameters->at(i));
                int callParam = getReturnType(curr->children[i+1]);
                if(paramType!=callParam) {
                    if(callParam == TOK_NULL) continue;
                    errprintf("%zu.%zu.%zu Argument type does not match"
                              " defined function argument type.\n",curr->
                              children[i+1]->filenr,curr->children[i+1]->
                              linenr,curr->children[i+1]->offset);
                }
            }
        }
    } else {
        errprintf("%zu.%zu.%zu Function not defined\n",
                  curr->children[0]->filenr,curr->children[0]->linenr,
                  curr->children[0]->offset);
    }
}
Example #3
0
string recursBinop(astree* curr, astree* func, int flag){
  int sym = curr->symbol;
  switch(sym){
    case '+': case '-': case '/': case '*':{
      string str1 = recursBinop(curr->children[0], func, flag);
      string str2 = recursBinop(curr->children[1], func, flag);
      fprintf(file_oil,"\tint i%d = %s %s %s;\n",ireg,str1.c_str(),
                      curr->lexinfo->c_str(),str2.c_str());
      ireg++;
      return "i" + to_string(ireg-1);
    }
    case TOK_IDENT:{
      symbol* temp = lookupSym(curr->lexinfo);
      int blockNum = 1;
      if(temp != NULL){
        blockNum = static_cast<int>(temp->block_nr);
      }else{
        if( func != NULL){
          for(size_t i = 0; i < func->children[1]
                                      ->children.size(); i++){
            if(*(curr->lexinfo) ==
              *(func->children[1]->children[i]->children[0]->lexinfo)){
                blockNum = 1;
            }
          }
        }
      }
      if ( flag == 0){
        return "__"+*(curr->lexinfo);
      }else{
        return "_"+to_string(blockNum)+"_"+*(curr->lexinfo);
      }


    }
    case TOK_INTCON:{
      string temp = *(curr->lexinfo);
      return temp;
    }
    case TOK_LE: case TOK_GE: case TOK_LT: case TOK_GT: case TOK_EQ:
    case TOK_NE:{
      string str1 = recursBinop(curr->children[0], NULL, flag);
      string str2 = recursBinop(curr->children[1], NULL, flag);
      return str1 +" "+ *(curr->lexinfo) +" "+str2;
      break;
    }
    default:
      return "";
      break;
  }
}
Example #4
0
void dumpStruct(astree* root){
  for(size_t i=0;i<root->children.size();i++){
    int sym = root->children[i]->symbol;
    if(sym == TOK_STRUCT){
      const string* strval = root->children[i]->children[0]->lexinfo;
      symbol* structSym = lookupSym(strval);
      if(structSym!=NULL){
        fprintf(file_oil,"struct s_%s {\n",structSym->type_id.c_str());
        for(size_t j=1;j<root->children[i]->children.size();j++){
          astree* temp = root->children[i]->children[j];
          const string* field = temp->children[0]->lexinfo;
          if(temp->children.size()>1)
            field = temp->children[1]->lexinfo;
          string type = getStrType(temp);
          fprintf(file_oil, "\t%s f_%s_%s;\n",
                            type.c_str(),strval->c_str(),
                                            field->c_str());
        }
        fprintf(file_oil,"}\n");
      }
    }
  }
}
Example #5
0
void printVardecl(astree* curr, astree* func, int flag){
  string result = "";
  result = recursBinop(curr->children[1], func, flag);
  string left = "";
  if(curr->children[0]->symbol == TOK_IDENT){
    symbol* temp = lookupSym(curr->children[0]->lexinfo);
    if(func != NULL){
      for(size_t i = 0; i < func->children[1]->children.size(); i++){
        if(*(curr->children[0]->lexinfo) ==
          *(func->children[1]->children[i]->children[0]->lexinfo)){
            int blockNum = 1;
            left+="_"+to_string(blockNum)+"_";
            left+=*(curr->children[0]->children[0]->lexinfo);
        }
      }
    }
    if(left == ""){
      int blockNum = static_cast<int>(curr->block);
      if(flag == 0){
          left+="__";
      }else{
        left+="_"+to_string(blockNum)+"_";
      }
      left+=*(curr->children[0]->lexinfo);
    }
  }else{
    int blockNum = static_cast<int>(curr->block);
    if(flag == 0){
          left+="int __";
    }else{
          left+="int _"+to_string(blockNum)+"_";
    }
    left+=*(curr->children[0]->children[0]->lexinfo);
  }
  fprintf(file_oil,"\t%s = %s;\n",left.c_str(),result.c_str());
}
Example #6
0
void dumpFunction(astree* root){
  for(size_t i = 0;i<root->children.size();i++){
    astree* curr = root->children[i];
    int sym = curr->symbol;
    if(sym == TOK_FUNCTION){
      fprintf(file_oil, "%s __%s (",
      getStrType(curr->children[0]).c_str(),
      curr->children[0]->children[0]->lexinfo->c_str());
      if(curr->children[1]->children.size()==0){
        fprintf(file_oil,")\n");
      }else{
        symbol* func = lookupSym(curr->children[0]->
                                children[0]->lexinfo);
        vector<symbol*> temp = *(func->parameters);
        for(size_t j = 0; j<temp.size();j++){
          symbol* tempSym = temp[j];
          string output = getStrType(curr->children[1]->children[j]);
          int blocknum = static_cast<int>(tempSym->block_nr);
          output+="_"+to_string(blocknum)+"_";
          output+=*(curr->children[1]->children[j]->
                                children[0]->lexinfo);
          if(j==temp.size()-1){
            fprintf(file_oil, "\n\t%s)\n",output.c_str());
          }else{
            fprintf(file_oil, "\n\t%s,",output.c_str());
          }
        }
      }
      fprintf(file_oil, "{\n");
      for(size_t k = 0;k<curr->children[2]->children.size();k++){
        int blockSym = curr->children[2]->children[k]->symbol;
        switch(blockSym){
          case TOK_VARDECL: case '=':
            printVardecl(curr->children[2]->children[k], curr, 1);
            break;
          case TOK_RETURN:{
            string result = "";
            if(curr->children[2]->children[k]->children.size() > 1){
              result = recursBinop(curr->children[2]->children[k]
                                          ->children[1], curr, 1);
            }else{
              result = recursBinop(curr->children[2]->children[k]
                                        ->children[0], curr, 1);
            }
            fprintf(file_oil, "\treturn %s\n", result.c_str());
            break;
          }
          case TOK_WHILE:
          {
            dumpWhile(curr->children[2]->children[k], 1);
            break;
          }
          case TOK_IF:
            dumpIf(curr, 1);
            break;
          case TOK_IFELSE:
            dumpIfElse(curr, 1);
            break;
          case TOK_CALL:
            dumpCall(curr);
          default:
            break;
        }
      }
    }
  }
  fprintf(file_oil, "}\n");
}
Example #7
0
int getReturnType(astree* root) {
    int sym = root->symbol;
    switch(sym) {
    case TOK_NULL:
        return sym;
        break;
    case TOK_INTCON:
        return sym;
        break;
    case TOK_CHARCON:
        return sym;
        break;
    case TOK_BOOL:
        return sym;
        break;
    case TOK_IDENT:
        if(lookup(root->lexinfo)) {
            symbol* val = lookupSym(root->lexinfo);
            return getIdentReturn(val);
        } else {
            errprintf("%zu.%zu.%zu"
                      " Variable being referenced is undefined\n",root->filenr,
                      root->linenr,root->offset);
            return -1;
        }
        break;
    case '+':
    case '-':
    case '*':
    case '/':
    case '%':
    {
        int left = getReturnType(root->children[0]);
        int right = getReturnType(root->children[1]);
        if(right == left && right == TOK_INTCON) {
            return right;
        } else {
            errprintf("%zu.%zu.%zu Type check error: %s "
                      "does not match %s\n"
                      ,root->children[0]->filenr,root->children[0]->linenr,
                      root->children[0]->offset,get_yytname(left)
                      ,get_yytname(right));
            return right;
        }
        break;
    }
    case TOK_NEWARRAY:
        return TOK_NEWARRAY;
        break;
    case TOK_NEWSTRING:
        return TOK_NEWSTRING;
        break;
    case TOK_CALL:
        checkCall(root);
        return getReturnType(root->children[0]);
        break;
    case TOK_POS:
    case TOK_NEG:
        return getReturnType(root->children[0]);
        break;
    case TOK_NEW:
        return getReturnType(root->children[0]);
        break;
    case TOK_TYPEID:
        return TOK_TYPEID;
        break;
    case '.':
        if(lookup(root->children[0]->lexinfo)) {
            symbol* tempSym = lookupSym(root->children[0]->lexinfo);
            string structType = tempSym->type_id;
            if(structType == "") {
                errprintf("%zu.%zu.%zu Referenced struct not defined\n",
                          root->children[0]->filenr,root->children[0]->linenr,
                          root->children[0]->offset);
                return -1;
            }
            if(lookup(&structType)) {
                symbol* structSym = lookupSym(&structType);
                symbol_table* tab = structSym->fields;
                auto fi = tab->find(root->children[1]->lexinfo);
                if(fi!=tab->cend()) {
                    symbol* structField = fi->second;
                    return getIdentReturn(structField);
                } else {
                    errprintf("%zu.%zu.%zu Field not defined\n",
                              root->children[1]->filenr,root->children[1]->linenr,
                              root->children[1]->offset);
                }
            }
        } else {
            errprintf("%zu.%zu.%zu Referenced struct not defined\n",
                      root->children[0]->filenr,root->children[0]->linenr,
                      root->children[0]->offset);
        }
        return -1;
        break;
    case TOK_ORD:
        if(getReturnType(root->children[0])==TOK_CHARCON) {
            return TOK_INTCON;
        } else {
            errprintf("%zu.%zu.%zu Ord must be called on type char\n",
                      root->children[0]->filenr,root->children[0]->linenr,
                      root->children[0]->offset);
        }
        break;
    case TOK_CHR:
        if(getReturnType(root->children[0])==TOK_INTCON) {
            return TOK_CHARCON;
        } else {
            errprintf("%zu.%zu.%zu Chr must be called on type int\n",
                      root->children[0]->filenr,root->children[0]->linenr,
                      root->children[0]->offset);
        }
        break;
    }
}
Example #8
0
void travVardecl(astree* root) {
    astree* node = root->children[0];
    astree* node1 = root->children[1];
    root->block = blockcount;
    int sym = node->symbol;
    int otherSym = getReturnType(node1);
    switch(sym) {
    case TOK_INT:
        checkDecl(node);
        if(otherSym==TOK_INTCON || otherSym==TOK_NULL) {
            symbol *newSym = create_symbol(node->children[0]);
            newSym->attributes.set(ATTR_int);
            newSym->attributes.set(ATTR_lval);
            newSym->attributes.set(ATTR_variable);
            if(symbol_stack.back() == nullptr || symbol_stack.empty()) {
                symbol_table* tab = new symbol_table();
                tab->insert(symbol_entry(node->children[0]->lexinfo,newSym));
                symbol_stack.pop_back();
                symbol_stack.push_back(tab);
            } else {
                symbol_stack.back()->insert(symbol_entry(node->children[0]->
                                            lexinfo,newSym));
            }
            dumpToFile(file_sym, newSym, node->children[0]);
        } else if(otherSym == TOK_NEWARRAY) {
            insertArr(node, node1);
        }
        break;

    case TOK_CHAR:
        checkDecl(node);
        if(otherSym==TOK_CHARCON || otherSym==TOK_NULL) {
            symbol *newSym = create_symbol(node->children[0]);
            newSym->attributes.set(ATTR_char);
            newSym->attributes.set(ATTR_lval);
            newSym->attributes.set(ATTR_variable);
            if(symbol_stack.back() == nullptr || symbol_stack.empty()) {
                symbol_table* tab = new symbol_table();
                tab->insert(symbol_entry(node->children[0]->lexinfo,newSym));
                symbol_stack.pop_back();
                symbol_stack.push_back(tab);
            } else {
                symbol_stack.back()->insert(symbol_entry(node->children[0]->
                                            lexinfo,newSym));
            }
            dumpToFile(file_sym, newSym, node->children[0]);
        } else if(otherSym == TOK_NEWARRAY) {
            insertArr(node, node1);
        }
        break;

    case TOK_BOOL:
        checkDecl(node);
        if(otherSym==TOK_TRUE ||
                otherSym==TOK_FALSE || otherSym==TOK_NULL) {
            symbol *newSym = create_symbol(node->children[0]);
            newSym->attributes.set(ATTR_bool);
            newSym->attributes.set(ATTR_lval);
            newSym->attributes.set(ATTR_variable);
            if(symbol_stack.back() == nullptr || symbol_stack.empty()) {
                symbol_table* tab = new symbol_table();
                tab->insert(symbol_entry(node->children[0]->lexinfo,newSym));
                symbol_stack.pop_back();
                symbol_stack.push_back(tab);
            } else {
                symbol_stack.back()->insert(symbol_entry(node->children[0]->
                                            lexinfo,newSym));
            }
            dumpToFile(file_sym, newSym, node->children[0]);
        } else if (otherSym == TOK_NEWARRAY) {
            insertArr(node, node1);
        }
        break;
    case TOK_STRING:
        checkDecl(node);
        if(otherSym == TOK_NEWSTRING) {
            if(node1->children[0]->symbol == TOK_INTCON ||
                    otherSym==TOK_NULL) {
                symbol *newSym = create_symbol(node->children[0]);
                newSym->attributes.set(ATTR_string);
                newSym->attributes.set(ATTR_lval);
                newSym->attributes.set(ATTR_variable);
                if(symbol_stack.back() == nullptr || symbol_stack.empty()) {
                    symbol_table* tab = new symbol_table();
                    tab->insert(symbol_entry(node->children[0]
                                             ->lexinfo,newSym));
                    symbol_stack.pop_back();
                    symbol_stack.push_back(tab);
                } else {
                    symbol_stack.back()->insert(symbol_entry(node->children[0]->
                                                lexinfo,newSym));
                }
                dumpToFile(file_sym, newSym, node->children[0]);
            } else {
                errprintf("%zu.%zu.%zu String size allocator not of "
                          "type int.\n",
                          node1->children[1]->filenr, node1->children[1]->linenr,
                          node1->children[1]->offset);
            }
        } else if (otherSym == TOK_STRINGCON || otherSym==TOK_NULL) {
            if(otherSym!=TOK_NULL)
                strvec.push_back(node1->lexinfo);
            symbol *newSym = create_symbol(node->children[0]);
            newSym->attributes.set(ATTR_string);
            newSym->attributes.set(ATTR_lval);
            newSym->attributes.set(ATTR_variable);
            if(symbol_stack.back() == nullptr || symbol_stack.empty()) {
                symbol_table* tab = new symbol_table();
                tab->insert(symbol_entry(node->children[0]->lexinfo,newSym));
                symbol_stack.pop_back();
                symbol_stack.push_back(tab);
            } else {
                symbol_stack.back()->insert(symbol_entry(node->children[0]->
                                            lexinfo,newSym));
            }

            dumpToFile(file_sym, newSym, node->children[0]);
        } else if(otherSym == TOK_NEWARRAY) {
            insertArr(node, node1);
        }
        break;
    case TOK_TYPEID:
        if(otherSym == TOK_TYPEID || otherSym==TOK_NULL
                || otherSym == TOK_STRUCT) {
            if(node1->symbol != TOK_CALL) {
                string leftStr = *node->lexinfo;
                string rightStr = *node1->children[0]->lexinfo;
                if(leftStr != rightStr) {
                    errprintf("%zu.%zu.%zu Type mismatch between constructor "
                              "and declaration.\n",
                              node1->children[1]->filenr, node1->children[1]->linenr,
                              node1->children[1]->offset);
                }
            } else {
                if(lookup(node1->children[0]->lexinfo)) {
                    symbol* funcSym = lookupSym(node1->children[0]->lexinfo);
                    string leftStr = *node->lexinfo;
                    string rightStr = funcSym->type_id;
                    if(leftStr != rightStr) {
                        errprintf("%zu.%zu.%zu Type mismatch between constructor "
                                  "and declaration.\n",
                                  node1->children[1]->filenr, node1->children[1]->linenr,
                                  node1->children[1]->offset);
                    }
                }
            }
            symbol *newSym = create_symbol(node->children[0]);
            newSym->attributes.set(ATTR_struct);
            newSym->attributes.set(ATTR_lval);
            newSym->attributes.set(ATTR_variable);
            newSym->type_id = *node->lexinfo;
            if(symbol_stack.back() == nullptr || symbol_stack.empty()) {
                symbol_table* tab = new symbol_table();
                tab->insert(symbol_entry(node->children[0]->lexinfo,newSym));
                symbol_stack.pop_back();
                symbol_stack.push_back(tab);
            } else {
                symbol_stack.back()->insert(symbol_entry(node->children[0]->
                                            lexinfo,newSym));
            }

            dumpToFile(file_sym, newSym, node->children[0]);
        } else {
            errprintf("%zu.%zu.%zu Variable not allocated correctly.\n",
                      node1->children[1]->filenr, node1->children[1]->linenr,
                      node1->children[1]->offset);
        }
        break;
    case TOK_IDENT:
        if(lookup(node->lexinfo)) {
            symbol* newSym = lookupSym(node->lexinfo);
            int type = getIdentReturn(newSym);
            if(type==TOK_STRUCT&&otherSym==TOK_TYPEID) {
                if(newSym->type_id!=*node1->children[0]->lexinfo) {
                    errprintf("%zu.%zu.%zu Variable being reassigned wrong "
                              "type",node->filenr,node->linenr,node->offset);
                }
            }
        } else {
            errprintf("%zu.%zu.%zu"
                      " Variable being referenced is undefined\n",node->filenr,
                      node->linenr,node->offset);
        }
    }
}