]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ast.rs
ba6fe1cda4f31b83eba478a36d0d186ab7f1d44c
[rust.git] / src / libsyntax / ast.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // The Rust abstract syntax tree.
12
13 use codemap::{span, spanned};
14 use abi::AbiSet;
15 use opt_vec::OptVec;
16
17 use core::cast;
18 use core::option::{None, Option, Some};
19 use core::task;
20 use core::to_bytes;
21 use core::to_str::ToStr;
22 use std::serialize::{Encodable, Decodable, Encoder, Decoder};
23
24
25 // an identifier contains an index into the interner
26 // table and a SyntaxContext to track renaming and
27 // macro expansion per Flatt et al., "Macros
28 // That Work Together"
29 #[deriving(Eq)]
30 pub struct ident { repr: Name, ctxt: SyntaxContext }
31
32 // a SyntaxContext represents a chain of macro-expandings
33 // and renamings. Each macro expansion corresponds to
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
50 #[deriving(Eq)]
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)
65 }
66
67 // a name represents an identifier
68 pub type Name = uint;
69 // a mark represents a unique id associated
70 // with a macro expansion
71 pub type Mrk = uint;
72
73 impl<S:Encoder> Encodable<S> for ident {
74     fn encode(&self, s: &S) {
75         let intr = match unsafe {
76             task::local_data::local_data_get(interner_key!())
77         } {
78             None => fail!(~"encode: TLS interner not set up"),
79             Some(intr) => intr
80         };
81
82         s.emit_str(*(*intr).get(*self));
83     }
84 }
85
86 impl<D:Decoder> Decodable<D> for ident {
87     fn decode(d: &D) -> ident {
88         let intr = match unsafe {
89             task::local_data::local_data_get(interner_key!())
90         } {
91             None => fail!(~"decode: TLS interner not set up"),
92             Some(intr) => intr
93         };
94
95         (*intr).intern(@d.read_str())
96     }
97 }
98
99 impl to_bytes::IterBytes for ident {
100     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
101         self.repr.iter_bytes(lsb0, f)
102     }
103 }
104
105 // Functions may or may not have names.
106 pub type fn_ident = Option<ident>;
107
108 #[auto_encode]
109 #[auto_decode]
110 #[deriving(Eq)]
111 pub struct Lifetime {
112     id: node_id,
113     span: span,
114     ident: ident
115 }
116
117 // a "Path" is essentially Rust's notion of a name;
118 // for instance: core::cmp::Eq  .  It's represented
119 // as a sequence of identifiers, along with a bunch
120 // of supporting information.
121 #[auto_encode]
122 #[auto_decode]
123 #[deriving(Eq)]
124 pub struct Path {
125     span: span,
126     global: bool,
127     idents: ~[ident],
128     rp: Option<@Lifetime>,
129     types: ~[@Ty],
130 }
131
132 pub type crate_num = int;
133
134 pub type node_id = int;
135
136 #[auto_encode]
137 #[auto_decode]
138 #[deriving(Eq)]
139 pub struct def_id {
140     crate: crate_num,
141     node: node_id,
142 }
143
144 pub static local_crate: crate_num = 0;
145 pub static crate_node_id: node_id = 0;
146
147 #[auto_encode]
148 #[auto_decode]
149 #[deriving(Eq)]
150 // The AST represents all type param bounds as types.
151 // typeck::collect::compute_bounds matches these against
152 // the "special" built-in traits (see middle::lang_items) and
153 // detects Copy, Send, Owned, and Const.
154 pub enum TyParamBound {
155     TraitTyParamBound(@trait_ref),
156     RegionTyParamBound
157 }
158
159 #[auto_encode]
160 #[auto_decode]
161 #[deriving(Eq)]
162 pub struct TyParam {
163     ident: ident,
164     id: node_id,
165     bounds: @OptVec<TyParamBound>
166 }
167
168 #[auto_encode]
169 #[auto_decode]
170 #[deriving(Eq)]
171 pub struct Generics {
172     lifetimes: OptVec<Lifetime>,
173     ty_params: OptVec<TyParam>
174 }
175
176 pub impl Generics {
177     fn is_parameterized(&self) -> bool {
178         self.lifetimes.len() + self.ty_params.len() > 0
179     }
180     fn is_lt_parameterized(&self) -> bool {
181         self.lifetimes.len() > 0
182     }
183     fn is_type_parameterized(&self) -> bool {
184         self.ty_params.len() > 0
185     }
186 }
187
188 #[auto_encode]
189 #[auto_decode]
190 #[deriving(Eq)]
191 pub enum def {
192     def_fn(def_id, purity),
193     def_static_method(/* method */ def_id,
194                       /* trait */  Option<def_id>,
195                       purity),
196     def_self(node_id, bool /* is_implicit */),
197     def_self_ty(/* trait id */ node_id),
198     def_mod(def_id),
199     def_foreign_mod(def_id),
200     def_const(def_id),
201     def_arg(node_id, bool /* is_mutbl */),
202     def_local(node_id, bool /* is_mutbl */),
203     def_variant(def_id /* enum */, def_id /* variant */),
204     def_ty(def_id),
205     def_trait(def_id),
206     def_prim_ty(prim_ty),
207     def_ty_param(def_id, uint),
208     def_binding(node_id, binding_mode),
209     def_use(def_id),
210     def_upvar(node_id,  // id of closed over var
211               @def,     // closed over def
212               node_id,  // expr node that creates the closure
213               node_id), // id for the block/body of the closure expr
214     def_struct(def_id),
215     def_typaram_binder(node_id), /* struct, impl or trait with ty params */
216     def_region(node_id),
217     def_label(node_id)
218 }
219
220
221 // The set of meta_items that define the compilation environment of the crate,
222 // used to drive conditional compilation
223 pub type crate_cfg = ~[@meta_item];
224
225 pub type crate = spanned<crate_>;
226
227 #[auto_encode]
228 #[auto_decode]
229 #[deriving(Eq)]
230 pub struct crate_ {
231     module: _mod,
232     attrs: ~[attribute],
233     config: crate_cfg,
234 }
235
236 pub type meta_item = spanned<meta_item_>;
237
238 #[auto_encode]
239 #[auto_decode]
240 #[deriving(Eq)]
241 pub enum meta_item_ {
242     meta_word(@~str),
243     meta_list(@~str, ~[@meta_item]),
244     meta_name_value(@~str, lit),
245 }
246
247 pub type blk = spanned<blk_>;
248
249 #[auto_encode]
250 #[auto_decode]
251 #[deriving(Eq)]
252 pub struct blk_ {
253     view_items: ~[@view_item],
254     stmts: ~[@stmt],
255     expr: Option<@expr>,
256     id: node_id,
257     rules: blk_check_mode,
258 }
259
260 #[auto_encode]
261 #[auto_decode]
262 #[deriving(Eq)]
263 pub struct pat {
264     id: node_id,
265     node: pat_,
266     span: span,
267 }
268
269 #[auto_encode]
270 #[auto_decode]
271 #[deriving(Eq)]
272 pub struct field_pat {
273     ident: ident,
274     pat: @pat,
275 }
276
277 #[auto_encode]
278 #[auto_decode]
279 #[deriving(Eq)]
280 pub enum binding_mode {
281     bind_by_copy,
282     bind_by_ref(mutability),
283     bind_infer
284 }
285
286 impl to_bytes::IterBytes for binding_mode {
287     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
288         match *self {
289           bind_by_copy => 0u8.iter_bytes(lsb0, f),
290
291           bind_by_ref(ref m) =>
292           to_bytes::iter_bytes_2(&1u8, m, lsb0, f),
293
294           bind_infer =>
295           2u8.iter_bytes(lsb0, f),
296         }
297     }
298 }
299
300 #[auto_encode]
301 #[auto_decode]
302 #[deriving(Eq)]
303 pub enum pat_ {
304     pat_wild,
305     // A pat_ident may either be a new bound variable,
306     // or a nullary enum (in which case the second field
307     // is None).
308     // In the nullary enum case, the parser can't determine
309     // which it is. The resolver determines this, and
310     // records this pattern's node_id in an auxiliary
311     // set (of "pat_idents that refer to nullary enums")
312     pat_ident(binding_mode, @Path, Option<@pat>),
313     pat_enum(@Path, Option<~[@pat]>), /* "none" means a * pattern where
314                                        * we don't bind the fields to names */
315     pat_struct(@Path, ~[field_pat], bool),
316     pat_tup(~[@pat]),
317     pat_box(@pat),
318     pat_uniq(@pat),
319     pat_region(@pat), // borrowed pointer pattern
320     pat_lit(@expr),
321     pat_range(@expr, @expr),
322     // [a, b, ..i, y, z] is represented as
323     // pat_vec(~[a, b], Some(i), ~[y, z])
324     pat_vec(~[@pat], Option<@pat>, ~[@pat])
325 }
326
327 #[auto_encode]
328 #[auto_decode]
329 #[deriving(Eq)]
330 pub enum mutability { m_mutbl, m_imm, m_const, }
331
332 impl to_bytes::IterBytes for mutability {
333     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
334         (*self as u8).iter_bytes(lsb0, f)
335     }
336 }
337
338 #[auto_encode]
339 #[auto_decode]
340 #[deriving(Eq)]
341 pub enum Sigil {
342     BorrowedSigil,
343     OwnedSigil,
344     ManagedSigil
345 }
346
347 impl to_bytes::IterBytes for Sigil {
348     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
349         (*self as uint).iter_bytes(lsb0, f)
350     }
351 }
352
353 impl ToStr for Sigil {
354     fn to_str(&self) -> ~str {
355         match *self {
356             BorrowedSigil => ~"&",
357             OwnedSigil => ~"~",
358             ManagedSigil => ~"@"
359          }
360     }
361 }
362
363 #[auto_encode]
364 #[auto_decode]
365 #[deriving(Eq)]
366 pub enum vstore {
367     // FIXME (#3469): Change uint to @expr (actually only constant exprs)
368     vstore_fixed(Option<uint>),     // [1,2,3,4]
369     vstore_uniq,                    // ~[1,2,3,4]
370     vstore_box,                     // @[1,2,3,4]
371     vstore_slice(Option<@Lifetime>) // &'foo? [1,2,3,4]
372 }
373
374 #[auto_encode]
375 #[auto_decode]
376 #[deriving(Eq)]
377 pub enum expr_vstore {
378     expr_vstore_uniq,                  // ~[1,2,3,4]
379     expr_vstore_box,                   // @[1,2,3,4]
380     expr_vstore_mut_box,               // @mut [1,2,3,4]
381     expr_vstore_slice,                 // &[1,2,3,4]
382     expr_vstore_mut_slice,             // &mut [1,2,3,4]
383 }
384
385 #[auto_encode]
386 #[auto_decode]
387 #[deriving(Eq)]
388 pub enum binop {
389     add,
390     subtract,
391     mul,
392     quot,
393     rem,
394     and,
395     or,
396     bitxor,
397     bitand,
398     bitor,
399     shl,
400     shr,
401     eq,
402     lt,
403     le,
404     ne,
405     ge,
406     gt,
407 }
408
409 #[auto_encode]
410 #[auto_decode]
411 #[deriving(Eq)]
412 pub enum unop {
413     box(mutability),
414     uniq(mutability),
415     deref,
416     not,
417     neg
418 }
419
420 pub type stmt = spanned<stmt_>;
421
422 #[auto_encode]
423 #[auto_decode]
424 #[deriving(Eq)]
425 pub enum stmt_ {
426     stmt_decl(@decl, node_id),
427
428     // expr without trailing semi-colon (must have unit type):
429     stmt_expr(@expr, node_id),
430
431     // expr with trailing semi-colon (may have any type):
432     stmt_semi(@expr, node_id),
433
434     // bool: is there a trailing sem-colon?
435     stmt_mac(mac, bool),
436 }
437
438 // FIXME (pending discussion of #1697, #2178...): local should really be
439 // a refinement on pat.
440 #[auto_encode]
441 #[auto_decode]
442 #[deriving(Eq)]
443 pub struct local_ {
444     is_mutbl: bool,
445     ty: @Ty,
446     pat: @pat,
447     init: Option<@expr>,
448     id: node_id,
449 }
450
451 pub type local = spanned<local_>;
452
453 pub type decl = spanned<decl_>;
454
455 #[auto_encode]
456 #[auto_decode]
457 #[deriving(Eq)]
458 pub enum decl_ { decl_local(~[@local]), decl_item(@item), }
459
460 #[auto_encode]
461 #[auto_decode]
462 #[deriving(Eq)]
463 pub struct arm {
464     pats: ~[@pat],
465     guard: Option<@expr>,
466     body: blk,
467 }
468
469 #[auto_encode]
470 #[auto_decode]
471 #[deriving(Eq)]
472 pub struct field_ {
473     mutbl: mutability,
474     ident: ident,
475     expr: @expr,
476 }
477
478 pub type field = spanned<field_>;
479
480 #[auto_encode]
481 #[auto_decode]
482 #[deriving(Eq)]
483 pub enum blk_check_mode { default_blk, unsafe_blk, }
484
485 #[auto_encode]
486 #[auto_decode]
487 #[deriving(Eq)]
488 pub struct expr {
489     id: node_id,
490     // Extra node ID is only used for index, assign_op, unary, binary, method
491     // call
492     callee_id: node_id,
493     node: expr_,
494     span: span,
495 }
496
497 #[auto_encode]
498 #[auto_decode]
499 #[deriving(Eq)]
500 pub enum CallSugar {
501     NoSugar,
502     DoSugar,
503     ForSugar
504 }
505
506 #[auto_encode]
507 #[auto_decode]
508 #[deriving(Eq)]
509 pub enum expr_ {
510     expr_vstore(@expr, expr_vstore),
511     expr_vec(~[@expr], mutability),
512     expr_call(@expr, ~[@expr], CallSugar),
513     expr_method_call(@expr, ident, ~[@Ty], ~[@expr], CallSugar),
514     expr_tup(~[@expr]),
515     expr_binary(binop, @expr, @expr),
516     expr_unary(unop, @expr),
517     expr_lit(@lit),
518     expr_cast(@expr, @Ty),
519     expr_if(@expr, blk, Option<@expr>),
520     expr_while(@expr, blk),
521     /* Conditionless loop (can be exited with break, cont, or ret)
522        Same semantics as while(true) { body }, but typestate knows that the
523        (implicit) condition is always true. */
524     expr_loop(blk, Option<ident>),
525     expr_match(@expr, ~[arm]),
526     expr_fn_block(fn_decl, blk),
527     // Inner expr is always an expr_fn_block. We need the wrapping node to
528     // easily type this (a function returning nil on the inside but bool on
529     // the outside).
530     expr_loop_body(@expr),
531     // Like expr_loop_body but for 'do' blocks
532     expr_do_body(@expr),
533     expr_block(blk),
534
535     expr_copy(@expr),
536     expr_assign(@expr, @expr),
537     expr_swap(@expr, @expr),
538     expr_assign_op(binop, @expr, @expr),
539     expr_field(@expr, ident, ~[@Ty]),
540     expr_index(@expr, @expr),
541     expr_path(@Path),
542     expr_addr_of(mutability, @expr),
543     expr_break(Option<ident>),
544     expr_again(Option<ident>),
545     expr_ret(Option<@expr>),
546     expr_log(@expr, @expr),
547
548     expr_inline_asm(inline_asm),
549
550     expr_mac(mac),
551
552     // A struct literal expression.
553     expr_struct(@Path, ~[field], Option<@expr>),
554
555     // A vector literal constructed from one repeated element.
556     expr_repeat(@expr /* element */, @expr /* count */, mutability),
557
558     // No-op: used solely so we can pretty-print faithfully
559     expr_paren(@expr)
560 }
561
562 // When the main rust parser encounters a syntax-extension invocation, it
563 // parses the arguments to the invocation as a token-tree. This is a very
564 // loose structure, such that all sorts of different AST-fragments can
565 // be passed to syntax extensions using a uniform type.
566 //
567 // If the syntax extension is an MBE macro, it will attempt to match its
568 // LHS "matchers" against the provided token tree, and if it finds a
569 // match, will transcribe the RHS token tree, splicing in any captured
570 // macro_parser::matched_nonterminals into the tt_nonterminals it finds.
571 //
572 // The RHS of an MBE macro is the only place a tt_nonterminal or tt_seq
573 // makes any real sense. You could write them elsewhere but nothing
574 // else knows what to do with them, so you'll probably get a syntax
575 // error.
576 //
577 #[auto_encode]
578 #[auto_decode]
579 #[deriving(Eq)]
580 #[doc="For macro invocations; parsing is delegated to the macro"]
581 pub enum token_tree {
582     // a single token
583     tt_tok(span, ::parse::token::Token),
584     // a delimited sequence (the delimiters appear as the first
585     // and last elements of the vector)
586     tt_delim(~[token_tree]),
587     // These only make sense for right-hand-sides of MBE macros:
588
589     // a kleene-style repetition sequence with a span, a tt_forest,
590     // an optional separator (?), and a boolean where true indicates
591     // zero or more (*), and false indicates one or more (+).
592     tt_seq(span, ~[token_tree], Option<::parse::token::Token>, bool),
593
594     // a syntactic variable that will be filled in by macro expansion.
595     tt_nonterminal(span, ident)
596 }
597
598 //
599 // Matchers are nodes defined-by and recognized-by the main rust parser and
600 // language, but they're only ever found inside syntax-extension invocations;
601 // indeed, the only thing that ever _activates_ the rules in the rust parser
602 // for parsing a matcher is a matcher looking for the 'matchers' nonterminal
603 // itself. Matchers represent a small sub-language for pattern-matching
604 // token-trees, and are thus primarily used by the macro-defining extension
605 // itself.
606 //
607 // match_tok
608 // ---------
609 //
610 //     A matcher that matches a single token, denoted by the token itself. So
611 //     long as there's no $ involved.
612 //
613 //
614 // match_seq
615 // ---------
616 //
617 //     A matcher that matches a sequence of sub-matchers, denoted various
618 //     possible ways:
619 //
620 //             $(M)*       zero or more Ms
621 //             $(M)+       one or more Ms
622 //             $(M),+      one or more comma-separated Ms
623 //             $(A B C);*  zero or more semi-separated 'A B C' seqs
624 //
625 //
626 // match_nonterminal
627 // -----------------
628 //
629 //     A matcher that matches one of a few interesting named rust
630 //     nonterminals, such as types, expressions, items, or raw token-trees. A
631 //     black-box matcher on expr, for example, binds an expr to a given ident,
632 //     and that ident can re-occur as an interpolation in the RHS of a
633 //     macro-by-example rule. For example:
634 //
635 //        $foo:expr   =>     1 + $foo    // interpolate an expr
636 //        $foo:tt     =>     $foo        // interpolate a token-tree
637 //        $foo:tt     =>     bar! $foo   // only other valid interpolation
638 //                                       // is in arg position for another
639 //                                       // macro
640 //
641 // As a final, horrifying aside, note that macro-by-example's input is
642 // also matched by one of these matchers. Holy self-referential! It is matched
643 // by an match_seq, specifically this one:
644 //
645 //                   $( $lhs:matchers => $rhs:tt );+
646 //
647 // If you understand that, you have closed to loop and understand the whole
648 // macro system. Congratulations.
649 //
650 pub type matcher = spanned<matcher_>;
651
652 #[auto_encode]
653 #[auto_decode]
654 #[deriving(Eq)]
655 pub enum matcher_ {
656     // match one token
657     match_tok(::parse::token::Token),
658     // match repetitions of a sequence: body, separator, zero ok?,
659     // lo, hi position-in-match-array used:
660     match_seq(~[matcher], Option<::parse::token::Token>, bool, uint, uint),
661     // parse a Rust NT: name to bind, name of NT, position in match array:
662     match_nonterminal(ident, ident, uint)
663 }
664
665 pub type mac = spanned<mac_>;
666
667 #[auto_encode]
668 #[auto_decode]
669 #[deriving(Eq)]
670 pub enum mac_ {
671     mac_invoc_tt(@Path,~[token_tree]),   // new macro-invocation
672 }
673
674 pub type lit = spanned<lit_>;
675
676 #[auto_encode]
677 #[auto_decode]
678 #[deriving(Eq)]
679 pub enum lit_ {
680     lit_str(@~str),
681     lit_int(i64, int_ty),
682     lit_uint(u64, uint_ty),
683     lit_int_unsuffixed(i64),
684     lit_float(@~str, float_ty),
685     lit_float_unsuffixed(@~str),
686     lit_nil,
687     lit_bool(bool),
688 }
689
690 // NB: If you change this, you'll probably want to change the corresponding
691 // type structure in middle/ty.rs as well.
692 #[auto_encode]
693 #[auto_decode]
694 #[deriving(Eq)]
695 pub struct mt {
696     ty: @Ty,
697     mutbl: mutability,
698 }
699
700 #[auto_encode]
701 #[auto_decode]
702 #[deriving(Eq)]
703 pub struct ty_field_ {
704     ident: ident,
705     mt: mt,
706 }
707
708 pub type ty_field = spanned<ty_field_>;
709
710 #[auto_encode]
711 #[auto_decode]
712 #[deriving(Eq)]
713 pub struct ty_method {
714     ident: ident,
715     attrs: ~[attribute],
716     purity: purity,
717     decl: fn_decl,
718     generics: Generics,
719     self_ty: self_ty,
720     id: node_id,
721     span: span,
722 }
723
724 #[auto_encode]
725 #[auto_decode]
726 #[deriving(Eq)]
727 // A trait method is either required (meaning it doesn't have an
728 // implementation, just a signature) or provided (meaning it has a default
729 // implementation).
730 pub enum trait_method {
731     required(ty_method),
732     provided(@method),
733 }
734
735 #[auto_encode]
736 #[auto_decode]
737 #[deriving(Eq)]
738 pub enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, }
739
740 impl ToStr for int_ty {
741     fn to_str(&self) -> ~str {
742         ::ast_util::int_ty_to_str(*self)
743     }
744 }
745
746 impl to_bytes::IterBytes for int_ty {
747     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
748         (*self as u8).iter_bytes(lsb0, f)
749     }
750 }
751
752 #[auto_encode]
753 #[auto_decode]
754 #[deriving(Eq)]
755 pub enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, }
756
757 impl ToStr for uint_ty {
758     fn to_str(&self) -> ~str {
759         ::ast_util::uint_ty_to_str(*self)
760     }
761 }
762
763 impl to_bytes::IterBytes for uint_ty {
764     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
765         (*self as u8).iter_bytes(lsb0, f)
766     }
767 }
768
769 #[auto_encode]
770 #[auto_decode]
771 #[deriving(Eq)]
772 pub enum float_ty { ty_f, ty_f32, ty_f64, }
773
774 impl ToStr for float_ty {
775     fn to_str(&self) -> ~str {
776         ::ast_util::float_ty_to_str(*self)
777     }
778 }
779
780 impl to_bytes::IterBytes for float_ty {
781     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
782         (*self as u8).iter_bytes(lsb0, f)
783     }
784 }
785
786 // NB Eq method appears below.
787 #[auto_encode]
788 #[auto_decode]
789 #[deriving(Eq)]
790 pub struct Ty {
791     id: node_id,
792     node: ty_,
793     span: span,
794 }
795
796 // Not represented directly in the AST, referred to by name through a ty_path.
797 #[auto_encode]
798 #[auto_decode]
799 #[deriving(Eq)]
800 pub enum prim_ty {
801     ty_int(int_ty),
802     ty_uint(uint_ty),
803     ty_float(float_ty),
804     ty_str,
805     ty_bool,
806 }
807
808 #[auto_encode]
809 #[auto_decode]
810 #[deriving(Eq)]
811 pub enum Onceness {
812     Once,
813     Many
814 }
815
816 impl ToStr for Onceness {
817     fn to_str(&self) -> ~str {
818         match *self {
819             Once => ~"once",
820             Many => ~"many"
821         }
822     }
823 }
824
825 impl to_bytes::IterBytes for Onceness {
826     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
827         (*self as uint).iter_bytes(lsb0, f);
828     }
829 }
830
831 #[auto_encode]
832 #[auto_decode]
833 #[deriving(Eq)]
834 pub struct TyClosure {
835     sigil: Sigil,
836     region: Option<@Lifetime>,
837     lifetimes: OptVec<Lifetime>,
838     purity: purity,
839     onceness: Onceness,
840     decl: fn_decl
841 }
842
843 #[auto_encode]
844 #[auto_decode]
845 #[deriving(Eq)]
846 pub struct TyBareFn {
847     purity: purity,
848     abis: AbiSet,
849     lifetimes: OptVec<Lifetime>,
850     decl: fn_decl
851 }
852
853 #[auto_encode]
854 #[auto_decode]
855 #[deriving(Eq)]
856 pub enum ty_ {
857     ty_nil,
858     ty_bot, /* bottom type */
859     ty_box(mt),
860     ty_uniq(mt),
861     ty_vec(mt),
862     ty_fixed_length_vec(mt, @expr),
863     ty_ptr(mt),
864     ty_rptr(Option<@Lifetime>, mt),
865     ty_closure(@TyClosure),
866     ty_bare_fn(@TyBareFn),
867     ty_tup(~[@Ty]),
868     ty_path(@Path, node_id),
869     ty_mac(mac),
870     // ty_infer means the type should be inferred instead of it having been
871     // specified. This should only appear at the "top level" of a type and not
872     // nested in one.
873     ty_infer,
874 }
875
876 impl to_bytes::IterBytes for Ty {
877     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
878         to_bytes::iter_bytes_2(&self.span.lo, &self.span.hi, lsb0, f);
879     }
880 }
881
882 #[auto_encode]
883 #[auto_decode]
884 #[deriving(Eq)]
885 pub enum asm_dialect {
886     asm_att,
887     asm_intel
888 }
889
890 #[auto_encode]
891 #[auto_decode]
892 #[deriving(Eq)]
893 pub struct inline_asm {
894     asm: @~str,
895     clobbers: @~str,
896     inputs: ~[(@~str, @expr)],
897     outputs: ~[(@~str, @expr)],
898     volatile: bool,
899     alignstack: bool,
900     dialect: asm_dialect
901 }
902
903 #[auto_encode]
904 #[auto_decode]
905 #[deriving(Eq)]
906 pub struct arg {
907     is_mutbl: bool,
908     ty: @Ty,
909     pat: @pat,
910     id: node_id,
911 }
912
913 #[auto_encode]
914 #[auto_decode]
915 #[deriving(Eq)]
916 pub struct fn_decl {
917     inputs: ~[arg],
918     output: @Ty,
919     cf: ret_style,
920 }
921
922 #[auto_encode]
923 #[auto_decode]
924 #[deriving(Eq)]
925 pub enum purity {
926     pure_fn, // declared with "pure fn"
927     unsafe_fn, // declared with "unsafe fn"
928     impure_fn, // declared with "fn"
929     extern_fn, // declared with "extern fn"
930 }
931
932 impl ToStr for purity {
933     fn to_str(&self) -> ~str {
934         match *self {
935             impure_fn => ~"impure",
936             unsafe_fn => ~"unsafe",
937             pure_fn => ~"pure",
938             extern_fn => ~"extern"
939         }
940     }
941 }
942
943 impl to_bytes::IterBytes for purity {
944     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
945         (*self as u8).iter_bytes(lsb0, f)
946     }
947 }
948
949 #[auto_encode]
950 #[auto_decode]
951 #[deriving(Eq)]
952 pub enum ret_style {
953     noreturn, // functions with return type _|_ that always
954               // raise an error or exit (i.e. never return to the caller)
955     return_val, // everything else
956 }
957
958 impl to_bytes::IterBytes for ret_style {
959     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
960         (*self as u8).iter_bytes(lsb0, f)
961     }
962 }
963
964 #[auto_encode]
965 #[auto_decode]
966 #[deriving(Eq)]
967 pub enum self_ty_ {
968     sty_static,                                // no self
969     sty_value,                                 // `self`
970     sty_region(Option<@Lifetime>, mutability), // `&'lt self`
971     sty_box(mutability),                       // `@self`
972     sty_uniq(mutability)                       // `~self`
973 }
974
975 pub type self_ty = spanned<self_ty_>;
976
977 #[auto_encode]
978 #[auto_decode]
979 #[deriving(Eq)]
980 pub struct method {
981     ident: ident,
982     attrs: ~[attribute],
983     generics: Generics,
984     self_ty: self_ty,
985     purity: purity,
986     decl: fn_decl,
987     body: blk,
988     id: node_id,
989     span: span,
990     self_id: node_id,
991     vis: visibility,
992 }
993
994 #[auto_encode]
995 #[auto_decode]
996 #[deriving(Eq)]
997 pub struct _mod {
998     view_items: ~[@view_item],
999     items: ~[@item],
1000 }
1001
1002 // Foreign mods can be named or anonymous
1003 #[auto_encode]
1004 #[auto_decode]
1005 #[deriving(Eq)]
1006 pub enum foreign_mod_sort { named, anonymous }
1007
1008 #[auto_encode]
1009 #[auto_decode]
1010 #[deriving(Eq)]
1011 pub struct foreign_mod {
1012     sort: foreign_mod_sort,
1013     abis: AbiSet,
1014     view_items: ~[@view_item],
1015     items: ~[@foreign_item],
1016 }
1017
1018 #[auto_encode]
1019 #[auto_decode]
1020 #[deriving(Eq)]
1021 pub struct variant_arg {
1022     ty: @Ty,
1023     id: node_id,
1024 }
1025
1026 #[auto_encode]
1027 #[auto_decode]
1028 #[deriving(Eq)]
1029 pub enum variant_kind {
1030     tuple_variant_kind(~[variant_arg]),
1031     struct_variant_kind(@struct_def),
1032 }
1033
1034 #[auto_encode]
1035 #[auto_decode]
1036 #[deriving(Eq)]
1037 pub struct enum_def {
1038     variants: ~[variant],
1039 }
1040
1041 #[auto_encode]
1042 #[auto_decode]
1043 #[deriving(Eq)]
1044 pub struct variant_ {
1045     name: ident,
1046     attrs: ~[attribute],
1047     kind: variant_kind,
1048     id: node_id,
1049     disr_expr: Option<@expr>,
1050     vis: visibility,
1051 }
1052
1053 pub type variant = spanned<variant_>;
1054
1055 #[auto_encode]
1056 #[auto_decode]
1057 #[deriving(Eq)]
1058 pub struct path_list_ident_ {
1059     name: ident,
1060     id: node_id,
1061 }
1062
1063 pub type path_list_ident = spanned<path_list_ident_>;
1064
1065 pub type view_path = spanned<view_path_>;
1066
1067 #[auto_encode]
1068 #[auto_decode]
1069 #[deriving(Eq)]
1070 pub enum view_path_ {
1071
1072     // quux = foo::bar::baz
1073     //
1074     // or just
1075     //
1076     // foo::bar::baz  (with 'baz =' implicitly on the left)
1077     view_path_simple(ident, @Path, node_id),
1078
1079     // foo::bar::*
1080     view_path_glob(@Path, node_id),
1081
1082     // foo::bar::{a,b,c}
1083     view_path_list(@Path, ~[path_list_ident], node_id)
1084 }
1085
1086 #[auto_encode]
1087 #[auto_decode]
1088 #[deriving(Eq)]
1089 pub struct view_item {
1090     node: view_item_,
1091     attrs: ~[attribute],
1092     vis: visibility,
1093     span: span,
1094 }
1095
1096 #[auto_encode]
1097 #[auto_decode]
1098 #[deriving(Eq)]
1099 pub enum view_item_ {
1100     view_item_extern_mod(ident, ~[@meta_item], node_id),
1101     view_item_use(~[@view_path]),
1102 }
1103
1104 // Meta-data associated with an item
1105 pub type attribute = spanned<attribute_>;
1106
1107 // Distinguishes between attributes that decorate items and attributes that
1108 // are contained as statements within items. These two cases need to be
1109 // distinguished for pretty-printing.
1110 #[auto_encode]
1111 #[auto_decode]
1112 #[deriving(Eq)]
1113 pub enum attr_style { attr_outer, attr_inner, }
1114
1115 // doc-comments are promoted to attributes that have is_sugared_doc = true
1116 #[auto_encode]
1117 #[auto_decode]
1118 #[deriving(Eq)]
1119 pub struct attribute_ {
1120     style: attr_style,
1121     value: @meta_item,
1122     is_sugared_doc: bool,
1123 }
1124
1125 /*
1126   trait_refs appear in impls.
1127   resolve maps each trait_ref's ref_id to its defining trait; that's all
1128   that the ref_id is for. The impl_id maps to the "self type" of this impl.
1129   If this impl is an item_impl, the impl_id is redundant (it could be the
1130   same as the impl's node id).
1131  */
1132 #[auto_encode]
1133 #[auto_decode]
1134 #[deriving(Eq)]
1135 pub struct trait_ref {
1136     path: @Path,
1137     ref_id: node_id,
1138 }
1139
1140 #[auto_encode]
1141 #[auto_decode]
1142 #[deriving(Eq)]
1143 pub enum visibility { public, private, inherited }
1144
1145 impl visibility {
1146     fn inherit_from(&self, parent_visibility: visibility) -> visibility {
1147         match self {
1148             &inherited => parent_visibility,
1149             &public | &private => *self
1150         }
1151     }
1152 }
1153
1154 #[auto_encode]
1155 #[auto_decode]
1156 #[deriving(Eq)]
1157 pub struct struct_field_ {
1158     kind: struct_field_kind,
1159     id: node_id,
1160     ty: @Ty,
1161 }
1162
1163 pub type struct_field = spanned<struct_field_>;
1164
1165 #[auto_encode]
1166 #[auto_decode]
1167 #[deriving(Eq)]
1168 pub enum struct_field_kind {
1169     named_field(ident, struct_mutability, visibility),
1170     unnamed_field   // element of a tuple-like struct
1171 }
1172
1173 #[auto_encode]
1174 #[auto_decode]
1175 #[deriving(Eq)]
1176 pub struct struct_def {
1177     fields: ~[@struct_field], /* fields */
1178     /* (not including ctor or dtor) */
1179     /* dtor is optional */
1180     dtor: Option<struct_dtor>,
1181     /* ID of the constructor. This is only used for tuple- or enum-like
1182      * structs. */
1183     ctor_id: Option<node_id>
1184 }
1185
1186 /*
1187   FIXME (#3300): Should allow items to be anonymous. Right now
1188   we just use dummy names for anon items.
1189  */
1190 #[auto_encode]
1191 #[auto_decode]
1192 #[deriving(Eq)]
1193 pub struct item {
1194     ident: ident,
1195     attrs: ~[attribute],
1196     id: node_id,
1197     node: item_,
1198     vis: visibility,
1199     span: span,
1200 }
1201
1202 #[auto_encode]
1203 #[auto_decode]
1204 #[deriving(Eq)]
1205 pub enum item_ {
1206     item_const(@Ty, @expr),
1207     item_fn(fn_decl, purity, AbiSet, Generics, blk),
1208     item_mod(_mod),
1209     item_foreign_mod(foreign_mod),
1210     item_ty(@Ty, Generics),
1211     item_enum(enum_def, Generics),
1212     item_struct(@struct_def, Generics),
1213     item_trait(Generics, ~[@trait_ref], ~[trait_method]),
1214     item_impl(Generics,
1215               Option<@trait_ref>, // (optional) trait this impl implements
1216               @Ty, // self
1217               ~[@method]),
1218     // a macro invocation (which includes macro definition)
1219     item_mac(mac),
1220 }
1221
1222 #[auto_encode]
1223 #[auto_decode]
1224 #[deriving(Eq)]
1225 pub enum struct_mutability { struct_mutable, struct_immutable }
1226
1227 impl to_bytes::IterBytes for struct_mutability {
1228     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
1229         (*self as u8).iter_bytes(lsb0, f)
1230     }
1231 }
1232
1233 pub type struct_dtor = spanned<struct_dtor_>;
1234
1235 #[auto_encode]
1236 #[auto_decode]
1237 #[deriving(Eq)]
1238 pub struct struct_dtor_ {
1239     id: node_id,
1240     attrs: ~[attribute],
1241     self_id: node_id,
1242     body: blk,
1243 }
1244
1245 #[auto_encode]
1246 #[auto_decode]
1247 #[deriving(Eq)]
1248 pub struct foreign_item {
1249     ident: ident,
1250     attrs: ~[attribute],
1251     node: foreign_item_,
1252     id: node_id,
1253     span: span,
1254     vis: visibility,
1255 }
1256
1257 #[auto_encode]
1258 #[auto_decode]
1259 #[deriving(Eq)]
1260 pub enum foreign_item_ {
1261     foreign_item_fn(fn_decl, purity, Generics),
1262     foreign_item_const(@Ty)
1263 }
1264
1265 // The data we save and restore about an inlined item or method.  This is not
1266 // part of the AST that we parse from a file, but it becomes part of the tree
1267 // that we trans.
1268 #[auto_encode]
1269 #[auto_decode]
1270 #[deriving(Eq)]
1271 pub enum inlined_item {
1272     ii_item(@item),
1273     ii_method(def_id /* impl id */, @method),
1274     ii_foreign(@foreign_item),
1275     ii_dtor(struct_dtor, ident, Generics, def_id /* parent id */)
1276 }
1277
1278 /* hold off on tests ... they appear in a later merge.
1279 #[cfg(test)]
1280 mod test {
1281     use core::option::{None, Option, Some};
1282     use core::uint;
1283     use std;
1284     use codemap::*;
1285     use super::*;
1286
1287
1288     #[test] fn xorpush_test () {
1289         let mut s = ~[];
1290         xorPush(&mut s,14);
1291         assert_eq!(s,~[14]);
1292         xorPush(&mut s,14);
1293         assert_eq!(s,~[]);
1294         xorPush(&mut s,14);
1295         assert_eq!(s,~[14]);
1296         xorPush(&mut s,15);
1297         assert_eq!(s,~[14,15]);
1298         xorPush (&mut s,16);
1299         assert_eq! (s,~[14,15,16]);
1300         xorPush (&mut s,16);
1301         assert_eq! (s,~[14,15]);
1302         xorPush (&mut s,15);
1303         assert_eq! (s,~[14]);
1304     }
1305
1306     #[test] fn test_marksof () {
1307         let stopname = uints_to_name(&~[12,14,78]);
1308         let name1 = uints_to_name(&~[4,9,7]);
1309         assert_eq!(marksof (MT,stopname),~[]);
1310         assert_eq! (marksof (Mark (4,@Mark(98,@MT)),stopname),~[4,98]);
1311         // does xoring work?
1312         assert_eq! (marksof (Mark (5, @Mark (5, @Mark (16,@MT))),stopname),
1313                      ~[16]);
1314         // does nested xoring work?
1315         assert_eq! (marksof (Mark (5,
1316                                     @Mark (10,
1317                                            @Mark (10,
1318                                                   @Mark (5,
1319                                                          @Mark (16,@MT))))),
1320                               stopname),
1321                      ~[16]);
1322         // stop has no effect on marks
1323         assert_eq! (marksof (Mark (9, @Mark (14, @Mark (12, @MT))),stopname),
1324                      ~[9,14,12]);
1325         // rename where stop doesn't match:
1326         assert_eq! (marksof (Mark (9, @Rename
1327                                     (name1,
1328                                      @Mark (4, @MT),
1329                                      uints_to_name(&~[100,101,102]),
1330                                      @Mark (14, @MT))),
1331                               stopname),
1332                      ~[9,14]);
1333         // rename where stop does match
1334         ;
1335         assert_eq! (marksof (Mark(9, @Rename (name1,
1336                                                @Mark (4, @MT),
1337                                                stopname,
1338                                                @Mark (14, @MT))),
1339                               stopname),
1340                      ~[9]);
1341     }
1342
1343     // are ASTs encodable?
1344     #[test] fn check_asts_encodable() {
1345         let bogus_span = span {lo:BytePos(10),
1346                                hi:BytePos(20),
1347                                expn_info:None};
1348         let e : crate =
1349             spanned{
1350             node: crate_{
1351                 module: _mod {view_items: ~[], items: ~[]},
1352                 attrs: ~[],
1353                 config: ~[]
1354             },
1355             span: bogus_span};
1356         // doesn't matter which encoder we use....
1357         let _f = (@e as @std::serialize::Encodable<std::json::Encoder>);
1358     }
1359
1360
1361 }
1362
1363 */
1364 //
1365 // Local Variables:
1366 // mode: rust
1367 // fill-column: 78;
1368 // indent-tabs-mode: nil
1369 // c-basic-offset: 4
1370 // buffer-file-coding-system: utf-8-unix
1371 // End:
1372 //