0.7.15 - 2012-02-09
add ability to restrict searchlist access in library templates by adding
#global declarations.
add ability to blow up on nested #defs.
fix escaping in i18n blocks.
fix some library function calls.

0.7.14 - 2011-07-12
added "library" implementation. this allows template code to be reused
without relying on class hierarchy.
includes fixes for optional whitespace.

0.7.13 - 2011-02-02 - Groundhog Day
unskew the implementation of udn/_udn modules, particularly the handling
of missing attributes.


0.7.12 - 2010-06-21
added #strip_lines directive. it strips leading and trailing whitespace
from each output line at compile time. this should improve readability of
certain complex templates where spaces must be removed. logicially, it performs
a .strip() on each line between #strip_lines and #end strip_lines before
sending it through the compiler. actually, the implementations much more
(needlessly?) complex.  Noted that other people aren't filling out the change
log. :(


0.7.7 - 2009-04-23
fixed a bug in checking when function has literal-only arguments
changed filter handling to generate better code, since the majority case
involves having a filter more often than not.


0.7.6 - 2009-02-22
added _udn module to accelerate resolving functions
restructure a number of calls to facilitate testing and acceleration
added escaping for literal $.
remove dopey argument structure for custom filters, this makes it much
easier to reuse a text formatting function as a filter.


0.7.5 - 2009-02-03
fix spurious print
raise an exception when $i18n macros do not have string args
fix dependency analysis - loop-variant identifiers were not correctly
resolved leading to bad code generation.


0.7.4 - 2008-12-01
fixed a parsing ambiguity with text placeholders followed by white space
and parens such as this:

$value (some more text)

this was getting misparsed as a function call.

fixed a parse error treating 'in' as an operator.
fixed the error messaging when a parse error occurs.
fixed optimization of dict literals.
disabled two optimizations when dealing with a binary 'and' operator.
this should solve an issue where short-circuit behavior was not being
preserved.


0.7.3 - 2008-07-21
fixed collapsed adjacent TextNodes such that they are in face a new object,
instead of modifying the object in place. this was leading to some wacky debug
output - not really any material bug.

changed (fixed?) optional whitespace handling for statements so that leading
whitespace on the following line is appropriately tagged.


0.7.2 - 2008-06-25
fixed dependency analysis for local scope when hoisting invariants.


0.7.1 - 2008-06-18
added 'in' operator which was forgotten somehow.

fixed syntax to allow for trailing whitespace in directives.

changed codegen for explicit caching to keep python from bitching about
variable usage.

fixed string literal to allow escaping.  allow #i18n blocks to have bare '#' in
the body of the macro. added 'i18n' macro function.  this works quite similarly
the #i18n, but let's you do $i18n where appropriate.  this uses a generic macro
function handler - so this might be useful in the future for more stuff.

allow #echo to be properly optimized.

fixed long-standing bug in crawling AST for current local identifiers.

fixed long-standing bug in string parsing with C-escaped entities \', \".

remove double analysis on the main template message body. this was manifesting
itself oddly as BlockNodes would get processed twice.

added some more code to make Cheeth/Spitfire co-existance more peaceful.

added debugging classes to highlight errors created by assuming that Spitfire
has autocalling.

added optimization for SliceNode.

added literal BufferWrite aggregation - this reduces writes when there are
a lot of text generated via macro expansion.

added caching for UDN expressions and fixed ResolveCounter test class.

placeholders resolved from the function registry can now determine whether or
not they need to be filtered at runtime, if the function can be imported at
compile time. the can also indicate that they should be cached indefinitely
at the module level. additionally, if we can determine that a registered
function takes only a single literal argument, we can cache it indefinitely
since the result should be the same for every execution.

added minimal recursive dependency analysis - this tries to figure out which
placeholders are actually calls to template functions and uses that to optimize
the resolution, calling and filtering.


0.7 - 2008-06-03
this is a fairly significant refactoring from the 0.6.x branch. the motivation
was encountering limits in the optimization strategies easily applied to
pseudo-code generated by the analyzer. most of that has been removed, so the
AST and semantic analyzer are arguably more 'pure'.

more node types need support in codegen - so that is added. this means a few
optimizations like _buffer_write are actually manufactured and don't go through
the optimizer.

added a generic tree walker, which might eventually supplant all of the error
prone versions of walking a tree.

factored out some of the optimization techniques - like hoisting. added some
reasonable code to do dependency analysis for hoisted expressions which should
prevent referencing undefined values.

added caching of resolved and filtered placeholders.

fixed scope search with ForNode when you are optimizing something in the
expression list. 

added 'cache' argument to extended placholder syntax - this will cache the
output of the expression indefinitely

added #echo 'literal when true' if condition else 'literal when false'# - 
bascially yet another conditional inline statement. it is contingent on doing
output so it restricts it from being useful in places where it might be very
hard to read.


0.6.18 - 2008-05-29
added a function registry - functions that should be available to all
templates are resolved at compile time and accessed as globals, reducing a
couple of function calls. it is implemented with 'import ... as ...' statements
that are automatically injected by the compiler, after parsing. there is no
dependency on the target code base until the template is imported.

changed the grammar to be more forgiving of whitespace in #set directive

substantially refactored the test runner to reuse more of the compiler core
and commmand line arguments. fixed a number of issues with importing and 
improved the perfomance of the test suite by about 100%.


0.6.17 - 2008-05-24
found a bug in the optimizer due to some half-baked techniques in the IfNode.
the best fix is to disable this type of optimization (which I've done). the
code emitted is now functional, but not optimal.  I've added an exermintal
optimization type to -03 which uses a second pass over the optimized ast to 
hoist branch and look invariant aliases. this required a number of sensitive
changes to the 'scoping' code, especially with loops. overally, i think the
extra pass over the optimized ast keeps the code a little more simple, but it
still feels like it should not be necessary.

i added a number of new tests to check these optimizations. some of these are
currently expected to fail. added a bunch more debugging code to the testing 
front end script to make it easier to diagnose problems as they show up.


0.6.16 - 2008-03-18
changed the placeholder grammar and added a test case for a particularly
annoying ambiguity. it looks like it could be an error in either yapps2 or my
understanding of how yapps2 handles optional clauses.  the temporary fix is to
embed some python directly in the grammar to handle this case specially. there
is a detailed comment there and the original code for the grammar is left
commented out until such time as i can arrive at a satisfactory understanding
of the core problem.


0.6.15 - 2008-02-10
changed placeholder handling during the analysis/optimization/codegen process.
this more closely match how GetUDNNode works and it actually greatly simplifies
a few parts of the optimizer. overall a win and fixes a couple of subtle bugs.

fixed optimization for keyword argument values and literal tuples.  probably a
literal tuple in a template should not be encouraged, but it does have value.
added some tests for this as well naturally.

reimplement resolve_placeholder as a module function to make it as similar to
resolve_udn as possible. also fixed a slight performance regression in the
generated code for resolve_placeholder. 

fixed up get_var/has_var to be consistent with Cheetah and have a sane list of
arguments.


0.6.14 - 2008-02-02
reimplemented resolve_placeholder in few different ways to test and
improve performance. there is no clear winner in all cases, but the new default
should be much better in typical workloads.

added optional format_string argument to placeholders. this makes it convenient
to do numeric formatting using '%3.3f' etc.

fixed a bug which was mangling whitespace between adjacent placeholder using
the extended notation with {}. also changed the parens pattern so that
whitespace after a bare placeholder function call is preserved properly.

fixed division operator.

added a few new test cases to cover these bugs.

added a new optimization to locally cache references to resolved placeholders.
it's enabled by default, but it may not yield that much gain. a better
optimization would be caching references to complete UDN expressions.

fixed a nasty bug in the __eq__/__hash__ overrides in the ast module. this was
causing some optimized code to end up in funky locations.

added altenate BufferIO class for a very mild boost in performance. (< 10%)

implement has_var as get_var - perusing the code, it looked wrong in a few
cases. probably better to just tune up the implementation of
resolve_placeholder if we need more speed.

collapse redundant imports in the template module.

added support for builtin variables

added new Scope class to encapsulate optimization state - needed for tricky
situations in if/else blocks. also added an explicit ElseNode to represent the
source tree more accurately.

allow the "implements" keywork to override the ban on "main" methods when a
template inherits from another.

analyze the individual paramters of a placeholder - this allows placesholders
with args to run with the minimum overhead.

fixed the equivalence definition for the CallFunctionNode

added a new compiler option to enable the whitespace normalizer. hopefully this
proves to be useful. it is a slight hack the way it is activated right now.

added a new @skip_filter decorator so that various formatting functions,
presumably coded in python, can skip this filter if they are outputting html.
this is mostly just and added level of convenience in case typing "|raw" at the
of every placeholder is a pain. actually, specifying raw output is mildly
faster, especially in aggregate, so it may pay to not use this in the long run.

0.6.13 - added support for dictionary literals. corrected a bug in the
optimizer which caused it to miss direct access to local variables in some
cases. pruned some junk from the grammar file too.

0.6.12 - added individual filter overrides for placeholders.

0.6.11 - added placeholder substitution filtering. added #filter directive for
setting the default filter per template. fixed bug in optimizing the implied
main() method in a template. added decorator for template functions. the 
default filter is "safe_values" - meaning it will only print strings and
numbers - everthing else that might have a wacky string representation is
replaced by an empty string.

0.6.10 - fixed token position tracking for macros (slight edge case for
placeholders).  re-enabled simple placeholder syntax inside macros as
requiring ${} seemed a bit weak.

0.6.9 - implemented output directory option. added #absolute_extends for
accessing invariant classes. fixed broken setup script.

0.6.8 - restructure compiler front-end settings passing - it was dopey. moved
global macro registry to a property of the compiler. re-enabled macro args so
comments can be passed through the #i18n directive. added a number of new args
to the compiler script.

0.6.7 - added a compiler front-end to make it easier to pass through state and
settings to different phases of compilation. this should make it easier to
communicate variables to non-core functionality like macros.

0.6.6 - for the i18n macro, added token position tracking so it is possible to
jump to the original text of placeholder or other future nested directive. made
some errors tolerate unicode data (print really should just deal with this
when you set the default system encoding). split off the i18n macro handler
into its own file to mimic registering of future macro implementations and
reduce crazy cyclic imports.

0.6.5 - remove resolve_placeholder call for members of __builtin__ when the
optimizer is turned on. enable psyco on the compiler itself - yields about
25% boost. added a new rule to parse the limited contents of an #i18n block.
removed some stale lines from codegen.

0.6.4 - added restricted variable set for macros and easy accessor function to
turn literal args into a nice dictionary. fixed keyword argument parsing to
correctly accept multiple keywords args. fixed macros so that they result in a
new tree fragment rather than a template. standardized the comma delimiter to
fix a few parse errors.

0.6.3 - further optimized calls to resolve_placeholder via calculating
globals() in advance and removed spurious calls to locals().

0.6.2 - caved and added #set directive. added True and False as literals.
expanded optimizer to handle unary operators and placeholder substitutions.
added more cases to get_local_identifiers().

0.6.1 - initial support for macros. special macro case for i18n. needs more
fleshing out, but can more or less handle the naive use cases. operating theory
is that each translation will get its own compiled template.

0.6.0 - spitfire/sparrow parity


0.5.10 - renamed from 'sparrow' to 'spitfire' - i wonder if i can make it out
of 0.6 without another rename.

0.5.9 - added support for omit-tag. this required quite a bit of internal
restructuring and begins to show some of the limitations of stream-based
templates in a DOM-oriented world. it works, but it feels a little unclean.
tweaked some of the repeat code and added sketchy EatPrevious node to allow
ex-post-facto AST cleanup. this also feels unclean. this might be better
solved by making the dom parser look ahead 1 or 2 nodes to determine the
significance of whitespace. that's a bit more involved and depends on your
allegiance to xhtml and your notion of preserving whitespace.

0.5.8 - expressions for repeat/define/content/replace are now properly parsed
rather than hacked. added support for emulating TAL behavior when a repeat
node has no content/replacement/children. added py-define - not sure i like
the syntax - the dollar sign is not required for the assignment variable, but
i'm not sure that's really consistent.

0.5.7 - formalizing the xhtml parsing extensions. added very basic tests for
the current functionality. starting to work on precedence. altered parser to
allow a new production for py:define - not sure if i like it. there is a bug
in -O2 mode - I've disabled testing until that becomes important.

0.5.6 - added globals() resolution to resolve_placeholder. added list arg
analysis.

0.5.5 - continued on the optimization. analysis and optimization are now two
distinct operations. optimization occurs inline and modifies the tree
structure in place. to effectively optimize, i need to be able to crawl up the
tree to find out scope information. added the 'replace' function to simplify
altering the AST during optimization - only partially implemented.

0.5.4 - added more parse-to-abstract tree conversion. this means that little
nuggets of code that bridge the template content and the runtime get tricky to
express as a tree fragment. the goal is making the AST as AST-like as possible
before sending off the tree to the analyzer. the increasingly annoying part is
the amount of code required to 'visit' the tree properly. the next phase is to
separate out the parse tree conversion and the performance analysis and
optimization phases. the other annoying thing is the sheer number of node
copies made during this phase -- compile is a one-time operation, but it feels
like it's getting ridiculous. this emits some partially optimized code, and
although the tests pass, I wouldn't use it at the moment.

0.5.3 - share more code between the crunner and sparrow compile. rework the
code for handling dynamic template compile and loading. added a basic demo of
an attribute language like TAL or Kid. mostly proves that the AST can support
another syntax without much effort.

0.5.2 - implemented optional whitespace and adjacent text node collapsing in
the analyzer (instead of codegen). added corresponding tests for -01 mode.

0.5.1 - renamed from 'cheeter' to 'sparrow'

0.5 - reorganized all of the code as a proper package layout.


0.4.6 - added optional brace syntax for disambiguating complex placeholders.

0.4.5 - fix optional whitespace when single line directive syntax is used.
talking about the 1 line #if mostly. this required a fair amount of hacking on
the parser side of things, but it removed the hack during analysis - on
balance I think this is probably better. removed a bit of dead code hanging
out.

0.4.4 - fix optional whitespace bug following between a directive and comment.

0.4.3 - new testing for preserving and optional whitespace.

0.4.2 - added optional whitespace parsing. right now this is a nasty
combination of parser and semantic analysis stuff. the reason is that the end
directive parsing doesn't recursively scan for individual tokens. so, leading
whitespace before a directive start gets tagged in the parser, but if the last
child node in a directive is a whitespace node, we tag it as optional. the
know problem at this stage is that whitespace between # marks gets marked as
optional as well.

0.4.1 - trying to remove leading whitespace in directives on a newline.

0.4 - factor out a lot of code -- there is now one common node structure
between the parser and semantic analyzer. still kept the 'build 2 trees'
approach because it somewhat simplifies the analysis step, since nodes can
move. might have to change the node to know its parent. removed dopey
autowalk_child_nodes attribute in ASTNodes - if you want to walk the tree,
you've got to specify how in code.


0.3.12 - added #attr directive.

0.3.11 - improve support for unicode/utf-8. at this point, templates should be
in utf-8 only. no support for specifying the source encoding directive yet.
the output of a template is a unicode object. add support for break/continue
statements. added get_var/has_var functions which necessitated rewriting the
parsing of argument lists. compiler phase has to do more code injection to
support these functions, which is a little ugly.

0.3.10 - implement template inheritance. clean up from/import to actually
parse out and reconstruct statements. supports multiple inheritance with no
arbitration. the average case for multiple inheritance is using functions like
a library. i added support for '#implements library' which indicates that no
main function will be produced - only the functions explicitly defined in the
template will be generated. currently the syntax for multiple inheritance is
specifying multiple #extends directives.

0.3.9 - added proper recursive handling for udn, calling and item access in
function and placeholder context. it seems annoying that i need to chunks of
code to make this work - i should be able to factor out the common syntax.

0.3.8 - added item lookup ([] access to __getitem__). restructure some of the
optional whitespace handling inside for loops (might eventually be relevant
elsewhere too). Tricky because fundamentally python ignores whitespace, yet
cheeter respects it.

0.3.7 - removed the 'python expression' hack in the for block. i can now
properly parse out python lists and tuple literals, so this should be fine.
this also means i can properly use placeholders as the source for a loop.
unified some of the "parens" parsing. if you have two patterns that aren't
identical but can match the same piece of text, you end up misinterpreting
certain tokens. i will probably have to do this to brackets and commas as
well.

0.3.6 - add support for filling the search list from a python file or a
pickled object. added simple support of unified-dotted-notation - seems to
work for one level. retooled the crunner.py test rig - something funky about
exec'ing code in your own namespace. placeholder context switching
(text-to-placeholder) is still problematic from time to time. implementation
feels messy.

0.3.5 - added binary op support for math and comparisons. unary negation also
works.

0.3.4 - added if, else and elif directives. elif is cosmetically ugly - it
doesn't emit nice python - if you have a huge block of elif clauses, it will
nest fairly deeply, but it is functional.

0.3.3 - handle bare $$ situation

0.3.2 - added proper arg handling for function declaration and calling. fixed
basic literal handling - no complex types yet (dict, list, tuple)

0.3.1 - restructure function calling, placeholder parsing and substitution to
be more tree-like. started using a richer node structure modeled after
Python's AST node classes. having some struggle as to how much Python i really
want to be parseable in a template. erring on the side of less is probably
better. reduced complexity should be fine as long as the basic building blocks
are functional and reliable.

0.3 - first version using a tree-like python code generator instead of trying
to magically write code and keep track of indenting


0.2.3 - added placeholder substitution and proper expression unpacking

0.2.2 - added basic for loop

0.2 - added test case runner and a few simple template modifiers (import,
from, slurp)


0.1 - first working version - simple text, blocks and definitions
