void test_code() { /* * * class Test { * int a, b; * int fun(int c) { * a = c; * b = 2*c; * } * } * */ SymTable global; Entity cls_test("Test", "class"); SymTable *classTable = cls_test.getSymTable(); global.insert(&cls_test); Entity a("a", "int"); Entity b("b", "int"); Entity meth_fun("fun", "meth"); Entity c("c", "int"); classTable->insert(&a); classTable->insert(&b); classTable->insert(&meth_fun); SymTable *methTable = meth_fun.getSymTable(); methTable->find("params")->getSymTable()->insert(&c); assert(true); global.printTable(); //TODO }
void test_ClassSymbolTableInsertion() { /* class hello {} */ SymTable global; Entity s("hello", "int"); global.insert(&s); assert(global.find("hello")==&s); }
NodeRecordAccess* Parser::ParseRec(NodeExpression* r, SymVar* &name) { SymType* Type = name->GetType(); if (t.GetValue() == ".") while (true) { SymTable* tab = ((SymTypeRecord*)(name->GetType()))->GetFields(); if (t.GetValue() == ".") t = sc.GetNextToken(); _Table::const_iterator _it = tab->find(t.GetValue()); if (_it == tab->end()) throw Error("unknown identifier", t); name = (SymVar*)(_it->second); r = new NodeRecordAccess(new Symbol("."), r, new NodeVar(name)); t = sc.GetNextToken(); if (t.GetValue() == ".") { Type = name->GetType(); if (!Type->IsRec()) throw Error("invalid record access", t); } else { Type = name->GetType(); break; } } r->SetType(Type); return (NodeRecordAccess*)r; }
NodeCall* Parser::ParseSub(SymProc* sym) { vector<NodeExpression*> params; int size = sym->GetArgNames()->size(); if (size != 0) { for (int i=0; i<size && t.GetValue() != ")"; ++i) { t = sc.GetNextToken(); NodeExpression* p = ParseExpression(); SymTable* st = sym->GetArgTable(); SymVarParam* h = (SymVarParam*)(st->find((*(sym->GetArgNames()))[i])->second); NodeExpression* help = new NodeExpression(h); help->SetType(h->GetType()); if (p->GetType()->IsScalar() && h->GetType()->IsScalar()) CheckTypes(help, p, true); else if (GetRootType(p->GetType()) != GetRootType(help->GetType())) throw Error("impossible cast types", t); params.push_back(p); } t = RequireToken(")" , "\")\" expected"); } if (params.size() != size) throw Error("incorrect number of parameters", t); NodeCall* func = new NodeCall(sym, params); if (sym->IsFunc()) func->SetType(sym->GetType()); return func; }
SymTable* Parser::ParseRecDecl(vector<string>* &flds) { vector<string> names; Token t1 = sc.GetNextToken(); t = t1; SymTable* fldTable = new SymTable(); while(t.GetValue() != "end") { do { t1 = t; t = sc.GetNextToken(); if (t1.GetType() != identifier && t1.GetValue() != "," && t1.GetValue() != ":") throw Error("incorrect record declaration", t); if(t1.GetType() == identifier) { Check(t1.GetValue(), fldTable); names.push_back(t1.GetValue()); } } while(t.GetValue() != ":"); SymType* type = ParseType(false); for (vector<string>::iterator it = names.begin(); it != names.end(); ++it) { if (fldTable->find(*it) != fldTable->end()) throw Error("incorrect record declaration", t); fldTable->insert(SymElem (*it, new SymVarLocal(*it, type))); flds->push_back((*it)); } names.clear(); t = sc.GetNextToken(); t = RequireToken(";" , "\";\" expected"); } return fldTable; }
SymTable* Parser::ParseArguments(vector<string>* &arguments) { SymTable* argTable = new SymTable; if (t.GetValue() != "(") return argTable; vector<string> argNames; bool isVar = false; do { t = sc.GetNextToken(); if (t.GetValue() == "var") { isVar = true; t = sc.GetNextToken(); } if (t.GetType() != identifier) throw Error("incorrect name of argument", t); argNames.push_back(t.GetValue()); arguments->push_back(t.GetValue()); t = sc.GetNextToken(); if (t.GetValue() == ",") continue; if (t.GetValue() == ":") { SymType* Type = ParseType(false); if (IsExplType(Type->GetName())) throw Error("arguments type mismatch", t); t = sc.GetNextToken(); for(vector<string>::iterator it= argNames.begin(); it != argNames.end(); ++it) { if (argTable->find(*it) != argTable->end()) throw Error("identifier already declared",t); if (isVar) argTable->insert(pair<string, SymVar*> (*it, new SymVarParam_var(*it, Type))); else argTable->insert(pair<string, SymVar*> (*it, new SymVarParam(*it, Type))); } isVar = false; argNames.clear(); if (t.GetValue() != ";" && t.GetValue() != ")") throw Error("incorrect function defenition", t); } } while(t.GetValue() != ")"); t = sc.GetNextToken(); return argTable; }
SymProc* Parser::ProcFunc(bool isFunc) { t = sc.GetNextToken(); SymType* Type = NULL; SymProc* sub = NULL; if (t.GetType() != identifier) throw Error("incorrect procedure name", t); SymTable* argTable = NULL; vector<string>* argNames = new vector<string>; _Table::iterator it = table->find(t.GetValue()); string name = t.GetValue(); t = sc.GetNextToken(); argTable = ParseArguments(argNames); TableStack.PushTable(argTable); if (isFunc) { if (t.GetValue() != ":") throw Error("type expected", t); Type = ParseType(false); t = sc.GetNextToken(); } t = RequireToken(";", "\";\" expected"); if (it != table->end()) { if (!(it->second->IsProc()) || !(((SymProc*)it->second)->IsForward())) throw Error("incorrect procedure definition", t); SymTable* argTableF = ((SymProc*)it->second)->GetArgTable(); vector<string>* argNamesF = ((SymProc*)it->second)->GetArgNames(); for (size_t i=0; i<argNames->size(); ++i) { if ((*argNames)[i] != (*argNamesF)[i] || !SymComp(argTable->find((*argNames)[i])->second , argTableF->find((*argNamesF)[i])->second)) throw Error("Header does not match previouse definition", t); } if (isFunc) sub = ParseProcDecl(name, argNames, argTable, true, Type); else sub = ParseProcDecl(name, argNames, argTable, false, Type); t = RequireToken(";", "\";\" expected"); } else { if (t.GetValue() == "forward") { t = sc.GetNextToken(); if (t.GetValue() != ";") throw Error("\";\" expected", t); if (isFunc) { sub = new SymFunc(name, argNames, argTable, NULL, true, NULL); ((SymFunc*)sub)->SetType(Type); } else sub = new SymProc(name, argNames, argTable, NULL, true); sub->print(os, false); table->insert(pair<string, SymProc*> (name, sub)); TableStack.PopTable(); } else { sub = ParseProcDecl(name, argNames, argTable, isFunc, Type); if (isFunc) ((SymFunc*)sub)->SetType(Type); sub->GetBody()->print(os, 0); } t = sc.GetNextToken(); } return sub; }