Skip to content

Commit ecb8e5f

Browse files
committed
---
yaml --- r: 73726 b: refs/heads/dist-snap c: d7638f9 h: refs/heads/master v: v3
1 parent cb53318 commit ecb8e5f

File tree

6 files changed

+167
-129
lines changed

6 files changed

+167
-129
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
99
refs/heads/incoming: b50030718cf28f2a5a81857a26b57442734fe854
10-
refs/heads/dist-snap: 77c2c0900f975e1fa9179c3e7492d62656734295
10+
refs/heads/dist-snap: d7638f9dba5cef5c4db7b9008196ede4450d8521
1111
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1212
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1313
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/src/libsyntax/ext/base.rs

Lines changed: 83 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@
1111
use core::prelude::*;
1212

1313
use ast;
14+
use ast::Name;
1415
use codemap;
1516
use codemap::{CodeMap, span, ExpnInfo, ExpandedFrom};
1617
use codemap::CallInfo;
1718
use diagnostic::span_handler;
1819
use ext;
1920
use parse;
2021
use parse::token;
22+
use parse::token::{intern};
2123

2224
use core::hashmap::HashMap;
2325
use core::vec;
@@ -91,29 +93,33 @@ pub enum SyntaxExtension {
9193
IdentTT(SyntaxExpanderTTItem),
9294
}
9395

96+
// The SyntaxEnv is the environment that's threaded through the expansion
97+
// of macros. It contains bindings for macros, and also a special binding
98+
// for " block" (not a legal identifier) that maps to a BlockInfo
9499
pub type SyntaxEnv = @mut MapChain<Name, Transformer>;
95100

96-
// Name : the domain of SyntaxEnvs
97-
// want to change these to uints....
98-
// note that we use certain strings that are not legal as identifiers
99-
// to indicate, for instance, how blocks are supposed to behave.
100-
type Name = @~str;
101-
102101
// Transformer : the codomain of SyntaxEnvs
103102

104-
// NB: it may seem crazy to lump both of these into one environment;
105-
// what would it mean to bind "foo" to BlockLimit(true)? The idea
106-
// is that this follows the lead of MTWT, and accommodates growth
107-
// toward a more uniform syntax syntax (sorry) where blocks are just
108-
// another kind of transformer.
109-
110103
pub enum Transformer {
111104
// this identifier maps to a syntax extension or macro
112105
SE(SyntaxExtension),
113-
// should blocks occurring here limit macro scopes?
114-
ScopeMacros(bool)
106+
// blockinfo : this is ... well, it's simpler than threading
107+
// another whole data stack-structured data structure through
108+
// expansion. Basically, there's an invariant that every
109+
// map must contain a binding for " block".
110+
BlockInfo(BlockInfo)
111+
}
112+
113+
pub struct BlockInfo {
114+
// should macros escape from this scope?
115+
macros_escape : bool,
116+
// what are the pending renames?
117+
pending_renames : @mut RenameList
115118
}
116119

