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; }
CString CFilePath::GetRoot( ERootType *pRootType, BOOL bGreedy) const { int nLen = 0; ERootType RootType = GetRootType(msPath, &nLen, bGreedy); if (pRootType) *pRootType = RootType; return msPath.Left(nLen); }
void CheckTypes(NodeExpression* &l, NodeExpression* &r, bool IsOneSide) { SymType* left = l->GetType(); SymType* right = r->GetType(); if (!(left->IsScalar() && right->IsScalar())) { if (GetRootType(left) != GetRootType(right)) throw Error("impossible cast types", t); } else if (IsOneSide) { if (left->IsInt() && right->IsReal()) throw Error("impossible cast types", t); if (!(left->IsInt() && right->IsInt()) && !(left->IsReal() && right->IsReal())) { r = new NodeIntToReal(r); r->SetType(GetRootType(left)); } } else { if (!(left->IsInt() && right->IsInt()) && !(left->IsReal() && right->IsReal())) { if (left->IsReal() && right->IsInt()) { r = new NodeIntToReal(r); r->SetType(GetRootType(left)); } else { l = new NodeIntToReal(l); l->SetType(GetRootType(right)); } } } }
CString CFilePath::SplitRoot(ERootType *pRootType) { CString sHead; if (!msPath.GetLength()) return sHead; int nRootLen = 0; ERootType RootType = GetRootType(msPath, &nRootLen, FALSE); if (pRootType) *pRootType = RootType; if (RootType == rtNoRoot) { int nStart = 0; if (GetFirstChar(msPath) == '\\') ++ nStart; int nPos = msPath.Find('\\', nStart); if (nPos < 0) { sHead = nStart ? msPath.Mid(nStart) : msPath; msPath.Empty(); } else { sHead = msPath.Mid(nStart, nPos-nStart); msPath = msPath.Mid(nPos+1); } } else { sHead = msPath.Left(nRootLen); if (nRootLen < msPath.GetLength() && msPath[nRootLen] == '\\') ++nRootLen; msPath = msPath.Mid(nRootLen); } return sHead; }
ERootType CFilePath::GetRootType( int *pnLen, BOOL bGreedy) const { return GetRootType(msPath, pnLen, bGreedy); }
ERootType CFilePath::GetRootType( LPCTSTR psPath, int *pnLen, BOOL bGreedy) { const TCHAR *psInvalidChars = L"\\/:*/\"<>|"; const TCHAR chBK = '\\'; if (!psPath || !*psPath) return GRT_Return(rtNoRoot, 0, pnLen); if (_istalpha(*psPath) && psPath[1] == ':') { if (psPath[2] == chBK) { return GRT_Return(rtDriveRoot, 3, pnLen); } else { return GRT_Return(rtDriveCur, 2, pnLen); } } if (psPath[0] == chBK && psPath[1] == chBK) { if (psPath[2] == '?' && psPath[3] == chBK) { int nExtraLen = 0; GetRootType(psPath+4, &nExtraLen) ; return GRT_Return(rtLongPath, 4 + nExtraLen, pnLen); } int nLen = 2 + _tcscspn(psPath + 2, psInvalidChars); TCHAR const *psEnd = psPath+nLen; if (*psEnd == 0) return GRT_Return(rtServerOnly, nLen, pnLen); if (*psEnd == chBK && psEnd[1] == 0) return GRT_Return(rtServerOnly, nLen + 1, pnLen); if (*psEnd == chBK) { if (!bGreedy) return GRT_Return(rtServer, nLen, pnLen); nLen += 1 + _tcscspn(psEnd + 1, psInvalidChars); psEnd = psPath + nLen; if (*psEnd == 0) return GRT_Return(rtServerShare, nLen, pnLen); if (*psEnd == '\\') return GRT_Return(rtServerShare, nLen + 1, pnLen); } } int nLen = _tcscspn(psPath, psInvalidChars); TCHAR const *psEnd = psPath + nLen; if (nLen > 0 && *psEnd == ':') { if (psEnd[1] == '/' && psEnd[2] == '/') return GRT_Return(rtProtocol, nLen + 3, pnLen); else return GRT_Return(rtPseudoProtocol, nLen + 1, pnLen); } return GRT_Return(rtNoRoot, 0, pnLen); }