libsyntax: Introduce routines and remove all @fn
s from libsyntax save the old visitor
This commit is contained in:
parent
e95996399f
commit
9a4de3f305
6 changed files with 85 additions and 55 deletions
|
@ -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 @@ impl Drop for DtorRes {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ mod tests {
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
28
src/libstd/routine.rs
Normal file
28
src/libstd/routine.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
// 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 reflect;
|
|||
pub mod condition;
|
||||
pub mod logging;
|
||||
pub mod util;
|
||||
|
||||
pub mod routine;
|
||||
|
||||
/* Unsupported interfaces */
|
||||
|
||||
|
|
|
@ -158,11 +158,14 @@ pub mod ct {
|
|||
|
||||
// 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 @@ pub mod ct {
|
|||
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 mod ct {
|
|||
}
|
||||
}
|
||||
|
||||
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 mod ct {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ mod test {
|
|||
|
||||
// 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 @@ mod test {
|
|||
|
||||
// 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 @@ mod test {
|
|||
|
||||
// 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",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue