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, bool autoCreate, bool named, RexxQueue *variable_list, RexxQueue *defaults, RexxQueue *minimumLength_list)
54 {
55  if (strict && autoCreate && named && !extraAllowed)
56  {
57  // use strict auto named arg
58  reportException(Error_Translation_user_defined, "STRICT AUTO requires the \"...\" argument marker at the end of the argument list");
59  }
60 
61  // set the variable count and the option flag
62  variableCount = count;
63  variableSize = extraAllowed; // we might allow an unchecked number of additional arguments
64  minimumRequired = 0; // do don't necessarily require any of these.
65  strictChecking = strict; // record if this is the strict form
66  autoCreation = autoCreate;
67  namedArg = named;
68 
69  // items are added to the queues in reverse order, so we pop them off and add
70  // them to the end of the list as we go.
71  while (count > 0) // loop through our variable set, adding everything in.
72  {
73  // decrement first, so we store at the correct offset.
74  count--;
75  OrefSet(this, variables[count].variable, (RexxVariableBase *)variable_list->pop());
76  OrefSet(this, variables[count].defaultValue, defaults->pop());
77  OrefSet(this, variables[count].minimumLength, (RexxInteger *)minimumLength_list->pop());
78 
79  if (this->strictChecking)
80  {
81  if (this->namedArg)
82  {
83  if (variables[count].defaultValue == OREF_NULL) minimumRequired++;
84  }
85  else
86  {
87  // if this is a real variable, see if this is the last of the required ones.
88  if (minimumRequired < count + 1 && variables[count].variable != OREF_NULL)
89  {
90  // no default value means this is a required argument, this is the min we'll accept.
91  if (variables[count].defaultValue == OREF_NULL)
92  {
93  minimumRequired = count + 1;
94  }
95  }
96  }
97  }
98  }
99 
100  if (this->namedArg && this->checkNamedArguments() == false)
101  {
102  reportException(Error_Translation_user_defined, "The named argument names are not unique, or their abbreviation is not distinctive enough");
103 
104  }
105 }
106 
107 
108 /**
109  * The runtime, non-debug live marking routine.
110  */
111 void RexxInstructionUseStrict::live(size_t liveMark)
112 {
113  size_t i; /* loop counter */
114  size_t count; /* argument count */
115 
116  memory_mark(this->nextInstruction); /* must be first one marked */
117  for (i = 0, count = variableCount; i < count; i++)
118  {
119  memory_mark(this->variables[i].variable);
120  memory_mark(this->variables[i].defaultValue);
121  memory_mark(this->variables[i].minimumLength);
122  }
123 }
124 
125 
126 /**
127  * The generalized live marking routine used for non-performance
128  * critical marking operations.
129  */
131 {
132  size_t i; /* loop counter */
133  size_t count; /* argument count */
134 
135  /* must be first one marked */
137  for (i = 0, count = variableCount; i < count; i++)
138  {
139  memory_mark_general(this->variables[i].variable);
140  memory_mark_general(this->variables[i].defaultValue);
141  memory_mark_general(this->variables[i].minimumLength);
142  }
143 }
144 
145 
146 /**
147  * The flattening routine, used for serializing object trees.
148  *
149  * @param envelope The envelope were's flattening into.
150  */
152 {
153  size_t i; /* loop counter */
154  size_t count; /* argument count */
155 
157 
158  flatten_reference(newThis->nextInstruction, envelope);
159  for (i = 0, count = variableCount; i < count; i++)
160  {
161  flatten_reference(newThis->variables[i].variable, envelope);
162  flatten_reference(newThis->variables[i].defaultValue, envelope);
163  flatten_reference(newThis->variables[i].minimumLength, envelope);
164  }
166 }
167 
168 
170 {
171  if (this->namedArg) this->executeNamedArguments(context, stack);
172  else this->executePositionalArguments(context, stack);
173 }
174 
175 
177 {
178  context->traceInstruction(this); // trace if necessary
179  // get the argument information from the context
180  RexxObject **arglist = context->getMethodArgumentList();
181  size_t argcount = context->getMethodArgumentCount();
182  // strict checking means we need to enforce min/max limits
183  if (strictChecking)
184  {
185  // not enough of the required arguments? That's an error
186  if (argcount < minimumRequired)
187  {
188  // this is a pain, but there are different errors for method errors vs. call errors.
189  if (context->inMethod())
190  {
192  }
193  else
194  {
196  }
197  }
198  // potentially too many?
199  if (!variableSize && argcount > variableCount)
200  {
201  if (context->inMethod())
202  {
204  }
205  else
206  {
208  }
209  }
210  }
211 
212  // now we process each of the variable definitions left-to-right
213  for (size_t i = 0; i < variableCount; i++)
214  {
215  // get our current variable. We're allowed to skip over variables, so
216  // there might not be anything here.
217  RexxVariableBase *variable = variables[i].variable;
218  if (variable != OREF_NULL)
219  {
220  // get the corresponding argument
221  RexxObject *argument = getArgument(arglist, argcount, i);
222  if (argument != OREF_NULL)
223  {
224  context->traceResult(argument); // trace if necessary
225  // assign the value
226  variable->assign(context, stack, argument);
227  }
228  else
229  {
230  // grab a potential default value
231  RexxObject *defaultValue = variables[i].defaultValue;
232 
233  // and omitted argument is only value if we've marked it as optional
234  // by giving it a default value
235  if (defaultValue != OREF_NULL)
236  {
237  // evaluate the default value now
238  defaultValue = defaultValue->evaluate(context, stack);
239  context->traceResult(defaultValue); // trace if necessary
240  // assign the value
241  variable->assign(context, stack, defaultValue);
242  stack->pop(); // remove the value from the stack
243  }
244  else
245  {
246  // not doing strict checks, revert to old rules and drop the variable.
247  if (!strictChecking)
248  {
249  variable->drop(context);
250 
251  }
252  else
253  {
254  if (context->inMethod())
255  {
256  reportException(Error_Incorrect_method_noarg, OREF_positional, i + 1);
257  }
258  else
259  {
260  reportException(Error_Incorrect_call_noarg, context->getCallname(), OREF_positional, i + 1);
261  }
262  }
263  }
264  }
265  }
266  }
267  context->pauseInstruction(); // do debug pause if necessary
268 }
269 
270 
271 /**
272  * Get the argument corresponding to a given argument position.
273  *
274  * @param arglist The argument list for the method.
275  * @param count The argument count.
276  * @param target The target argument offset.
277  *
278  * @return The argument corresponding to the position. Returns OREF_NULL
279  * if the argument doesn't exist.
280  */
281 RexxObject *RexxInstructionUseStrict::getArgument(RexxObject **arglist, size_t count, size_t target)
282 {
283  // is this beyond what we've been provided with?
284  if (target + 1 > count)
285  {
286  return OREF_NULL;
287  }
288  // return the target item
289  return arglist[target];
290 }
291 
292 
294 {
295  context->traceInstruction(this); // trace if necessary
296  // get the argument information from the context
297  RexxObject **arglist = context->getMethodArgumentList();
298  size_t argcount = context->getMethodArgumentCount();
299  size_t named_argcount = context->getMethodNamedArgumentCount();
300 
301  // strict checking means we need to enforce min/max limits
302  if (strictChecking)
303  {
304  // not enough of the required arguments? That's an error
305  if (named_argcount < minimumRequired)
306  {
307  if (context->inMethod())
308  {
310  }
311  else
312  {
314  }
315  }
316  // potentially too many?
317  if (!variableSize && named_argcount > variableCount)
318  {
319  if (context->inMethod())
320  {
322  }
323  else
324  {
326  }
327  }
328  }
329 
330  // Helper storage to associate the values passed by the caller to the expected arguments declared in the USE instruction
331  NamedArguments expectedNamedArguments(this->variableCount);
332 
333  // Iterate over the named arguments declared by the callee with the instruction USE NAMED ARG.
334  // Collect their names.
335  for (size_t i = 0; i < this->variableCount; i++)
336  {
337  RexxVariableBase *variable = this->variables[i].variable;
338  expectedNamedArguments[i].name = variable->getName()->getStringData();
339  expectedNamedArguments[i].minimumLength = -1; // by default, no abbreviation
340  RexxInteger *RexxMinimumLength = this->variables[i].minimumLength;
341  if (RexxMinimumLength != OREF_NULL) RexxMinimumLength->numberValue(expectedNamedArguments[i].minimumLength);
342  }
343 
344  // Iterate over the named arguments passed by the caller, match them with the names declared by the callee.
345  // In case of additional argument not declared by the callee (no match):
346  // - If strict without ellipsis (...) then an error is raised
347  // - otherwise if mode auto then a variable is created.
348  // - otherwise the additional argument is ignored
349  for (size_t i= argcount; i < (argcount + (2 * named_argcount)); i+=2)
350  {
351  RexxString *argName = (RexxString *)arglist[i];
352  RexxObject *argValue = arglist[i+1];
353  bool match = expectedNamedArguments.check(argName, argValue, this->strictChecking && !this->variableSize);
354  if (!match && this->autoCreation)
355  {
356  context->traceResult(argValue); // trace if necessary
357  RexxVariableBase *retriever = OREF_NULL;
358  if (argName != OREF_NULL) retriever = RexxVariableDictionary::getVariableRetriever(argName);
359  if (retriever == OREF_NULL || argName->getCharC(0) == '.' || isdigit(argName->getCharC(0)))
360  {
361  RexxString *error = argName->concatToCstring("Expected a symbol for the named argument name; found \"");
362  ProtectedObject p(error);
363  error = error->concatWithCstring("\"");
364  p = error;
366  }
367  // a variable having already a value is not overwritten by an auto named argument
368  if (!retriever->exists(context)) retriever->assign(context, stack, argValue);
369  }
370  }
371 
372  // Now that we have matched each named argument of the caller, we can decide if a default value on callee side is needed.
373  // There is no evaluation of a default value when a value has been provided by the caller.
374  // The order of evaluation is the order of declaration in USE NAMED ARG (left-to-right).
375  // The automatic variables are already created and can be used during the evaluation of a default value.
376  for (size_t i=0; i < this->variableCount; i++)
377  {
378  RexxVariableBase *variable = this->variables[i].variable;
379  NamedArgument &namedArgument = expectedNamedArguments[i];
380  if (namedArgument.assigned)
381  {
382  RexxObject *argValue = namedArgument.value;
383  context->traceResult(argValue); // trace if necessary
384  variable->assign(context, stack, argValue);
385  }
386  else
387  {
388  // grab a potential default value
389  RexxObject *defaultValue = this->variables[i].defaultValue;
390 
391  // and omitted argument is only value if we've marked it as optional
392  // by giving it a default value
393  if (defaultValue != OREF_NULL)
394  {
395  // evaluate the default value now
396  defaultValue = defaultValue->evaluate(context, stack);
397  context->traceResult(defaultValue); // trace if necessary
398  // assign the value
399  variable->assign(context, stack, defaultValue);
400  stack->pop(); // remove the value from the stack
401  }
402  else
403  {
404  if (!this->strictChecking)
405  {
406  // not doing strict checks, revert to old rules and drop the variable.
407  variable->drop(context);
408 
409  }
410  else
411  {
412  if (context->inMethod())
413  {
414  reportException(Error_Incorrect_method_noarg, OREF_named, variable->getName());
415  }
416  else
417  {
418  reportException(Error_Incorrect_call_noarg, context->getCallname(), OREF_named, variable->getName());
419  }
420  }
421  }
422  }
423  }
424 
425  context->pauseInstruction(); // do debug pause if necessary
426 }
427 
428 
429 // Helper to check that the abbreviated argument names are distinct from each other.
430 // This check is made at parse time, not at runtime.
432 {
433  // Helper storage to detect the collisions of names
434  NamedArguments expectedNamedArguments(this->variableCount);
435 
436  // Iterate over the named arguments declared by the callee with the instruction USE NAMED ARG.
437  // Collect their names.
438  for (size_t i = 0; i < this->variableCount; i++)
439  {
440  RexxVariableBase *variable = this->variables[i].variable;
441  expectedNamedArguments[i].name = variable->getName()->getStringData();
442  expectedNamedArguments[i].minimumLength = -1; // by default, no abbreviation
443  RexxInteger *RexxMinimumLength = this->variables[i].minimumLength;
444  if (RexxMinimumLength != OREF_NULL) RexxMinimumLength->numberValue(expectedNamedArguments[i].minimumLength);
445  }
446 
447  // Iterate over the collected named arguments, and check each one with all the followings
448  // If there is a match then return false : the names are not unique
449  for (size_t i = 0; i < this->variableCount; i++)
450  {
451  bool match = expectedNamedArguments.check(expectedNamedArguments[i].name, OREF_NULL, false, expectedNamedArguments[i].minimumLength, i+1);
452  if (match) return false;
453  }
454  return true;
455 }
456 
457 
458 /*============================================================================*/
459 /* Named argument helpers for internal methods */
460 /*============================================================================*/
461 
462 void NamedArguments::check(RexxObject **namedArglist, size_t namedArgCount, bool strict, bool extraAllowed, size_t minimumRequired)
463 {
464  // strict checking means we need to enforce min/max limits
465  if (strict)
466  {
467  // not enough of the required arguments? That's an error
468  if (namedArgCount < minimumRequired)
469  {
470  reportException(Error_Incorrect_method_minarg, OREF_named, minimumRequired);
471  }
472  // potentially too many?
473  if (!extraAllowed && namedArgCount > this->count)
474  {
476  }
477  }
478 
479  // Iterate over the named arguments passed by the caller, match them with the names declared by the callee.
480  // In case of additional argument not declared by the callee (no match):
481  // - If strict and not extraAllowed then an error is raised
482  // - otherwise the additional argument is ignored.
483  for (size_t i= 0; i < (2 * namedArgCount); i+=2)
484  {
485  RexxString *argName = (RexxString *)namedArglist[i];
486  RexxObject *argValue = namedArglist[i+1];
487  bool match = this->check(argName, argValue, strict && !extraAllowed);
488  }
489 
490  // Now that we have matched each named argument of the caller, we can check if some mandatory arguments are missing.
491  if (strict)
492  {
493  for (size_t i=0; i < this->count; i++)
494  {
495  NamedArgument &namedArgument = (*this)[i];
496  if (!namedArgument.assigned && namedArgument.value == OREF_NULL)
497  {
498  reportException(Error_Incorrect_method_noarg, OREF_named, namedArgument.name);
499  }
500  }
501  }
502 }
503 
504 
505 /*
506 Store the value of the named argument in the right box, if recognized (abbreviation supported)
507 Assumption: you will not call this helper with the same name twice, because once a name has been matched, it is skipped.
508 Example:
509  // USE NAMED ARG ITEM(2), INDEX(2)=0, MAXDEPTH(1)=10
510  NamedArguments namedArguments(3);
511  namedArguments[0] = NamedArgument("ITEM", 2, OREF_NULL); // At least 2 characters, no default value
512  namedArguments[1] = NamedArgument("INDEX", 2, IntegerZero); // At least 2 characters, default value = 0
513  namedArguments[2] = NamedArgument("MAXDEPTH", 1, IntegerTen); // At least 1 character, default value = 10
514  // For each named argument passed by the caller
515  namedArguments.check(name1, value1);
516  namedArguments.check(name2, value2);
517  namedArguments.check(name3, value3);
518 */
519 
520 bool NamedArguments::check(RexxString *name, RexxObject *value, bool strict, ssize_t name_minimumLength, size_t from)
521 {
522  if (name == NULL) return false;
523  return this->check(name->getStringData(), value, strict, name_minimumLength, from);
524 }
525 
526 bool NamedArguments::check(const char *name, RexxObject *value, bool strict, ssize_t name_minimumLength, size_t from)
527 {
528  if (name == NULL) return false;
529 
530  // The logic is similar to RexxString::abbrev, but here I avoid to use strlen.
531  // For a given expected argument name, there is only one loop over the characters, which stops as soon as possible.
532  // So, passing a named argument like N:value where the expected argument name is "NAMEDPARAMETERS" with abbrev=1
533  // should be *almost* as efficient as testing if the first character is equal to "N".
534  // (this kind of test is done in RexxObject::run: testing only the first character and ignoring the rest of the characters)
535 
536  // There is no order for the named argument, so try all the expected names
537  // At parse-time, 'from' will be different from 0 (index+1 of the current name being checked for collision).
538  for (size_t i=from; i < this->count; i++)
539  {
540  if (this->namedArguments[i].assigned) continue; // Already matched (assumption: you will not call this helper with the same name twice)
541 
542  const char *nameIterator = name;
543  const char *expectedNameIterator = this->namedArguments[i].name;
544 
545  ssize_t nameMinimumLength = name_minimumLength; // always -1 at run-time, can be -1 or >=1 at parse-time
546  ssize_t expectedNameMinimumLength = this->namedArguments[i].minimumLength;
547 
548  while(1)
549  {
550  if (expectedNameMinimumLength != 0) // can be -1 (no abbreviation) or >=1 (abbreviation)
551  {
552  // Checking the mandatory characters of expectedName
553 
554  if (nameMinimumLength == 0 && *expectedNameIterator == '\0')
555  {
556  /*
557  Illustration:
558  USE NAMED ARG namedArguments(1), namedArgument
559  Possible values for namedArguments(1):
560  "n", "na", "nam", "name", ..., "namedArgumen" don't match with "namedArgument".
561  "namedArgument" will match ! Must trigger an error.
562  "namedArguments" dont match with "namedArgument".
563  */
564 
565  // We are at parse-time (because nameMinimumLength != -1), we check that the names are unique.
566  // All the mandatory characters of 'name' have matched with 'expectedName'.
567  // We are in the optional characters of 'name' (because nameMinimumLength == 0).
568  // All the characters of 'expectedName' have been checked (because *expectedNameIterator == '\0').
569  // We have a match even if 'name' has more characters (potential match detected at parse-time)
570 
571  if (value != OREF_NULL) this->namedArguments[i].value = value;
572  this->namedArguments[i].assigned = true;
573  return true;
574  }
575 
576  if (*nameIterator != *expectedNameIterator) break; // no match
577 
578  // Here, we know that the 2 characters are equal
579  // If one of them is \0 then the other is also \0
580  if (*nameIterator == '\0')
581  {
582  // good, the name matches an expected argument name
583  if (value != OREF_NULL) this->namedArguments[i].value = value;
584  this->namedArguments[i].assigned = true;
585  return true;
586  }
587 
588  if (nameMinimumLength > 0) nameMinimumLength--; // Will stay -1 when no abbreviation on caller side, or 0 when all mandatory characters have been checked
589  if (expectedNameMinimumLength > 0) expectedNameMinimumLength--; // Will stay 1 when no abbreviation on called side, or 0 when all mandatory characters have been checked
590  }
591  else // if (expectedNameMinimumLength == 0)
592  {
593  // Checking the optional characters of expectedName
594  if (*nameIterator == '\0')
595  {
596  // good, the name matches an expected argument name
597  if (value != OREF_NULL) this->namedArguments[i].value = value;
598  this->namedArguments[i].assigned = true;
599  return true;
600  }
601 
602  if (nameMinimumLength == 0)
603  {
604  /*
605  Illustration
606  USE NAMED ARG item(1), index(1)=
607  */
608 
609  // We are at parse-time (because nameMinimumLength != -1), we check that the names are unique.
610  // All the mandatory characters of 'name' have matched with 'expectedName'.
611  // We are in the optional characters of 'name' (because nameMinimumLength == 0).
612  // We are in the optional characters of 'expectedName' (because expectedNameMinimumLength == 0)
613  // We have a match even if 'name' and 'expectedName' have more characters (potential match detected at parse-time)
614 
615  if (value != OREF_NULL) this->namedArguments[i].value = value;
616  this->namedArguments[i].assigned = true;
617  return true;
618  }
619 
620  if (*nameIterator != *expectedNameIterator) break; // no match
621 
622  if (nameMinimumLength > 0) nameMinimumLength--; // Will stay -1 when no abbreviation on caller side, or 0 when all mandatory characters have been checked
623  }
624  nameIterator++;
625  expectedNameIterator++;
626  }
627  }
628  // The name did not match an expected argument name
629  RexxString *rexxname = new_string(name);
630  ProtectedObject p(rexxname);
631  if (strict) reportException(Error_Invalid_argument_general, OREF_named, rexxname, "is not an expected argument name");
632  return false;
633 }
634 
void reportException(wholenumber_t error)
#define OREF_NULL
Definition: RexxCore.h:60
#define OrefSet(o, r, v)
Definition: RexxCore.h:94
#define Error_Incorrect_call_noarg
#define Error_Incorrect_call_minarg
#define Error_Incorrect_method_maxarg
#define Error_Invalid_argument_general
#define Error_Incorrect_method_minarg
#define Error_Incorrect_call_maxarg
#define Error_Incorrect_method_noarg
#define Error_Translation_user_defined
#define Error_Symbol_expected_user_defined
#define memory_mark(oref)
Definition: RexxMemory.hpp:445
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:493
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:446
#define cleanUpFlatten
Definition: RexxMemory.hpp:479
#define setUpFlatten(type)
Definition: RexxMemory.hpp:473
RexxString * new_string(const char *s, stringsizeB_t bl, sizeC_t cl=-1)
void check(RexxObject **namedArglist, size_t namedArgCount, bool strict, bool extraAllowed, size_t minimumRequired=0)
NamedArgument * namedArguments
Definition: RexxCore.h:525
const size_t count
Definition: RexxCore.h:522
RexxString * getCallname()
size_t getMethodArgumentCount()
void traceResult(RexxObject *v)
void traceInstruction(RexxInstruction *v)
RexxObject ** getMethodArgumentList()
size_t getMethodNamedArgumentCount()
RexxInstruction * nextInstruction
void execute(RexxActivation *, RexxExpressionStack *)
void executeNamedArguments(RexxActivation *, RexxExpressionStack *)
RexxObject * getArgument(RexxObject **arglist, size_t count, size_t target)
void executePositionalArguments(RexxActivation *, RexxExpressionStack *)
RexxInstructionUseStrict(size_t, bool, bool, bool, bool, RexxQueue *, RexxQueue *, RexxQueue *)
bool numberValue(wholenumber_t &result, size_t precision)
virtual RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
RexxObject * pop()
Definition: QueueClass.hpp:80
const char * getStringData()
RexxString * concatWithCstring(const char *)
RexxString * concatToCstring(const char *)
codepoint_t getCharC(sizeC_t p)
virtual bool exists(RexxActivation *)
virtual void assign(RexxActivation *, RexxExpressionStack *, RexxObject *)
virtual RexxString * getName()
virtual void drop(RexxActivation *)
static RexxVariableBase * getVariableRetriever(RexxString *variable)
RexxInteger * minimumLength
RexxVariableBase * variable
RexxObject * defaultValue
bool assigned
Definition: RexxCore.h:487
const char * name
Definition: RexxCore.h:482
RexxObject * value
Definition: RexxCore.h:486
ssize_t minimumLength
Definition: RexxCore.h:485
SSIZE_T ssize_t