Initial symbol documentation, find-symbol

* doc/tame.texi: Include `Symbol Table'.

* src/symtable.xsl: Added.
* test/symtable.xspec: Added, testing `find-symbol'.
master
Mike Gerwitz 2016-08-23 11:04:50 -04:00
parent 83599cef70
commit ea3edc18ca
3 changed files with 249 additions and 0 deletions

View File

@ -53,6 +53,7 @@ Free Documentation License".
@menu
* Preprocessor:: Metaprogramming system
* Dependency Graph:: Dependency processing and flow analysis
* Symbol Table:: Lookup table for all objects
* License:: Document License
@end menu
@ -109,6 +110,7 @@ Free Documentation License".
@c chapter
@raisesections
@include ../src/graph.texi
@include ../src/symtable.texi
@lowersections
@include license.texi

101
src/symtable.xsl 100644
View File

@ -0,0 +1,101 @@
<?xml version="1.0"?>
<!--
Symbol table
Copyright (C) 2016 LoVullo Associates, Inc.
This file is part of TAME.
TAME 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 3 of the License, 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, see
<http://www.gnu.org/licenses/>.
-->
<stylesheet version="2.0"
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:f="http://mikegerwitz.com/hoxsl/apply"
xmlns:symtable="http://www.lovullo.com/tame/symtable"
xmlns:preproc="http://www.lovullo.com/rater/preproc">
<import href="symtable.xsl.apply" />
<!--
@node Symbol Table
@section Symbol Table
The @dfn{symbol table} holds declarations for each symbol known to
a@tie{}particular package.
Symbol tables are represented by @code{preproc:syms}
elements.@footnote{
The @code{preproc} namespace exists for legacy reasons;
it will change in the future.}
A @dfn{symbol} is an abstract representation of some object@mdash{
}a calculation, classification, typedef, etc.@mdash{
}containing the source location and useful metadata.
@todo{Document symbol format and metadata.}
Symbols are represented by @code{preproc:sym} elements.
-->
<!--
Produce a list of duplicate symbols in@tie{}@var{$symtable},
grouped by @code{@@name}.
All duplicates will be returned@mdash{
}that is, if @math{S_1} appears before duplicate @math{S_2}
in the symbol table, both@tie{}@math{S_1} and@tie{}@math{S_2}
will be returned.
If two symbols have duplicate @code{@@name}s but the same
@code{@@src},
then they are not considered to be duplicates,
@emph{unless} another duplicate symbol of the
same@tie{}@code{@@name} is found with a different @code{@@src},
in which case all symbols will be returned.
This allows sloppy comparison on concatenated symbol tables before
tidying it up.
Externs are ignored, since they represent symbols that need to be
satisfied at some point@mdash{
}this will be checked during linking.
Symbols (@code{preproc:sym} nodes) are returned by reference.
This method name is ``find'' duplicates rather than ``get'' to
emphasize that processing is performed, which is potentially
intensive given a large symbol table@tie{}@var{$symtable}.
-->
<function name="symtable:find-duplicates" as="element( preproc:sym )*">
<param name="symtable" as="element( preproc:syms )" />
<for-each-group select="$symtable/preproc:sym[
not( @extern = 'true' ) ]"
group-by="@name">
<!-- @src may be omitted to convey a local symbol -->
<variable name="srcs" as="xs:string*"
select="distinct-values(
for $sym in current-group()
return if ( exists( $sym/@src ) ) then
$sym/@src
else
'.' )" />
<sequence select="if ( count( $srcs ) gt 1 ) then
current-group()
else
()" />
</for-each-group>
</function>
</stylesheet>

146
test/symtable.xspec 100644
View File

@ -0,0 +1,146 @@
<?xml version="1.0"?>
<!--
Tests dependency graph
Copyright (C) 2016 LoVullo Associates, Inc.
This file is part of TAME.
TAME 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 3 of the License, 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, see
<http://www.gnu.org/licenses/>.
-->
<description xmlns="http://www.jenitennison.com/xslt/xspec"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://www.jenitennison.com/xslt/xspec"
xmlns:symtable="http://www.lovullo.com/tame/symtable"
xmlns:preproc="http://www.lovullo.com/rater/preproc"
xmlns:foo="http://www.lovullo.com/_junk"
stylesheet="../src/symtable.xsl">
<variable name="table" as="element( preproc:syms )">
<preproc:syms>
<preproc:sym name="dup-a"
src="dup-a-first"
foo:dup="true" />
<preproc:sym name="dup-b"
src="dup-b-first"
foo:dup="true" />
<preproc:sym name="dup-a"
src="dup-a-second"
foo:dup="true" />
<preproc:sym name="dup-b"
src="dup-b-second"
foo:dup="true" />
<preproc:sym name="dup-b"
src="dup-b-third"
foo:dup="true" />
<!-- one of them is the same package as another; all three
should be recognized as duplicates so that the caller can
resolve or report intelligently -->
<preproc:sym name="dup-c-somesame"
src="dup-c-first"
foo:dup="true" />
<preproc:sym name="dup-c-somesame"
src="dup-c-same"
foo:unique="first"
foo:dup="true" />
<preproc:sym name="dup-c-somesame"
src="dup-c-same"
foo:unique="second"
foo:dup="true" />
<preproc:sym name="non-dup"
src="ok" />
<preproc:sym name="non-dup-samepkg"
src="same" />
<preproc:sym name="non-dup-samepkg"
src="same" />
<!-- some symbols may be missing @src entirely to denote a local
symbol -->
<preproc:sym name="no-src" />
<!-- same package, no @src -->
<preproc:sym name="no-src-local"
foo:uniq="a" />
<preproc:sym name="no-src-local"
foo:uniq="b" />
<!-- so it should be considered in determining a duplicate -->
<preproc:sym name="no-src-dup"
foo:uniq="a"
foo:dup="true" />
<preproc:sym name="no-src-dup"
foo:uniq="b"
foo:dup="true" />
<preproc:sym name="no-src-dup"
src="no-src"
foo:dup="true" />
<!-- ignore externs (one) -->
<preproc:sym name="extern-dup-one"
src="extern-a" />
<preproc:sym name="extern-dup-one"
extern="true"
src="extern-b" />
<!-- ignore externs (both) -->
<preproc:sym name="extern-dup-both"
extern="true"
src="extern-a" />
<preproc:sym name="extern-dup-both"
extern="true"
src="extern-b" />
<!-- ignore externs (combo) -->
<preproc:sym name="extern-dup-bothish"
src="extern-a" />
<preproc:sym name="extern-dup-bothish"
extern="true"
src="extern-b" />
<preproc:sym name="extern-dup-bothish"
extern="true"
src="extern-c" />
</preproc:syms>
</variable>
<variable name="dupes" as="element( preproc:sym )+"
select="$table/preproc:sym[ @foo:dup = 'true' ]" />
<variable name="distinct-dupes" as="xs:string+"
select="distinct-values(
$table/preproc:sym[
@foo:dup = 'true' ]/@name )" />
<scenario label="symtable:find-duplicates">
<call function="symtable:find-duplicates">
<param name="symtable"
select="$table" />
</call>
<expect label="finds all duplicates"
test="empty( $dupes except $x:result )" />
<expect label="does not find any non-duplicates"
test="empty( $x:result except $dupes )" />
<expect label="returns all duplicates by reference"
test="every $sym in $x:result
satisfies $sym/parent::* is $table" />
</scenario>
</description>