@@ -22,45 +22,53 @@ use core::to_str::ToStr;
22
22
use std:: serialize:: { Encodable , Decodable , Encoder , Decoder } ;
23
23
24
24
25
- /* can't import macros yet, so this is copied from token.rs. See its comment
26
- * there. */
27
- macro_rules! interner_key (
28
- ( ) => ( cast:: transmute:: <( uint, uint) ,
29
- & fn ( +v: @@:: parse:: token:: ident_interner) >(
30
- ( -3 as uint, 0 u) ) )
31
- )
32
-
33
25
// an identifier contains an index into the interner
34
26
// table and a SyntaxContext to track renaming and
35
27
// macro expansion per Flatt et al., "Macros
36
28
// That Work Together"
37
29
#[ deriving( Eq ) ]
38
- pub struct ident { repr : Name }
30
+ pub struct ident { repr : Name , ctxt : SyntaxContext }
39
31
40
32
// a SyntaxContext represents a chain of macro-expandings
41
33
// and renamings. Each macro expansion corresponds to
42
34
// a fresh uint
35
+
36
+ // I'm representing this syntax context as an index into
37
+ // a table, in order to work around a compiler bug
38
+ // that's causing unreleased memory to cause core dumps
39
+ // and also perhaps to save some work in destructor checks.
40
+ // the special uint '0' will be used to indicate an empty
41
+ // syntax context
42
+
43
+ // this uint is a reference to a table stored in thread-local
44
+ // storage.
45
+ pub type SyntaxContext = uint ;
46
+
47
+ pub type SCTable = ~[ SyntaxContext_ ] ;
48
+ pub static empty_ctxt : uint = 0 ;
49
+
43
50
#[ deriving( Eq ) ]
44
- pub enum SyntaxContext {
45
- MT ,
46
- Mark ( Mrk , ~SyntaxContext ) ,
47
- Rename ( ~ident, Name , ~SyntaxContext )
51
+ #[ auto_encode]
52
+ #[ auto_decode]
53
+ pub enum SyntaxContext_ {
54
+ EmptyCtxt ,
55
+ Mark ( Mrk , SyntaxContext ) ,
56
+ // flattening the name and syntaxcontext into the rename...
57
+ // HIDDEN INVARIANTS:
58
+ // 1) the first name in a Rename node
59
+ // can only be a programmer-supplied name.
60
+ // 2) Every Rename node with a given Name in the
61
+ // "to" slot must have the same name and context
62
+ // in the "from" slot. In essence, they're all
63
+ // pointers to a single "rename" event node.
64
+ Rename ( ident , Name , SyntaxContext )
48
65
}
49
66
50
- /*
51
- // ** this is going to have to apply to paths, not to idents.
52
- // Returns true if these two identifiers access the same
53
- // local binding or top-level binding... that's what it
54
- // should do. For now, it just compares the names.
55
- pub fn free_ident_eq (a : ident, b: ident) -> bool{
56
- a.repr == b.repr
57
- }
58
- */
59
- // a name represents a string, interned
60
- type Name = uint ;
67
+ // a name represents an identifier
68
+ pub type Name = uint ;
61
69
// a mark represents a unique id associated
62
70
// with a macro expansion
63
- type Mrk = uint ;
71
+ pub type Mrk = uint ;
64
72
65
73
impl < S : Encoder > Encodable < S > for ident {
66
74
fn encode( & self , s : & S ) {
@@ -1310,22 +1318,77 @@ pub enum inlined_item {
1310
1318
ii_dtor( struct_dtor, ident, Generics , def_id /* parent id */ )
1311
1319
}
1312
1320
1321
+ /* hold off on tests ... they appear in a later merge.
1313
1322
#[cfg(test)]
1314
1323
mod test {
1315
- //are asts encodable?
1316
-
1317
- // it looks like this *will* be a compiler bug, after
1318
- // I get deriving_eq for crates into incoming :)
1319
- /*
1324
+ use core::option::{None, Option, Some};
1325
+ use core::uint;
1320
1326
use std;
1321
1327
use codemap::*;
1322
1328
use super::*;
1323
1329
1330
+
1331
+ #[test] fn xorpush_test () {
1332
+ let mut s = ~[];
1333
+ xorPush(&mut s,14);
1334
+ assert_eq!(s,~[14]);
1335
+ xorPush(&mut s,14);
1336
+ assert_eq!(s,~[]);
1337
+ xorPush(&mut s,14);
1338
+ assert_eq!(s,~[14]);
1339
+ xorPush(&mut s,15);
1340
+ assert_eq!(s,~[14,15]);
1341
+ xorPush (&mut s,16);
1342
+ assert_eq! (s,~[14,15,16]);
1343
+ xorPush (&mut s,16);
1344
+ assert_eq! (s,~[14,15]);
1345
+ xorPush (&mut s,15);
1346
+ assert_eq! (s,~[14]);
1347
+ }
1348
+
1349
+ #[test] fn test_marksof () {
1350
+ let stopname = uints_to_name(&~[12,14,78]);
1351
+ let name1 = uints_to_name(&~[4,9,7]);
1352
+ assert_eq!(marksof (MT,stopname),~[]);
1353
+ assert_eq! (marksof (Mark (4,@Mark(98,@MT)),stopname),~[4,98]);
1354
+ // does xoring work?
1355
+ assert_eq! (marksof (Mark (5, @Mark (5, @Mark (16,@MT))),stopname),
1356
+ ~[16]);
1357
+ // does nested xoring work?
1358
+ assert_eq! (marksof (Mark (5,
1359
+ @Mark (10,
1360
+ @Mark (10,
1361
+ @Mark (5,
1362
+ @Mark (16,@MT))))),
1363
+ stopname),
1364
+ ~[16]);
1365
+ // stop has no effect on marks
1366
+ assert_eq! (marksof (Mark (9, @Mark (14, @Mark (12, @MT))),stopname),
1367
+ ~[9,14,12]);
1368
+ // rename where stop doesn't match:
1369
+ assert_eq! (marksof (Mark (9, @Rename
1370
+ (name1,
1371
+ @Mark (4, @MT),
1372
+ uints_to_name(&~[100,101,102]),
1373
+ @Mark (14, @MT))),
1374
+ stopname),
1375
+ ~[9,14]);
1376
+ // rename where stop does match
1377
+ ;
1378
+ assert_eq! (marksof (Mark(9, @Rename (name1,
1379
+ @Mark (4, @MT),
1380
+ stopname,
1381
+ @Mark (14, @MT))),
1382
+ stopname),
1383
+ ~[9]);
1384
+ }
1385
+
1386
+ // are ASTs encodable?
1324
1387
#[test] fn check_asts_encodable() {
1325
1388
let bogus_span = span {lo:BytePos(10),
1326
1389
hi:BytePos(20),
1327
1390
expn_info:None};
1328
- let _e : crate =
1391
+ let e : crate =
1329
1392
spanned{
1330
1393
node: crate_{
1331
1394
module: _mod {view_items: ~[], items: ~[]},
@@ -1334,10 +1397,13 @@ mod test {
1334
1397
},
1335
1398
span: bogus_span};
1336
1399
// doesn't matter which encoder we use....
1337
- let _f = (_e as std::serialize::Encodable:: <std::json::Encoder>);
1400
+ let _f = (@e as @ std::serialize::Encodable<std::json::Encoder>);
1338
1401
}
1339
- */
1402
+
1403
+
1340
1404
}
1405
+
1406
+ */
1341
1407
//
1342
1408
// Local Variables:
1343
1409
// mode: rust
0 commit comments