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