ParseInstruction.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 Parse Parse 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 "RexxActivity.hpp"
51 #include "ParseInstruction.hpp"
52 #include "ParseTrigger.hpp"
53 #include "ParseTarget.hpp"
54 #include "Token.hpp"
55 #include "Interpreter.hpp"
56 
57 
59  RexxObject *_expression, /* string expression source */
60  unsigned short string_source, /* source of the parsed string */
61  size_t flags, /* option flags */
62  size_t templateCount, /* count of template items */
63  RexxQueue *parse_template ) /* parsing template array */
64 /******************************************************************************/
65 /* Function: Complete parse instruction initialization */
66 /******************************************************************************/
67 {
68  /* save the expression */
69  OrefSet(this, this->expression, _expression);
70  instructionFlags = (uint16_t)flags; /* save the expression */
71  stringSource = string_source; // our instruction type is determined by the source
72  this->trigger_count = templateCount; /* save the size */
73  while (templateCount > 0) /* loop through the template list */
74  {
75  /* copying each trigger */
76  OrefSet(this, this->triggers[--templateCount], (RexxTrigger *)parse_template->pop());
77  }
78 }
79 
81  RexxActivation *context, /* current activation context */
82  RexxExpressionStack *stack ) /* evaluation stack */
83 /****************************************************************************/
84 /* Function: Execute a REXX PARSE instruction */
85 /****************************************************************************/
86 {
87  RexxObject *value; /* parsed value */
88  RexxObject **argList; /* current argument list */
89  size_t argCount; /* the argument list size */
90  RexxTarget target; /* created target value */
91  RexxTrigger *trigger; /* current trigger */
92  size_t size; /* size of template array */
93  bool multiple; /* processing an argument list */
94  size_t i; /* loop counter */
95 
96  context->traceInstruction(this); /* trace if necessary */
97  multiple = false; /* default to no argument list */
98  value = OREF_NULLSTRING; /* no value yet */
99  argList = OREF_NULL; /* neither is there an argument list */
100  argCount = 0;
101 
102  switch (stringSource) /* get data from variaous sources */
103  {
104 
105  case SUBKEY_PULL: /* PARSE PULL instruction */
106  /* read a line from the queue */
108  stack->push(value); /* add the value to the stack */
109  break;
110 
111  case SUBKEY_LINEIN: /* PARSE LINEIN instruction */
112  /* read a line from the stream */
113  value = ActivityManager::currentActivity->lineIn(context);
114  stack->push(value); /* add the value to the stack */
115  break;
116 
117  case SUBKEY_ARG: /* PARSE ARG instruction */
118  multiple = true; /* have an argument list */
119  /* get the current argument list */
120  argList = context->getMethodArgumentList();
121  argCount = context->getMethodArgumentCount();
122  break;
123 
124  case SUBKEY_SOURCE: /* PARSE SOURCE instruction */
125  value = context->sourceString(); /* retrieve the source string */
126  stack->push(value); /* add the value to the stack */
127  break;
128 
129  case SUBKEY_VERSION: /* PARSE VERSION instruction */
130  /* retrieve the version string */
132  break;
133 
134  case SUBKEY_VAR: /* PARSE VAR name instruction */
135  /* get the variable value */
136  value = this->expression->evaluate(context, stack);
137  stack->push(value); /* add the value to the stack */
138  break;
139 
140  case SUBKEY_VALUE: /* PARSE VALUE expr WITH instruction */
141  /* have an expression? */
142  if (this->expression != OREF_NULL)
143  {
144  /* get the expression value */
145  value = this->expression->evaluate(context, stack);
146  }
147  else
148  {
149  value = OREF_NULLSTRING; /* must have been "parse value with" */
150  }
151  stack->push(value); /* add the value to the stack */
152  break;
153  }
154  /* create the parse target */
155  target.init(value, argList, argCount, instructionFlags&parse_translate, multiple, context, stack);
156 
157  size = this->trigger_count; /* get the template size */
158  for (i = 0; i < size; i++) /* loop through the template list */
159  {
160  trigger = this->triggers[i]; /* get the next trigger value */
161  if (trigger == OREF_NULL) /* end of this template portion? */
162  {
163  target.next(context); /* reset for the next string */
164  }
165  else /* process this trigger */
166  {
167  trigger->parse(context, stack, &target);
168  }
169  }
170  context->pauseInstruction(); /* do debug pause if necessary */
171 }
172 
173 void RexxInstructionParse::live(size_t liveMark)
174 /******************************************************************************/
175 /* Function: Normal garbage collection live marking */
176 /******************************************************************************/
177 {
178  size_t i; /* loop counter */
179  size_t count; /* argument count */
180 
181  memory_mark(this->nextInstruction); /* must be first one marked */
182  for (i = 0, count = this->trigger_count; i < count; i++)
183  {
184  memory_mark(this->triggers[i]);
185  }
186  memory_mark(this->expression);
187 }
188 
190 /******************************************************************************/
191 /* Function: Generalized object marking */
192 /******************************************************************************/
193 {
194  size_t i; /* loop counter */
195  size_t count; /* argument count */
196 
197  /* must be first one marked */
199  for (i = 0, count = this->trigger_count; i < count; i++)
200  {
201  memory_mark_general(this->triggers[i]);
202  }
204 }
205 
207 /******************************************************************************/
208 /* Function: Flatten an object */
209 /******************************************************************************/
210 {
211  size_t i; /* loop counter */
212  size_t count; /* argument count */
213 
215 
216  flatten_reference(newThis->nextInstruction, envelope);
217  for (i = 0, count = this->trigger_count; i < count; i++)
218  {
219  flatten_reference(newThis->triggers[i], envelope);
220  }
221  flatten_reference(newThis->expression, envelope);
223 }
224 
#define parse_translate
#define OREF_NULL
Definition: RexxCore.h:61
#define OrefSet(o, r, v)
Definition: RexxCore.h:101
#define memory_mark(oref)
Definition: RexxMemory.hpp:450
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:498
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:451
#define cleanUpFlatten
Definition: RexxMemory.hpp:484
#define setUpFlatten(type)
Definition: RexxMemory.hpp:478
#define SUBKEY_VAR
Definition: Token.hpp:233
#define SUBKEY_VERSION
Definition: Token.hpp:234
#define SUBKEY_SOURCE
Definition: Token.hpp:227
#define SUBKEY_LINEIN
Definition: Token.hpp:216
#define SUBKEY_ARG
Definition: Token.hpp:205
#define SUBKEY_PULL
Definition: Token.hpp:225
#define SUBKEY_VALUE
Definition: Token.hpp:232
static RexxActivity *volatile currentActivity
static RexxString * getVersionNumber()
Definition: Version.cpp:52
size_t getMethodArgumentCount()
RexxString * sourceString()
void traceInstruction(RexxInstruction *v)
RexxObject ** getMethodArgumentList()
RexxString * pullInput(RexxActivation *)
RexxString * lineIn(RexxActivation *)
void push(RexxObject *value)
uint16_t instructionFlags
RexxInstruction * nextInstruction
void liveGeneral(int reason)
void execute(RexxActivation *, RexxExpressionStack *)
RexxInstructionParse(RexxObject *, unsigned short, size_t, size_t, RexxQueue *)
void flatten(RexxEnvelope *)
RexxTrigger * triggers[1]
virtual RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
RexxObject * pop()
Definition: QueueClass.hpp:80
void init(RexxObject *, RexxObject **, size_t, size_t, bool, RexxActivation *, RexxExpressionStack *)
Definition: ParseTarget.cpp:52
void next(RexxActivation *)
Definition: ParseTarget.cpp:74
void parse(RexxActivation *, RexxExpressionStack *, RexxTarget *)
unsigned short uint16_t