ExpressionStem.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 /******************************************************************************/
39 /* REXX Translator ExpressionStem.cpp */
40 /* */
41 /* Primitive Translator Expression Parsing Stem Reference Class */
42 /* */
43 /******************************************************************************/
44 /******************************************************************************/
45 
46 #include <stdlib.h>
47 #include "RexxCore.h"
48 #include "StringClass.hpp"
49 #include "RexxActivation.hpp"
50 #include "RexxVariable.hpp"
52 #include "StemClass.hpp"
53 #include "ExpressionStem.hpp"
54 
56  RexxString * stemName, /* stem name to access */
57  size_t var_index) /* lookaside index for stem */
58 /******************************************************************************/
59 /* Function: Initialize a translator STEM object */
60 /******************************************************************************/
61 {
62  /* set the name */
63  OrefSet(this, this->stem, stemName); /* set the name */
64  this->index = var_index; /* and the index */
65 }
66 
67 void RexxStemVariable::live(size_t liveMark)
68 /******************************************************************************/
69 /* Function: Normal garbage collection live marking */
70 /******************************************************************************/
71 {
72  memory_mark(this->stem);
73 }
74 
76 /******************************************************************************/
77 /* Function: Generalized object marking */
78 /******************************************************************************/
79 {
81 }
82 
84 /******************************************************************************/
85 /* Function: Flatten an object */
86 /******************************************************************************/
87 {
89 
90  flatten_reference(newThis->stem, envelope);
91 
93 }
94 
96  RexxActivation *context, /* current activation context */
97  RexxExpressionStack *stack ) /* evaluation stack */
98 /******************************************************************************/
99 /* Function: Evaluate a REXX stem variable */
100 /******************************************************************************/
101 {
102  /* look up the name */
103  RexxObject *value = context->getLocalStem(this->stem, this->index);
104  /* NOTE: stem accesses do NOT */
105  /* report NOVALUE so that DO OVER, */
106  /* call-by-reference with a stem and */
107  /* return with a stem does not */
108  /* trigger a novalue trap */
109  /* unexpectedly */
110  stack->push(value); /* place on the evaluation stack */
111  /* trace if necessary */
112  context->traceVariable(stem, value);
113  return value; /* return the located variable */
114 }
115 
117  RexxVariableDictionary *dictionary) /* current activation dictionary */
118 /******************************************************************************/
119 /* Function: retrieve a stem variable's value (notready condition will */
120 /* not be raised) */
121 /******************************************************************************/
122 {
123  /* look up the name */
124  return dictionary->getStem(this->stem);
125 }
126 
128  RexxActivation *context) /* current activation context */
129 /******************************************************************************/
130 /* Function: retrieve a stem variable's value (notready condition will */
131 /* not be raised) */
132 /******************************************************************************/
133 {
134  /* look up the name */
135  return context->getLocalStem(stem, index);
136 }
137 
138 /**
139  * Retrieve the real value of a stem variable. Stem variables
140  * will always be created on first reference, so there is no
141  * difference between getValue() and getRealValue().
142  *
143  * @param dictionary The source variable dictionary.
144  *
145  * @return The stem object representing this variable.
146  */
148 {
149  return dictionary->getStem(this->stem);
150 }
151 
152 /**
153  * Retrieve the real value of a stem variable. Stem variables
154  * will always be created on first reference, so there is no
155  * difference between getValue() and getRealValue().
156  *
157  * @param context The current execution context.
158  *
159  * @return The stem object representing this variable.
160  */
162 {
163  return context->getLocalStem(stem, index);
164 }
165 
167  RexxActivation *context, /* current activation context */
168  RexxObject *value ) /* new value to be assigned */
169 /******************************************************************************/
170 /* Function: Fast set of a stem variable value */
171 /******************************************************************************/
172 {
173  /* look up the name */
174  RexxVariable *variable = context->getLocalStemVariable(stem, index);
175  if (isOfClass(Stem, value))
176  { /* stem to stem assignment */
177  variable->set(value); /* overlay the reference stem object */
178  }
179  else
180  {
181  /* create a new stem object as value */
182  RexxStem *stem_table = new RexxStem (this->stem);
183  variable->set(stem_table); /* overlay the reference stem object */
184  stem_table->setValue(value); /* set the default value */
185  }
186 }
187 
188 
190  RexxVariableDictionary *dictionary, /* current activation dictionary */
191  RexxObject *value ) /* new value to be assigned */
192 /******************************************************************************/
193 /* Function: Fast set of a stem variable value */
194 /******************************************************************************/
195 {
196  /* look up the name */
197  RexxVariable *variable = dictionary->getStemVariable(this->stem);
198  if (isOfClass(Stem, value))
199  { /* stem to stem assignment */
200  variable->set(value); /* overlay the reference stem object */
201  }
202  else
203  {
204  /* create a new stem object as value */
205  RexxStem *stem_table = new RexxStem (this->stem);
206  variable->set(stem_table); /* overlay the reference stem object */
207  stem_table->setValue(value); /* set the default value */
208  }
209 }
210 
211 
213  RexxActivation *context) /* current activation context */
214 /******************************************************************************/
215 /* Function: Check the existance of a REXX stem variable */
216 /******************************************************************************/
217 {
218  /* retrieve the variable value */
219  return context->localStemVariableExists(stem, index);
220 }
221 
223  RexxActivation *context, /* current activation context */
224  RexxExpressionStack *stack, /* current evaluation stack */
225  RexxObject *value ) /* new value to assign */
226 /******************************************************************************/
227 /* Function: Assign a value to a stem variable */
228 /******************************************************************************/
229 {
230  RexxVariable *variable = context->getLocalStemVariable(stem, index);
231  if (isOfClass(Stem, value))
232  { /* stem to stem assignment */
233  variable->set(value); /* overlay the reference stem object */
234  }
235  else
236  {
237  /* create a new stem object as value */
238  RexxStem *stem_table = new RexxStem (this->stem);
239  variable->set(stem_table); /* overlay the reference stem object */
240  stem_table->setValue(value); /* set the default value */
241  }
242  // trace the assignment
243  context->traceAssignment(stem, value);
244 }
245 
247  RexxActivation *context) /* target variable dictionary */
248 /******************************************************************************/
249 /* Function: Drop a variable object */
250 /******************************************************************************/
251 {
252  /* drop the stem value */
253  context->dropLocalStem(stem, index);
254  // jlf: I want a trace
255  context->traceAssignment(stem, OREF_TRACE_is_dropped, false);
256 }
257 
258 /**
259  * Drop a variable that's directly in a variable dictionary.
260  *
261  * @param dictionary The target dictionary
262  */
264 {
265  // dropping the stem name is sufficient
266  dictionary->dropStemVariable(stem);
267 }
268 
270  RexxActivation *context, /* current activation context */
271  RexxActivation *parent, /* the parent activation context */
272  RexxExpressionStack *stack) /* current evaluation stack */
273 /******************************************************************************/
274 /* Function: Expose a stem variable */
275 /******************************************************************************/
276 {
277  /* get the old variable entry */
278  RexxVariable *old_variable = parent->getLocalStemVariable(stem, index);
279 
280  /* set the entry in the new table */
281  if (index == 0)
282  {
283  context->updateLocalVariable(old_variable);
284  }
285  else
286  {
287  context->putLocalVariable(old_variable, index);
288  }
289 }
290 
291 
293  RexxActivation *context, /* current activation context */
294  RexxExpressionStack *stack, /* current evaluation stack */
295  /* variable scope we're exposing from*/
296  RexxVariableDictionary *object_dictionary)
297 /******************************************************************************/
298 /* Function: Expose a stem variable */
299 /******************************************************************************/
300 {
301  /* get the old variable entry */
302  RexxVariable *old_stem = object_dictionary->getStemVariable(stem);
303  /* set the entry in the new table */
304  context->putLocalVariable(old_stem, index);
305 }
306 
307 
309  RexxActivation *context ) /* current activation context */
310 /******************************************************************************/
311 /* Set a guard variable notification on a stem variable */
312 /******************************************************************************/
313 {
314  /* look up the name */
315  RexxVariable *variable = context->getLocalStemVariable(this->stem, this->index);
316  variable->inform(ActivityManager::currentActivity); /* mark the variable entry */
317 }
318 
320  RexxActivation *context ) /* current activation context */
321 /******************************************************************************/
322 /* Remove a guard variable notification on an object variable */
323 /******************************************************************************/
324 {
325  /* look up the name */
326  RexxVariable *variable = context->getLocalStemVariable(this->stem, this->index);
327  variable->uninform(ActivityManager::currentActivity); /* mark the variable entry */
328 }
329 
330 
332  RexxActivation *context, RexxString *prefix, int order, int type, size_t start,
333  size_t end, size_t firstcol, size_t lastcol)
334 /******************************************************************************/
335 /* Sort the elements of a stem variable as if they were an array. */
336 /******************************************************************************/
337 {
338  /* get the stem object */
339  RexxStem *stem_table = context->getLocalStem(stem, index);
340  /* the stem object handles the sorting. */
341  return stem_table->sort(prefix, order, type, start, end, firstcol, lastcol);
342 }
343 
344 void *RexxStemVariable::operator new(size_t size)
345 /******************************************************************************/
346 /* Function: Create a new translator object */
347 /******************************************************************************/
348 {
349  /* Get new object */
350  return new_object(size, T_StemVariableTerm);
351 }
352 
354  RexxActivation *context) /* current activation context */
355 /******************************************************************************/
356 /* Function: Translate to upper case the contents of a variable object */
357 /******************************************************************************/
358 {
359  RexxObject *value = this->getValue(context);
360  RexxString *string = REQUEST_STRING(value);
361  ProtectedObject p(string);
362  this->set(context, string->upper());
363 }
@ T_StemVariableTerm
RexxString * REQUEST_STRING(RexxObject *object)
Definition: RexxCore.h:295
#define OrefSet(o, r, v)
Definition: RexxCore.h:101
#define isOfClass(t, r)
Definition: RexxCore.h:224
#define memory_mark(oref)
Definition: RexxMemory.hpp:450
RexxObject * new_object(size_t s)
Definition: RexxMemory.hpp:436
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:498
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:451
#define cleanUpFlatten
Definition: RexxMemory.hpp:484
#define setUpFlatten(type)
Definition: RexxMemory.hpp:478
static RexxActivity *volatile currentActivity
void dropLocalStem(RexxString *name, size_t index)
void updateLocalVariable(RexxVariable *variable)
void putLocalVariable(RexxVariable *variable, size_t index)
bool localStemVariableExists(RexxString *stemName, size_t index)
RexxStem * getLocalStem(RexxString *name, size_t index)
void traceAssignment(RexxString *n, RexxObject *v, bool quoteValue=true)
void traceVariable(RexxString *n, RexxObject *v)
RexxVariable * getLocalStemVariable(RexxString *name, size_t index)
void push(RexxObject *value)
bool sort(RexxString *prefix, int order, int type, size_t start, size_t end, size_t firstcol, size_t lastcol)
Definition: StemClass.cpp:1457
void setValue(RexxObject *value)
Definition: StemClass.cpp:153
void assign(RexxActivation *, RexxExpressionStack *, RexxObject *)
void setGuard(RexxActivation *)
void flatten(RexxEnvelope *)
void set(RexxActivation *, RexxObject *)
void drop(RexxActivation *)
RexxObject * getRealValue(RexxVariableDictionary *)
void upper(RexxActivation *)
RexxObject * getValue(RexxVariableDictionary *)
void procedureExpose(RexxActivation *, RexxActivation *, RexxExpressionStack *)
RexxString * stem
bool exists(RexxActivation *)
RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
RexxStemVariable(RESTORETYPE restoreType)
void clearGuard(RexxActivation *)
void expose(RexxActivation *, RexxExpressionStack *, RexxVariableDictionary *)
void live(size_t)
void liveGeneral(int reason)
bool sort(RexxActivation *context, RexxString *prefix, int order, int type, size_t start, size_t end, size_t firstcol, size_t lastcol)
RexxString * upper()
RexxStem * getStem(RexxString *stemName)
void dropStemVariable(RexxString *)
RexxVariable * getStemVariable(RexxString *stemName)
void uninform(RexxActivity *)
void set(RexxObject *value)
void inform(RexxActivity *)
int type
Definition: cmdparse.cpp:1888