]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ext/asm.rs
Remove 'Local Variable' comments
[rust.git] / src / libsyntax / ext / asm.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 /*
12  * Inline assembly support.
13  */
14
15 use ast;
16 use codemap::span;
17 use ext::base;
18 use ext::base::*;
19 use parse;
20 use parse::token;
21
22 enum State {
23     Asm,
24     Outputs,
25     Inputs,
26     Clobbers,
27     Options
28 }
29
30 fn next_state(s: State) -> Option<State> {
31     match s {
32         Asm      => Some(Outputs),
33         Outputs  => Some(Inputs),
34         Inputs   => Some(Clobbers),
35         Clobbers => Some(Options),
36         Options  => None
37     }
38 }
39
40 pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
41                -> base::MacResult {
42     let p = parse::new_parser_from_tts(cx.parse_sess(),
43                                        cx.cfg(),
44                                        vec::from_slice(tts));
45
46     let mut asm = ~"";
47     let mut outputs = ~[];
48     let mut inputs = ~[];
49     let mut cons = ~"";
50     let mut volatile = false;
51     let mut alignstack = false;
52     let mut dialect = ast::asm_att;
53
54     let mut state = Asm;
55
56     // Not using labeled break to get us through one round of bootstrapping.
57     let mut continue = true;
58     while continue {
59         match state {
60             Asm => {
61                 asm = expr_to_str(cx, p.parse_expr(),
62                                   ~"inline assembly must be a string literal.");
63             }
64             Outputs => {
65                 while *p.token != token::EOF &&
66                       *p.token != token::COLON &&
67                       *p.token != token::MOD_SEP {
68
69                     if outputs.len() != 0 {
70                         p.eat(&token::COMMA);
71                     }
72
73                     let constraint = p.parse_str();
74                     p.expect(&token::LPAREN);
75                     let out = p.parse_expr();
76                     p.expect(&token::RPAREN);
77
78                     let out = @ast::expr {
79                         id: cx.next_id(),
80                         callee_id: cx.next_id(),
81                         span: out.span,
82                         node: ast::expr_addr_of(ast::m_mutbl, out)
83                     };
84
85                     outputs.push((constraint, out));
86                 }
87             }
88             Inputs => {
89                 while *p.token != token::EOF &&
90                       *p.token != token::COLON &&
91                       *p.token != token::MOD_SEP {
92
93                     if inputs.len() != 0 {
94                         p.eat(&token::COMMA);
95                     }
96
97                     let constraint = p.parse_str();
98                     p.expect(&token::LPAREN);
99                     let in = p.parse_expr();
100                     p.expect(&token::RPAREN);
101
102                     inputs.push((constraint, in));
103                 }
104             }
105             Clobbers => {
106                 let mut clobs = ~[];
107                 while *p.token != token::EOF &&
108                       *p.token != token::COLON &&
109                       *p.token != token::MOD_SEP {
110
111                     if clobs.len() != 0 {
112                         p.eat(&token::COMMA);
113                     }
114
115                     let clob = ~"~{" + *p.parse_str() + ~"}";
116                     clobs.push(clob);
117                 }
118
119                 cons = str::connect(clobs, ",");
120             }
121             Options => {
122                 let option = *p.parse_str();
123
124                 if option == ~"volatile" {
125                     volatile = true;
126                 } else if option == ~"alignstack" {
127                     alignstack = true;
128                 } else if option == ~"intel" {
129                     dialect = ast::asm_intel;
130                 }
131
132                 if *p.token == token::COMMA {
133                     p.eat(&token::COMMA);
134                 }
135             }
136         }
137
138         while *p.token == token::COLON   ||
139               *p.token == token::MOD_SEP ||
140               *p.token == token::EOF {
141             state = if *p.token == token::COLON {
142                 p.bump();
143                 match next_state(state) {
144                     Some(x) => x,
145                     None    => {
146                         continue = false;
147                         break
148                     }
149                 }
150             } else if *p.token == token::MOD_SEP {
151                 p.bump();
152                 let s = match next_state(state) {
153                     Some(x) => x,
154                     None    => {
155                         continue = false;
156                         break
157                     }
158                 };
159                 match next_state(s) {
160                     Some(x) => x,
161                     None    => {
162                         continue = false;
163                         break
164                     }
165                 }
166             } else if *p.token == token::EOF {
167                 continue = false;
168                 break;
169             } else {
170                state
171             };
172         }
173     }
174
175     MRExpr(@ast::expr {
176         id: cx.next_id(),
177         callee_id: cx.next_id(),
178         node: ast::expr_inline_asm(ast::inline_asm {
179             asm: @asm,
180             clobbers: @cons,
181             inputs: inputs,
182             outputs: outputs,
183             volatile: volatile,
184             alignstack: alignstack,
185             dialect: dialect
186         }),
187         span: sp
188     })
189 }