SglExprLex::ScanResult SglExprLex::searchResult2scanResult(Tables::SearchResult sr) { ScanResult tokens[maxOverloadSymbols]; ScanResult tmp; SymType stype; tokens[0].type = UNKNOWNTOKEN; tokens[0].symbol = 0; if (sr.count > maxOverloadSymbols) sr.count = 0; for (int i = -1; ++i < sr.count; ++sr.pt) { tmp.symbol = sr.pt.value(); stype = tmp.symbol? tmp.symbol->type() : unassigned; switch(stype) { case tagSym: tmp.type = baseTag(tmp.symbol); break; case operatorSym: tmp.type = opToken(tmp.symbol); break; default: tmp.type = symbolType(stype); } // sort overloaded symbols (insertion sort) int j = i; for (; --j >= 0 && tokenOrder(tokens[j].type) < tokenOrder(tmp.type);) tokens[j+1] = tokens[j]; tokens[j+1] = tmp; } for (int i = sr.count; --i > 0;) pending.enqueue(tokens[i]); if (sr.count == 1) { switch (stype) { case operatorSym: if (!tmp.symbol->asOp()->isUnary()) { // append a NOPREFIX token for not overloaded binary operators tmp.type = NOPREFIX; tmp.symbol = 0; pending.enqueue(tmp); } break; case tagSym: if (tmp.symbol->asTag()->complement()) { // split a complement tag into a base token and a complement token pending.enqueue(tmp); tokens[0].type = CMPLTAG; } break; default: ; } } return tokens[0]; }
// parses the next token // returns false if done void opScanner::ScanTokens(const inputtype& Input) { // if we've reached the end of the Input stream, // add an EOF token and return false int size = Input.Size(); int current = 0; // TODO: the input list of chars is really a bad idea // Input should be a vector, and we should not alter it, // instead we should iterate over it (maybe w/ an iterator we pass // around. while (current != size) { // scan for the next token // (with the correct precedence) if (current != size && Newline(Input, current)) ; else if (current != size && CComment(Input, current)) ; else if (current != size && Comment(Input, current)) ; else if (current != size && String(Input, current)) ; else if (current != size && WhiteSpace(Input, current)) ; else if (current != size && Operator(Input, current)) ; else if (current != size && Hexadecimals(Input, current)) ; else if (current != size && Number(Input, current)) ; else if (current != size && GetId(Input, current)) ; else if (current != size) { opToken newToken(T_ANYCHAR, Input[current], CurrentLine); Tokens.PushBack(newToken); ++current; } } Tokens.PushBack(opToken(T_EOF, "", CurrentLine)); }
// TODO: should we replace this with @/spacer? // do concatenation expansion void OPMacroNode::ExpandConcatenation(opNode* cloned) { iterator i = cloned->GetBegin(); iterator end = cloned->GetEnd(); // check for concatenation at ends if (i != end) { opNode* errored = NULL; if (i->GetId() == T_CONCATENATION) errored = *i; else if (cloned->GetLast()->GetId() == T_CONCATENATION) errored = *cloned->GetLast(); if (errored) { opError::MessageError( errored, "## opmacro operator cannot concatenate block boundaries."); } } while (i != end) { opNode* current = *i; if (current->IsTerminal()) { if (current->GetId() != T_CONCATENATION) { ++i; continue; } iterator nexti = i; ++nexti; iterator previ = i; --previ; opNode* previous = *previ; opNode* next = *nexti; if (next->IsTerminal() && previous->IsTerminal()) { // make sure they aren't whitespace! if (previous->IsWhitespace() || next->IsWhitespace()) { opError::MessageError( current, "## opmacro operator cannot concatenate whitespace."); } // all we have to do is // delete all 3 // insert a node at previous's position (preserve line #! // set the value to our string // set the id to T_ID, or else do a lookup on it // thats all folks // now we need to grab the pasted string opString pastedstring = previous->GetStringValue() + next->GetStringValue(); int line = current->GetLine(); FileNode* file = current->GetFile(); iterator newi = nexti; ++newi; // delete all 3 nodes cloned->DeleteNode(previ); cloned->DeleteNode(i); cloned->DeleteNode(nexti); stacked<TerminalNode> newnode = NEWNODE( TerminalNode(opToken(T_ID, pastedstring, line), file)); cloned->InsertNode(newnode, newi); i = newi; continue; } } else ExpandConcatenation(current); ++i; } }