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)  

ExpressionStack.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 Kernel */
40 /* */
41 /* Primitive Expression Stack Class */
42 /* */
43 /******************************************************************************/
44 #include <stdlib.h>
45 #include "RexxCore.h"
46 #include "StringClass.hpp"
47 #include "ExpressionStack.hpp"
48 #include "ActivityManager.hpp"
49 
50 void RexxExpressionStack::live(size_t liveMark)
51 /******************************************************************************/
52 /* Function: Normal garbage collection live marking */
53 /******************************************************************************/
54 {
55  RexxObject **entry; /* marked stack entry */
56 
57  /* loop through the stack entries */
58  for (entry = this->stack; entry <= this->top; entry++)
59  {
60  memory_mark(*entry); /* marking each one */
61  }
62 }
63 
65 /******************************************************************************/
66 /* Function: Generalized object marking */
67 /******************************************************************************/
68 {
69  RexxObject **entry; /* marked stack entry */
70 
71  for (entry = this->stack; entry <= this->top; entry++)
72  {
73  memory_mark_general(*entry); /* marking each one */
74  }
75 }
76 
78 /******************************************************************************/
79 /* Function: Flatten an object */
80 /******************************************************************************/
81 {
83 
84  size_t i; /* pointer for scanning stack entries*/
85  size_t count; /* number of elements */
86 
87  count = this->top - this->stack; /* get the total count */
88  /* loop through the stack entries */
89  for (i = 0; i < count; i++)
90  {
91  flatten_reference(newThis->stack[i], envelope);
92  }
93 
95 }
96 
98 /******************************************************************************/
99 /* Function: Migrate the expression stack to a new activity */
100 /******************************************************************************/
101 {
102  RexxObject **oldFrame = stack;
103  /* allocate a new frame */
104  activity->allocateStackFrame(this, size);
105  /* copy the enties over to the new stack. */
106  memcpy(stack, oldFrame, sizeof(RexxObject *) * size);
107 }
108 
110  size_t argcount, /* count of arguments */
111  size_t min, /* minimum required arguments */
112  size_t max, /* maximum required arguments */
113  const char *function ) /* function being processed */
114 /******************************************************************************/
115 /* Function: Verify that a function has received all of its required */
116 /* arguments, and did not receive extras. */
117 /******************************************************************************/
118 {
119  size_t i; /* loop counter */
120  size_t j;
121  RexxObject **current; /* pointer to the current stack item */
122 
123  if (argcount < min) /* too few arguments? */
124  {
125  /* report an error */
127  }
128  else if (argcount > max) /* too many arguments? */
129  {
130  /* report an error */
132  }
133  else /* need to expand number of args */
134  {
135  /* address the stack elements */
136  current = this->pointer(argcount - 1);
137  for (i = min; i; i--) /* check on required arguments */
138  {
139  if (*current++ == OREF_NULL) /* omitted argument? */
140  {
141  j = min - i + 1; /* argument location */
142  /* missing required argument */
144  }
145  }
146  }
147 }
148 
150  size_t position) /* position of argument */
151 /******************************************************************************/
152 /* Function: Retrieve an object from the expression stack and potentially */
153 /* convert it into a string argument. */
154 /******************************************************************************/
155 {
156  RexxObject *argument = this->peek(position); /* get the argument in question */
157  if (isOfClass(String, argument)) /* string object already? */
158  {
159  return(RexxString *)argument; /* finished */
160  }
161  /* get the string form, raising a */
162  /* NOSTRING condition if necessary */
163  RexxString *newStr = argument->requestString();
164  this->replace(position, newStr); /* replace the argument */
165  return newStr; /* return the replacement value */
166 }
167 
169  size_t position) /* position of argument */
170 /******************************************************************************/
171 /* Function: Retrieve an object from the expression stack and potentially */
172 /* convert it into a string argument. */
173 /******************************************************************************/
174 {
175  RexxObject *argument = this->peek(position); /* get the argument in question */
176  if (argument == OREF_NULL) /* missing a required argument? */
177  {
178  return OREF_NULL; /* finished already */
179  }
180  if (isOfClass(String, argument)) /* string object already? */
181  {
182  return(RexxString *)argument; /* finished */
183  }
184  /* get the string form, raising a */
185  /* NOSTRING condition if necessary */
186  RexxString *newStr = argument->requestString();
187  this->replace(position, newStr); /* replace the argument */
188  return newStr; /* return the replacement value */
189 }
190 
192  size_t position, /* position of argument */
193  size_t argcount, /* count of arguments */
194  const char *function) /* function being processed */
195 /******************************************************************************/
196 /* Function: Retrieve an object from the expression stack and potentially */
197 /* convert it into an integer argument. */
198 /******************************************************************************/
199 {
200 
201  RexxObject *argument = this->peek(position); /* get the argument in question */
202  if (isOfClass(Integer, argument)) /* integer object already? */
203  {
204  return(RexxInteger *)argument; /* finished */
205  }
206  /* return the string form of argument*/
207  wholenumber_t numberValue; /* converted long value */
208  if (!argument->requestNumber(numberValue, Numerics::ARGUMENT_DIGITS))
209  {
210  /* report an exception */
211  reportException(Error_Incorrect_call_whole, function, argcount - position, argument);
212  }
213  RexxInteger *newInt = new_integer(numberValue); /* create an integer object */
214  this->replace(position, newInt); /* replace the argument */
215  return newInt; /* return the replacement value */
216 }
217 
218 
220  size_t position, /* position of argument */
221  size_t argcount, /* count of arguments */
222  const char *function) /* function being processed */
223 /******************************************************************************/
224 /* Function: Retrieve an object from the expression stack and potentially */
225 /* convert it into an integer argument. */
226 /******************************************************************************/
227 {
228  RexxObject *argument = this->peek(position); /* get the argument in question */
229  if (argument == OREF_NULL) /* missing an optional argument? */
230  {
231  return OREF_NULL; /* nothing there */
232  }
233  if (isOfClass(Integer, argument)) /* integer object already? */
234  {
235  return(RexxInteger *)argument; /* finished */
236  }
237  /* return the string form of argument*/
238  wholenumber_t numberValue; /* converted long value */
239  if (!argument->requestNumber(numberValue, Numerics::ARGUMENT_DIGITS))
240  {
241  /* report an exception */
242  reportException(Error_Incorrect_call_whole, function, argcount - position, argument);
243  }
244  RexxInteger *newInt = new_integer(numberValue); /* create an integer object */
245  this->replace(position, newInt); /* replace the argument */
246  return newInt; /* return the replacement value */
247 }
248 
249 
261 RexxObject *RexxExpressionStack::requiredBigIntegerArg(size_t position, size_t argcount, const char *function)
262 {
263 
264  RexxObject *argument = this->peek(position); /* get the argument in question */
265  // get this in the form of an object that is valid as a 64-bit integer, ready to
266  // be passed along as an argument to native code.
267  RexxObject *newArgument = Numerics::int64Object(argument);
268  // returns a null value if it doesn't convert properly
269  if (newArgument == OREF_NULL)
270  {
271  /* report an exception */
272  reportException(Error_Incorrect_call_whole, function, argcount - position, argument);
273  }
274  this->replace(position, newArgument); /* replace the argument */
275  return newArgument;
276 }
277 
278 
290 RexxObject *RexxExpressionStack::optionalBigIntegerArg(size_t position, size_t argcount, const char *function)
291 {
292  RexxObject *argument = this->peek(position); /* get the argument in question */
293  if (argument == OREF_NULL) /* missing an optional argument? */
294  {
295  return OREF_NULL; /* nothing there */
296  }
297  // get this in the form of an object that is valid as a 64-bit integer, ready to
298  // be passed along as an argument to native code.
299  RexxObject *newArgument = Numerics::int64Object(argument);
300  // returns a null value if it doesn't convert properly
301  if (newArgument == OREF_NULL)
302  {
303  /* report an exception */
304  reportException(Error_Incorrect_call_whole, function, argcount - position, argument);
305  }
306  this->replace(position, newArgument); /* replace the argument */
307  return newArgument;
308 }
RexxExpressionStack::replace
void replace(size_t offset, RexxObject *value)
Definition: ExpressionStack.hpp:82
Numerics::int64Object
static RexxObject * int64Object(RexxObject *source)
Definition: Numerics.cpp:447
RexxExpressionStack
Definition: ExpressionStack.hpp:53
RexxExpressionStack::pointer
RexxObject ** pointer(size_t v)
Definition: ExpressionStack.hpp:90
ExpressionStack.hpp
RexxExpressionStack::size
size_t size
Definition: ExpressionStack.hpp:98
Error_Incorrect_call_whole
#define Error_Incorrect_call_whole
Definition: RexxErrorCodes.h:333
Error_Incorrect_call_noarg
#define Error_Incorrect_call_noarg
Definition: RexxErrorCodes.h:331
new_integer
RexxInteger * new_integer(wholenumber_t v)
Definition: IntegerClass.hpp:198
memory_mark_general
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:437
ActivityManager.hpp
RexxExpressionStack::expandArgs
void expandArgs(size_t, size_t, size_t, const char *)
Definition: ExpressionStack.cpp:109
reportException
void reportException(wholenumber_t error)
Definition: ActivityManager.hpp:136
RexxExpressionStack::flatten
void flatten(RexxEnvelope *)
Definition: ExpressionStack.cpp:77
RexxEnvelope
Definition: RexxEnvelope.hpp:53
isOfClass
#define isOfClass(t, r)
Definition: RexxCore.h:211
RexxActivity::allocateStackFrame
void allocateStackFrame(RexxExpressionStack *stack, size_t entries)
Definition: RexxActivity.hpp:299
Numerics::ARGUMENT_DIGITS
static const size_t ARGUMENT_DIGITS
Definition: Numerics.hpp:68
RexxExpressionStack::stack
RexxObject ** stack
Definition: ExpressionStack.hpp:100
RexxObject::requestNumber
bool requestNumber(wholenumber_t &, size_t)
Definition: ObjectClass.cpp:1352
OREF_NULL
#define OREF_NULL
Definition: RexxCore.h:60
RexxActivity
Definition: RexxActivity.hpp:127
RexxExpressionStack::optionalStringArg
RexxString * optionalStringArg(size_t)
Definition: ExpressionStack.cpp:168
RexxExpressionStack::top
RexxObject ** top
Definition: ExpressionStack.hpp:99
RexxExpressionStack::live
void live(size_t)
Definition: ExpressionStack.cpp:50
flatten_reference
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:440
cleanUpFlatten
#define cleanUpFlatten
Definition: RexxMemory.hpp:432
StringClass.hpp
Error_Incorrect_call_maxarg
#define Error_Incorrect_call_maxarg
Definition: RexxErrorCodes.h:330
RexxExpressionStack::peek
RexxObject * peek(size_t v)
Definition: ExpressionStack.hpp:89
RexxExpressionStack::requiredBigIntegerArg
RexxObject * requiredBigIntegerArg(size_t, size_t, const char *)
Definition: ExpressionStack.cpp:261
Error_Incorrect_call_minarg
#define Error_Incorrect_call_minarg
Definition: RexxErrorCodes.h:329
RexxExpressionStack::requiredIntegerArg
RexxInteger * requiredIntegerArg(size_t, size_t, const char *)
Definition: ExpressionStack.cpp:191
memory_mark
#define memory_mark(oref)
Definition: RexxMemory.hpp:436
RexxExpressionStack::optionalIntegerArg
RexxInteger * optionalIntegerArg(size_t, size_t, const char *)
Definition: ExpressionStack.cpp:219
wholenumber_t
ssize_t wholenumber_t
Definition: rexx.h:229
RexxExpressionStack::optionalBigIntegerArg
RexxObject * optionalBigIntegerArg(size_t, size_t, const char *)
Definition: ExpressionStack.cpp:290
setUpFlatten
#define setUpFlatten(type)
Definition: RexxMemory.hpp:427
RexxExpressionStack::requiredStringArg
RexxString * requiredStringArg(size_t)
Definition: ExpressionStack.cpp:149
RexxExpressionStack::migrate
void migrate(RexxActivity *)
Definition: ExpressionStack.cpp:97
RexxCore.h
RexxInteger
Definition: IntegerClass.hpp:56
RexxObject::requestString
RexxString * requestString()
Definition: ObjectClass.cpp:1124
RexxObject
Definition: ObjectClass.hpp:311
RexxExpressionStack::liveGeneral
void liveGeneral(int reason)
Definition: ExpressionStack.cpp:64
RexxString
Definition: StringClass.hpp:119