@@ -27,32 +27,48 @@ use std::serialize::{Encodable, Decodable, Encoder, Decoder};
27
27
// macro expansion per Flatt et al., "Macros
28
28
// That Work Together"
29
29
#[ deriving( Eq ) ]
30
- pub struct ident { repr : Name }
30
+ pub struct ident { repr : Name , ctxt : SyntaxContext }
31
31
32
32
// a SyntaxContext represents a chain of macro-expandings
33
33
// and renamings. Each macro expansion corresponds to
34
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
+
35
50
#[ deriving( Eq ) ]
36
- pub enum SyntaxContext {
37
- MT ,
38
- Mark ( Mrk , ~SyntaxContext ) ,
39
- 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 )
40
65
}
41
66
42
- /*
43
- // ** this is going to have to apply to paths, not to idents.
44
- // Returns true if these two identifiers access the same
45
- // local binding or top-level binding... that's what it
46
- // should do. For now, it just compares the names.
47
- pub fn free_ident_eq (a : ident, b: ident) -> bool{
48
- a.repr == b.repr
49
- }
50
- */
51
- // a name represents a string, interned
52
- type Name = uint ;
67
+ // a name represents an identifier
68
+ pub type Name = uint ;
53
69
// a mark represents a unique id associated
54
70
// with a macro expansion
55
- type Mrk = uint ;
71
+ pub type Mrk = uint ;
56
72
57
73
impl < S : Encoder > Encodable < S > for ident {
58
74
fn encode( & self , s : & S ) {
@@ -1302,22 +1318,77 @@ pub enum inlined_item {
1302
1318
ii_dtor( struct_dtor, ident, Generics , def_id /* parent id */ )
1303
1319
}
1304
1320
1321
+ /* hold off on tests ... they appear in a later merge.
1305
1322
#[cfg(test)]
1306
1323
mod test {
1307
- //are asts encodable?
1308
-
1309
- // it looks like this *will* be a compiler bug, after
1310
- // I get deriving_eq for crates into incoming :)
1311
- /*
1324
+ use core::option::{None, Option, Some};
1325
+ use core::uint;
1312
1326
use std;
1313
1327
use codemap::*;
1314
1328
use super::*;
1315
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?
1316
1387
#[test] fn check_asts_encodable() {
1317
1388
let bogus_span = span {lo:BytePos(10),
1318
1389
hi:BytePos(20),
1319
1390
expn_info:None};
1320
- let _e : crate =
1391
+ let e : crate =
1321
1392
spanned{
1322
1393
node: crate_{
1323
1394
module: _mod {view_items: ~[], items: ~[]},
@@ -1326,10 +1397,13 @@ mod test {
1326
1397
},
1327
1398
span: bogus_span};
1328
1399
// doesn't matter which encoder we use....
1329
- let _f = (_e as std::serialize::Encodable:: <std::json::Encoder>);
1400
+ let _f = (@e as @ std::serialize::Encodable<std::json::Encoder>);
1330
1401
}
1331
- */
1402
+
1403
+
1332
1404
}
1405
+
1406
+ */
1333
1407
//
1334
1408
// Local Variables:
1335
1409
// mode: rust
0 commit comments