|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r55908 - in trunk/tools/quickbook: detail doc test
From: daniel_james_at_[hidden]
Date: 2009-08-31 07:36:48
Author: danieljames
Date: 2009-08-31 07:36:47 EDT (Mon, 31 Aug 2009)
New Revision: 55908
URL: http://svn.boost.org/trac/boost/changeset/55908
Log:
Implement static/lexical scoping for 1.5. Refs #2034.
Added:
trunk/tools/quickbook/test/fail-template-lookup1.quickbook (contents, props changed)
trunk/tools/quickbook/test/templates_1_5.gold (contents, props changed)
trunk/tools/quickbook/test/templates_1_5.quickbook (contents, props changed)
Text files modified:
trunk/tools/quickbook/detail/actions.cpp | 28 ++++++++++++++++++++++++----
trunk/tools/quickbook/detail/template_stack.cpp | 22 +++++++++++++++++++---
trunk/tools/quickbook/detail/template_stack.hpp | 30 +++++++++++++++++++++++++-----
trunk/tools/quickbook/doc/quickbook.qbk | 1 +
trunk/tools/quickbook/test/Jamfile.v2 | 2 ++
trunk/tools/quickbook/test/templates_1_4.quickbook | 2 +-
6 files changed, 72 insertions(+), 13 deletions(-)
Modified: trunk/tools/quickbook/detail/actions.cpp
==============================================================================
--- trunk/tools/quickbook/detail/actions.cpp (original)
+++ trunk/tools/quickbook/detail/actions.cpp 2009-08-31 07:36:47 EDT (Mon, 31 Aug 2009)
@@ -512,7 +512,7 @@
actions.template_info.push_back(std::string(first, last));
actions.templates.add(
actions.template_info[0]
- , boost::make_tuple(actions.template_info, first.get_position()));
+ , template_symbol(actions.template_info, first.get_position()));
actions.template_info.clear();
}
@@ -565,6 +565,7 @@
get_arguments(
std::vector<std::string>& template_info
, std::vector<std::string> const& template_
+ , template_scope const& scope
, boost::spirit::classic::file_position const& pos
, quickbook::actions& actions
)
@@ -578,7 +579,7 @@
std::vector<std::string> tinfo;
tinfo.push_back(*tpl);
tinfo.push_back(*arg);
- template_symbol template_(tinfo, pos);
+ template_symbol template_(tinfo, pos, &scope);
if (actions.templates.find_top_scope(*tpl))
{
@@ -665,6 +666,17 @@
return;
}
+ // The template arguments should have the scope that the template was
+ // called from, not the template's own scope.
+ //
+ // Note that for quickbook 1.4- this value is just ignored when the
+ // arguments are expanded.
+ template_scope const& call_scope = actions.templates.top_scope();
+
+ template_symbol const* symbol =
+ actions.templates.find(actions.template_info[0]);
+ BOOST_ASSERT(symbol);
+
std::string result;
actions.push(); // scope the actions' states
{
@@ -672,6 +684,13 @@
actions.templates.find(actions.template_info[0]);
BOOST_ASSERT(symbol);
+ // Quickbook 1.4-: When expanding the tempalte continue to use the
+ // current scope (the dynamic scope).
+ // Quickbook 1.5+: Use the scope the template was defined in
+ // (the static scope).
+ if (qbk_version_n >= 105)
+ actions.templates.set_parent_scope(*boost::get<2>(*symbol));
+
std::vector<std::string> template_ = boost::get<0>(*symbol);
boost::spirit::classic::file_position template_pos = boost::get<1>(*symbol);
@@ -693,7 +712,8 @@
bool get_arg_result;
std::vector<std::string>::const_iterator tpl;
boost::tie(get_arg_result, tpl) =
- get_arguments(template_info, template_, pos, actions);
+ get_arguments(template_info, template_,
+ call_scope, pos, actions);
if (!get_arg_result)
{
@@ -1069,7 +1089,7 @@
std::vector<std::string> tinfo;
tinfo.push_back(id);
tinfo.push_back(snippet);
- storage.push_back(boost::make_tuple(tinfo, first.get_position()));
+ storage.push_back(template_symbol(tinfo, first.get_position()));
callout_id += callouts.size();
callouts.clear();
Modified: trunk/tools/quickbook/detail/template_stack.cpp
==============================================================================
--- trunk/tools/quickbook/detail/template_stack.cpp (original)
+++ trunk/tools/quickbook/detail/template_stack.cpp 2009-08-31 07:36:47 EDT (Mon, 31 Aug 2009)
@@ -23,7 +23,7 @@
template_symbol* template_stack::find(std::string const& symbol) const
{
- for (deque::const_iterator i = scopes.begin(); i != scopes.end(); ++i)
+ for (template_scope const* i = &*scopes.begin(); i; i = i->parent_scope)
{
if (template_symbol* ts = boost::spirit::classic::find(i->symbols, symbol.c_str()))
return ts;
@@ -41,22 +41,38 @@
BOOST_ASSERT(!scopes.empty());
return scopes.front().symbols;
}
+
+ template_scope const& template_stack::top_scope() const
+ {
+ BOOST_ASSERT(!scopes.empty());
+ return scopes.front();
+ }
+ // TODO: Should symbols defined by '[import]' use the current scope?
void template_stack::add(std::string const& symbol, template_symbol const& ts)
{
BOOST_ASSERT(!scopes.empty());
- boost::spirit::classic::add(scopes.front().symbols, symbol.c_str(), ts);
- }
+ boost::spirit::classic::add(scopes.front().symbols, symbol.c_str(),
+ boost::get<2>(ts) ? ts :
+ template_symbol(boost::get<0>(ts), boost::get<1>(ts), &top_scope()));
+ }
void template_stack::push()
{
+ template_scope const& old_front = scopes.front();
scopes.push_front(template_scope());
+ set_parent_scope(old_front);
}
void template_stack::pop()
{
scopes.pop_front();
}
+
+ void template_stack::set_parent_scope(template_scope const& parent)
+ {
+ scopes.front().parent_scope = &parent;
+ }
}
Modified: trunk/tools/quickbook/detail/template_stack.hpp
==============================================================================
--- trunk/tools/quickbook/detail/template_stack.hpp (original)
+++ trunk/tools/quickbook/detail/template_stack.hpp 2009-08-31 07:36:47 EDT (Mon, 31 Aug 2009)
@@ -21,6 +21,8 @@
namespace quickbook
{
+ struct template_scope;
+
// template symbols with N arguments are stored as follows:
//
// vector<std::string>
@@ -28,21 +30,34 @@
// 1: template param name[0]
// 2: template param name[1]
// ...
- // template param name[N]
- // template body
// N: template param name[N-1]
// N+1: template body
// file position
+ // template scope (only used for 1.5+, 1.4- uses the dynamic scope)
typedef boost::tuple<
std::vector<std::string>
- , boost::spirit::classic::file_position>
+ , boost::spirit::classic::file_position
+ , template_scope const*>
template_symbol;
typedef boost::spirit::classic::symbols<template_symbol> template_symbols;
+ // template scope
+ //
+ // 1.4-: parent_scope is the previous scope on the stack
+ // (the template's dynamic parent).
+ // 1.5+: parent_scope is the template's lexical parent.
+ //
+ // This means that a search along the parent_scope chain will follow the
+ // correct lookup chain for that version of quickboook.
+ //
+ // symbols contains the templates defined in this scope.
+
struct template_scope
{
+ template_scope() : parent_scope() {}
+ template_scope const* parent_scope;
template_symbols symbols;
};
@@ -64,8 +79,7 @@
// search all scopes for the longest matching symbol.
typename Scanner::iterator_t f = scan.first;
std::ptrdiff_t len = -1;
- for (template_stack::deque::const_iterator i = ts.scopes.begin();
- i != ts.scopes.end(); ++i)
+ for (template_scope const* i = &*ts.scopes.begin(); i; i = i->parent_scope)
{
boost::spirit::classic::match<> m = i->symbols.parse(scan);
if (m.length() > len)
@@ -84,10 +98,16 @@
template_symbol* find(std::string const& symbol) const;
template_symbol* find_top_scope(std::string const& symbol) const;
template_symbols const& top() const;
+ template_scope const& top_scope() const;
+ // Add the given template symbol to the current scope.
+ // If it doesn't have a scope, sets the symbol's scope to the current scope.
void add(std::string const& symbol, template_symbol const& ts);
void push();
void pop();
+ // Set the current scope's parent.
+ void set_parent_scope(template_scope const&);
+
boost::spirit::classic::functor_parser<parser> scope;
private:
Modified: trunk/tools/quickbook/doc/quickbook.qbk
==============================================================================
--- trunk/tools/quickbook/doc/quickbook.qbk (original)
+++ trunk/tools/quickbook/doc/quickbook.qbk 2009-08-31 07:36:47 EDT (Mon, 31 Aug 2009)
@@ -176,6 +176,7 @@
* Improved handling of unmatched escape in code blocks.
* Support for python snippets.
* `teletype` source mode.
+* Use static scoping in templates, should be a lot more intuitive.
[endsect]
Modified: trunk/tools/quickbook/test/Jamfile.v2
==============================================================================
--- trunk/tools/quickbook/test/Jamfile.v2 (original)
+++ trunk/tools/quickbook/test/Jamfile.v2 2009-08-31 07:36:47 EDT (Mon, 31 Aug 2009)
@@ -22,6 +22,7 @@
[ quickbook-test escape ]
[ quickbook-test templates ]
[ quickbook-test templates_1_4 ]
+ [ quickbook-test templates_1_5 ]
[ quickbook-test xinclude ]
[ quickbook-test import ]
[ quickbook-fail-test fail-include ]
@@ -33,6 +34,7 @@
[ quickbook-fail-test fail-post-process ]
[ quickbook-fail-test fail-parse-error1 ]
[ quickbook-fail-test fail-parse-error2 ]
+ [ quickbook-fail-test fail-template-lookup1 ]
;
Added: trunk/tools/quickbook/test/fail-template-lookup1.quickbook
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/fail-template-lookup1.quickbook 2009-08-31 07:36:47 EDT (Mon, 31 Aug 2009)
@@ -0,0 +1,7 @@
+[article Fail Template Lookup 1
+ [quickbook 1.5]
+]
+
+[template test1[] [a]]
+[template test2[a] [test1]]
+[test2 1]
\ No newline at end of file
Modified: trunk/tools/quickbook/test/templates_1_4.quickbook
==============================================================================
--- trunk/tools/quickbook/test/templates_1_4.quickbook (original)
+++ trunk/tools/quickbook/test/templates_1_4.quickbook 2009-08-31 07:36:47 EDT (Mon, 31 Aug 2009)
@@ -13,4 +13,4 @@
[template y new]
[template foo3[a y] [a]]
-[foo3 [y] old]
\ No newline at end of file
+[foo3 [y] old]
Added: trunk/tools/quickbook/test/templates_1_5.gold
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/templates_1_5.gold 2009-08-31 07:36:47 EDT (Mon, 31 Aug 2009)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+<article id="template_1_5" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>Template 1.5</title>
+ <articleinfo>
+ </articleinfo>
+ <para>
+ static scoping
+ </para>
+ <para>
+ new
+ </para>
+ <para>
+ foo foo
+ </para>
+</article>
Added: trunk/tools/quickbook/test/templates_1_5.quickbook
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/templates_1_5.quickbook 2009-08-31 07:36:47 EDT (Mon, 31 Aug 2009)
@@ -0,0 +1,23 @@
+[article Template 1.5
+ [quickbook 1.5]
+]
+
+[/ 1.5 uses static scoping ]
+
+[template x static scoping]
+[template foo1[] [x]]
+[template foo2[x] [foo1]]
+[foo2 dynamic scoping]
+
+[/ In 1.5 template arguments are scoped at the point they are defined]
+
+[template y new]
+[template foo3[a y] [a]]
+[foo3 [y] old]
+
+[/ From https://svn.boost.org/trac/boost/ticket/2034 ]
+
+[template same[x] [x]]
+[template echo[a b] [a] [b]]
+[template echo_twice[x] [echo [same [x]]..[same [x]]]]
+[echo_twice foo]
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk