diff options
| author | Luqman Aden <me@luqman.ca> | 2013-03-12 00:01:09 -0700 |
|---|---|---|
| committer | Luqman Aden <me@luqman.ca> | 2013-03-12 01:03:34 -0700 |
| commit | 5aa734d6a1946e526832bb602e1bb271bf26c0b1 (patch) | |
| tree | f9c2332f54666a31c4bb7ffa5a2cb1e85e2c895a /src/libsyntax | |
| parent | 885d0d3d3369bef72590a4d5671c0de83e968dda (diff) | |
| download | rust-5aa734d6a1946e526832bb602e1bb271bf26c0b1.tar.gz rust-5aa734d6a1946e526832bb602e1bb271bf26c0b1.zip | |
Parse operands properly and add a way to indicate volatile asm.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/asm.rs | 140 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 8 |
3 files changed, 137 insertions, 14 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index b7c30360613..dab5de47aa6 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -601,7 +601,8 @@ pub enum expr_ { expr_ret(Option<@expr>), expr_log(log_level, @expr, @expr), - expr_inline_asm(@~str /* asm */, @~str /* constraints */), + /* asm, clobbers + constraints, volatile */ + expr_inline_asm(@~str, @~str, bool), expr_mac(mac), diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index bbf42389907..229d1d2a95e 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -20,29 +20,147 @@ use ast; use codemap::span; use ext::base; use ext::base::*; +use parse; +use parse::token; + +enum State { + Asm, + Outputs, + Inputs, + Clobbers, + Options +} + +fn next_state(s: State) -> Option<State> { + match s { + Asm => Some(Outputs), + Outputs => Some(Inputs), + Inputs => Some(Clobbers), + Clobbers => Some(Options), + Options => None + } +} pub fn expand_asm(cx: ext_ctxt, sp: span, tts: &[ast::token_tree]) -> base::MacResult { - let args = get_exprs_from_tts(cx, tts); - if args.len() == 0 { - cx.span_fatal(sp, "ast! takes at least 1 argument."); + + let p = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), + vec::from_slice(tts)); + + let mut asm = ~""; + let mut outputs = ~[]; + let mut inputs = ~[]; + let mut cons = ~""; + let mut volatile = false; + + let mut state = Asm; + loop outer: { + + match state { + Asm => { + asm = expr_to_str(cx, p.parse_expr(), + ~"inline assembly must be a string literal."); + } + Outputs => { + while *p.token != token::EOF && + *p.token != token::COLON && + *p.token != token::MOD_SEP { + + if outputs.len() != 0 { + p.eat(&token::COMMA); + } + + let constraint = p.parse_str(); + p.expect(&token::LPAREN); + let out = p.parse_expr(); + p.expect(&token::RPAREN); + + outputs.push((constraint, out)); + } + } + Inputs => { + while *p.token != token::EOF && + *p.token != token::COLON && + *p.token != token::MOD_SEP { + + if inputs.len() != 0 { + p.eat(&token::COMMA); + } + + let constraint = p.parse_str(); + p.expect(&token::LPAREN); + let in = p.parse_expr(); + p.expect(&token::RPAREN); + + inputs.push((constraint, in)); + } + } + Clobbers => { + let mut clobs = ~[]; + while *p.token != token::EOF && + *p.token != token::COLON && + *p.token != token::MOD_SEP { + + if clobs.len() != 0 { + p.eat(&token::COMMA); + } + + let clob = ~"~{" + *p.parse_str() + ~"}"; + clobs.push(clob); + } + + cons = str::connect(clobs, ","); + } + Options => { + let option = *p.parse_str(); + + if option == ~"volatile" { + volatile = true; + } + + if *p.token == token::COMMA { + p.eat(&token::COMMA); + } + } + } + + while *p.token == token::COLON || + *p.token == token::MOD_SEP || + *p.token == token::EOF { + state = if *p.token == token::COLON { + p.bump(); + match next_state(state) { + Some(x) => x, + None => break outer + } + } else if *p.token == token::MOD_SEP { + p.bump(); + let s = match next_state(state) { + Some(x) => x, + None => break outer + }; + match next_state(s) { + Some(x) => x, + None => break outer + } + } else if *p.token == token::EOF { + break outer; + } else { + state + }; + } } - let asm = - expr_to_str(cx, args[0], - ~"inline assembly must be a string literal."); - let cons = if args.len() > 1 { - expr_to_str(cx, args[1], - ~"constraints must be a string literal.") - } else { ~"" }; MRExpr(@ast::expr { id: cx.next_id(), callee_id: cx.next_id(), - node: ast::expr_inline_asm(@asm, @cons), + node: ast::expr_inline_asm(@asm, @cons, volatile), span: sp }) } + + // // Local Variables: // mode: rust diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 25c18adb2fb..6b1a72b92ff 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1398,8 +1398,12 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) { } } } - ast::expr_inline_asm(a, c) => { - word(s.s, ~"__asm__"); + ast::expr_inline_asm(a, c, v) => { + if v { + word(s.s, ~"__volatile__ asm!"); + } else { + word(s.s, ~"asm!"); + } popen(s); print_string(s, *a); word_space(s, ~","); |
