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)  

ExpressionFunction.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 Function Invocation Class */
42 /* */
43 /******************************************************************************/
44 #include <stdlib.h>
45 #include "RexxCore.h"
46 #include "StringClass.hpp"
47 #include "QueueClass.hpp"
48 #include "DirectoryClass.hpp"
49 #include "RexxActivation.hpp"
50 #include "RexxInstruction.hpp"
51 #include "ExpressionFunction.hpp"
52 #include "Token.hpp"
53 #include "StackClass.hpp"
54 #include "RexxActivity.hpp"
55 #include "ProtectedObject.hpp"
56 
58  RexxString *function_name, /* name of the function */
59  size_t argCount, /* count of arguments */
60  RexxQueue *arglist, /* function arguments */
61  size_t builtinIndex, /* index of possible built-in func */
62  bool string ) /* string or symbol invocation */
63 /******************************************************************************/
64 /* Function: Create a function expression object */
65 /******************************************************************************/
66 {
67  /* NOTE: the name oref needs to */
68  /* be filled in prior to doing any */
69  /* thing that might cause a gc */
70  /* set the default target */
71  OrefSet(this, this->functionName, function_name);
72  /* save the argument count */
73  this->argument_count = (uint8_t)argCount;
74  while (argCount > 0) /* now copy the argument pointers */
75  {
76  /* in reverse order */
77  OrefSet(this, this->arguments[--argCount], arglist->pop());
78  }
79  /* set the builtin index for later */
80  /* resolution step */
81  this->builtin_index = (uint16_t)builtinIndex;
82 
83  if (string) /* have a string lookup? */
84  {
85  this->flags |= function_nointernal;/* do not check for internal routines*/
86  }
87 }
88 
90  RexxDirectory *labels) /* current table of labels */
91 /******************************************************************************/
92 /* Function: Resolve a function target location */
93 /******************************************************************************/
94 {
95  /* internal routines allowed? */
96  if (!(this->flags&function_nointernal))
97  {
98  if (labels != OREF_NULL) /* have a labels table? */
99  {
100  /* check the label table */
101  OrefSet(this, this->target, (RexxInstruction *)labels->at(this->functionName));
102  }
103  this->flags |= function_internal; /* this is an internal call */
104  }
105  if (this->target == OREF_NULL) /* not found yet? */
106  {
107  /* have a builtin function? */
108  if (this->builtin_index != NO_BUILTIN)
109  {
110  this->flags |= function_builtin; /* this is a builtin function */
111  }
112  else
113  {
114  this->flags |= function_external;/* have an external routine */
115  }
116  }
117 }
118 
119 void RexxExpressionFunction::live(size_t liveMark)
120 /******************************************************************************/
121 /* Function: Normal garbage collection live marking */
122 /******************************************************************************/
123 {
124  size_t i; /* loop counter */
125  size_t count; /* argument count */
126 
127  memory_mark(this->functionName);
128  memory_mark(this->target);
129  for (i = 0, count = this->argument_count; i < count; i++)
130  {
131  memory_mark(this->arguments[i]);
132  }
133 }
134 
136 /******************************************************************************/
137 /* Function: Generalized object marking */
138 /******************************************************************************/
139 {
140  size_t i; /* loop counter */
141  size_t count; /* argument count */
142 
145  for (i = 0, count = this->argument_count; i < count; i++)
146  {
147  memory_mark_general(this->arguments[i]);
148  }
149 }
150 
152 /******************************************************************************/
153 /* Function: Flatten an object */
154 /******************************************************************************/
155 {
156  size_t i; /* loop counter */
157  size_t count; /* argument count */
158 
160 
161  flatten_reference(newThis->functionName, envelope);
162  flatten_reference(newThis->target, envelope);
163  for (i = 0, count = this->argument_count; i < count; i++)
164  {
165  flatten_reference(newThis->arguments[i], envelope);
166  }
167 
169 }
170 
172  RexxActivation *context, /* current activation context */
173  RexxExpressionStack *stack ) /* evaluation stack */
174 /******************************************************************************/
175 /* Function: Execute a REXX function */
176 /******************************************************************************/
177 {
178  ProtectedObject result; /* returned result */
179  size_t argcount; /* count of arguments */
180  size_t i; /* loop counter */
181  size_t stacktop; /* top location on the stack */
182 
183  ActivityManager::currentActivity->checkStackSpace(); /* have enough stack space? */
184 
185  stacktop = stack->location(); /* save the stack top */
186 
187  argcount = this->argument_count; /* get the argument count */
188  for (i = 0; i < argcount; i++) /* loop through the argument list */
189  {
190  /* real argument? */
191  if (this->arguments[i] != OREF_NULL)
192  {
193  /* evaluate the expression */
194  result = this->arguments[i]->evaluate(context, stack);
195  /* trace if necessary */
196  context->traceIntermediate(result, TRACE_PREFIX_ARGUMENT);
197  }
198  else
199  {
200  stack->push(OREF_NULL); /* push an non-existent argument */
201  /* trace if necessary */
202  context->traceIntermediate(OREF_NULLSTRING, TRACE_PREFIX_ARGUMENT);
203  }
204  }
205 
206  /* process various call types */
207  switch (this->flags&function_type_mask)
208  {
209 
210  case function_internal: /* need to process internal routine */
211  /* go process the internal call */
212  context->internalCall(this->functionName, this->target, argcount, stack, result);
213  break;
214 
215  case function_builtin: /* builtin function call */
216  /* call the function */
217  result = (RexxObject *) (*(RexxSource::builtinTable[this->builtin_index]))(context, argcount, stack);
218  break;
219 
220  case function_external: /* need to call externally */
221  /* go process the internal call */
222  context->externalCall(this->functionName, argcount, stack, OREF_FUNCTIONNAME, result);
223  break;
224  }
225  if ((RexxObject *)result == OREF_NULL) /* result returned? */
226  {
227  /* raise an error */
228  if (this->functionName)
229  {
231  }
232  else
233  {
234  reportException(Error_Function_no_data); // no name => don't try to print one out...!
235  }
236  }
237  stack->setTop(stacktop); /* remove arguments from the stack */
238  stack->push((RexxObject *)result); /* push onto the stack */
239  /* trace if necessary */
240  context->traceFunction(functionName, (RexxObject *)result);
241  return(RexxObject *)result; /* and return this to the caller */
242 }
243 
244 void *RexxExpressionFunction::operator new(size_t size,
245  size_t argCount) /* count of arguments */
246 /******************************************************************************/
247 /* Function: Create a new translator object */
248 /******************************************************************************/
249 {
250  if (argCount == 0)
251  {
252  // allocate with singleton item chopped off
253  return new_object(size - sizeof(RexxObject *), T_FunctionCallTerm);
254  }
255  else
256  {
257  /* Get new object */
258  return new_object(size + (argCount - 1) * sizeof(RexxObject *), T_FunctionCallTerm);
259  }
260 }
RexxActivation::internalCall
RexxObject * internalCall(RexxString *, RexxInstruction *, size_t, RexxExpressionStack *, ProtectedObject &)
Definition: RexxActivation.cpp:2844
RexxExpressionStack
Definition: ExpressionStack.hpp:53
RexxActivation::externalCall
RexxObject * externalCall(RexxString *, size_t, RexxExpressionStack *, RexxString *, ProtectedObject &)
Definition: RexxActivation.cpp:2597
RexxInternalObject::evaluate
virtual RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
Definition: ObjectClass.hpp:269
RexxExpressionFunction::flatten
void flatten(RexxEnvelope *)
Definition: ExpressionFunction.cpp:151
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
function_external
#define function_external
Definition: ExpressionFunction.hpp:51
RexxQueue::pop
RexxObject * pop()
Definition: QueueClass.hpp:80
RexxInstruction
Definition: RexxInstruction.hpp:54
RexxActivity::checkStackSpace
void checkStackSpace()
Definition: RexxActivity.cpp:1964
RexxDirectory::at
RexxObject * at(RexxString *)
Definition: DirectoryClass.cpp:567
reportException
void reportException(wholenumber_t error)
Definition: ActivityManager.hpp:136
RexxActivation::traceIntermediate
void traceIntermediate(RexxObject *v, int p)
Definition: RexxActivation.hpp:373
RexxInstruction.hpp
RexxEnvelope
Definition: RexxEnvelope.hpp:53
RexxExpressionFunction::liveGeneral
void liveGeneral(int reason)
Definition: ExpressionFunction.cpp:135
RexxExpressionFunction
Definition: ExpressionFunction.hpp:54
Error_Function_no_data_function
#define Error_Function_no_data_function
Definition: RexxErrorCodes.h:386
RexxExpressionFunction::target
RexxInstruction * target
Definition: ExpressionFunction.hpp:73
RexxExpressionFunction::live
void live(size_t)
Definition: ExpressionFunction.cpp:119
RexxActivation::traceFunction
void traceFunction(RexxString *n, RexxObject *v)
Definition: RexxActivation.hpp:378
function_internal
#define function_internal
Definition: ExpressionFunction.hpp:49
ExpressionFunction.hpp
OREF_NULL
#define OREF_NULL
Definition: RexxCore.h:60
RexxExpressionFunction::evaluate
RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
Definition: ExpressionFunction.cpp:171
function_builtin
#define function_builtin
Definition: ExpressionFunction.hpp:50
RexxSource::builtinTable
static pbuiltin builtinTable[]
Definition: SourceFile.hpp:406
RexxDirectory
Definition: DirectoryClass.hpp:49
ProtectedObject.hpp
flatten_reference
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:440
cleanUpFlatten
#define cleanUpFlatten
Definition: RexxMemory.hpp:432
RexxExpressionFunction::argument_count
uint8_t argument_count
Definition: ExpressionFunction.hpp:76
ProtectedObject
Definition: ProtectedObject.hpp:46
StringClass.hpp
RexxExpressionFunction::arguments
RexxObject * arguments[1]
Definition: ExpressionFunction.hpp:77
function_type_mask
#define function_type_mask
Definition: ExpressionFunction.hpp:48
TRACE_PREFIX_ARGUMENT
Definition: RexxActivity.hpp:92
RexxExpressionStack::push
void push(RexxObject *value)
Definition: ExpressionStack.hpp:77
StackClass.hpp
RexxExpressionFunction::RexxExpressionFunction
RexxExpressionFunction(RexxString *, size_t, RexxQueue *, size_t, bool)
Definition: ExpressionFunction.cpp:57
memory_mark
#define memory_mark(oref)
Definition: RexxMemory.hpp:436
T_FunctionCallTerm
Definition: ClassTypeCodes.h:133
RexxActivation
Definition: RexxActivation.hpp:156
Token.hpp
RexxExpressionFunction::resolve
void resolve(RexxDirectory *)
Definition: ExpressionFunction.cpp:89
function_nointernal
#define function_nointernal
Definition: ExpressionFunction.hpp:47
NO_BUILTIN
#define NO_BUILTIN
Definition: Token.hpp:296
Error_Function_no_data
#define Error_Function_no_data
Definition: RexxErrorCodes.h:385
QueueClass.hpp
setUpFlatten
#define setUpFlatten(type)
Definition: RexxMemory.hpp:427
ActivityManager::currentActivity
static RexxActivity *volatile currentActivity
Definition: ActivityManager.hpp:95
RexxExpressionFunction::builtin_index
int16_t builtin_index
Definition: ExpressionFunction.hpp:74
RexxActivity.hpp
RexxExpressionFunction::functionName
RexxString * functionName
Definition: ExpressionFunction.hpp:72
RexxExpressionStack::location
size_t location()
Definition: ExpressionStack.hpp:91
RexxCore.h
DirectoryClass.hpp
RexxExpressionFunction::flags
uint8_t flags
Definition: ExpressionFunction.hpp:75
new_object
RexxObject * new_object(size_t s)
Definition: RexxMemory.hpp:422
RexxExpressionStack::setTop
void setTop(size_t v)
Definition: ExpressionStack.hpp:92
RexxObject
Definition: ObjectClass.hpp:311
RexxString
Definition: StringClass.hpp:119