/** * @return true if the token stream in its present state can convert * the token stream to a case expression. * * @param parser -- Parser that is used to parse out whole elements. * @param stream -- The token stream. * @param elements -- The element output, first element is the condition, every * other element should be case element containers, and the * last element could be a default element. * @return true if the stream of tokens can be accepted, false otherwise. */ bool Case_::CanAccept_( Parser const& parser , TokenStream& stream , std::vector<strine::Element>& elements ) const { bool can_accept = MatchToken_(stream, "(") && MatchToken_(stream, "case"); if (can_accept && stream.HasTokens()) { Element current_element; can_accept =parser.ParseAny(stream, current_element); elements.push_back(current_element); } else { can_accept = false; } while(can_accept && stream.HasTokens()) { stream.Push(); bool isEnd = MatchToken_(stream, ")"); if (isEnd) { stream.Consume(); break; } // Reset the stream, attempt to parse a list. stream.Rollback(); // Right now I'm not sure what symbol to use for an "ANY"- needs to // be something self-explanatory. bool isAlmostEnd = MatchToken_(stream, "->"); if (isAlmostEnd) { stream.Consume(); assert(0); break; } stream.Rollback(); // Typically we'll have a condition. can_accept = (MatchToken_(stream, "[")) && CanAcceptListRemainder_(parser, stream, elements); } return can_accept; }
/** * Parse out the token stream. * * @param parser Not used. * @param in The input token stream. * @param elements The elements. * @return the element that was parsed. */ Element Function_::Parse_( Parser const& /* parser */ , TokenStream& in , std::vector<Element> const& elements) const { in.Consume(); std::shared_ptr<Function_> f(new Function_()); size_t const NUMBER_OF_ARGS = (elements.empty()) ? 0 : elements.size() - 1; std::vector<Variable> parms; bool isAVariable = false; for(size_t i=0; i<NUMBER_OF_ARGS; ++i) { Variable v = CastToVariable(elements[i], isAVariable); if (isAVariable) { parms.push_back(v); } } f->SetArguments(parms); if (false == elements.empty()) { f->SetBody( elements[elements.size() - 1] ); } else { f->SetBody(Nil()); } return Function(f, SourceLocation()); }
/** * Parse out the token stream. * * @param in -- The input token stream. * @return the element that was parsed. */ Element Error_::Parse_( Parser const& , TokenStream& in , std::vector<strine::Element> const& elements) const { in.Consume(); std::shared_ptr<Error_> s(new Error_()); std::shared_ptr<String_ > str = std::dynamic_pointer_cast<String_>(elements[0].ElementHandle()); if (0 != str) { s->SetIdentifier(str->Value()); } if (elements.size() >= 3) { std::shared_ptr<Number_ > number = std::dynamic_pointer_cast<Number_>(elements[1].ElementHandle()); if (0 != number) { s->SetRow(number->IntValue()); } number = std::dynamic_pointer_cast<Number_>(elements[2].ElementHandle()); if (0 != number) { s->SetColumn(number->IntValue()); } } return Error(s, SourceLocation()); }
/** * Parse out the token stream. * * @param in -- The input token stream. * @return the element that was parsed. */ Element Case_::Parse_( Parser const& , TokenStream& in , std::vector<strine::Element> const& elements) const { in.Consume(); Case_* s = new Case_(); s->SetCondition(elements[0]); size_t const ELEMENTS_SIZE = elements.size(); for(size_t i=1; i<ELEMENTS_SIZE; i += 2) { size_t nextIndex = i + 1; // Check to see if you have a fallthrough case. if (nextIndex >= ELEMENTS_SIZE) { s->SetFallthrough(elements[i]); } // Just a regular ol' element pairing. else { s->Add(elements[i], elements[nextIndex]); } } return Case(s, SourceLocation()); }
/** * Parse out the token stream. * * @param in -- The input token stream. * @return the element that was parsed. */ Element Quoted_::Parse_( Parser const& , TokenStream& in , std::vector<Element> const& elements) const { in.Consume(); Quoted quoted; quoted.SetElement(elements[0]); return quoted; }
/** * Parse out the token stream. * * @param in -- The input token stream. * @return the element that was parsed. */ Element Evaluate_::Parse_( Parser const& , TokenStream& in , std::vector<strine::Element> const& elements) const { in.Consume(); std::shared_ptr<Evaluate_> s (new Evaluate_(this->strine)); s->SetElement(elements[0]); return Evaluate(s, SourceLocation()); }
/** * Parse out the token stream. * * @param in -- The input token stream. * @return the element that was parsed. */ Element Set_::Parse_( Parser const& , TokenStream& in , std::vector<strine::Element> const& elements) const { in.Consume(); Set_* s = new Set_(); s->SetIdentifier(elements[0].ToString()); s->SetElement(elements[1]); return Set(s, SourceLocation()); }
/** * Parse out the token stream. * * @param in -- The input token stream. * @return the element that was parsed. */ Element If_::Parse_( Parser const& , TokenStream& in , std::vector<Element> const& elements) const { in.Consume(); std::shared_ptr<If_> s ( new If_() ); s->SetCondition(elements[0]); s->SetTrue(elements[1]); s->SetFalse(elements[2]); return If(s, SourceLocation()); }
/** * Parse out the token stream. * * @param in -- The input token stream. * @return the element that was parsed. */ Element Builtin_::Parse_( Parser const& , TokenStream& in , std::vector<Element> const& elements) const { in.Consume(); std::shared_ptr<String_> s = std::dynamic_pointer_cast<String_>(elements[0].ElementHandle()); Element element; std::shared_ptr<Builtin_> b(new Builtin_(this->table)); if (0 != s) { b->SetName( s->Value() ); } if (elements.size() > 1) { b->SetAdditionalParameter(elements[1]); } return Builtin(b, SourceLocation()); }
/** * @return true if the token stream in its present state can convert * the token stream to a set expression. * * @param in -- The token stream. * @return true if the stream of tokens can be accepted, false otherwise. */ bool Function_::CanAccept_( Parser const& parser , TokenStream& stream , std::vector<strine::Element>& elements) const { bool can_accept = false; // ( if (stream.HasTokens()) { Element current_element = stream.NextToken(); can_accept = (current_element.Type() == Types::TOKEN) && (current_element.ToString() == "("); } // function if (can_accept && stream.HasTokens()) { Element current_element = stream.NextToken(); can_accept = (current_element.Type() == Types::TOKEN) && (current_element.ToString() == "function"); } // ( if (can_accept && stream.HasTokens()) { Element current_element = stream.NextToken(); can_accept = (current_element.Type() == Types::TOKEN) && (current_element.ToString() == "("); } // args while(can_accept && stream.HasTokens()) { strine::Element current_element = stream.NextToken(); if (current_element.Type() == Types::TOKEN) { if (current_element.ToString() == ")") { break; } else { can_accept = false; } } else if (current_element.Type() == Types::VARIABLE) { elements.push_back(current_element); } else { can_accept = false; } } if (can_accept) { stream.Push(); strine::Element new_body; can_accept = parser.ParseAny(stream, new_body); if (can_accept && stream.HasTokens()) { stream.Consume(); Element current_element = stream.NextToken(); can_accept = (current_element.Type() == Types::TOKEN) && (current_element.ToString() == ")"); elements.push_back(new_body); } else { stream.Rollback(); can_accept = false; } } return can_accept; }
/** * @return true if the token stream in its present state can convert * the token stream to a builtin expression. * * @param in -- The token stream. * @return true if the stream of tokens can be accepted, false otherwise. */ bool Builtin_::CanAccept_( Parser const& parser , TokenStream& stream , std::vector<Element>& elements) const { bool can_accept = false; // ( if (stream.HasTokens()) { Element current_element = stream.NextToken(); can_accept = (current_element.Type() == Types::TOKEN) && (current_element.ToString() == "("); } can_accept = can_accept && stream.HasTokens(); // builtin if (can_accept) { Element current_element = stream.NextToken(); can_accept = (current_element.Type() == Types::TOKEN) && (current_element.ToString() == "builtin"); } can_accept = can_accept && stream.HasTokens(); // Symbol if (can_accept) { Element current_element = stream.NextToken(); can_accept = (current_element.Type() == Types::STRING); elements.push_back(current_element); } can_accept = can_accept && stream.HasTokens(); // if (can_accept) { if (ParseEnd_(stream)) { stream.NextToken(); } else { Element current_element; stream.Push(); can_accept = parser.ParseAny( stream, current_element ); if (false == can_accept) { stream.Rollback(); } else { elements.push_back(current_element); stream.Consume(); } can_accept = ParseEnd_(stream); if (can_accept) { stream.NextToken(); } } } return can_accept; }