From e12711540a00ded4021250f7b2a31773fc4dc734 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 17 Dec 2013 16:46:18 -0800 Subject: librustc: Implement placement `box` for GC and unique pointers. --- src/libsyntax/ast.rs | 2 ++ src/libsyntax/fold.rs | 3 +++ src/libsyntax/parse/parser.rs | 16 +++++++++++++++- src/libsyntax/print/pprust.rs | 7 +++++++ src/libsyntax/visit.rs | 4 ++++ 5 files changed, 31 insertions(+), 1 deletion(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 8864c678b95..bdc5c375bc4 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -547,6 +547,8 @@ pub enum CallSugar { #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub enum Expr_ { ExprVstore(@Expr, ExprVstore), + // First expr is the place; second expr is the value. + ExprBox(@Expr, @Expr), ExprVec(~[@Expr], Mutability), ExprCall(@Expr, ~[@Expr], CallSugar), ExprMethodCall(NodeId, @Expr, Ident, ~[P], ~[@Expr], CallSugar), diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 8fab2df7a5d..a681de65c7a 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -724,6 +724,9 @@ pub fn noop_fold_expr(e: @Expr, folder: &mut T) -> @Expr { ExprVstore(e, v) => { ExprVstore(folder.fold_expr(e), v) } + ExprBox(p, e) => { + ExprBox(folder.fold_expr(p), folder.fold_expr(e)) + } ExprVec(ref exprs, mutt) => { ExprVec(exprs.map(|&x| folder.fold_expr(x)), mutt) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 26653fe4a1e..0847167267d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -23,7 +23,7 @@ use ast::{BlockCheckMode, UnBox}; use ast::{Crate, CrateConfig, Decl, DeclItem}; use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, enum_def, explicit_self}; use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain}; -use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock}; +use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox}; use ast::{ExprBreak, ExprCall, ExprCast, ExprDoBody}; use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex}; use ast::{ExprLit, ExprLogLevel, ExprLoop, ExprMac}; @@ -2325,6 +2325,20 @@ impl Parser { token::IDENT(_, _) if self.is_keyword(keywords::Box) => { self.bump(); + // Check for a place: `box(PLACE) EXPR`. + if self.eat(&token::LPAREN) { + // Support `box() EXPR` as the default. + if !self.eat(&token::RPAREN) { + let place = self.parse_expr(); + self.expect(&token::RPAREN); + let subexpression = self.parse_prefix_expr(); + hi = subexpression.span.hi; + ex = ExprBox(place, subexpression); + return self.mk_expr(lo, hi, ex); + } + } + + // Otherwise, we use the unique pointer default. let subexpression = self.parse_prefix_expr(); hi = subexpression.span.hi; // HACK: turn `box [...]` into a boxed-evec diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 82a7d550f64..f8b7720da7b 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1155,6 +1155,13 @@ pub fn print_expr(s: &mut ps, expr: &ast::Expr) { print_expr_vstore(s, v); print_expr(s, e); }, + ast::ExprBox(p, e) => { + word(&mut s.s, "box"); + word(&mut s.s, "("); + print_expr(s, p); + word_space(s, ")"); + print_expr(s, e); + } ast::ExprVec(ref exprs, mutbl) => { ibox(s, indent_unit); word(&mut s.s, "["); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 6484855d9d9..b67e2e7d9fa 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -618,6 +618,10 @@ pub fn walk_expr>(visitor: &mut V, expression: &Expr, en ExprVstore(subexpression, _) => { visitor.visit_expr(subexpression, env.clone()) } + ExprBox(place, subexpression) => { + visitor.visit_expr(place, env.clone()); + visitor.visit_expr(subexpression, env.clone()) + } ExprVec(ref subexpressions, _) => { walk_exprs(visitor, *subexpressions, env.clone()) } -- cgit 1.4.1-3-g733a5