PEBL 2.2
Psychology Experiment Building Language - Cross-platform psychological experiment development system
PNode.cpp
Go to the documentation of this file.
1//* -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*- */
3// Name: src/base/PNode.cpp
4// Purpose: Primary data structure for code
5// Author: Shane T. Mueller, Ph.D.
6// Copyright: (c) 2003-2026 Shane T. Mueller <smueller@obereed.net>
7// License: GPL 2
8//
9//
10//
11// This file is part of the PEBL project.
12//
13// PEBL is free software; you can redistribute it and/or modify
14// it under the terms of the GNU General Public License as published by
15// the Free Software Foundation; either version 2 of the License, or
16// (at your option) any later version.
17//
18// PEBL is distributed in the hope that it will be useful,
19// but WITHOUT ANY WARRANTY; without even the implied warranty of
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21// GNU General Public License for more details.
22//
23// You should have received a copy of the GNU General Public License
24// along with PEBL; if not, write to the Free Software
25// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27#include "PNode.h"
28#include "grammar.tab.hpp"
29#include "../utility/Defs.h"
30#include <iostream>
31#include <string>
32#include <stdlib.h>
33
34using std::cerr;
35using std::cout;
36using std::endl;
37using std::flush;
38using std::ostream;
39using std::string;
40
41#undef VERBOSE_PNODE_CONSTRUCTION_MESSAGES
42
44/*PNode::PNode(PNODE_TYPE type):
45 mType(type),
46 mTrace(0),
47 mSourceFile("<Unknown File>"),
48 mLineNumber(0)
49 {
50
51};
52*/
55 mTrace(0),
56 mSourceFile(""),
57 mLineNumber(0),
58 mFunctName("")
59{
60
61
62}
63
65PNode::PNode(PNODE_TYPE type, const string & filename, int linenumber):
66 mType(type),
67 mTrace(0),
68 mSourceFile(filename),
69 mLineNumber(linenumber),
70 mFunctName("")
71{
72
73}
74
75
77{
78 mType = (pn.GetType());
80
81}
84{
85 // Standard Destructor
86}
87
88
89//Overload of the << operator
90ostream& operator<<(ostream& out, const PNode & node)
91{
92 node.SendToStream(out);
93 return out;
94}
95
96ostream & PNode::SendToStream(ostream & out) const
97{
98 out << "<Anonymous PNode of Type: " << GetType() << ">" << flush;
99 return out;
100}
101
102void PNode::SetFileInfo(const string & filename, int linenumber)
103{
104 mSourceFile = filename;
105 mLineNumber = linenumber;
106}
107void PNode::SetFunctionName(const std::string & funcname)
108{
109 mFunctName = funcname;
110}
111
113{
114 //A generic PNode doesn't necessarily have children, so
115 //don't do anything.
116}
117
118//******************************************************************************
119// OpNode
120//******************************************************************************
121/*
122
123OpNode::OpNode(int op, PNode *left, PNode *right):
124 PNode(PEBL_OP_NODE,"", 0),
125 mOp(op),
126 mLeft(left),
127 mRight(right)
128
129 {
130
131#ifdef VERBOSE_PNODE_CONSTRUCTION_MESSAGES
132 cerr << "\tConstructing PNode of type [" << op << "]:[" << GetOpName() <<"]\n";
133#endif
134
135}
136*/
137
138
139OpNode::OpNode(int op, PNode *left, PNode *right, const std::string & filename, int linenumber):
140 PNode(PEBL_OP_NODE,filename,linenumber),
141 mOp(op),
142 mLeft(left),
143 mRight(right)
144{
145
146#ifdef VERBOSE_PNODE_CONSTRUCTION_MESSAGES
147 cerr << "\tConstructing PNode of type [" << op << "]:[" << GetOpName() <<"]\n";
148#endif
149
150
151}
152
154 PNode(op),
155 mOp(0),
156 mLeft(NULL),
157 mRight(NULL)
158{
159 mOp = op.GetOp();
160 mLeft = op.GetLeft();
161 mRight = op.GetRight();
162}
163
165{
166
167 mOp = op.GetOp();
168 mLeft = op.GetLeft();
169 mRight = op.GetRight();
170 return *this;
171}
172
173
175{
176 //cerr << "destroying children\n";
177 if(mLeft)
178 {
180 delete mLeft;
181 mLeft=NULL;
182 }
183 if(mRight)
184 {
186 delete mRight;
187 mRight=NULL;
188 }
189}
190
191
192// The original parse tree contains a high-level tree of PEBL_FUNCTIONS
193// nodes. The branches get picked off the tree and placed in a functionmap,
194// and get destroyed when the functionmap get destroyed. But, the top of the
195// original parse tree remains, causing a memory leak that never gets cleaned up
196// appropriately, unless this is called after Loader::GetFunctions
198{
199
200 if(GetOp() == PEBL_FUNCTION)
201 {
202 //This is a function node, which means we should remove
203 //the datanode on the left. The right node is a lambda function, which
204 //gets taken over by the function map.
205 if(mLeft)
206 {
207 delete mLeft;
208 mLeft = NULL;
209 }
210 }
211 else if(GetOp() == PEBL_FUNCTIONS)
212 {
213 //This is a PEBL_FUNCTIONS node; it contains links to other PEBL_FUNCTIONS
214 //as well as PEBL_FUNCTION nodes. Destroy them as well.
215
216 if(mLeft)
217 {
218 ((OpNode*)mLeft)->DestroyFunctionTree();
219 delete mLeft;
220 mLeft = NULL;
221 }
222 if(mRight)
223 {
224 ((OpNode*)mRight)->DestroyFunctionTree();
225 delete mRight;
226 mRight = NULL;
227 }
228
229 }
230
231}
232
233
234
235//Standard Destructor. This doesn't automatically destroy children
236//nodes--to do that, use DestroyChildren();
238{
239#ifdef VERBOSE_PNODE_CONSTRUCTION_MESSAGES
240 cout <<" deleting OpNode: " << *this << endl;
241#endif
242}
243
244
245std::string OpNode::GetOpName() const
246{
247 switch(GetOp())
248 {
249
250 case PEBL_ADD: return "PEBL_ADD";
251 case PEBL_AND: return "PEBL_AND";
252 case PEBL_ARGLIST: return "PEBL_ARGLIST";
253 case PEBL_ASSIGN: return "PEBL_ASSIGN";
254 case PEBL_BREAK: return "PEBL_BREAK";
255 case PEBL_COMMA: return "PEBL_COMMA";
256 case PEBL_DIVIDE: return "PEBL_DIVIDE";
257 case PEBL_DEFINE: return "PEBL_DEFINE";
258 case PEBL_DOT: return "PEBL_DOT";
259 case PEBL_ELSE: return "PEBL_ELSE";
260 case PEBL_END: return "PEBL_END";
261 case PEBL_EQ: return "PEBL_EQ";
262 case PEBL_FUNCTION: return "PEBL_FUNCTION";
263 case PEBL_FUNCTIONS: return "PEBL_FUNCTIONS";
264 case PEBL_GE: return "PEBL_GE";
265 case PEBL_GT: return "PEBL_GT";
266 case PEBL_IF: return "PEBL_IF";
267 case PEBL_IFELSE: return "PEBL_IFELSE";
268 case PEBL_LAMBDAFUNCTION: return "PEBL_LAMBDAFUNCTION";
269 case PEBL_LBRACE: return "PEBL_LBRACE";
270 case PEBL_LBRACKET: return "PEBL_LBRACKET";
271 case PEBL_LIBRARYFUNCTION: return "PEBL_LIBRARYFUNCTION";
272 case PEBL_LISTHEAD: return "PEBL_LISTHEAD";
273 case PEBL_LISTITEM: return "PEBL_LISTITEM";
274 case PEBL_LE: return "PEBL_LE";
275 case PEBL_LOOP: return "PEBL_LOOP";
276 case PEBL_LPAREN: return "PEBL_LPAREN";
277 case PEBL_LT: return "PEBL_LT";
278 case PEBL_MULTIPLY: return "PEBL_MULTIPLY";
279 case PEBL_NE: return "PEBL_NE";
280 case PEBL_NEWLINE: return "PEBL_NEWLINE";
281 case PEBL_NOT: return "PEBL_NOT";
282 case PEBL_OR: return "PEBL_OR";
283 case PEBL_POWER: return "PEBL_POWER";
284 case PEBL_RBRACE: return "PEBL_RBRACE";
285 case PEBL_RBRACKET: return "PEBL_RBRACKET";
286 case PEBL_RETURN: return "PEBL_RETURN";
287 case PEBL_RPAREN: return "PEBL_RPAREN";
288 case PEBL_SEMI: return "PEBL_SEMI";
289 case PEBL_START: return "PEBL_START";
290 case PEBL_STATEMENTS: return "PEBL_STATEMENTS";
291 case PEBL_SUBTRACT: return "PEBL_SUBTRACT";
292 case PEBL_UMINUS: return "PEBL_UMINUS";
293 case PEBL_VARLIST: return "PEBL_VARLIST";
294 case PEBL_VARIABLEDATUM: return "PEBL_VARIABLEDATUM";
295 case PEBL_WHILE: return "PEBL_WHILE";
296
297 case PEBL_FLOAT: return "PEBL_FLOAT";
298 case PEBL_INTEGER: return "PEBL_INTEGER";
299 case PEBL_STRING: return "PEBL_STRING";
300 case PEBL_SYMBOL: return "PEBL_SYMBOL";
301 case PEBL_FUNCTIONNAME: return "PEBL_FUNCTIONNAME";
302
303
304
305 case PEBL_AND_TAIL: return "PEBL_AND_TAIL";
306 case PEBL_ADD_TAIL: return "PEBL_ADD_TAIL";
307 case PEBL_ASSIGN_TAIL: return "PEBL_ASSIGN_TAIL";
308 case PEBL_BREAK_TAIL : return "PEBL_BREAK_TAIL";
309 case PEBL_DIVIDE_TAIL : return "PEBL_DIVIDE_TAIL";
310 case PEBL_EQ_TAIL: return "PEBL_EQ_TAIL";
311 case PEBL_GE_TAIL : return "PEBL_GE_TAIL";
312 case PEBL_GT_TAIL : return "PEBL_GT_TAIL";
313 case PEBL_IF_TAIL : return "PEBL_IF_TAIL";
314 case PEBL_IF_TAIL2 : return "PEBL_IF_TAIL2";
315 case PEBL_ELSE_TAIL : return "PEBL_ELSE_TAIL";
316 case PEBL_LE_TAIL : return "PEBL_LE_TAIL";
317 case PEBL_LISTITEM_TAIL : return "PEBL_LISTITEM_TAIL";
318 case PEBL_LOOP_TAIL1 : return "PEBL_LOOP_TAIL1";
319 case PEBL_LOOP_TAIL2: return "PEBL_LOOP_TAIL2";
320 case PEBL_LT_TAIL: return "PEBL_LT_TAIL";
321 case PEBL_MULTIPLY_TAIL: return "PEBL_MULTIPLY_TAIL";
322 case PEBL_NE_TAIL: return "PEBL_NE_TAIL";
323 case PEBL_NOT_TAIL: return "PEBL_NOT_TAIL";
324 case PEBL_OR_TAIL: return "PEBL_OR_TAIL";
325 case PEBL_POWER_TAIL: return "PEBL_POWER_TAIL";
326 case PEBL_RETURN_TAIL: return "PEBL_RETURN_TAIL";
327 case PEBL_SUBTRACT_TAIL: return "PEBL_SUBTRACT_TAIL";
328 case PEBL_STATEMENTS_TAIL1: return "PEBL_STATEMENTS_TAIL1";
329 case PEBL_STATEMENTS_TAIL2: return "PEBL_STATEMENTS_TAIL2";
330 case PEBL_WHILE_TAIL: return "PEBL_WHILE_TAIL";
331 case PEBL_WHILE_TAIL2: return "PEBL_WHILE_TAIL2";
332 case PEBL_FUNCTION_TAIL1: return "PEBL_FUNCTION_TAIL1";
333 case PEBL_FUNCTION_TAIL2: return "PEBL_FUNCTION_TAIL2";
334 case PEBL_FUNCTION_TAIL_LIBFUNCTION: return "PEBL_FUNCTION_TAIL_LIBFUNCTION";
335
336
337 default: return "UNKNOWN PEBL OPERATION";
338
339 }
340}
341
342
343
344//Overload of the << operator
345
346ostream& OpNode::SendToStream(ostream& out) const
347{
348
349 out << "<OpNode of Type: " << GetOpName() << ">" <<flush;
350 return out;
351
352}
353
354
355//******************************************************************************
356// DataNode
357//******************************************************************************
358
359/*
360DataNode::DataNode(const Variant value):
361 PNode(PEBL_DATA_NODE, "", 0)
362{
363 //This automatically makes a deep copy (I think)
364#ifdef VERBOSE_PNODE_CONSTRUCTION_MESSAGES
365 cerr << "\tConstructing DataNode of variant value " << flush << value << endl;
366#endif
367 mValue = value;
368}
369*/
370
371DataNode::DataNode(const Variant value,const std::string & filename, int linenumber):
372 PNode(PEBL_DATA_NODE, filename, linenumber),
373 mValue(0)
374{
375 //This automatically makes a deep copy (I think)
376#ifdef VERBOSE_PNODE_CONSTRUCTION_MESSAGES
377 cerr << "\tConstructing DataNode of variant value " << flush << value << endl;
378#endif
379
380 mValue = value;
381}
382
383/*
384DataNode::DataNode():
385 PNode(PEBL_DATA_NODE)
386{
387
388#ifdef VERBOSE_PNODE_CONSTRUCTION_MESSAGES
389 cerr << "\tConstructing DataNode without value \n";
390#endif
391}
392*/
393
394DataNode::DataNode(const string & filename, int linenumber):
395 PNode(PEBL_DATA_NODE, filename, linenumber),
396 mValue((int)0)
397{
398
399#ifdef VERBOSE_PNODE_CONSTRUCTION_MESSAGES
400 cerr << "\tConstructing DataNode without value \n";
401#endif
402 mValue = Variant();
403}
404
405
406/*
407DataNode::DataNode(pInt ivalue):
408 PNode(PEBL_DATA_NODE)
409{
410 mValue = ivalue;
411
412#ifdef VERBOSE_PNODE_CONSTRUCTION_MESSAGES
413 cerr << "\tConstructing DataNode of Integer value " << flush << ivalue << endl;
414#endif
415
416};
417*/
418
419
420DataNode::DataNode(pInt ivalue, const string & filename, int linenumber):
421 PNode(PEBL_DATA_NODE, filename, linenumber),
422 mValue(ivalue)
423{
424// mValue = ivalue;
425
426#ifdef VERBOSE_PNODE_CONSTRUCTION_MESSAGES
427 cerr << "\tConstructing DataNode of Integer value " << flush << ivalue << endl;
428#endif
429
430}
431
432/*
433DataNode::DataNode(pDouble fvalue):
434 PNode(PEBL_DATA_NODE)
435{
436 mValue = fvalue;
437#ifdef VERBOSE_PNODE_CONSTRUCTION_MESSAGES
438 cerr << "\tConstructing DataNode of Float value " << flush << fvalue << endl;
439#endif
440};
441*/
442
443
444DataNode::DataNode(pDouble fvalue, const string & filename, int linenumber):
445 PNode(PEBL_DATA_NODE, filename, linenumber),
446 mValue(fvalue)
447{
448// mValue = fvalue;
449#ifdef VERBOSE_PNODE_CONSTRUCTION_MESSAGES
450 cerr << "\tConstructing DataNode of Float value " << flush << fvalue << endl;
451#endif
452}
453
454
456{
457#ifdef VERBOSE_PNODE_CONSTRUCTION_MESSAGES
458 cout <<" deleting DataNode: " << *this << endl;
459#endif
460}
461
462//Overload of the << operator
463ostream& DataNode::SendToStream(ostream& out) const
464{
465 out << "<DataNode of Type: " << GetType() << " and Value: " << GetValue()<< ">" << flush;
466 return out;
467}
#define NULL
Definition BinReloc.cpp:317
#define pInt
Definition Defs.h:8
#define pDouble
Definition Defs.h:7
ostream & operator<<(ostream &out, const PNode &node)
Definition PNode.cpp:90
PNODE_TYPE
Definition PNode.h:33
@ PEBL_OP_NODE
Definition PNode.h:35
@ PEBL_UNDEFINED_NODE
Definition PNode.h:34
@ PEBL_DATA_NODE
Definition PNode.h:36
virtual std::ostream & SendToStream(std::ostream &out) const
Definition PNode.cpp:463
Variant mValue
Definition PNode.h:164
virtual ~DataNode()
Definition PNode.cpp:455
DataNode(const Variant value, const std::string &filename, int linenumber)
Definition PNode.cpp:371
const Variant & GetValue() const
Definition PNode.h:152
virtual void DestroyChildren()
Definition PNode.cpp:174
virtual ~OpNode()
Definition PNode.cpp:237
OpNode(int type, PNode *left, PNode *right, const std::string &filename, int linenumber)
Definition PNode.cpp:139
PNode * mRight
A link to the right-child node.
Definition PNode.h:131
PNode * GetRight() const
Definition PNode.h:115
std::string GetOpName() const
Definition PNode.cpp:245
int GetOp() const
Definition PNode.h:111
virtual std::ostream & SendToStream(std::ostream &out) const
Definition PNode.cpp:346
PNode * GetLeft() const
Definition PNode.h:114
int mOp
Definition PNode.h:125
PNode * mLeft
A link to the left-child node.
Definition PNode.h:128
OpNode operator=(const OpNode &op)
Definition PNode.cpp:164
virtual void DestroyFunctionTree()
Definition PNode.cpp:197
Definition PNode.h:45
virtual void DestroyChildren()
Definition PNode.cpp:112
virtual ~PNode()
The Standard destructor.
Definition PNode.cpp:83
int GetLineNumber() const
Definition PNode.h:69
PNODE_TYPE mType
Definition PNode.h:84
void SetFileInfo(const std::string &filename, int linenumber)
Definition PNode.cpp:102
std::string mSourceFile
Source file of origin.
Definition PNode.h:92
virtual std::ostream & SendToStream(std::ostream &out) const
Definition PNode.cpp:96
int mLineNumber
Closest Line number of origin.
Definition PNode.h:95
std::string mFunctName
Definition PNode.h:97
void SetFunctionName(const std::string &funcname)
Definition PNode.cpp:107
PNODE_TYPE GetType() const
Access mType data.
Definition PNode.h:61
std::string GetFilename() const
Definition PNode.h:68
PNode()
The Standard constructor.
Definition PNode.cpp:53