15 #ifndef Om_Language_Literal_
23 #ifndef Om_Macro_Precompilation_
25 #include "boost/test/unit_test.hpp"
33 BOOST_AUTO_TEST_SUITE(LiteralTest)
35 BOOST_AUTO_TEST_CASE(EqualityTest) {
39 System::Get().Evaluate(
"= {a{b}{c}\nd{e}} {a{b}{c}\nd{e}}")
61 BOOST_AUTO_TEST_CASE(RecursionTest) {
62 size_t const theDepth = 50000;
64 std::string theString;
66 size_t theLevel = theDepth;
70 theString =
"{" + theString +
"}";
77 Reader theReader(theCodePointSource);
79 theLiteral.ParseElements(theReader);
90 BOOST_AUTO_TEST_SUITE_END()
103 #ifndef Om_Macro_Precompilation_
112 Om::Language::Literal
116 inline char const * Type_::GetName() {
122 inline Type_::~Literal() {
126 !this->thisElementDeque.empty()
128 std::auto_ptr<Element> theElement(
129 this->thisElementDeque.pop_front().release()
134 (*theElement)->GiveElements(*
this);
139 inline Type_::Literal():
140 thisElementDeque() {}
142 inline Type_ & Type_::operator =(Literal theLiteral) {
143 this->Swap(theLiteral);
147 template <
typename TheElement>
148 inline void Type_::BackGive(Consumer & theConsumer) {
150 !this->thisElementDeque.empty() &&
151 dynamic_cast<TheElement
const *
>(
152 &this->thisElementDeque.back()
155 this->thisElementDeque.pop_back()->GiveElements(theConsumer);
159 inline void Type_::BackGiveElement(Consumer & theConsumer) {
161 !this->thisElementDeque.empty()
163 this->thisElementDeque.pop_back()->GiveElements(theConsumer);
167 inline void Type_::Clear() {
168 this->thisElementDeque.clear();
171 template <
typename TheElement>
172 inline void Type_::FrontGive(Consumer & theConsumer) {
174 !this->thisElementDeque.empty() &&
175 dynamic_cast<TheElement
const *
>(
176 &this->thisElementDeque.front()
179 this->thisElementDeque.pop_front()->GiveElements(theConsumer);
183 inline void Type_::FrontGiveElement(Consumer & theConsumer) {
185 !this->thisElementDeque.empty()
187 this->thisElementDeque.pop_front()->GiveElements(theConsumer);
191 inline std::auto_ptr<
193 > Type_::GetElementRange() {
194 return std::auto_ptr<
197 new ElementRange<Literal>(*
this)
201 inline std::auto_ptr<
203 > Type_::GetElementRange()
const {
204 return std::auto_ptr<
207 new ElementRange<Literal const>(*
this)
211 inline void Type_::GiveElements(Consumer & theConsumer) {
214 this->thisElementDeque.begin(),
215 this->thisElementDeque.end()
217 this->thisElementDeque.clear();
220 inline void Type_::GiveElements(Consumer & theConsumer)
const {
223 this->thisElementDeque.begin(),
224 this->thisElementDeque.end()
228 inline bool Type_::IsEmpty()
const {
229 return this->thisElementDeque.empty();
232 inline void Type_::ParseElements(Reader & theReader) {
233 std::stack<Literal *> theStack;
237 switch (*theReader) {
241 this != theStack.top()
247 std::auto_ptr<Literal> theLiteral(
new Literal);
248 Literal * theLiteralPointer = theLiteral.get();
250 Operand theOperand(theLiteral);
251 theStack.top()->TakeOperand(theOperand);
253 theStack.push(theLiteralPointer);
262 Separator theSeparator(theReader);
263 theStack.top()->TakeSeparator(theSeparator);
272 Operator theOperator(theReader);
273 theStack.top()->TakeOperator(theOperator);
281 inline void Type_::ParseQuotedElements(Reader & theReader) {
283 theLiteral.ParseElements(theReader);
284 this->TakeQuotedProducer(theLiteral);
287 inline void Type_::Swap(Literal & theLiteral) {
288 this->thisElementDeque.swap(theLiteral.thisElementDeque);
291 template <
typename TheOperand>
292 inline void Type_::TakeOperand(TheOperand & theOperand) {
294 !theOperand.IsEmpty()
296 this->thisElementDeque.push_back(
301 template <
typename TheOperator>
302 inline void Type_::TakeOperator(TheOperator & theOperator) {
304 !theOperator.IsEmpty()
306 this->TakeAtom(theOperator);
309 template <
typename TheProducer>
310 inline void Type_::TakeQuotedProducer(TheProducer & theProducer) {
311 this->thisElementDeque.push_back(
313 theProducer.GiveProgram()
318 template <
typename TheSeparator>
319 inline void Type_::TakeSeparator(TheSeparator & theSeparator) {
321 !theSeparator.IsEmpty()
323 this->TakeAtom(theSeparator);
328 template <
typename TheElementIterator>
329 inline void Type_::GiveElements(
330 Consumer & theConsumer,
331 TheElementIterator theCurrent,
332 TheElementIterator
const theEnd
336 theEnd != theCurrent;
339 theCurrent->GiveElements(theConsumer);
345 template <
typename TheAtom>
346 inline void Type_::TakeAtom(TheAtom & theAtom) {
351 this->thisElementDeque.empty() ||
352 !this->thisElementDeque.back().Merge(theAtom)
354 this->thisElementDeque.push_back(
365 Om::Language::Literal::ElementRange
369 inline Type_<Om::Language::Literal>::ElementRange(Literal & theLiteral):
370 Om::Source::CollectionFrontSource<
372 ElementDeque::iterator
373 >(theLiteral.thisElementDeque) {}
375 inline Type_<Om::Language::Literal const>::ElementRange(Literal
const & theLiteral):
376 Om::Source::CollectionFrontSource<
378 ElementDeque::const_iterator
379 >(theLiteral.thisElementDeque) {}
390 theFirst.
Swap(theSecond);
The Literal Program implementation.
A CodePoint Source that reads each code unit from the iterator.
Any object that items can be pulled from.
#define Om_Language_Literal_GetName_()
std::auto_ptr< TheGiveable > Give(TheGiveable &)
Calls Move on the object.
void swap(Om::Language::Expression &, Om::Language::Expression &)
#define Om_Language_Symbol_SeparatorSymbol_GetCases_()
Generates switch cases for each Om::Language::Symbol::SeparatorSymbol.