diff options
author | Jeffrey H. Kingston <jeff@it.usyd.edu.au> | 2010-09-14 19:21:41 +0000 |
---|---|---|
committer | Jeffrey H. Kingston <jeff@it.usyd.edu.au> | 2010-09-14 19:21:41 +0000 |
commit | 71bdb35d52747e6d7d9f55df4524d57c2966be94 (patch) | |
tree | 480ee5eefccc40d5f3331cc52d66f722fd19bfb9 /z30.c | |
parent | b41263ea7578fa9742486135c762803b52794105 (diff) | |
download | lout-71bdb35d52747e6d7d9f55df4524d57c2966be94.tar.gz |
Lout 3.17.
git-svn-id: http://svn.savannah.nongnu.org/svn/lout/trunk@2 9365b830-b601-4143-9ba8-b4a8e2c3339c
Diffstat (limited to 'z30.c')
-rw-r--r-- | z30.c | 192 |
1 files changed, 192 insertions, 0 deletions
@@ -0,0 +1,192 @@ +/*@z30.c:Symbol uses:InsertUses()@********************************************/ +/* */ +/* THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.17) */ +/* COPYRIGHT (C) 1991, 1999 Jeffrey H. Kingston */ +/* */ +/* Jeffrey H. Kingston (jeff@cs.usyd.edu.au) */ +/* Basser Department of Computer Science */ +/* The University of Sydney 2006 */ +/* AUSTRALIA */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either Version 2, or (at your option) */ +/* any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA */ +/* */ +/* FILE: z30.c */ +/* MODULE: Symbol Uses */ +/* EXTERNS: InsertUses(), FlattenUses(), SearchUses(), */ +/* FirstExternTarget(), NextExternTarget() */ +/* */ +/*****************************************************************************/ +#include "externs.h" + + +/*****************************************************************************/ +/* */ +/* InsertUses(x, y) */ +/* */ +/* Record the fact that symbol x uses symbol y, by linking them. */ +/* Increment count of the number of times y is used, if y is a parameter. */ +/* */ +/*****************************************************************************/ + +void InsertUses(OBJECT x, OBJECT y) +{ OBJECT tmp; + debug2(DSU, D, "InsertUses( %s, %s )", SymName(x), SymName(y)); + if( type(x) == LOCAL && type(y) == LOCAL && !predefined(y) ) + { GetMem(tmp, USES_SIZE, no_fpos); item(tmp) = y; + if( base_uses(x) == nilobj ) next(tmp) = tmp; + else next(tmp) = next(base_uses(x)), next(base_uses(x)) = tmp; + base_uses(x) = tmp; + } + if( is_par(type(y)) ) + { + uses_count(y) += (enclosing(y) == x ? 1 : 2); + if( dirty(y) || uses_count(y) > 1 ) dirty(enclosing(y)) = TRUE; + } + else if( sym_body(y) == nilobj || dirty(y) ) dirty(x) = TRUE; + debug5(DSU, D, "InsertUses returning ( %s %s; %s %s, count = %d )", + SymName(x), (dirty(x) ? "dirty" : "clean"), + SymName(y), (dirty(y) ? "dirty" : "clean"), uses_count(y)); +} /* end InsertUses */ + + +/*@::GatherUses(), GatherAllUses(), FlattenUses()@****************************/ +/* */ +/* static GatherUses(x, sym) */ +/* static GatherAllUses(x) */ +/* */ +/* GatherUses adds all the unmarked descendants of x to the uses relation */ +/* of sym; GatherAllUses applies gather_uses to all descendants of x. */ +/* */ +/*****************************************************************************/ + +static void GatherUses(OBJECT x, OBJECT sym) +{ OBJECT link, y, tmp; + if( base_uses(x) != nilobj ) + { link = next(base_uses(x)); + do + { y = item(link); + if( marker(y) != sym ) + { if( y != sym ) + { marker(y) = sym; + GetMem(tmp, USES_SIZE, no_fpos); item(tmp) = y; + if( uses(sym) == nilobj ) next(tmp) = tmp; + else next(tmp) = next(uses(sym)), next(uses(sym)) = tmp; + uses(sym) = tmp; + if( indefinite(y) ) indefinite(sym) = TRUE; + if( uses_extern_target(y) ) uses_extern_target(sym) = TRUE; + GatherUses(y, sym); + } + else recursive(sym) = TRUE; + } + link = next(link); + } while( link != next(base_uses(x)) ); + } +} /* end GatherUses */ + + +static void GatherAllUses(OBJECT x) +{ OBJECT link, y; + for( link = Down(x); link != x; link = NextDown(link) ) + { Child(y, link); + if( type(y) == LOCAL ) GatherUses(y, y); + GatherAllUses(y); + } +} /* end GatherAllUses */ + + +/*****************************************************************************/ +/* */ +/* FlattenUses() */ +/* */ +/* Traverse the directed graph assembled by InsertUses, finding its */ +/* transitive closure and storing this explicitly in uses(x) for all x. */ +/* */ +/*****************************************************************************/ + +void FlattenUses(void) +{ GatherAllUses(StartSym); +} /* end FlattenUses */ + + +/*@::SearchUses(), FirstExternTarget(), NextExternTarget()@*******************/ +/* */ +/* BOOLEAN SearchUses(x, y) */ +/* */ +/* Discover whether symbol x uses symbol y by searching the uses list of x. */ +/* */ +/*****************************************************************************/ + +BOOLEAN SearchUses(OBJECT x, OBJECT y) +{ OBJECT p; + debug3(DSU, DD, "SearchUses(%s, %s) uses: %d", SymName(x),SymName(y),uses(x)); + if( x == y ) return TRUE; + if( uses(x) != nilobj ) + { p = next(uses(x)); + do + { debug1(DSU, DDD, " checking %s", SymName(item(p))); + if( item(p) == y ) return TRUE; + p = next(p); + } while( p != next(uses(x)) ); + } + return FALSE; +} /* end SearchUses */ + + +/*****************************************************************************/ +/* */ +/* OBJECT FirstExternTarget(sym, cont) */ +/* OBJECT NextExternTarget(sym, cont) */ +/* */ +/* Together these two procedures return all symbols which are both used by */ +/* sym and a target for at least one external galley. Return nilobj at end.*/ +/* */ +/*****************************************************************************/ + +OBJECT FirstExternTarget(OBJECT sym, OBJECT *cont) +{ OBJECT res; + debug1(DSU, D, "FirstExternTarget( %s )", SymName(sym)); + res = nilobj; *cont = nilobj; + if( is_extern_target(sym) ) res = sym; + else if( uses(sym) != nilobj ) + { *cont = next(uses(sym)); + do + { if( is_extern_target(item(*cont)) ) + { res = item(*cont); + break; + } + *cont = next(*cont); + } while( *cont != next(uses(sym)) ); + } + debug1(DSU, D, "FirstExternTarget returning %s", SymName(res)); + return res; +} /* end FirstExternTarget */ + +OBJECT NextExternTarget(OBJECT sym, OBJECT *cont) +{ OBJECT res; + debug1(DSU, D, "NextExternTarget( %s )", SymName(sym)); + res = nilobj; + if( *cont != nilobj ) + { *cont = next(*cont); + while( *cont != next(uses(sym)) ) + { if( is_extern_target(item(*cont)) ) + { res = item(*cont); + break; + } + *cont = next(*cont); + } + } + debug1(DSU, D, "NextExternTarget returning %s", SymName(res)); + return res; +} /* end NextExternTarget */ |