/* Copyright (c) 1979 Regents of the University of California */
* pxp - Pascal execution profiler
* Version 1.1 February 1978
* LIST MANIPULATION ROUTINES
* The grammar for Pascal is written left recursively.
* Because of this, the portions of parse trees which are to resemble
* lists are in the somewhat inconvenient position of having
* the nodes built from left to right, while we want to eventually
* have as semantic value the leftmost node.
* We could carry the leftmost node as semantic value, but this
* would be inefficient as to add a new node to the list we would
* have to chase down to the end. Other solutions involving a head
* and tail pointer waste space.
* The simple solution to this apparent dilemma is to carry along
* a pointer to the leftmost node in a list in the rightmost node
* which is the current semantic value of the list.
* When we have completed building the list, we can retrieve this
* left end pointer very easily; neither adding new elements to the list
* nor finding the left end is thus expensive. As the bottommost node
* has an unused next pointer in it, no space is wasted either.
* The nodes referred to here are of the T_LISTPP type and have
* T_LISTPP some_pointer next_element
* Here some_pointer points to the things of interest in the list,
* and next_element to the next thing in the list except for the
* rightmost node, in which case it points to the leftmost node.
* The next_element of the rightmost node is of course zapped to the
* NIL pointer when the list is completed.
* Thinking of the lists as tree we heceforth refer to the leftmost
* node as the "top", and the rightmost node as the "bottom" or as
return (tree3(T_LISTPP
, new, spacep
));
* Add a new element to an existing list
return (tree3(T_LISTPP
, new, top
));
* Fix up the list which has virtual root vroot.
* We grab the top pointer and return it, zapping the spot
* where it was so that the tree is not circular.
* Set up a T_VAR node for a qualified variable.
* Init is the initial entry in the qualification,
* or NIL if there is none.
* if we are building pTrees, there has to be an extra slot for
* a pointer to the namelist entry of a field, if this T_VAR refers
* to a field name within a WITH statement.
* this extra field is set in lvalue, and used in VarCopy.
return (tree4(T_VAR
, NOCON
, var
, init
));
return tree5( T_VAR
, NOCON
, var
, init
, NIL
);
* set up a T_TYREC node for a record
* if we are building pTrees, there has to be an extra slot for
* a pointer to the namelist entry of the record.
* this extra field is filled in in gtype, and used in RecTCopy.
setuptyrec( line
, fldlst
)
return tree3( T_TYREC
, line
, fldlst
);
return tree4( T_TYREC
, line
, fldlst
, NIL
);
* set up a T_FIELD node for a field.
* if we are building pTrees, there has to be an extra slot for
* a pointer to the namelist entry of the field.
* this extra field is set in lvalue, and used in SelCopy.
setupfield( field
, other
)
return tree3( T_FIELD
, field
, other
);
return tree4( T_FIELD
, field
, other
, NIL
);