Om
define_operation.cpp
Go to the documentation of this file.
1 
15 #ifndef Om_Language_Operation_DefineOperation_
16 
18 
19  #ifdef Om_Macro_Test_
20 
21  #ifndef Om_Macro_Precompilation_
22 
23  #include "boost/test/unit_test.hpp"
24 
25  #endif
26 
27 namespace Om {
28 
29  namespace Language {
30 
31  namespace Operation {
32 
33  BOOST_AUTO_TEST_SUITE(DefineOperationTest)
34 
35  BOOST_AUTO_TEST_CASE(DefinitionTest) {
36  BOOST_CHECK_EQUAL(
37  "{define}",
38  System::Get().Evaluate("drop find {define} system")
39  );
40  }
41 
42  BOOST_AUTO_TEST_CASE(BasicSubstitutionTest) {
43  BOOST_CHECK_EQUAL(
44  "B",
45  System::Get().Evaluate("define {A {B}} {A}")
46  );
47  }
48 
49  BOOST_AUTO_TEST_CASE(IdentityDefinitionTest) {
50  BOOST_CHECK_EQUAL(
51  "",
52  System::Get().Evaluate("define {A {}} {A}")
53  );
54  }
55 
56  BOOST_AUTO_TEST_CASE(EmptyDefinitionTest) {
57  BOOST_CHECK_EQUAL(
58  "A",
59  System::Get().Evaluate("define {A} {A}")
60  );
61  }
62 
63  BOOST_AUTO_TEST_CASE(EmptyLexiconTest) {
64  BOOST_CHECK_EQUAL(
65  "",
66  System::Get().Evaluate("define {} {}")
67  );
68  }
69 
70  BOOST_AUTO_TEST_CASE(EmptyKeyFallThroughTest) {
71  BOOST_CHECK_EQUAL(
72  "{A}",
73  System::Get().Evaluate("define {{{A}}} {B}")
74  );
75  }
76 
77  // Confirms that the last definition wins.
78  BOOST_AUTO_TEST_CASE(MultipleDefinitionTest) {
79  BOOST_CHECK_EQUAL(
80  "{C}",
81  System::Get().Evaluate("define { A {{B}} A {{C}} } {A}")
82  );
83  }
84 
85  // Confirms that the last definition wins.
86  BOOST_AUTO_TEST_CASE(MultipleEmptyKeyTest) {
87  BOOST_CHECK_EQUAL(
88  "{C}",
89  System::Get().Evaluate("define { {{B}} {{C}} } {A}")
90  );
91  }
92 
93  // Confirms that underlying non-constant definitions are used.
94  BOOST_AUTO_TEST_CASE(ChainedLookupTest) {
95  BOOST_CHECK_EQUAL(
96  (
97  "B\n"
98  "B"
99  ),
100  System::Get().Evaluate("define {A {B}} {dequote {A} A}")
101  );
102 
103  BOOST_CHECK_EQUAL(
104  "{1}",
105  System::Get().Evaluate(
106  "define{\n"
107  "a` b\n"
108  "{{1}}\n"
109  "}{do{a b}}\n"
110  )
111  );
112  BOOST_CHECK_EQUAL(
113  "1",
114  System::Get().Evaluate("define fill {a` b} {1} {do{a b}}")
115  );
116  BOOST_CHECK_EQUAL(
117  "{1}",
118  System::Get().Evaluate("define {a` b{{1}}} {do{a b}}")
119  );
120  BOOST_CHECK_EQUAL(
121  "{2}{1}",
122  System::Get().Evaluate(
123  "define"
124  "{"
125  "the` flaven{{1}}"
126  "the` glaven{{2}}"
127  "}"
128  "{do{the` glaven} do{the` flaven}}"
129  )
130  );
131  }
132 
133  // Confirms evaluation order in nested scopes.
134  BOOST_AUTO_TEST_CASE(NestedEvaluationOrderTest) {
135  BOOST_CHECK_EQUAL(
136  "{a-default}",
137  System::Get().Evaluate(
138  "define { b {B} {{b-default}} }{"
139  "define { a {A} {{a-default}} } { b }"
140  "}"
141  )
142  );
143  BOOST_CHECK_EQUAL(
144  "{b-default}",
145  System::Get().Evaluate(
146  "define { b {B} {{b-default}} }{"
147  "define { a {A} } { b }"
148  "}"
149  )
150  );
151  }
152 
153  BOOST_AUTO_TEST_CASE(SimpleNestedTest) {
154  BOOST_CHECK_EQUAL(
155  "c",
156  System::Get().Evaluate("define{a{define{b{c}}{b}}}{a}")
157  );
158  }
159 
160  BOOST_AUTO_TEST_CASE(DeletedOperatorTest) {
161  BOOST_CHECK_EQUAL(
162  "A",
163  System::Get().Evaluate("define {define} {define {a{A}} {a}}")
164  );
165  }
166 
167  BOOST_AUTO_TEST_CASE(EvaluationTest) {
168  BOOST_CHECK_EQUAL(
169  "{1}{3}{2}",
170  System::Get().Evaluate("define {a{{1}c{2}} c{{3}}} {a}")
171  );
172  }
173 
174  BOOST_AUTO_TEST_SUITE_END()
175 
176  }
177 
178  }
179 
180 }
181 
182  #endif
183 
184 #else
185 
186  #include "om/language/environment.hpp"
187 
188  #ifndef Om_Macro_Precompilation_
189 
190  #include "boost/utility/in_place_factory.hpp"
191 
192  #endif
193 
194 // MARK: - Om::Language::Operation::DefineOperation
195 
196  #define Type_ \
197  Om::Language::Operation::DefineOperation
198 
199 // MARK: public (static)
200 
201 inline char const * Type_::GetName() {
203 }
204 
205 template <typename TheDefineOperation>
206 inline void Type_::GiveElements(
207  TheDefineOperation & theDefineOperation,
208  Consumer & theConsumer
209 ) {
210  theConsumer.TakeElement(
211  GetOperator()
212  );
213  if (theDefineOperation.thisLexicon) {
214  theConsumer.TakeQuotedElements(*theDefineOperation.thisLexicon);
215  }
216 }
217 
218 // MARK: public (non-static)
219 
220 inline Type_::DefineOperation():
221 thisLexicon() {}
222 
223 template <typename TheOperand>
224 inline bool Type_::TakeOperand(
225  Evaluation & theEvaluation,
226  TheOperand & theOperand
227 ) {
228  assert(
229  !theOperand.IsEmpty()
230  );
231  return this->TakeQuotedProducer(
232  theEvaluation,
233  *theOperand.GetProgram()
234  );
235 }
236 
237 template <typename TheProducer>
238 inline bool Type_::TakeQuotedProducer(
239  Evaluation & theEvaluation,
240  TheProducer & theProducer
241 ) {
242  if (this->thisLexicon) {
243  Expression theExpression;
244  {
245  Environment theEnvironment;
246  theEnvironment.Push(
247  System::Get()
248  );
249  theEnvironment.Push(
250  theEvaluation.GetTranslator()
251  );
252  theEnvironment.Push(*this->thisLexicon);
253  Evaluator theScope(
254  theExpression,
255  theEnvironment
256  );
257  theProducer.GiveElements(theScope);
258  }
259  theEvaluation.TakeProducer(theExpression);
260  return true;
261  }
262  this->thisLexicon = boost::in_place();
263  assert(this->thisLexicon);
264  this->thisLexicon->TakeElements(theProducer);
265  return false;
266 }
267 
268  #undef Type_
269 
270 #endif
static System & Get()
Om header file.
#define Om_Language_Operation_DefineOperation_GetName_()
Om header file.
The Om library.
Definition: code_point.hpp:26