* functions to copy pi declarations to pTrees
* these should be all the functions
* that mark the inTree field of the namelist
* copy a T_PROG, T_PDEC, or T_FDEC into a PorFNode
* porf [0] T_PROG T_PDEC or T_FDEC
* [1] lineof "program" or trailing ";"
* [2] program, procedure, or function name
* [3] file or formal parameter list
* [4] function return type or pNIL
union pNodeBodies
*PorFp
;
extern struct nl
*program
;
* programs are defnl'ed but not entered, but extern program works
else nlporf
= nllook( porf
[2] );
if ( nlporf
-> inTree
!= pNIL
) {
pDEF( nlporf
-> inTree
).PorFForward
= TRUE
;
PorF
= pNewNode( PorFTAG
, sizeof( struct PorFNode
) );
PorFp
= &( pDEF( PorF
) );
PorFp
-> PorFName
= sCopy( porf
[2] );
PorFHeader
[ ++ nesting
] = PorF
;
PorFp
-> PorFParams
= tCopy( porf
[3] );
else PorFp
-> PorFParams
= FileCopy( porf
[3] );
PorFp
-> PorFLabels
= pNIL
;
PorFp
-> PorFConsts
= pNIL
;
PorFp
-> PorFTypes
= pNIL
;
PorFp
-> PorFVars
= pNIL
;
PorFp
-> PorFBody
= pNIL
;
PorFp
-> PorFReturns
= tCopy( porf
[4] );
PorFp
-> PorFForward
= FALSE
;
* looks for defined (but not entered) symbols
* (either files or formal parameters)
* which hang down the chain field of
* program, procedure or function namelist entry.
chainlookup( porf
, symb
)
for ( paramp
= porf
->chain
; paramp
!= NIL
; paramp
= paramp
->chain
)
if ( paramp
-> symbol
== symb
)
* copy a list of file names to a list of threads to VarDNodes
* (or threads to the BVarNodes for input or output)
* for later inclusion in the variable declaration list.
* as a special case, the files are found chained to the program nl entry.
extern struct nl
*program
;
extern struct nl
*output
;
for ( filep
= files
; filep
!= NIL
; filep
= (int *) filep
[2] ) {
struct nl
*file
= chainlookup( program
, filep
[1] );
if ( filep
[1] == input
-> symbol
) {
file
-> inTree
= input
-> inTree
;
Thread
= ThreadName( input
);
} else if ( filep
[1] == output
-> symbol
) {
file
-> inTree
= output
-> inTree
;
Thread
= ThreadName( output
);
pPointer File
= pNewNode( VarDTAG
, sizeof( struct VarDNode
) );
pPointer Name
= sCopy( filep
[1] );
pDEF( File
).VarDName
= Name
;
pDEF( File
).VarDType
= pNIL
;
Thread
= ThreadName( file
);
List
= pNewNode( ListTAG
, sizeof( struct ListNode
) );
pDEF( List
).ListItem
= Thread
;
pDEF( List
).ListUp
= After
;
pDEF( List
).ListDown
= pNIL
;
else pDEF( After
).ListDown
= List
;
* copy a formal parameter declaration to a TypedNode
* and a list of ValPNodes or VarPNodes.
* param [0] T_PVAL or T_PVAR
pPointer Typed
= pNewNode( TypedTAG
, sizeof( struct TypedNode
) );
pPointer Type
= tCopy( param
[2] );
Name
= pUSE( PorFHeader
[ nesting
] ).PorFName
;
name
= *hash( pUSE( Name
).StringValue
, 0 );
panic( "ParamCopy:nllook" );
pDEF( Typed
).TypedType
= Type
;
for ( idl
= (int *)param
[1] ; idl
!= NIL
; idl
= (int *)idl
[2] ) {
Param
= pNewNode( ValPTAG
, sizeof( struct ValPNode
) );
Param
= pNewNode( VarPTAG
, sizeof( struct VarPNode
) );
panic("ParamCopy:param[0]");
pDEF( Param
).ParamDName
= Name
;
pDEF( Param
).ParamDType
= Type
;
chainlookup( porf
, idl
[1] ) -> inTree
= Param
;
List
= pNewNode( ListTAG
, sizeof( struct ListNode
) );
pDEF( List
).ListItem
= Param
;
pDEF( List
).ListUp
= After
;
pDEF( List
).ListDown
= pNIL
;
pDEF( Typed
).TypedNames
= List
;
else pDEF( After
).ListDown
= List
;
* construct a list of LabelDNodes from a list of YINTs
for ( labelp
= labels
; labelp
!= NIL
; labelp
= (int *) labelp
[2] ) {
Label
= pNewNode( LabelDTAG
, sizeof( struct LabelDNode
) );
Name
= sCopy( labelp
[1] );
pDEF( Label
).LabelDName
= Name
;
nllook( labelp
[1] ) -> inTree
= Label
;
List
= pNewNode( ListTAG
, sizeof( struct ListNode
) );
pDEF( List
).ListItem
= Label
;
pDEF( List
).ListUp
= After
;
pDEF( List
).ListDown
= pNIL
;
else pDEF( After
).ListDown
= List
;
* copy a constant declaration to a ConstDNode
pPointer Const
= pNewNode( ConstDTAG
, sizeof( struct ConstDNode
) );
pPointer Name
= sCopy( id
);
pPointer ConstValue
= tCopy( decl
);
pDEF( Const
).ConstDName
= Name
;
pDEF( Const
).ConstDValue
= ConstValue
;
nllook( id
) -> inTree
= Const
;
* copy a type declaration to a TypeDNode.
* note that pointers' types are filled in later.
pPointer Type
= pNewNode( TypeDTAG
, sizeof( struct TypeDNode
) );
pPointer Name
= sCopy( id
);
pPointer TypeType
= tCopy( decl
);
struct nl
*np
= nllook( id
);
pDEF( Type
).TypeDName
= Name
;
pDEF( Type
).TypeDType
= TypeType
;
if ( ( np
-> type
) -> class == PTR
) {
( np
-> type
) -> inTree
= TypeType
;
* copies a T_RFIELD node to a TypedNode
* with a type and a list of FieldDNodes
* uses the extern inrecord to know which record its in.
extern struct nl
*inrecord
;
pPointer Typed
= pNewNode( TypedTAG
, sizeof( struct TypedNode
) );
pPointer Type
= tCopy( rfield
[3] );
pDEF( Typed
).TypedNames
= pNIL
;
pDEF( Typed
).TypedType
= Type
;
for ( idlp
= (int *)rfield
[2] ; idlp
!= NIL
; idlp
= (int *)idlp
[2] ) {
= pNewNode( FieldDTAG
, sizeof( struct FieldDNode
) );
pPointer Name
= sCopy( idlp
[1] );
panic( "FieldCopy:inrecord" );
field
= reclook( inrecord
, idlp
[1] );
panic( "FieldCopy:reclook" );
pDEF( FieldD
).FieldDName
= Name
;
pDEF( FieldD
).FieldDType
= Type
;
field
-> inTree
= FieldD
;
List
= pNewNode( ListTAG
, sizeof( struct ListNode
) );
pDEF( List
).ListItem
= FieldD
;
pDEF( List
).ListUp
= After
;
pDEF( List
).ListDown
= pNIL
;
pDEF( Typed
).TypedNames
= List
;
else pDEF( After
).ListDown
= List
;
* copies a T_VARPT node to a VarntNode and a FieldDNode
* [4] list of variant cases
* uses the extern inrecord to know which record its in.
extern struct nl
*inrecord
;
pPointer Varnt
= pNewNode( VarntTAG
, sizeof( struct VarntNode
) );
pPointer Tag
= pNewNode( FieldDTAG
, sizeof( struct FieldDNode
) );
pPointer Name
= sCopy( tyvarpt
[2] );
pPointer Type
= tCopy( tyvarpt
[3] );
pPointer Cases
= tCopy( tyvarpt
[4] );
pDEF( Tag
).FieldDName
= Name
;
pDEF( Tag
).FieldDType
= Type
;
reclook( inrecord
, tyvarpt
[2] ) -> inTree
= Tag
;
pDEF( Varnt
).VarntTag
= Tag
;
pDEF( Varnt
).VarntCases
= Cases
;
* copies a T_TYSCAL node to an EnumTNode and a list of ScalDNodes
pPointer EnumT
= pNewNode( EnumTTAG
, sizeof( struct EnumTNode
) );
for ( idp
= (int *) tyscal
[2] ; idp
!= NIL
; idp
= (int *) idp
[2] ) {
ScalD
= pNewNode( ScalDTAG
, sizeof( struct ScalDNode
) );
pDEF( ScalD
).ScalDName
= Name
;
nllook( idp
[1] ) -> inTree
= ScalD
;
List
= pNewNode( ListTAG
, sizeof( struct ListNode
) );
pDEF( List
).ListItem
= ScalD
;
pDEF( List
).ListUp
= After
;
pDEF( List
).ListDown
= pNIL
;
pDEF( EnumT
).EnumTScalars
= List
;
else pDEF( After
).ListDown
= List
;
* copies a variable declaration to a TypedNode
* with a type and a list of VarDNodes
* also, deals with previously declared (e.g. program files) variables.
pPointer Typed
= pNewNode( TypedTAG
, sizeof( struct TypedNode
) );
pPointer Type
= tCopy( type
);
pDEF( Typed
).TypedNames
= pNIL
;
pDEF( Typed
).TypedType
= Type
;
for ( idlp
= (int *) idl
; idlp
!= NIL
; idlp
= (int *) idlp
[2] ) {
if ( ( var
= nllook( idlp
[1] ) ) -> inTree
== pNIL
) {
* usual case, a new variable
VarD
= pNewNode( VarDTAG
, sizeof( struct VarDNode
) );
pDEF( VarD
).VarDName
= Name
;
* previously declared (file) variable, already in tree
* gets hung on list of variables, in addition
pDEF( VarD
).VarDType
= Type
;
if ( ( var
-> type
) -> class == PTR
) {
( var
-> type
) -> inTree
= Type
;
List
= pNewNode( ListTAG
, sizeof( struct ListNode
) );
pDEF( List
).ListItem
= VarD
;
pDEF( List
).ListUp
= After
;
pDEF( List
).ListDown
= pNIL
;
pDEF( Typed
).TypedNames
= List
;
else pDEF( After
).ListDown
= List
;
* including cheapo versions of all the builtins (eech!)
extern char *in_consts
[];
extern char *in_ctypes
[];
PorFHeader
[ nesting
] = pNewNode( GlobTAG
, sizeof( struct GlobNode
) );
pWorld
= PorFHeader
[ nesting
];
pSeize( PorFHeader
[ nesting
] );
Glob
= &( pDEF( PorFHeader
[ nesting
] ) );
dumpnl( NIL
, "pTreeInit" );
for ( cp
= in_consts
; *cp
; cp
++ ) {
pPointer BCon
= pNewNode( BConstTAG
, sizeof( struct BConstNode
) );
pPointer Name
= sCopy( *cp
);
pDEF( BCon
).BConstName
= Name
;
List
= ListAppend( List
, BCon
);
nllook( *cp
) -> inTree
= BCon
;
Glob
-> GlobConsts
= List
;
* built in simple and constructed types
for ( cp
= in_types
; *cp
; cp
++ ) {
pPointer BType
= pNewNode( BTypeTAG
, sizeof( struct BTypeNode
) );
pPointer Name
= sCopy( *cp
);
pDEF( BType
).BTypeName
= Name
;
List
= ListAppend( List
, BType
);
nllook( *cp
) -> inTree
= BType
;
* constructed types (aren't any more difficult)
for ( cp
= in_ctypes
; *cp
; cp
++ ) {
pPointer BType
= pNewNode( BTypeTAG
, sizeof( struct BTypeNode
) );
pPointer Name
= sCopy( *cp
);
pDEF( BType
).BTypeName
= Name
;
List
= ListAppend( List
, BType
);
nllook( *cp
) -> inTree
= BType
;
for ( cp
= in_vars
; *cp
; cp
++ ) {
pPointer BVar
= pNewNode( BVarTAG
, sizeof( struct BVarNode
) );
pPointer Name
= sCopy( *cp
);
pDEF( BVar
).BVarName
= Name
;
List
= ListAppend( List
, BVar
);
nllook( *cp
) -> inTree
= BVar
;
* built in functions and procedures
for ( cp
= in_funcs
; *cp
; cp
++ ) {
pPointer BFunc
= pNewNode( BFuncTAG
, sizeof( struct BFuncNode
) );
pPointer Name
= sCopy( *cp
);
pDEF( BFunc
).BFuncName
= Name
;
List
= ListAppend( List
, BFunc
);
nllook( *cp
) -> inTree
= BFunc
;
for ( cp
= in_procs
; *cp
; cp
++ ) {
pPointer BProc
= pNewNode( BProcTAG
, sizeof( struct BProcNode
) );
pPointer Name
= sCopy( *cp
);
pDEF( BProc
).BProcName
= Name
;
List
= ListAppend( List
, BProc
);
nllook( *cp
) -> inTree
= BProc
;
pRelease( PorFHeader
[ nesting
] );
* table and returns a pointer to
* [this is a copy of lookup, except it calls nllook1
* whose only variation from lookup1 is that it doesn't set NUSED]
register struct udinfo
*udp
;
derror("%s is undefined", s
);
* It is not an error to call nllook1 if the symbol is not defined.
* Also nllook1 will return FVARs while nllook never will.
* [this is a copy of lookup1, except that it doesn't set NUSED]
* We first check the field names
* of the currently active with
* statements (expensive since they
for (p
= withlist
; p
!= NIL
; p
= p
->nl_next
) {
if (reclook(q
, s
) != NIL
)
* Return the WITHPTR, lvalue understands.
* Symbol table is a 64 way hash
* on the low bits of the character
* pointer value. (Simple, but effective)
for (p
= disptab
[i
]; p
!= NIL
; p
= p
->nl_next
)
if (p
->symbol
== s
&& p
->class != FIELD
&& p
->class != BADUSE
) {
bn
= (p
->nl_block
& 037);