120+
// a list of ident->name renamings
121+
type RenameList = ~[(ast::ident,Name)];
122+
117123
// The base map of methods for expanding syntax extension
118124
// AST nodes into full ASTs
119125
pub fn syntax_expander_table() -> SyntaxEnv {
@@ -127,77 +133,80 @@ pub fn syntax_expander_table() -> SyntaxEnv {
127133
}
128134
let mut syntax_expanders = HashMap::new();
129135
// NB identifier starts with space, and can't conflict with legal idents
130-
syntax_expanders.insert(@~" block",
131-
@ScopeMacros(true));
132-
syntax_expanders.insert(@~"macro_rules",
136+
syntax_expanders.insert(intern(&" block"),
137+
@BlockInfo(BlockInfo{
138+
macros_escape : false,
139+
pending_renames : @mut ~[]
140+
}));
141+
syntax_expanders.insert(intern(&"macro_rules"),
133142
builtin_item_tt(
134143
ext::tt::macro_rules::add_new_extension));
135-
syntax_expanders.insert(@~"fmt",
144+
syntax_expanders.insert(intern(&"fmt"),
136145
builtin_normal_tt(ext::fmt::expand_syntax_ext));
137146
syntax_expanders.insert(
138-
@~"auto_encode",
147+
intern(&"auto_encode"),
139148
@SE(ItemDecorator(ext::auto_encode::expand_auto_encode)));
140149
syntax_expanders.insert(
141-
@~"auto_decode",
150+
intern(&"auto_decode"),
142151
@SE(ItemDecorator(ext::auto_encode::expand_auto_decode)));
143-
syntax_expanders.insert(@~"env",
152+
syntax_expanders.insert(intern(&"env"),
144153
builtin_normal_tt(ext::env::expand_syntax_ext));
145-
syntax_expanders.insert(@~"bytes",
154+
syntax_expanders.insert(intern("bytes"),
146155
builtin_normal_tt(ext::bytes::expand_syntax_ext));
147-
syntax_expanders.insert(@~"concat_idents",
156+
syntax_expanders.insert(intern("concat_idents"),
148157
builtin_normal_tt(
149158
ext::concat_idents::expand_syntax_ext));
150-
syntax_expanders.insert(@~"log_syntax",
159+
syntax_expanders.insert(intern(&"log_syntax"),
151160
builtin_normal_tt(
152161
ext::log_syntax::expand_syntax_ext));
153-
syntax_expanders.insert(@~"deriving",
162+
syntax_expanders.insert(intern(&"deriving"),
154163
@SE(ItemDecorator(
155164
ext::deriving::expand_meta_deriving)));
156165

157166
// Quasi-quoting expanders
158-
syntax_expanders.insert(@~"quote_tokens",
167+
syntax_expanders.insert(intern(&"quote_tokens"),
159168
builtin_normal_tt(ext::quote::expand_quote_tokens));
160-
syntax_expanders.insert(@~"quote_expr",
169+
syntax_expanders.insert(intern(&"quote_expr"),
161170
builtin_normal_tt(ext::quote::expand_quote_expr));
162-
syntax_expanders.insert(@~"quote_ty",
171+
syntax_expanders.insert(intern(&"quote_ty"),
163172
builtin_normal_tt(ext::quote::expand_quote_ty));
164-
syntax_expanders.insert(@~"quote_item",
173+
syntax_expanders.insert(intern(&"quote_item"),
165174
builtin_normal_tt(ext::quote::expand_quote_item));
166-
syntax_expanders.insert(@~"quote_pat",
175+
syntax_expanders.insert(intern(&"quote_pat"),
167176
builtin_normal_tt(ext::quote::expand_quote_pat));
168-
syntax_expanders.insert(@~"quote_stmt",
177+
syntax_expanders.insert(intern(&"quote_stmt"),
169178
builtin_normal_tt(ext::quote::expand_quote_stmt));
170179

171-
syntax_expanders.insert(@~"line",
180+
syntax_expanders.insert(intern(&"line"),
172181
builtin_normal_tt(
173182
ext::source_util::expand_line));
174-
syntax_expanders.insert(@~"col",
183+
syntax_expanders.insert(intern(&"col"),
175184
builtin_normal_tt(
176185
ext::source_util::expand_col));
177-
syntax_expanders.insert(@~"file",
186+
syntax_expanders.insert(intern(&"file"),
178187
builtin_normal_tt(
179188
ext::source_util::expand_file));
180-
syntax_expanders.insert(@~"stringify",
189+
syntax_expanders.insert(intern(&"stringify"),
181190
builtin_normal_tt(
182191
ext::source_util::expand_stringify));
183-
syntax_expanders.insert(@~"include",
192+
syntax_expanders.insert(intern(&"include"),
184193
builtin_normal_tt(
185194
ext::source_util::expand_include));
186-
syntax_expanders.insert(@~"include_str",
195+
syntax_expanders.insert(intern(&"include_str"),
187196
builtin_normal_tt(
188197
ext::source_util::expand_include_str));
189-
syntax_expanders.insert(@~"include_bin",
198+
syntax_expanders.insert(intern(&"include_bin"),
190199
builtin_normal_tt(
191200
ext::source_util::expand_include_bin));
192-
syntax_expanders.insert(@~"module_path",
201+
syntax_expanders.insert(intern(&"module_path"),
193202
builtin_normal_tt(
194203
ext::source_util::expand_mod));
195-
syntax_expanders.insert(@~"proto",
204+
syntax_expanders.insert(intern(&"proto"),
196205
builtin_item_tt(ext::pipes::expand_proto));
197-
syntax_expanders.insert(@~"asm",
206+
syntax_expanders.insert(intern(&"asm"),
198207
builtin_normal_tt(ext::asm::expand_asm));
199208
syntax_expanders.insert(
200-
@~"trace_macros",
209+
intern(&"trace_macros"),
201210
builtin_normal_tt(ext::trace_macros::expand_trace_macros));
202211
MapChain::new(~syntax_expanders)
203212
}
@@ -478,7 +487,39 @@ impl <K: Eq + Hash + IterBytes ,V: Copy> MapChain<K,V>{
478487
ConsMapChain (~ref mut map,_) => map.insert(key,ext)
479488
}
480489
}
490+
// insert the binding into the topmost frame for which the binding
491+
// associated with 'n' exists and satisfies pred
492+
// ... there are definitely some opportunities for abstraction
493+
// here that I'm ignoring. (e.g., manufacturing a predicate on
494+
// the maps in the chain, and using an abstract "find".
495+
fn insert_into_frame(&mut self, key: K, ext: @V, n: K, pred: &fn(&@V)->bool) {
496+
match *self {
497+
BaseMapChain (~ref mut map) => {
498+
if satisfies_pred(map,&n,pred) {
499+
map.insert(key,ext);
500+
} else {
501+
fail!(~"expected map chain containing satisfying frame")
502+
}
503+
},
504+
ConsMapChain (~ref mut map, rest) => {
505+
if satisfies_pred(map,&n,pred) {
506+
map.insert(key,ext);
507+
} else {
508+
rest.insert_into_frame(key,ext,n,pred)
509+
}
510+
}
511+
}
512+
}
513+
}
481514
515+
fn satisfies_pred<K : Eq + Hash + IterBytes,V>(map : &mut HashMap<K,V>,
516+
n: &K,
517+
pred: &fn(&V)->bool)
518+
-> bool {
519+
match map.find(n) {
520+
Some(ref v) => (pred(*v)),
521+
None => false
522+
}
482523
}
483524
484525
#[cfg(test)]

0 commit comments

Comments
 (0)