15 #ifndef Om_Language_Expression_
23 #ifndef Om_Macro_Precompilation_
25 #include "boost/test/unit_test.hpp"
33 BOOST_AUTO_TEST_SUITE(ExpressionTest)
35 BOOST_AUTO_TEST_CASE(GeneralTest) {
73 BOOST_AUTO_TEST_CASE(EqualityTest) {
81 "= expression{a{b}{c}d{e}} {"
91 System::Get().Evaluate(
"= expression{a{b}{c}} {a{b}{c}}")
115 System::Get().Evaluate(
"= expression{a{b}{c}} {A{B}{C}}")
131 BOOST_AUTO_TEST_CASE(ReadTest) {
132 char const theCode[] = (
140 std::string theResult;
143 std::back_insert_iterator<std::string>
145 std::back_inserter(theResult)
147 Writer theWriter(theCodePointSink);
150 Reader theReader(theCodePointSource);
151 Expression theExpression;
152 theExpression.ParseElements(theReader);
153 theExpression.GiveElements(theWriter);
164 std::string(theResult)
168 BOOST_AUTO_TEST_SUITE_END()
180 #ifndef Om_Macro_Precompilation_
182 #include "boost/ref.hpp"
183 #include "boost/utility/in_place_factory.hpp"
190 Om::Language::Expression
194 inline char const * Type_::GetName() {
200 inline Type_::Expression():
203 inline Type_ & Type_::operator =(Expression theExpression) {
204 this->Swap(theExpression);
208 inline void Type_::BackGiveForm(Consumer & theConsumer) {
210 !this->thisFormDeque.empty()
212 this->thisFormDeque.back().GiveElements(theConsumer);
213 this->thisFormDeque.pop_back();
217 inline void Type_::BackGiveTerm(Consumer & theConsumer) {
219 !this->thisFormDeque.empty()
221 Form & theForm = this->thisFormDeque.back();
223 theForm.BackGiveTerm(theConsumer)
228 this->thisFormDeque.pop_back();
233 inline void Type_::BackPopTerm() {
235 !this->thisFormDeque.empty()
237 Form & theForm = this->thisFormDeque.back();
239 theForm.BackPopTerm()
244 this->thisFormDeque.pop_back();
248 template <
typename TheOperand>
249 inline void Type_::BackTakeOperand(TheOperand & theOperand) {
250 this->GetBackTaker().BackTakeOperand(theOperand);
253 template <
typename TheOperator>
254 inline void Type_::BackTakeOperator(TheOperator & theOperator) {
256 !theOperator.IsEmpty()
258 this->thisFormDeque.push_back(
261 this->thisFormDeque.back().TakeOperator(theOperator);
264 template <
typename TheProducer>
265 inline void Type_::BackTakeQuotedProducer(TheProducer & theProducer) {
266 this->GetBackTaker().BackTakeQuotedProducer(theProducer);
269 inline void Type_::Clear() {
270 this->thisFormDeque.clear();
273 inline void Type_::FrontGiveForm(Consumer & theConsumer) {
275 !this->thisFormDeque.empty()
277 this->thisFormDeque.front().GiveElements(theConsumer);
278 this->thisFormDeque.pop_front();
282 inline void Type_::FrontGiveTerm(Consumer & theConsumer) {
284 !this->thisFormDeque.empty()
286 Form & theForm = this->thisFormDeque.front();
288 theForm.FrontGiveTerm(theConsumer)
293 this->thisFormDeque.pop_front();
298 inline void Type_::FrontPopTerm() {
300 !this->thisFormDeque.empty()
302 Form & theForm = this->thisFormDeque.front();
304 theForm.FrontPopTerm()
309 this->thisFormDeque.pop_front();
313 template <
typename TheOperand>
314 inline void Type_::FrontTakeOperand(TheOperand & theOperand) {
315 this->GetFrontTaker().FrontTakeOperand(theOperand);
318 template <
typename TheOperator>
319 inline void Type_::FrontTakeOperator(TheOperator & theOperator) {
321 !theOperator.IsEmpty()
323 this->GetFrontTaker().TakeOperator(theOperator);
326 template <
typename TheProducer>
327 inline void Type_::FrontTakeQuotedProducer(TheProducer & theProducer) {
328 this->GetFrontTaker().FrontTakeQuotedProducer(theProducer);
331 inline std::auto_ptr<
333 > Type_::GetElementRange()
const {
334 return std::auto_ptr<
337 new ElementRange(*
this)
341 inline void Type_::GiveElements(Consumer & theConsumer) {
344 this->thisFormDeque.begin(),
345 this->thisFormDeque.end()
350 inline void Type_::GiveElements(Consumer & theConsumer)
const {
353 this->thisFormDeque.begin(),
354 this->thisFormDeque.end()
358 inline bool Type_::IsEmpty()
const {
359 return this->thisFormDeque.empty();
362 inline void Type_::ParseElements(Reader & theReader) {
369 inline void Type_::ParseQuotedElements(Reader & theReader) {
371 theLiteral.ParseElements(theReader);
372 this->TakeQuotedProducer(theLiteral);
375 inline void Type_::Swap(Expression & theExpression) {
376 this->thisFormDeque.swap(theExpression.thisFormDeque);
379 inline void Type_::TakeElements(Expression & theExpression) {
381 !theExpression.IsEmpty()
386 this->Take(theExpression);
388 FormDeque & theFormDeque = theExpression.thisFormDeque;
390 !theFormDeque.empty()
393 FormDeque::iterator theCurrent = theFormDeque.begin();
395 theCurrent->GetOperator().IsEmpty()
397 theFormDeque.front().GiveElements(*
this);
398 theFormDeque.pop_front();
404 theCurrent = theFormDeque.begin();
407 FormDeque::iterator
const theEnd = theFormDeque.end();
408 assert(theEnd != theCurrent);
411 !theCurrent->GetOperator().IsEmpty()
413 this->thisFormDeque.push_back(
416 this->thisFormDeque.back().Swap(*theCurrent);
417 }
while (theEnd != ++theCurrent);
419 Expression().Swap(theExpression);
424 inline void Type_::TakeElements(Expression
const & theExpression) {
426 !theExpression.IsEmpty()
431 this->Take(theExpression);
433 FormDeque
const & theFormDeque = theExpression.thisFormDeque;
435 !theFormDeque.empty()
438 FormDeque::const_iterator
const theEnd = theFormDeque.end();
439 FormDeque::const_iterator theCurrent = theFormDeque.begin();
440 assert(theEnd != theCurrent);
442 theCurrent->GetOperator().IsEmpty()
444 theFormDeque.front().GiveElements(*
this);
447 this->thisFormDeque.insert(
448 this->thisFormDeque.end(),
456 inline void Type_::TakeElements(Producer & theProducer) {
458 typeid(theProducer) ==
typeid(Expression)
461 static_cast<Expression &
>(theProducer)
464 theProducer.GiveElements(*
this);
468 inline void Type_::TakeElements(Producer
const & theProducer) {
470 typeid(theProducer) ==
typeid(Expression
const)
473 static_cast<Expression
const &
>(theProducer)
476 theProducer.GiveElements(*
this);
480 template <
typename TheOperand>
481 inline void Type_::TakeOperand(TheOperand & theOperand) {
483 !theOperand.IsEmpty()
485 this->BackTakeOperand(theOperand);
488 template <
typename TheOperator>
489 inline void Type_::TakeOperator(TheOperator & theOperator) {
491 !theOperator.IsEmpty()
493 this->BackTakeOperator(theOperator);
496 template <
typename TheProducer>
497 inline void Type_::TakeQuotedProducer(TheProducer & theProducer) {
498 this->BackTakeQuotedProducer(theProducer);
501 template <
typename TheSeparator>
502 inline void Type_::TakeSeparator(TheSeparator &) {}
506 template <
typename TheFormIterator>
507 inline void Type_::GiveElements(
508 Consumer & theConsumer,
509 TheFormIterator theCurrent,
510 TheFormIterator
const theEnd
512 if (theEnd != theCurrent) {
516 theConsumer.TakeElement(
517 Separator::GetLineSeparator()
521 !theCurrent->IsEmpty()
523 theCurrent->GiveElements(theConsumer);
524 if (theEnd == ++theCurrent) {
535 this->thisFormDeque.empty()
537 this->thisFormDeque.push_back(
541 return this->thisFormDeque.back();
546 this->thisFormDeque.empty() ||
547 !this->thisFormDeque.front().GetOperator().IsEmpty()
549 this->thisFormDeque.push_front(
553 return this->thisFormDeque.front();
561 Om::Language::Expression::FormRange
565 inline Type_<Om::Language::Form>::FormRange(Expression & theExpression):
566 Om::Source::CollectionFrontSource<
569 >(theExpression.thisFormDeque) {}
571 inline Type_<Om::Language::Form const>::FormRange(Expression
const & theExpression):
572 Om::Source::CollectionFrontSource<
574 FormDeque::const_iterator
575 >(theExpression.thisFormDeque) {}
582 Om::Language::Expression::ElementRange
586 inline Type_::ElementRange(Expression
const & theExpression):
588 theExpression.thisFormDeque.begin()
591 theExpression.thisFormDeque.end()
593 thisFormElementRange() {
594 if (this->thisFormEnd != this->thisFormIterator) {
595 this->thisFormElementRange = boost::in_place(
596 boost::ref(*this->thisFormIterator)
598 assert(*this->thisFormElementRange);
602 inline bool Type_::operator !()
const {
603 return !this->thisFormElementRange;
607 assert(this->thisFormElementRange);
609 *this->thisFormElementRange ?
610 **this->thisFormElementRange :
611 Separator::GetLineSeparator()
615 inline bool Type_::Equals(ElementRange
const & theElementRange)
const {
617 this->thisFormElementRange == theElementRange.thisFormElementRange &&
618 this->thisFormIterator == theElementRange.thisFormIterator
622 inline void Type_::End() {
623 this->thisFormElementRange = boost::none;
626 inline void Type_::Pop() {
627 assert(this->thisFormElementRange);
628 assert(this->thisFormEnd != this->thisFormIterator);
629 if (*this->thisFormElementRange) {
630 this->thisFormElementRange->Pop();
631 if (!*this->thisFormElementRange) {
632 if (this->thisFormEnd == ++this->thisFormIterator) {
637 this->thisFormElementRange = boost::in_place(
638 boost::ref(*this->thisFormIterator)
640 assert(*this->thisFormElementRange);
647 Type_
const & theFirst,
648 Type_
const & theSecond
650 return theFirst.Equals(theSecond);
654 Type_
const & theFirst,
655 Type_
const & theSecond
657 return !theFirst.Equals(theSecond);
669 theFirst.
Swap(theSecond);
A Program that contains a single elemental item (or none, when IsEmpty() returns true).
The Expression Program implementation.
A CodePoint Sink that pushes each code unit to the iterator.
A CodePoint Source that reads each code unit from the iterator.
Any object that items can be pulled from.
#define Om_Language_Expression_GetName_()
bool operator!=(DefaultAtom< TheImplementation > const &, DefaultAtom< TheImplementation > const &)
bool operator==(DefaultAtom< TheImplementation > const &, DefaultAtom< TheImplementation > const &)
void swap(Om::Language::Expression &, Om::Language::Expression &)