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; }
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); } }
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; } }
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"); } } } }
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()); }
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"); }
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; } }
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); } } }