15 #ifndef Om_Language_Lexicon_
21 #ifndef Om_Macro_Precompilation_
23 #include "boost/test/unit_test.hpp"
31 BOOST_AUTO_TEST_SUITE(LexiconTest)
33 BOOST_AUTO_TEST_CASE(BasicTest) {
51 BOOST_AUTO_TEST_CASE(CopyTest) {
60 System::Get().Evaluate(
"->[lexicon]{b} copy lexicon{a}")
76 System::Get().Evaluate(
"->[lexicon]{b}copy lexicon{a}")
84 System::Get().Evaluate(
"[lexicon]<-{b}copy lexicon{a}")
96 "[lexicon]<- {{C}} [lexicon]<- {c} "
97 "copy lexicon {a {A} b {B}}"
102 BOOST_AUTO_TEST_CASE(EqualityTest) {
110 "= lexicon{a{b}c{d}} {"
148 BOOST_AUTO_TEST_CASE(ReadTest) {
149 char const theCode[] =
"0\n\t {1\n\t {2\n\t } 3\n\t } 4\n\t";
150 std::string theResult;
153 std::back_insert_iterator<std::string>
155 std::back_inserter(theResult)
157 Writer theWriter(theCodePointSink);
160 Reader theReader(theCodePointSource);
162 theLexicon.ParseElements(theReader);
163 theLexicon.GiveElements(theWriter);
167 "0{1\n\t {2\n\t } 3\n\t }\n"
174 BOOST_AUTO_TEST_CASE(NormalizationTest) {
183 System::Get().Evaluate(
"lexicon{A{1} B{2} A{3} C A{4} D E{5}}")
201 System::Get().Evaluate(
"lexicon{ A{1}{2} B C{3}{4} }")
209 System::Get().Evaluate(
"->[lexicon]{ A{1}{2} }{ A{3} }")
217 System::Get().Evaluate(
"[lexicon]<-{ A{1} }{ A{2}{3} }")
221 BOOST_AUTO_TEST_CASE(TakeQuotedProducerTest) {
227 static void Check(Lexicon
const & theLexicon) {
230 Give(theLineSeparator)
233 Lexicon::ElementRange theElementRange(theLexicon);
234 Lexicon::ElementRange theOtherElementRange(theLexicon);
235 BOOST_CHECK(theElementRange);
236 BOOST_CHECK(theElementRange == theOtherElementRange);
237 Element
const & theElement = *theElementRange;
238 BOOST_CHECK(theOperand == theElement);
239 theElementRange.Pop();
240 theOtherElementRange.Pop();
241 BOOST_CHECK(!theElementRange);
242 BOOST_CHECK(theElementRange == theOtherElementRange);
249 theLexicon.TakeQuotedProducer(theLineSeparator);
251 Lexicon theCopiedLexicon;
252 theCopiedLexicon = theLexicon;
253 BOOST_CHECK(theLexicon == theCopiedLexicon);
255 Local::Check(theLexicon);
256 Local::Check(theCopiedLexicon);
259 BOOST_AUTO_TEST_SUITE_END()
276 Om::Language::Lexicon
280 inline char const * Type_::GetName() {
286 inline Type_::Lexicon():
290 inline Type_::Lexicon(Lexicon
const & theLexicon):
291 DefaultProgram<Lexicon>(theLexicon),
295 PairList::Node
const * theNode = theLexicon.thisPairList.GetNode(PairList::theFrontNodeIndex);
297 theNode = theNode->GetNode(PairList::theBackNodeIndex)
299 std::auto_ptr<PairList::Node> theNewNode(
300 new PairList::Node(*theNode)
306 this->thisPairList.LinkNode(
307 PairList::theBackNodeIndex,
311 this->thisMap.insert(
312 theNode->GetValue().GetOperator().GetString(),
318 inline Type_ & Type_::operator =(Lexicon theLexicon) {
319 this->Swap(theLexicon);
323 inline void Type_::BackGivePair(Consumer & theConsumer) {
325 PairList::theBackNodeIndex,
330 inline void Type_::Clear() {
331 this->thisPairList.Clear();
332 this->thisMap.clear();
336 typedef Map::const_iterator Iterator;
337 Iterator theIterator(
339 theOperator.GetString()
343 this->thisMap.end() == theIterator
345 return Pair::GetEmpty();
347 return theIterator->second->GetValue();
350 inline void Type_::FrontGivePair(Consumer & theConsumer) {
352 PairList::theFrontNodeIndex,
357 inline std::auto_ptr<
359 > Type_::GetElementRange()
const {
360 return std::auto_ptr<
363 new ElementRange(*
this)
367 inline void Type_::GiveElements(Consumer & theConsumer) {
369 this->thisPairList.GetNode(PairList::theFrontNodeIndex),
375 inline void Type_::GiveElements(Consumer & theConsumer)
const {
377 this->thisPairList.GetNode(PairList::theFrontNodeIndex),
382 inline bool Type_::IsEmpty()
const {
384 !this->thisMap.empty() ||
385 this->thisPairList.IsEmpty()
387 return this->thisMap.empty();
390 inline void Type_::ParseElements(Reader & theReader) {
397 inline void Type_::ParseQuotedElements(Reader & theReader) {
399 theLiteral.ParseElements(theReader);
400 this->TakeQuotedProducer(theLiteral);
403 inline void Type_::Swap(Lexicon & theLexicon) {
404 this->thisMap.swap(theLexicon.thisMap);
405 this->thisPairList.Swap(theLexicon.thisPairList);
408 template <
typename TheOperand>
409 inline void Type_::TakeOperand(TheOperand & theOperand) {
411 !theOperand.IsEmpty()
413 this->GetOperandTaker().GetValue().TakeOperand(theOperand);
416 template <
typename TheOperator>
417 inline void Type_::TakeOperator(TheOperator & theOperator) {
419 !theOperator.IsEmpty()
421 this->GetOperandTaker(theOperator);
424 template <
typename TheProducer>
425 inline void Type_::TakeQuotedProducer(TheProducer & theProducer) {
426 this->GetOperandTaker().GetValue().TakeQuotedProducer(theProducer);
429 template <
typename TheSeparator>
430 inline void Type_::TakeSeparator(TheSeparator &) {}
432 inline bool Type_::Translate(
433 Evaluation & theEvaluation,
434 Operator
const & theOperator
436 Pair
const & thePair = this->Find(theOperator);
443 Operand
const & theOperand = thePair.GetOperand();
448 thePair.GetOperator() == theOperator
450 return System::Get().Translate(
456 theEvaluation.TakeProducer(
457 *theOperand.GetProgram()
464 template <
typename TheNode>
465 inline void Type_::GiveElements(
467 Consumer & theConsumer
473 theConsumer.TakeElement(
474 Separator::GetLineSeparator()
479 !theNode->GetValue().IsEmpty()
481 theNode->GetValue().GiveElements(theConsumer);
482 theNode = theNode->GetNode(PairList::theBackNodeIndex);
492 inline Type_::PairList::Node & Type_::GetOperandTaker() {
493 PairList::Node *
const theNode = this->thisPairList.GetNode(PairList::theBackNodeIndex);
496 !theNode->GetValue().GetOperand().IsEmpty()
498 Operator
const theOperator;
499 return this->GetOperandTaker(theOperator);
504 template <
typename TheOperator>
505 inline Type_::PairList::Node & Type_::GetOperandTaker(TheOperator & theOperator) {
506 std::string
const & theString = theOperator.GetString();
507 typename Map::iterator
const theIterator = this->thisMap.find(theString);
509 this->thisMap.end() == theIterator
511 PairList::Node * theNode;
513 std::auto_ptr<PairList::Node> theNewNode(
new PairList::Node);
514 theNode = theNewNode.get();
515 this->thisMap.insert(
522 theNode->GetValue().TakeOperator(theOperator);
524 theNode->GetValue().GetOperand().IsEmpty()
527 this->thisPairList.LinkNode(
528 PairList::theBackNodeIndex,
535 PairList::Node & theNode = *theIterator->second;
537 theNode.GetValue().ClearOperand();
539 this->thisPairList.RelinkNode(
540 PairList::theBackNodeIndex,
548 inline void Type_::GivePair(
549 PairList::NodeIndex
const theNodeIndex,
550 Consumer & theConsumer
553 PairList::Node
const *
const theNode = this->thisPairList.UnlinkNode(theNodeIndex)
555 Map::iterator
const theIterator = this->thisMap.find(
556 theNode->GetValue().GetOperator().GetString()
559 this->thisMap.end() != theIterator
562 Map::auto_type theOldNode = this->thisMap.release(theIterator);
564 theOldNode->GetValue().GiveElements(theConsumer);
575 theFirst.Swap(theSecond);
583 Om::Language::Lexicon::ElementRange
587 inline Type_::ElementRange():
591 inline Type_::ElementRange(Lexicon
const & theLexicon):
593 theLexicon.thisPairList.GetNode(PairList::theFrontNodeIndex)
597 thisNode->GetValue().GetOperator().IsEmpty()
600 inline bool Type_::operator !()
const {
601 return !this->thisNode;
605 assert(this->thisNode);
606 switch (this->thisOffset) {
609 !this->thisNode->GetValue().GetOperator().IsEmpty()
611 return this->thisNode->GetValue().GetOperator();
614 !this->thisNode->GetValue().GetOperand().IsEmpty()
616 return this->thisNode->GetValue().GetOperand();
618 return Separator::GetLineSeparator();
622 inline bool Type_::Equals(ElementRange
const & theElementRange)
const {
624 this->thisNode == theElementRange.thisNode &&
625 this->thisOffset == theElementRange.thisOffset
629 inline void Type_::Pop() {
632 !this->thisNode->GetValue().IsEmpty()
634 switch (this->thisOffset) {
637 !this->thisNode->GetValue().GetOperand().IsEmpty()
639 this->thisOffset = 1;
644 this->thisNode = this->thisNode->GetNode(PairList::theBackNodeIndex);
645 this->thisOffset = 2;
648 this->thisOffset = this->thisNode->GetValue().GetOperator().IsEmpty();
656 Type_
const & theFirst,
657 Type_
const & theSecond
659 return theFirst.Equals(theSecond);
663 Type_
const & theFirst,
664 Type_
const & theSecond
666 return !theFirst.Equals(theSecond);
A Program that contains a single elemental item (or none, when IsEmpty() returns true).
An Operator and an Operand.
static Separator const & GetLineSeparator()
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_Lexicon_GetName_()
bool operator!=(DefaultAtom< TheImplementation > const &, DefaultAtom< TheImplementation > const &)
bool operator==(DefaultAtom< TheImplementation > const &, DefaultAtom< TheImplementation > const &)
std::auto_ptr< TheGiveable > Give(TheGiveable &)
Calls Move on the object.
void swap(Om::Language::Expression &, Om::Language::Expression &)