提交 9a4de3f3 编写于 作者: P Patrick Walton

libsyntax: Introduce routines and remove all `@fn`s from libsyntax save the old visitor

上级 e9599639
......@@ -36,22 +36,22 @@
* still held if needed.
*/
use std::option;
use std::cast;
use std::ptr;
use std::routine::Runnable;
use std::util;
/**
* The type representing a foreign chunk of memory
*
*/
pub struct CVec<T> {
priv base: *mut T,
priv len: uint,
priv rsrc: @DtorRes
priv rsrc: @DtorRes,
}
struct DtorRes {
dtor: Option<@fn()>,
dtor: Option<~Runnable>,
}
#[unsafe_destructor]
......@@ -64,9 +64,11 @@ fn drop(&mut self) {
}
}
fn DtorRes(dtor: Option<@fn()>) -> DtorRes {
DtorRes {
dtor: dtor
impl DtorRes {
fn new(dtor: Option<~Runnable>) -> DtorRes {
DtorRes {
dtor: dtor,
}
}
}
......@@ -83,10 +85,10 @@ fn DtorRes(dtor: Option<@fn()>) -> DtorRes {
* * len - The number of elements in the buffer
*/
pub unsafe fn CVec<T>(base: *mut T, len: uint) -> CVec<T> {
return CVec{
return CVec {
base: base,
len: len,
rsrc: @DtorRes(option::None)
rsrc: @DtorRes::new(None)
};
}
......@@ -101,12 +103,12 @@ pub unsafe fn CVec<T>(base: *mut T, len: uint) -> CVec<T> {
* * dtor - A function to run when the value is destructed, useful
* for freeing the buffer, etc.
*/
pub unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: @fn())
-> CVec<T> {
pub unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: ~Runnable)
-> CVec<T> {
return CVec{
base: base,
len: len,
rsrc: @DtorRes(option::Some(dtor))
rsrc: @DtorRes::new(Some(dtor))
};
}
......@@ -153,6 +155,17 @@ mod tests {
use std::libc::*;
use std::libc;
use std::routine::Runnable;
struct LibcFree {
mem: *c_void,
}
impl Runnable for LibcFree {
fn run(~self) {
libc::free(self.mem)
}
}
fn malloc(n: size_t) -> CVec<u8> {
#[fixed_stack_segment];
......@@ -163,12 +176,11 @@ fn malloc(n: size_t) -> CVec<u8> {
assert!(mem as int != 0);
return c_vec_with_dtor(mem as *mut u8, n as uint, || f(mem));
}
fn f(mem: *c_void) {
#[fixed_stack_segment]; #[inline(never)];
unsafe { libc::free(mem) }
return c_vec_with_dtor(mem as *mut u8,
n as uint,
~LibcFree {
mem: mem,
} as ~Runnable);
}
}
......
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/*!
* Routines are like closures except that they own their arguments and can
* only run once.
*/
/// A routine that takes no arguments and returns nothing.
pub trait Runnable {
/// The entry point for the routine.
fn run(~self);
}
/// A convenience routine that does nothing.
pub struct NoOpRunnable;
impl Runnable for NoOpRunnable {
fn run(~self) {}
}
......@@ -189,7 +189,7 @@ pub mod linkhack {
pub mod condition;
pub mod logging;
pub mod util;
pub mod routine;
/* Unsupported interfaces */
......
......@@ -158,11 +158,14 @@ pub struct Conv {
// A fragment of the output sequence
#[deriving(Eq)]
pub enum Piece { PieceString(~str), PieceConv(Conv), }
pub enum Piece {
PieceString(~str),
PieceConv(Conv),
}
pub type ErrorFn = @fn(&str) -> !;
pub type ErrorFn<'self> = &'self fn(&str) -> !;
pub fn parse_fmt_string(s: &str, err: ErrorFn) -> ~[Piece] {
pub fn parse_fmt_string<'a>(s: &str, err: ErrorFn<'a>) -> ~[Piece] {
fn push_slice(ps: &mut ~[Piece], s: &str, from: uint, to: uint) {
if to > from {
ps.push(PieceString(s.slice(from, to).to_owned()));
......@@ -185,7 +188,10 @@ fn push_slice(ps: &mut ~[Piece], s: &str, from: uint, to: uint) {
i += 1;
} else {
push_slice(&mut pieces, s, h, i - 1);
let Parsed {val, next} = parse_conversion(s, i, lim, err);
let Parsed {
val,
next
} = parse_conversion(s, i, lim, |s| err(s));
pieces.push(val);
i = next;
}
......@@ -224,8 +230,8 @@ pub fn peek_num(s: &str, i: uint, lim: uint) -> Option<Parsed<uint>> {
}
}
pub fn parse_conversion(s: &str, i: uint, lim: uint, err: ErrorFn) ->
Parsed<Piece> {
pub fn parse_conversion<'a>(s: &str, i: uint, lim: uint, err: ErrorFn<'a>)
-> Parsed<Piece> {
let param = parse_parameter(s, i, lim);
// avoid copying ~[Flag] by destructuring
let Parsed {val: flags_val, next: flags_next} = parse_flags(s,
......@@ -308,8 +314,8 @@ pub fn parse_precision(s: &str, i: uint, lim: uint) -> Parsed<Count> {
}
}
pub fn parse_type(s: &str, i: uint, lim: uint, err: ErrorFn) ->
Parsed<Ty> {
pub fn parse_type<'a>(s: &str, i: uint, lim: uint, err: ErrorFn<'a>)
-> Parsed<Ty> {
if i >= lim { err("missing type in conversion"); }
// FIXME (#2249): Do we really want two signed types here?
......
......@@ -38,7 +38,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree])
fn parse_fmt_err_(cx: @ExtCtxt, sp: Span, msg: &str) -> ! {
cx.span_fatal(sp, msg);
}
let parse_fmt_err: @fn(&str) -> ! = |s| parse_fmt_err_(cx, fmtspan, s);
let parse_fmt_err: &fn(&str) -> ! = |s| parse_fmt_err_(cx, fmtspan, s);
let pieces = parse_fmt_string(fmt, parse_fmt_err);
MRExpr(pieces_to_expr(cx, sp, pieces, args))
}
......
......@@ -869,35 +869,19 @@ mod test {
use parse::token;
use print::pprust;
use super::*;
struct IdentFolder {
f: @fn(ast::ident)->ast::ident,
}
impl ast_fold for IdentFolder {
fn fold_ident(@self, i: ident) -> ident {
(self.f)(i)
}
}
// taken from expand
// given a function from idents to idents, produce
// an ast_fold that applies that function:
pub fn fun_to_ident_folder(f: @fn(ast::ident)->ast::ident) -> @ast_fold {
@IdentFolder {
f: f,
} as @ast_fold
}
// this version doesn't care about getting comments or docstrings in.
fn fake_print_crate(s: @pprust::ps, crate: &ast::Crate) {
pprust::print_mod(s, &crate.module, crate.attrs);
}
// change every identifier to "zz"
pub fn to_zz() -> @fn(ast::Ident)->ast::Ident {
let zz_id = token::str_to_ident("zz");
|_id| {zz_id}
struct ToZzIdentFolder;
impl ast_fold for ToZzIdentFolder {
fn fold_ident(&self, _: ident) -> ident {
token::str_to_ident("zz")
}
}
// maybe add to expand.rs...
......@@ -917,7 +901,7 @@ pub fn to_zz() -> @fn(ast::Ident)->ast::Ident {
// make sure idents get transformed everywhere
#[test] fn ident_transformation () {
let zz_fold = fun_to_ident_folder(to_zz());
let zz_fold = ToZzIdentFolder;
let ast = string_to_crate(@"#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}");
assert_pred!(matches_codepattern,
"matches_codepattern",
......@@ -928,7 +912,7 @@ pub fn to_zz() -> @fn(ast::Ident)->ast::Ident {
// even inside macro defs....
#[test] fn ident_transformation_in_defs () {
let zz_fold = fun_to_ident_folder(to_zz());
let zz_fold = ToZzIdentFolder;
let ast = string_to_crate(@"macro_rules! a {(b $c:expr $(d $e:token)f+
=> (g $(d $d $e)+))} ");
assert_pred!(matches_codepattern,
......@@ -940,7 +924,7 @@ pub fn to_zz() -> @fn(ast::Ident)->ast::Ident {
// and in cast expressions... this appears to be an existing bug.
#[test] fn ident_transformation_in_types () {
let zz_fold = fun_to_ident_folder(to_zz());
let zz_fold = ToZzIdentFolder;
let ast = string_to_crate(@"fn a() {let z = 13 as int;}");
assert_pred!(matches_codepattern,
"matches_codepattern",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册