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)  

UseStrictInstruction.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 USE STRICT instruction class */
42 /* */
43 /******************************************************************************/
44 #include <stdlib.h>
45 #include "RexxCore.h"
46 #include "ArrayClass.hpp"
47 #include "QueueClass.hpp"
48 #include "RexxActivation.hpp"
49 #include "UseStrictInstruction.hpp"
51 
52 
53 RexxInstructionUseStrict::RexxInstructionUseStrict(size_t count, bool strict, bool extraAllowed, RexxQueue *variable_list, RexxQueue *defaults)
54 {
55  // set the variable count and the option flag
56  variableCount = count;
57  variableSize = extraAllowed; // we might allow an unchecked number of additional arguments
58  minimumRequired = 0; // do don't necessarily require any of these.
59  strictChecking = strict; // record if this is the strict form
60 
61  // items are added to the queues in reverse order, so we pop them off and add
62  // them to the end of the list as we go.
63  while (count > 0) // loop through our variable set, adding everything in.
64  {
65  // decrement first, so we store at the correct offset.
66  count--;
67  OrefSet(this, variables[count].variable, (RexxVariableBase *)variable_list->pop());
68  OrefSet(this, variables[count].defaultValue, defaults->pop());
69 
70  // if this is a real variable, see if this is the last of the required ones.
71  if (minimumRequired < count + 1 && variables[count].variable != OREF_NULL)
72  {
73  // no default value means this is a required argument, this is the min we'll accept.
74  if (variables[count].defaultValue == OREF_NULL)
75  {
76  minimumRequired = count + 1;
77  }
78  }
79  }
80 }
81 
82 
86 void RexxInstructionUseStrict::live(size_t liveMark)
87 {
88  size_t i; /* loop counter */
89  size_t count; /* argument count */
90 
91  memory_mark(this->nextInstruction); /* must be first one marked */
92  for (i = 0, count = variableCount; i < count; i++)
93  {
94  memory_mark(this->variables[i].variable);
95  memory_mark(this->variables[i].defaultValue);
96  }
97 }
98 
99 
105 {
106  size_t i; /* loop counter */
107  size_t count; /* argument count */
108 
109  /* must be first one marked */
111  for (i = 0, count = variableCount; i < count; i++)
112  {
113  memory_mark_general(this->variables[i].variable);
114  memory_mark_general(this->variables[i].defaultValue);
115  }
116 }
117 
118 
125 {
126  size_t i; /* loop counter */
127  size_t count; /* argument count */
128 
130 
131  flatten_reference(newThis->nextInstruction, envelope);
132  for (i = 0, count = variableCount; i < count; i++)
133  {
134  flatten_reference(newThis->variables[i].variable, envelope);
135  flatten_reference(newThis->variables[i].defaultValue, envelope);
136  }
138 }
139 
140 
142 {
143  context->traceInstruction(this); // trace if necessary
144  // get the argument information from the context
145  RexxObject **arglist = context->getMethodArgumentList();
146  size_t argcount = context->getMethodArgumentCount();
147  // strict checking means we need to enforce min/max limits
148  if (strictChecking)
149  {
150  // not enough of the required arguments? That's an error
151  if (argcount < minimumRequired)
152  {
153  // this is a pain, but there are different errors for method errors vs. call errors.
154  if (context->inMethod())
155  {
157  }
158  else
159  {
161  }
162  }
163  // potentially too many?
164  if (!variableSize && argcount > variableCount)
165  {
166  if (context->inMethod())
167  {
169  }
170  else
171  {
173  }
174  }
175  }
176 
177  // now we process each of the variable definitions left-to-right
178  for (size_t i = 0; i < variableCount; i++)
179  {
180  // get our current variable. We're allowed to skip over variables, so
181  // there might not be anything here.
182  RexxVariableBase *variable = variables[i].variable;
183  if (variable != OREF_NULL)
184  {
185  // get the corresponding argument
186  RexxObject *argument = getArgument(arglist, argcount, i);
187  if (argument != OREF_NULL)
188  {
189  context->traceResult(argument); // trace if necessary
190  // assign the value
191  variable->assign(context, stack, argument);
192  }
193  else
194  {
195  // grab a potential default value
196  RexxObject *defaultValue = variables[i].defaultValue;
197 
198  // and omitted argument is only value if we've marked it as optional
199  // by giving it a default value
200  if (defaultValue != OREF_NULL)
201  {
202  // evaluate the default value now
203  defaultValue = defaultValue->evaluate(context, stack);
204  context->traceResult(defaultValue); // trace if necessary
205  // assign the value
206  variable->assign(context, stack, defaultValue);
207  stack->pop(); // remove the value from the stack
208  }
209  else
210  {
211  // not doing strict checks, revert to old rules and drop the variable.
212  if (!strictChecking)
213  {
214  variable->drop(context);
215 
216  }
217  else
218  {
219  if (context->inMethod())
220  {
222  }
223  else
224  {
226  }
227  }
228  }
229  }
230  }
231  }
232  context->pauseInstruction(); // do debug pause if necessary
233 }
234 
235 
246 RexxObject *RexxInstructionUseStrict::getArgument(RexxObject **arglist, size_t count, size_t target)
247 {
248  // is this beyond what we've been provided with?
249  if (target + 1 > count)
250  {
251  return OREF_NULL;
252  }
253  // return the target item
254  return arglist[target];
255 }
256 
257 
RexxExpressionStack
Definition: ExpressionStack.hpp:53
RexxInternalObject::evaluate
virtual RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
Definition: ObjectClass.hpp:269
Error_Incorrect_call_noarg
#define Error_Incorrect_call_noarg
Definition: RexxErrorCodes.h:331
RexxActivation::getMethodArgumentList
RexxObject ** getMethodArgumentList()
Definition: RexxActivation.hpp:423
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
RexxInstructionUseStrict::getArgument
RexxObject * getArgument(RexxObject **arglist, size_t count, size_t target)
Definition: UseStrictInstruction.cpp:246
Error_Incorrect_method_minarg
#define Error_Incorrect_method_minarg
Definition: RexxErrorCodes.h:454
RexxQueue::pop
RexxObject * pop()
Definition: QueueClass.hpp:80
RexxActivation::traceResult
void traceResult(RexxObject *v)
Definition: RexxActivation.hpp:392
RexxInstructionUseStrict
Definition: UseStrictInstruction.hpp:57
RexxVariableBase
Definition: ExpressionBaseVariable.hpp:47
Error_Incorrect_method_noarg
#define Error_Incorrect_method_noarg
Definition: RexxErrorCodes.h:457
reportException
void reportException(wholenumber_t error)
Definition: ActivityManager.hpp:136
RexxEnvelope
Definition: RexxEnvelope.hpp:53
RexxActivation::getCallname
RexxString * getCallname()
Definition: RexxActivation.hpp:353
RexxExpressionStack::pop
RexxObject * pop()
Definition: ExpressionStack.hpp:78
RexxInstruction::nextInstruction
RexxInstruction * nextInstruction
Definition: RexxInstruction.hpp:85
RexxInstructionUseStrict::variableCount
size_t variableCount
Definition: UseStrictInstruction.hpp:73
OREF_NULL
#define OREF_NULL
Definition: RexxCore.h:60
ArrayClass.hpp
ExpressionBaseVariable.hpp
RexxInstructionUseStrict::RexxInstructionUseStrict
RexxInstructionUseStrict(size_t, bool, bool, RexxQueue *, RexxQueue *)
Definition: UseStrictInstruction.cpp:53
RexxActivation::pauseInstruction
void pauseInstruction()
Definition: RexxActivation.hpp:401
flatten_reference
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:440
cleanUpFlatten
#define cleanUpFlatten
Definition: RexxMemory.hpp:432
UseStrictInstruction.hpp
Error_Incorrect_method_maxarg
#define Error_Incorrect_method_maxarg
Definition: RexxErrorCodes.h:456
Error_Incorrect_call_maxarg
#define Error_Incorrect_call_maxarg
Definition: RexxErrorCodes.h:330
RexxInstructionUseStrict::execute
void execute(RexxActivation *, RexxExpressionStack *)
Definition: UseStrictInstruction.cpp:141
RexxVariableBase::assign
virtual void assign(RexxActivation *, RexxExpressionStack *, RexxObject *)
Definition: ExpressionBaseVariable.hpp:53
Error_Incorrect_call_minarg
#define Error_Incorrect_call_minarg
Definition: RexxErrorCodes.h:329
RexxActivation::getMethodArgumentCount
size_t getMethodArgumentCount()
Definition: RexxActivation.hpp:424
memory_mark
#define memory_mark(oref)
Definition: RexxMemory.hpp:436
RexxInstructionUseStrict::live
void live(size_t)
Definition: UseStrictInstruction.cpp:86
RexxActivation
Definition: RexxActivation.hpp:156
UseVariable::variable
RexxVariableBase * variable
Definition: UseStrictInstruction.hpp:52
RexxVariableBase::drop
virtual void drop(RexxActivation *)
Definition: ExpressionBaseVariable.hpp:54
QueueClass.hpp
RexxInstructionUseStrict::flatten
void flatten(RexxEnvelope *)
Definition: UseStrictInstruction.cpp:124
RexxInstructionUseStrict::liveGeneral
void liveGeneral(int reason)
Definition: UseStrictInstruction.cpp:104
RexxActivation::traceInstruction
void traceInstruction(RexxInstruction *v)
Definition: RexxActivation.hpp:396
setUpFlatten
#define setUpFlatten(type)
Definition: RexxMemory.hpp:427
RexxInstructionUseStrict::minimumRequired
size_t minimumRequired
Definition: UseStrictInstruction.hpp:74
RexxActivation::inMethod
bool inMethod()
Definition: RexxActivation.hpp:343
RexxCore.h
RexxInstructionUseStrict::variableSize
bool variableSize
Definition: UseStrictInstruction.hpp:75
UseVariable::defaultValue
RexxObject * defaultValue
Definition: UseStrictInstruction.hpp:53
RexxInstructionUseStrict::strictChecking
bool strictChecking
Definition: UseStrictInstruction.hpp:76
RexxObject
Definition: ObjectClass.hpp:311
RexxInstructionUseStrict::variables
UseVariable variables[1]
Definition: UseStrictInstruction.hpp:77