Token Parser::RequireToken(string _t, string err) { if (t.GetValue() != _t) throw Error(err, t); return sc.GetNextToken(); }
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; }