ooRexx  4.2.0-source
About: ooRexx (Open Object Rexx) is a free implementation of Object Rexx. Object Rexx is an enhancement of the classic Rexx interpreter; a full-featured programming language with a human-oriented syntax.
  Fossies Dox: ooRexx-4.2.0-source.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

ExpressionMessage.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 */
40 /* */
41 /* Primitive Message Instruction Parse Class */
42 /* */
43 /******************************************************************************/
44 #include <stdlib.h>
45 #include "RexxCore.h"
46 #include "StringClass.hpp"
47 #include "QueueClass.hpp"
48 #include "RexxActivation.hpp"
49 #include "ExpressionMessage.hpp"
50 #include "Token.hpp"
51 #include "SourceFile.hpp"
52 #include "ProtectedObject.hpp"
53 
55  RexxObject *_target, /* message send target */
56  RexxString *name, /* message name */
57  RexxObject *_super, /* message super class */
58  size_t argCount, /* count of arguments */
59  RexxQueue *arglist, /* message argument list */
60  bool double_form) /* type of message send */
61 /******************************************************************************/
62 /* Function: Create a new message expression object */
63 /******************************************************************************/
64 {
65  /* also make sure name is cleared */
66  /* name doubles as hash so ClearObjec*/
67  this->messageName = OREF_NULL; /* doesn't clear hash field. */
68 
69  OrefSet(this, this->target, _target); /* fill in the target */
70  /* the message name */
71  OrefSet(this, this->messageName, name->upper());
72  OrefSet(this, this->super, _super); /* the super class target */
73  doubleTilde = double_form; // set the argument form
74  /* get the count of arguments */
75  this->argumentCount = argCount;
76  while (argCount > 0) /* now copy the argument pointers */
77  {
78  /* in reverse order */
79  OrefSet(this, this->arguments[--argCount], arglist->pop());
80  }
81 }
82 
84  RexxActivation *context, /* current activation context */
85  RexxExpressionStack *stack ) /* evaluation stack */
86 /******************************************************************************/
87 /* Function: Evaluate a message send in an expression */
88 /******************************************************************************/
89 {
90  ProtectedObject result; /* message expression result */
91  RexxObject *_super; /* target super class */
92  size_t argcount; /* count of arguments */
93  RexxObject *_target; /* message target */
94  size_t i; /* loop counter */
95 
96  /* evaluate the target */
97  _target = this->target->evaluate(context, stack);
98  if (this->super != OREF_NULL) /* have a message lookup override? */
99  {
100 
101  if (_target != context->getReceiver()) /* sender and receiver different? */
102  {
103  /* this is an error */
105  }
106  /* get the variable value */
107  _super = this->super->evaluate(context, stack);
108  stack->toss(); /* pop the top item */
109  }
110  else
111  {
112  _super = OREF_NULL; /* use the default lookup */
113  }
114 
115  argcount = this->argumentCount; /* get the argument count */
116  /* loop through the argument list */
117  for (i = 0; i < (size_t)argcount; i++)
118  {
119  /* real argument? */
120  if (this->arguments[i] != OREF_NULL)
121  {
122  /* evaluate the expression */
123  RexxObject *resultArg = this->arguments[i]->evaluate(context, stack);
124  /* trace if necessary */
125  context->traceIntermediate(resultArg, TRACE_PREFIX_ARGUMENT);
126  }
127  else
128  {
129  stack->push(OREF_NULL); /* push an non-existent argument */
130  /* trace if necessary */
131  context->traceIntermediate(OREF_NULLSTRING, TRACE_PREFIX_ARGUMENT);
132  }
133  }
134  if (_super == OREF_NULL) /* no super class override? */
135  {
136  /* issue the fast message */
137  stack->send(this->messageName, argcount, result);
138  }
139  else
140  {
141  /* evaluate the message w/override */
142  stack->send(this->messageName, _super, argcount, result);
143  }
144  stack->popn(argcount); /* remove any arguments */
145  if (this->doubleTilde) /* double twiddle form? */
146  {
147  result = _target; /* get the target element */
148  }
149  else
150  {
151  stack->prefixResult(result); /* replace top element on stack */
152  }
153 
154  if ((RexxObject *)result == OREF_NULL) /* in an expression and need a result*/
155  {
156  /* need to raise an exception */
158  }
159  /* trace if necessary */
160  context->traceMessage(messageName, (RexxObject *)result);
161  return(RexxObject *)result; /* return the result */
162 }
163 
164 void RexxExpressionMessage::live(size_t liveMark)
165 /******************************************************************************/
166 /* Function: Normal garbage collection live marking */
167 /******************************************************************************/
168 {
169  size_t i; /* loop counter */
170  size_t count; /* argument count */
171 
172  memory_mark(this->messageName);
173  memory_mark(this->target);
174  memory_mark(this->super);
175  for (i = 0, count = this->argumentCount; i < count; i++)
176  {
177  memory_mark(this->arguments[i]);
178  }
179 }
180 
182 /******************************************************************************/
183 /* Function: Generalized object marking */
184 /******************************************************************************/
185 {
186  size_t i; /* loop counter */
187  size_t count; /* argument count */
188 
191  memory_mark_general(this->super);
192  for (i = 0, count = this->argumentCount; i < count; i++)
193  {
194  memory_mark_general(this->arguments[i]);
195  }
196 }
197 
199 /******************************************************************************/
200 /* Function: Flatten an object */
201 /******************************************************************************/
202 {
203  size_t i; /* loop counter */
204  size_t count; /* argument count */
205 
207 
208  flatten_reference(newThis->messageName, envelope);
209  flatten_reference(newThis->target, envelope);
210  flatten_reference(newThis->super, envelope);
211  for (i = 0, count = this->argumentCount; i < count; i++)
212  {
213  flatten_reference(newThis->arguments[i], envelope);
214  }
215 
217 }
218 
219 void *RexxExpressionMessage::operator new(size_t size,
220  size_t argCount) /* count of arguments */
221 /******************************************************************************/
222 /* Function: Create a new translator object */
223 /******************************************************************************/
224 {
225  /* Get new object */
226  return new_object(size + (argCount - 1) * sizeof(RexxObject *), T_MessageSendTerm);
227 }
228 
230  RexxActivation *context, /* current activation context */
231  RexxExpressionStack *stack, /* current evaluation stack */
232  RexxObject *value ) /* new value to assign */
233 /******************************************************************************/
234 /* Function: Emulate a variable assignment using a method */
235 /******************************************************************************/
236 {
237  // evaluate the target
238  RexxObject *_target = this->target->evaluate(context, stack);
239  RexxObject *_super = OREF_NULL;
240  // message override?
241  if (this->super != OREF_NULL)
242  {
243  // in this context, the value needs to be SELF
244  if (_target != context->getReceiver())
245  {
247  }
248  // evaluate the superclass override
249  _super = this->super->evaluate(context, stack);
250  stack->toss();
251  }
252  // push the assignment value on to the stack as the argument
253  stack->push(value);
254  // now push the rest of the arguments. This might be something like a[1,2,3,4] as
255  // an assignment term. The assignment value is the first argument, followed by
256  // any other arguments that are part of the encoded message term.
257  size_t argcount = (size_t)this->argumentCount;
258 
259  for (size_t i = 0; i < argcount; i++)
260  {
261  // non-omitted argument?
262  if (this->arguments[i] != OREF_NULL)
263  {
264  // evaluate and potentiall trace
265  RexxObject *resultArg = this->arguments[i]->evaluate(context, stack);
266  context->traceResult(resultArg);
267  }
268  else
269  {
270  // non existant arg....we may still need to trace that
271  stack->push(OREF_NULL);
272  context->traceResult(OREF_NULLSTRING);
273  }
274  }
275 
276  ProtectedObject result;
277 
278  // now send the message the appropriate way
279  if (_super == OREF_NULL)
280  {
281  // normal message send
282  stack->send(this->messageName, argcount + 1, result);
283  }
284  else
285  {
286  // send with an override
287  stack->send(this->messageName, _super, argcount + 1, result);
288  }
289  /* trace if necessary */
290  context->traceAssignment(messageName, (RexxObject *)result);
291  // remove all arguments (arguments + target + assignment value)
292  stack->popn(argcount + 2);
293 }
294 
295 
296 
304 {
305  // add an equal sign to the name
306  messageName = source->commonString(messageName->concat(OREF_EQUAL));
307 }
308 
RexxActivation::traceAssignment
void traceAssignment(RexxString *n, RexxObject *v)
Definition: RexxActivation.hpp:386
RexxExpressionMessage::live
void live(size_t)
Definition: ExpressionMessage.cpp:164
RexxExpressionStack
Definition: ExpressionStack.hpp:53
RexxExpressionStack::prefixResult
void prefixResult(RexxObject *value)
Definition: ExpressionStack.hpp:86
RexxInternalObject::evaluate
virtual RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
Definition: ObjectClass.hpp:269
memory_mark_general
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:437
RexxQueue
Definition: QueueClass.hpp:49
RexxActivation.hpp
OrefSet
#define OrefSet(o, r, v)
Definition: RexxCore.h:94
RexxExpressionMessage::arguments
RexxObject * arguments[1]
Definition: ExpressionMessage.hpp:69
RexxQueue::pop
RexxObject * pop()
Definition: QueueClass.hpp:80
RexxActivation::traceResult
void traceResult(RexxObject *v)
Definition: RexxActivation.hpp:392
RexxExpressionMessage::flatten
void flatten(RexxEnvelope *)
Definition: ExpressionMessage.cpp:198
T_MessageSendTerm
Definition: ClassTypeCodes.h:134
reportException
void reportException(wholenumber_t error)
Definition: ActivityManager.hpp:136
RexxActivation::traceIntermediate
void traceIntermediate(RexxObject *v, int p)
Definition: RexxActivation.hpp:373
RexxExpressionMessage::target
RexxObject * target
Definition: ExpressionMessage.hpp:64
RexxEnvelope
Definition: RexxEnvelope.hpp:53
RexxExpressionMessage
Definition: ExpressionMessage.hpp:47
ExpressionMessage.hpp
RexxSource
Definition: SourceFile.hpp:131
RexxActivation::traceMessage
void traceMessage(RexxString *n, RexxObject *v)
Definition: RexxActivation.hpp:380
RexxExpressionMessage::evaluate
RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
Definition: ExpressionMessage.cpp:83
OREF_NULL
#define OREF_NULL
Definition: RexxCore.h:60
RexxExpressionMessage::RexxExpressionMessage
RexxExpressionMessage(RexxObject *, RexxString *, RexxObject *, size_t, RexxQueue *, bool)
Definition: ExpressionMessage.cpp:54
ProtectedObject.hpp
flatten_reference
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:440
cleanUpFlatten
#define cleanUpFlatten
Definition: RexxMemory.hpp:432
ProtectedObject
Definition: ProtectedObject.hpp:46
StringClass.hpp
RexxActivation::getReceiver
virtual RexxObject * getReceiver()
Definition: RexxActivation.cpp:2042
RexxExpressionMessage::messageName
RexxString * messageName
Definition: ExpressionMessage.hpp:65
TRACE_PREFIX_ARGUMENT
Definition: RexxActivity.hpp:92
RexxExpressionStack::push
void push(RexxObject *value)
Definition: ExpressionStack.hpp:77
Error_Execution_super
#define Error_Execution_super
Definition: RexxErrorCodes.h:542
memory_mark
#define memory_mark(oref)
Definition: RexxMemory.hpp:436
RexxExpressionMessage::makeAssignment
void makeAssignment(RexxSource *source)
Definition: ExpressionMessage.cpp:303
RexxExpressionMessage::argumentCount
size_t argumentCount
Definition: ExpressionMessage.hpp:67
Error_No_result_object_message
#define Error_No_result_object_message
Definition: RexxErrorCodes.h:437
RexxActivation
Definition: RexxActivation.hpp:156
Token.hpp
RexxExpressionMessage::super
RexxObject * super
Definition: ExpressionMessage.hpp:66
QueueClass.hpp
setUpFlatten
#define setUpFlatten(type)
Definition: RexxMemory.hpp:427
RexxExpressionMessage::assign
void assign(RexxActivation *, RexxExpressionStack *, RexxObject *)
Definition: ExpressionMessage.cpp:229
RexxExpressionStack::toss
void toss()
Definition: ExpressionStack.hpp:93
RexxCore.h
RexxExpressionStack::popn
void popn(size_t c)
Definition: ExpressionStack.hpp:87
RexxExpressionStack::send
void send(RexxString *message, RexxObject *scope, size_t count, ProtectedObject &result)
Definition: ExpressionStack.hpp:73
new_object
RexxObject * new_object(size_t s)
Definition: RexxMemory.hpp:422
RexxSource::commonString
RexxString * commonString(RexxString *)
Definition: SourceFile.cpp:4330
RexxString::upper
RexxString * upper()
Definition: StringClass.cpp:1442
RexxString::concat
RexxString * concat(RexxString *)
Definition: StringClass.cpp:1172
SourceFile.hpp
RexxObject
Definition: ObjectClass.hpp:311
RexxExpressionMessage::liveGeneral
void liveGeneral(int reason)
Definition: ExpressionMessage.cpp:181
RexxExpressionMessage::doubleTilde
bool doubleTilde
Definition: ExpressionMessage.hpp:68
RexxString
Definition: StringClass.hpp:119