diff options
| author | Tim Chevalier <chevalier@alum.wellesley.edu> | 2013-02-05 10:33:28 -0800 |
|---|---|---|
| committer | Tim Chevalier <chevalier@alum.wellesley.edu> | 2013-02-05 10:33:28 -0800 |
| commit | 2dcb3ed745d04048941a8130f3603c5759b2b142 (patch) | |
| tree | b02ae43f09244c7f4549a9c4171516d0cc257997 /src/libsyntax | |
| parent | 6f0bede97c3468eaba8cf59702d04c7ede8f4b0a (diff) | |
| parent | 2f46b763da2c098913884f101b6d71d69af41b49 (diff) | |
Merge
Diffstat (limited to 'src/libsyntax')
36 files changed, 556 insertions, 408 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index e85f41c54a2..bc808495ca3 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -10,7 +10,7 @@ // The Rust abstract syntax tree. -use codemap::{span, FileName}; +use codemap::{span, FileName, spanned}; use core::cast; use core::cmp; @@ -21,10 +21,6 @@ use core::to_bytes; use core::to_str::ToStr; use std::serialize::{Encodable, Decodable, Encoder, Decoder}; -#[auto_encode] -#[auto_decode] -pub struct spanned<T> { node: T, span: span } - /* can't import macros yet, so this is copied from token.rs. See its comment * there. */ macro_rules! interner_key ( @@ -40,7 +36,7 @@ pub impl<S: Encoder> ident: Encodable<S> { let intr = match unsafe { task::local_data::local_data_get(interner_key!()) } { - None => fail ~"encode: TLS interner not set up", + None => die!(~"encode: TLS interner not set up"), Some(intr) => intr }; @@ -53,7 +49,7 @@ pub impl<D: Decoder> ident: Decodable<D> { let intr = match unsafe { task::local_data::local_data_get(interner_key!()) } { - None => fail ~"decode: TLS interner not set up", + None => die!(~"decode: TLS interner not set up"), Some(intr) => intr }; @@ -690,7 +686,7 @@ pub enum expr_ { expr_cast(@expr, @Ty), expr_if(@expr, blk, Option<@expr>), expr_while(@expr, blk), - /* Conditionless loop (can be exited with break, cont, ret, or fail) + /* Conditionless loop (can be exited with break, cont, or ret) Same semantics as while(true) { body }, but typestate knows that the (implicit) condition is always true. */ expr_loop(blk, Option<ident>), @@ -716,7 +712,6 @@ pub enum expr_ { expr_index(@expr, @expr), expr_path(@path), expr_addr_of(mutability, @expr), - expr_fail(Option<@expr>), expr_break(Option<ident>), expr_again(Option<ident>), expr_ret(Option<@expr>), @@ -928,8 +923,8 @@ pub enum trait_method { pub enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, } pub impl int_ty : ToStr { - pure fn to_str() -> ~str { - ::ast_util::int_ty_to_str(self) + pure fn to_str(&self) -> ~str { + ::ast_util::int_ty_to_str(*self) } } @@ -964,8 +959,8 @@ pub impl int_ty : cmp::Eq { pub enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, } pub impl uint_ty : ToStr { - pure fn to_str() -> ~str { - ::ast_util::uint_ty_to_str(self) + pure fn to_str(&self) -> ~str { + ::ast_util::uint_ty_to_str(*self) } } @@ -998,8 +993,8 @@ pub impl uint_ty : cmp::Eq { pub enum float_ty { ty_f, ty_f32, ty_f64, } pub impl float_ty : ToStr { - pure fn to_str() -> ~str { - ::ast_util::float_ty_to_str(self) + pure fn to_str(&self) -> ~str { + ::ast_util::float_ty_to_str(*self) } } @@ -1101,8 +1096,8 @@ pub enum Onceness { } pub impl Onceness : ToStr { - pure fn to_str() -> ~str { - match self { + pure fn to_str(&self) -> ~str { + match *self { Once => ~"once", Many => ~"many" } @@ -1193,8 +1188,8 @@ pub enum purity { } pub impl purity : ToStr { - pure fn to_str() -> ~str { - match self { + pure fn to_str(&self) -> ~str { + match *self { impure_fn => ~"impure", unsafe_fn => ~"unsafe", pure_fn => ~"pure", diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index a96829ed063..e6a4639ad80 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -25,8 +25,8 @@ use core::cmp; use core::either; use core::str; use core::vec; -use std::map::HashMap; -use std::map; +use std::oldmap::HashMap; +use std::oldmap; use std; pub enum path_elt { @@ -106,7 +106,7 @@ pub enum ast_node { node_struct_ctor(@struct_def, @item, @path), } -pub type map = std::map::HashMap<node_id, ast_node>; +pub type map = std::oldmap::HashMap<node_id, ast_node>; pub struct ctx { map: map, mut path: path, @@ -134,7 +134,7 @@ pub fn mk_ast_map_visitor() -> vt { pub fn map_crate(diag: span_handler, c: crate) -> map { let cx = ctx { - map: std::map::HashMap(), + map: std::oldmap::HashMap(), mut path: ~[], mut local_id: 0u, diag: diag, @@ -316,7 +316,7 @@ pub fn map_struct_def(struct_def: @ast::struct_def, parent_node: ast_node, cx.map.insert(ctor_id, node_struct_ctor(struct_def, item, p)); } - _ => fail ~"struct def parent wasn't an item" + _ => die!(~"struct def parent wasn't an item") } } } @@ -400,7 +400,7 @@ pub fn node_item_query<Result>(items: map, id: node_id, error_msg: ~str) -> Result { match items.find(id) { Some(node_item(it, _)) => query(it), - _ => fail(error_msg) + _ => die!(error_msg) } } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 1ae23240404..c659d6d6020 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -13,7 +13,7 @@ use core::prelude::*; use ast::*; use ast; use ast_util; -use codemap::{span, BytePos}; +use codemap::{span, BytePos, dummy_sp}; use parse::token; use visit; @@ -24,28 +24,6 @@ use core::str; use core::to_bytes; use core::vec; -pub pure fn spanned<T>(+lo: BytePos, +hi: BytePos, +t: T) -> spanned<T> { - respan(mk_sp(lo, hi), move t) -} - -pub pure fn respan<T>(sp: span, +t: T) -> spanned<T> { - spanned {node: t, span: sp} -} - -pub pure fn dummy_spanned<T>(+t: T) -> spanned<T> { - respan(dummy_sp(), move t) -} - -/* assuming that we're not in macro expansion */ -pub pure fn mk_sp(+lo: BytePos, +hi: BytePos) -> span { - span {lo: lo, hi: hi, expn_info: None} -} - -// make this a const, once the compiler supports it -pub pure fn dummy_sp() -> span { return mk_sp(BytePos(0), BytePos(0)); } - - - pub pure fn path_name_i(idents: &[ident], intr: @token::ident_interner) -> ~str { // FIXME: Bad copies (#2543 -- same for everything else that says "bad") @@ -66,7 +44,7 @@ pub pure fn stmt_id(s: stmt) -> node_id { stmt_decl(_, id) => id, stmt_expr(_, id) => id, stmt_semi(_, id) => id, - stmt_mac(*) => fail ~"attempted to analyze unexpanded stmt", + stmt_mac(*) => die!(~"attempted to analyze unexpanded stmt") } } @@ -75,7 +53,7 @@ pub fn variant_def_ids(d: def) -> {enm: def_id, var: def_id} { def_variant(enum_id, var_id) => { return {enm: enum_id, var: var_id} } - _ => fail ~"non-variant in variant_def_ids" + _ => die!(~"non-variant in variant_def_ids") } } @@ -93,7 +71,7 @@ pub pure fn def_id_of_def(d: def) -> def_id { local_def(id) } - def_prim_ty(_) => fail + def_prim_ty(_) => die!() } } @@ -320,38 +298,38 @@ pub pure fn struct_field_visibility(field: ast::struct_field) -> visibility { } pub trait inlined_item_utils { - fn ident() -> ident; - fn id() -> ast::node_id; - fn accept<E>(e: E, v: visit::vt<E>); + fn ident(&self) -> ident; + fn id(&self) -> ast::node_id; + fn accept<E>(&self, e: E, v: visit::vt<E>); } pub impl inlined_item: inlined_item_utils { - fn ident() -> ident { - match self { - ii_item(i) => /* FIXME (#2543) */ copy i.ident, - ii_foreign(i) => /* FIXME (#2543) */ copy i.ident, - ii_method(_, m) => /* FIXME (#2543) */ copy m.ident, - ii_dtor(_, nm, _, _) => /* FIXME (#2543) */ copy nm + fn ident(&self) -> ident { + match *self { + ii_item(i) => /* FIXME (#2543) */ copy i.ident, + ii_foreign(i) => /* FIXME (#2543) */ copy i.ident, + ii_method(_, m) => /* FIXME (#2543) */ copy m.ident, + ii_dtor(_, nm, _, _) => /* FIXME (#2543) */ copy nm } } - fn id() -> ast::node_id { - match self { - ii_item(i) => i.id, - ii_foreign(i) => i.id, - ii_method(_, m) => m.id, - ii_dtor(ref dtor, _, _, _) => (*dtor).node.id + fn id(&self) -> ast::node_id { + match *self { + ii_item(i) => i.id, + ii_foreign(i) => i.id, + ii_method(_, m) => m.id, + ii_dtor(ref dtor, _, _, _) => (*dtor).node.id } } - fn accept<E>(e: E, v: visit::vt<E>) { - match self { - ii_item(i) => (v.visit_item)(i, e, v), - ii_foreign(i) => (v.visit_foreign_item)(i, e, v), - ii_method(_, m) => visit::visit_method_helper(m, e, v), - ii_dtor(ref dtor, _, tps, parent_id) => { + fn accept<E>(&self, e: E, v: visit::vt<E>) { + match *self { + ii_item(i) => (v.visit_item)(i, e, v), + ii_foreign(i) => (v.visit_foreign_item)(i, e, v), + ii_method(_, m) => visit::visit_method_helper(m, e, v), + ii_dtor(ref dtor, _, tps, parent_id) => { visit::visit_struct_dtor_helper((*dtor), tps, parent_id, e, v); - } + } } } } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index dd6a996b730..ca28641c4a3 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -13,7 +13,7 @@ use core::prelude::*; use ast; -use ast_util::{spanned, dummy_spanned}; +use codemap::{spanned, dummy_spanned}; use attr; use codemap::BytePos; use diagnostic::span_handler; @@ -24,8 +24,8 @@ use core::either::Either; use core::either; use core::option; use core::vec; -use std::map::HashMap; -use std::map; +use std::oldmap::HashMap; +use std::oldmap; use std; /* Constructors */ @@ -199,7 +199,7 @@ fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool { // FIXME (#607): Needs implementing // This involves probably sorting the list by name and // meta_item variant - fail ~"unimplemented meta_item variant" + die!(~"unimplemented meta_item variant") } } } @@ -269,9 +269,9 @@ pub fn sort_meta_items(+items: ~[@ast::meta_item]) -> ~[@ast::meta_item] { } // This is sort of stupid here, converting to a vec of mutables and back - let v: ~[mut @ast::meta_item] = vec::cast_to_mut(items); + let mut v: ~[@ast::meta_item] = items; std::sort::quick_sort(v, lteq); - vec::cast_from_mut(move v) + move v } pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: ~str) -> @@ -358,12 +358,12 @@ pub fn find_inline_attr(attrs: &[ast::attribute]) -> inline_attr { pub fn require_unique_names(diagnostic: span_handler, metas: &[@ast::meta_item]) { - let map = map::HashMap(); + let map = oldmap::HashMap(); for metas.each |meta| { let name = get_meta_item_name(*meta); // FIXME: How do I silence the warnings? --pcw (#2619) - if map.contains_key(name) { + if map.contains_key_ref(&name) { diagnostic.span_fatal(meta.span, fmt!("duplicate meta item `%s`", name)); } diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 980d4a236e0..31ed65d8065 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -23,8 +23,6 @@ source code snippets, etc. use core::prelude::*; -use ast_util; - use core::cmp; use core::dvec::DVec; use core::str; @@ -130,6 +128,10 @@ pub struct span { expn_info: Option<@ExpnInfo> } +#[auto_encode] +#[auto_decode] +pub struct spanned<T> { node: T, span: span } + pub impl span : cmp::Eq { pure fn eq(&self, other: &span) -> bool { return (*self).lo == (*other).lo && (*self).hi == (*other).hi; @@ -144,10 +146,32 @@ pub impl<S: Encoder> span: Encodable<S> { pub impl<D: Decoder> span: Decodable<D> { static fn decode(_d: &D) -> span { - ast_util::dummy_sp() + dummy_sp() } } +pub pure fn spanned<T>(+lo: BytePos, +hi: BytePos, +t: T) -> spanned<T> { + respan(mk_sp(lo, hi), move t) +} + +pub pure fn respan<T>(sp: span, +t: T) -> spanned<T> { + spanned {node: t, span: sp} +} + +pub pure fn dummy_spanned<T>(+t: T) -> spanned<T> { + respan(dummy_sp(), move t) +} + +/* assuming that we're not in macro expansion */ +pub pure fn mk_sp(+lo: BytePos, +hi: BytePos) -> span { + span {lo: lo, hi: hi, expn_info: None} +} + +// make this a const, once the compiler supports it +pub pure fn dummy_sp() -> span { return mk_sp(BytePos(0), BytePos(0)); } + + + /// A source code location used for error reporting pub struct Loc { /// Information about the original source @@ -158,6 +182,20 @@ pub struct Loc { col: CharPos } +/// A source code location used as the result of lookup_char_pos_adj +// Actually, *none* of the clients use the filename *or* file field; +// perhaps they should just be removed. +pub struct LocWithOpt { + filename: ~str, + line: uint, + col: CharPos, + file: Option<@FileMap>, +} + +// used to be structural records. Better names, anyone? +pub struct FileMapAndLine {fm: @FileMap, line: uint} +pub struct FileMapAndBytePos {fm: @FileMap, pos: BytePos} + /// Extra information for tracking macro expansion of spans pub enum ExpnInfo { ExpandedFrom({call_site: span, @@ -204,10 +242,19 @@ pub struct FileMap { } pub impl FileMap { + // EFFECT: register a start-of-line offset in the + // table of line-beginnings. + // UNCHECKED INVARIANT: these offsets must be added in the right + // order and must be in the right places; there is shared knowledge + // about what ends a line between this file and parse.rs fn next_line(&self, +pos: BytePos) { + // the new charpos must be > the last one (or it's the first one). + assert ((self.lines.len() == 0) + || (self.lines[self.lines.len() - 1] < pos)); self.lines.push(pos); } + // get a line from the list of pre-computed line-beginnings pub fn get_line(&self, line: int) -> ~str { unsafe { let begin: BytePos = self.lines[line] - self.start_pos; @@ -279,27 +326,25 @@ pub impl CodeMap { return self.lookup_pos(pos); } - pub fn lookup_char_pos_adj(&self, +pos: BytePos) - -> {filename: ~str, line: uint, col: CharPos, file: Option<@FileMap>} + pub fn lookup_char_pos_adj(&self, +pos: BytePos) -> LocWithOpt { let loc = self.lookup_char_pos(pos); match (loc.file.substr) { - FssNone => { - {filename: /* FIXME (#2543) */ copy loc.file.name, - line: loc.line, - col: loc.col, - file: Some(loc.file)} - } - FssInternal(sp) => { - self.lookup_char_pos_adj( - sp.lo + (pos - loc.file.start_pos)) - } - FssExternal(ref eloc) => { - {filename: /* FIXME (#2543) */ copy (*eloc).filename, - line: (*eloc).line + loc.line - 1u, - col: if loc.line == 1 {eloc.col + loc.col} else {loc.col}, - file: None} - } + FssNone => + LocWithOpt { + filename: /* FIXME (#2543) */ copy loc.file.name, + line: loc.line, + col: loc.col, + file: Some(loc.file)}, + FssInternal(sp) => + self.lookup_char_pos_adj( + sp.lo + (pos - loc.file.start_pos)), + FssExternal(ref eloc) => + LocWithOpt { + filename: /* FIXME (#2543) */ copy (*eloc).filename, + line: (*eloc).line + loc.line - 1u, + col: if loc.line == 1 {eloc.col + loc.col} else {loc.col}, + file: None} } } @@ -319,7 +364,7 @@ pub impl CodeMap { } pub fn span_to_str(&self, sp: span) -> ~str { - if self.files.len() == 0 && sp == ast_util::dummy_sp() { + if self.files.len() == 0 && sp == dummy_sp() { return ~"no-location"; } @@ -356,7 +401,7 @@ pub impl CodeMap { for self.files.each |fm| { if fm.name == filename { return *fm; } } //XXjdm the following triggers a mismatched type bug // (or expected function, found _|_) - fail; // ("asking for " + filename + " which we don't know about"); + die!(); // ("asking for " + filename + " which we don't know about"); } } @@ -376,15 +421,14 @@ priv impl CodeMap { } } if (a >= len) { - fail fmt!("position %u does not resolve to a source location", - pos.to_uint()) + die!(fmt!("position %u does not resolve to a source location", + pos.to_uint())) } return a; } - fn lookup_line(&self, +pos: BytePos) - -> {fm: @FileMap, line: uint} + fn lookup_line(&self, pos: BytePos) -> FileMapAndLine { let idx = self.lookup_filemap_idx(pos); let f = self.files[idx]; @@ -394,11 +438,11 @@ priv impl CodeMap { let m = (a + b) / 2u; if f.lines[m] > pos { b = m; } else { a = m; } } - return {fm: f, line: a}; + return FileMapAndLine {fm: f, line: a}; } fn lookup_pos(&self, +pos: BytePos) -> Loc { - let {fm: f, line: a} = self.lookup_line(pos); + let FileMapAndLine {fm: f, line: a} = self.lookup_line(pos); let line = a + 1u; // Line numbers start at 1 let chpos = self.bytepos_to_local_charpos(pos); let linebpos = f.lines[a]; @@ -424,11 +468,11 @@ priv impl CodeMap { } fn lookup_byte_offset(&self, +bpos: BytePos) - -> {fm: @FileMap, pos: BytePos} { + -> FileMapAndBytePos { let idx = self.lookup_filemap_idx(bpos); let fm = self.files[idx]; let offset = bpos - fm.start_pos; - return {fm: fm, pos: offset}; + return FileMapAndBytePos {fm: fm, pos: offset}; } // Converts an absolute BytePos to a CharPos relative to the file it is @@ -458,6 +502,36 @@ priv impl CodeMap { } } +#[cfg(test)] +mod test { + use super::*; + use util::testing::check_equal; + + #[test] + fn t1 () { + let cm = CodeMap::new(); + let fm = cm.new_filemap(~"blork.rs",@~"first line.\nsecond line"); + fm.next_line(BytePos(0)); + check_equal(&fm.get_line(0),&~"first line."); + // TESTING BROKEN BEHAVIOR: + fm.next_line(BytePos(10)); + check_equal(&fm.get_line(1),&~"."); + } + + #[test] + #[should_fail] + fn t2 () { + let cm = CodeMap::new(); + let fm = cm.new_filemap(~"blork.rs",@~"first line.\nsecond line"); + // TESTING *REALLY* BROKEN BEHAVIOR: + fm.next_line(BytePos(0)); + fm.next_line(BytePos(10)); + fm.next_line(BytePos(2)); + } +} + + + // // Local Variables: // mode: rust diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index d2f6b7956ef..c454f5dde2b 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -63,7 +63,7 @@ struct codemap_t { impl codemap_t: span_handler { fn span_fatal(sp: span, msg: &str) -> ! { self.handler.emit(Some((self.cm, sp)), msg, fatal); - fail; + die!(); } fn span_err(sp: span, msg: &str) { self.handler.emit(Some((self.cm, sp)), msg, error); @@ -89,7 +89,7 @@ impl codemap_t: span_handler { impl handler_t: handler { fn fatal(msg: &str) -> ! { (self.emit)(None, msg, fatal); - fail; + die!(); } fn err(msg: &str) { (self.emit)(None, msg, error); diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index a2484e2d6df..03aa0cde811 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -98,8 +98,8 @@ use ext::base::*; use parse; use core::vec; -use std::map; -use std::map::HashMap; +use std::oldmap; +use std::oldmap::HashMap; // Transitional reexports so qquote can find the paths it is looking for mod syntax { @@ -311,7 +311,7 @@ priv impl ext_ctxt { } fn stmt(expr: @ast::expr) -> @ast::stmt { - @ast::spanned { node: ast::stmt_semi(expr, self.next_id()), + @codemap::spanned { node: ast::stmt_semi(expr, self.next_id()), span: expr.span } } @@ -322,7 +322,7 @@ priv impl ext_ctxt { self.expr( span, ast::expr_lit( - @ast::spanned { node: ast::lit_str(s), + @codemap::spanned { node: ast::lit_str(s), span: span})), ast::expr_vstore_uniq)) } @@ -331,7 +331,7 @@ priv impl ext_ctxt { self.expr( span, ast::expr_lit( - @ast::spanned { node: ast::lit_uint(i as u64, ast::ty_u), + @codemap::spanned { node: ast::lit_uint(i as u64, ast::ty_u), span: span})) } @@ -342,7 +342,7 @@ priv impl ext_ctxt { } fn blk(span: span, stmts: ~[@ast::stmt]) -> ast::blk { - ast::spanned { + codemap::spanned { node: ast::blk_ { view_items: ~[], stmts: stmts, @@ -355,7 +355,7 @@ priv impl ext_ctxt { } fn expr_blk(expr: @ast::expr) -> ast::blk { - ast::spanned { + codemap::spanned { node: ast::blk_ { view_items: ~[], stmts: ~[], @@ -593,7 +593,7 @@ fn mk_ser_method( ident: cx.ident_of(~"encode"), attrs: ~[], tps: ~[], - self_ty: ast::spanned { node: ast::sty_region(ast::m_imm), + self_ty: codemap::spanned { node: ast::sty_region(ast::m_imm), span: span }, purity: ast::impure_fn, decl: ser_decl, @@ -651,7 +651,7 @@ fn mk_deser_method( ident: cx.ident_of(~"decode"), attrs: ~[], tps: ~[], - self_ty: ast::spanned { node: ast::sty_static, span: span }, + self_ty: codemap::spanned { node: ast::sty_static, span: span }, purity: ast::impure_fn, decl: deser_decl, body: deser_body, @@ -762,7 +762,7 @@ fn mk_struct_deser_impl( ] ); - ast::spanned { + codemap::spanned { node: ast::field_ { mutbl: field.mutbl, ident: field.ident, @@ -812,8 +812,8 @@ fn mk_struct_fields(fields: ~[@ast::struct_field]) -> ~[field] { do fields.map |field| { let (ident, mutbl) = match field.node.kind { ast::named_field(ident, mutbl, _) => (ident, mutbl), - _ => fail ~"[auto_encode] does not support \ - unnamed fields", + _ => die!(~"[auto_encode] does not support \ + unnamed fields") }; field { @@ -954,9 +954,9 @@ fn mk_enum_ser_body( ast::tuple_variant_kind(args) => ser_variant(cx, span, variant.node.name, v_idx, args), ast::struct_variant_kind(*) => - fail ~"struct variants unimplemented", + die!(~"struct variants unimplemented"), ast::enum_variant_kind(*) => - fail ~"enum variants unimplemented", + die!(~"enum variants unimplemented"), } }; @@ -1025,7 +1025,7 @@ fn mk_enum_deser_variant_nary( } fn mk_enum_deser_body( - cx: ext_ctxt, + ext_cx: ext_ctxt, span: span, name: ast::ident, variants: ~[ast::variant] @@ -1035,11 +1035,11 @@ fn mk_enum_deser_body( ast::tuple_variant_kind(args) => { if args.is_empty() { // for a nullary variant v, do "v" - cx.expr_path(span, ~[variant.node.name]) + ext_cx.expr_path(span, ~[variant.node.name]) } else { // for an n-ary variant v, do "v(a_1, ..., a_n)" mk_enum_deser_variant_nary( - cx, + ext_cx, span, variant.node.name, args @@ -1047,100 +1047,105 @@ fn mk_enum_deser_body( } }, ast::struct_variant_kind(*) => - fail ~"struct variants unimplemented", + die!(~"struct variants unimplemented"), ast::enum_variant_kind(*) => - fail ~"enum variants unimplemented", + die!(~"enum variants unimplemented") }; let pat = @ast::pat { - id: cx.next_id(), - node: ast::pat_lit(cx.lit_uint(span, v_idx)), + id: ext_cx.next_id(), + node: ast::pat_lit(ext_cx.lit_uint(span, v_idx)), span: span, }; ast::arm { pats: ~[pat], guard: None, - body: cx.expr_blk(body), + body: ext_cx.expr_blk(body), } }; + let quoted_expr = quote_expr!( + ::core::sys::begin_unwind(~"explicit failure", ~"empty", 1); + ).node; + let impossible_case = ast::arm { pats: ~[@ast::pat { - id: cx.next_id(), + id: ext_cx.next_id(), node: ast::pat_wild, span: span, }], guard: None, // FIXME(#3198): proper error message - body: cx.expr_blk(cx.expr(span, ast::expr_fail(None))), + body: ext_cx.expr_blk(ext_cx.expr(span, quoted_expr)), }; arms.push(impossible_case); // ast for `|i| { match i { $(arms) } }` - let expr_lambda = cx.expr( + let expr_lambda = ext_cx.expr( span, ast::expr_fn_block( ast::fn_decl { inputs: ~[ast::arg { - mode: ast::infer(cx.next_id()), + mode: ast::infer(ext_cx.next_id()), is_mutbl: false, ty: @ast::Ty { - id: cx.next_id(), + id: ext_cx.next_id(), node: ast::ty_infer, span: span }, pat: @ast::pat { - id: cx.next_id(), + id: ext_cx.next_id(), node: ast::pat_ident( ast::bind_by_copy, - ast_util::ident_to_path(span, cx.ident_of(~"i")), + ast_util::ident_to_path(span, + ext_cx.ident_of(~"i")), None), span: span, }, - id: cx.next_id(), + id: ext_cx.next_id(), }], output: @ast::Ty { - id: cx.next_id(), + id: ext_cx.next_id(), node: ast::ty_infer, span: span, }, cf: ast::return_val, }, - cx.expr_blk( - cx.expr( + ext_cx.expr_blk( + ext_cx.expr( span, - ast::expr_match(cx.expr_var(span, ~"i"), arms) + ast::expr_match(ext_cx.expr_var(span, ~"i"), arms) ) ) ) ); // ast for `__d.read_enum_variant($(expr_lambda))` - let expr_lambda = cx.lambda_expr( - cx.expr_call( + let expr_lambda = ext_cx.lambda_expr( + ext_cx.expr_call( span, - cx.expr_field( + ext_cx.expr_field( span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_enum_variant") + ext_cx.expr_var(span, ~"__d"), + ext_cx.ident_of(~"read_enum_variant") ), ~[expr_lambda] ) ); // ast for `__d.read_enum($(e_name), $(expr_lambda))` - cx.expr_call( + ext_cx.expr_call( span, - cx.expr_field( + ext_cx.expr_field( span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_enum") + ext_cx.expr_var(span, ~"__d"), + ext_cx.ident_of(~"read_enum") ), ~[ - cx.lit_str(span, @cx.str_of(name)), + ext_cx.lit_str(span, @ext_cx.str_of(name)), expr_lambda ] ) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index d0974e0654c..3efae955965 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -11,9 +11,8 @@ use core::prelude::*; use ast; -use ast_util::dummy_sp; use codemap; -use codemap::{CodeMap, span, ExpnInfo, ExpandedFrom}; +use codemap::{CodeMap, span, ExpnInfo, ExpandedFrom, dummy_sp}; use diagnostic::span_handler; use ext; use parse; @@ -21,7 +20,7 @@ use parse::{parser, token}; use core::io; use core::vec; -use std::map::HashMap; +use std::oldmap::HashMap; // new-style macro! tt code: // diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 6d44a412742..4d8fd39c960 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -32,7 +32,7 @@ pub fn mk_expr(cx: ext_ctxt, } pub fn mk_lit(cx: ext_ctxt, sp: span, lit: ast::lit_) -> @ast::expr { - let sp_lit = @ast::spanned { node: lit, span: sp }; + let sp_lit = @codemap::spanned { node: lit, span: sp }; mk_expr(cx, sp, ast::expr_lit(sp_lit)) } pub fn mk_int(cx: ext_ctxt, sp: span, i: int) -> @ast::expr { @@ -149,7 +149,7 @@ pub fn mk_uniq_str(cx: ext_ctxt, sp: span, s: ~str) -> @ast::expr { } pub fn mk_field(sp: span, f: &{ident: ast::ident, ex: @ast::expr}) -> ast::field { - ast::spanned { + codemap::spanned { node: ast::field_ { mutbl: ast::m_imm, ident: f.ident, expr: f.ex }, span: sp, } @@ -188,7 +188,7 @@ pub fn mk_global_struct_e(cx: ext_ctxt, pub fn mk_glob_use(cx: ext_ctxt, sp: span, path: ~[ast::ident]) -> @ast::view_item { - let glob = @ast::spanned { + let glob = @codemap::spanned { node: ast::view_path_glob(mk_raw_path(sp, path), cx.next_id()), span: sp, }; @@ -209,7 +209,7 @@ pub fn mk_local(cx: ext_ctxt, sp: span, mutbl: bool, span: sp, }; let ty = @ast::Ty { id: cx.next_id(), node: ast::ty_infer, span: sp }; - let local = @ast::spanned { + let local = @codemap::spanned { node: ast::local_ { is_mutbl: mutbl, ty: ty, @@ -219,14 +219,14 @@ pub fn mk_local(cx: ext_ctxt, sp: span, mutbl: bool, }, span: sp, }; - let decl = ast::spanned {node: ast::decl_local(~[local]), span: sp}; - @ast::spanned { node: ast::stmt_decl(@decl, cx.next_id()), span: sp } + let decl = codemap::spanned {node: ast::decl_local(~[local]), span: sp}; + @codemap::spanned { node: ast::stmt_decl(@decl, cx.next_id()), span: sp } } pub fn mk_block(cx: ext_ctxt, span: span, view_items: ~[@ast::view_item], stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> @ast::expr { - let blk = ast::spanned { + let blk = codemap::spanned { node: ast::blk_ { view_items: view_items, stmts: stmts, @@ -242,7 +242,7 @@ pub fn mk_block_(cx: ext_ctxt, span: span, +stmts: ~[@ast::stmt]) -> ast::blk { - ast::spanned { + codemap::spanned { node: ast::blk_ { view_items: ~[], stmts: stmts, @@ -257,7 +257,7 @@ pub fn mk_simple_block(cx: ext_ctxt, span: span, expr: @ast::expr) -> ast::blk { - ast::spanned { + codemap::spanned { node: ast::blk_ { view_items: ~[], stmts: ~[], @@ -307,13 +307,14 @@ pub fn mk_pat_struct(cx: ext_ctxt, mk_pat(cx, span, move pat) } pub fn mk_bool(cx: ext_ctxt, span: span, value: bool) -> @ast::expr { - let lit_expr = ast::expr_lit(@ast::spanned { node: ast::lit_bool(value), - span: span }); + let lit_expr = ast::expr_lit(@codemap::spanned { + node: ast::lit_bool(value), + span: span }); build::mk_expr(cx, span, move lit_expr) } pub fn mk_stmt(cx: ext_ctxt, span: span, expr: @ast::expr) -> @ast::stmt { let stmt_ = ast::stmt_semi(expr, cx.next_id()); - @ast::spanned { node: move stmt_, span: span } + @codemap::spanned { node: move stmt_, span: span } } pub fn mk_ty_path(cx: ext_ctxt, span: span, diff --git a/src/libsyntax/ext/deriving.rs b/src/libsyntax/ext/deriving.rs index d542b104e54..8e87357f8b5 100644 --- a/src/libsyntax/ext/deriving.rs +++ b/src/libsyntax/ext/deriving.rs @@ -18,12 +18,12 @@ use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def}; use ast::{enum_variant_kind, expr, expr_match, ident, item, item_}; use ast::{item_enum, item_impl, item_struct, m_imm, meta_item, method}; use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; -use ast::{re_anon, spanned, stmt, struct_def, struct_variant_kind}; +use ast::{re_anon, stmt, struct_def, struct_variant_kind}; use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, ty_param}; use ast::{ty_param_bound, ty_path, ty_rptr, unnamed_field, variant}; use ext::base::ext_ctxt; use ext::build; -use codemap::span; +use codemap::{span, spanned}; use parse::token::special_idents::clownshoes_extensions; use core::dvec; diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 0ab94710f40..227a86e0766 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -20,7 +20,7 @@ use parse::{parser, parse_expr_from_source_str, new_parser_from_tts}; use core::option; use core::vec; -use std::map::HashMap; +use std::oldmap::HashMap; pub fn expand_expr(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt, e: expr_, s: span, fld: ast_fold, @@ -154,7 +154,7 @@ pub fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>, fld: ast_fold) -> Option<@ast::item> { let (pth, tts) = match it.node { - item_mac(ast::spanned { node: mac_invoc_tt(pth, ref tts), _}) => { + item_mac(codemap::spanned { node: mac_invoc_tt(pth, ref tts), _}) => { (pth, (*tts)) } _ => cx.span_bug(it.span, ~"invalid item macro invocation") @@ -234,7 +234,7 @@ pub fn expand_stmt(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt, {call_site: sp, callie: {name: *extname, span: exp_sp}})); let expanded = match exp(cx, mac.span, tts) { MRExpr(e) => - @ast::spanned { node: stmt_expr(e, cx.next_id()), + @codemap::spanned { node: stmt_expr(e, cx.next_id()), span: e.span}, MRAny(_,_,stmt_mkr) => stmt_mkr(), _ => cx.span_fatal( @@ -296,6 +296,15 @@ pub fn core_macros() -> ~str { ) ) + macro_rules! fail( + ($msg: expr) => ( + ::core::sys::begin_unwind($msg, file!().to_owned(), line!()) + ); + () => ( + die!(~\"explicit failure\") + ) + ) + macro_rules! fail_unless( ($cond:expr) => { if !$cond { diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index 8abca3d97f9..58ab05987a6 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -17,10 +17,11 @@ use core::prelude::*; use ast::{ident, node_id}; use ast; -use ast_util::{ident_to_path, respan, dummy_sp}; +use ast_util::{ident_to_path}; use ast_util; use attr; -use codemap::span; +use codemap::{span, respan, dummy_sp}; +use codemap; use ext::base::{ext_ctxt, mk_ctxt}; use ext::quote::rt::*; @@ -310,7 +311,7 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { // XXX: Total hack: import `core::kinds::Owned` to work around a // parser bug whereby `fn f<T: ::kinds::Owned>` doesn't parse. let vi = ast::view_item_import(~[ - @ast::spanned { + @codemap::spanned { node: ast::view_path_simple( self.ident_of(~"Owned"), path( @@ -319,19 +320,19 @@ pub impl ext_ctxt: ext_ctxt_ast_builder { self.ident_of(~"kinds"), self.ident_of(~"Owned") ], - ast_util::dummy_sp() + codemap::dummy_sp() ), ast::type_value_ns, self.next_id() ), - span: ast_util::dummy_sp() + span: codemap::dummy_sp() } ]); let vi = @ast::view_item { node: vi, attrs: ~[], vis: ast::private, - span: ast_util::dummy_sp() + span: codemap::dummy_sp() }; self.item( diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs index a74214c8758..1502332859c 100644 --- a/src/libsyntax/ext/pipes/parse_proto.rs +++ b/src/libsyntax/ext/pipes/parse_proto.rs @@ -40,13 +40,13 @@ pub impl parser::Parser: proto_parser { self.expect(token::COLON); let dir = match copy self.token { token::IDENT(n, _) => self.interner.get(n), - _ => fail + _ => die!() }; self.bump(); let dir = match dir { @~"send" => send, @~"recv" => recv, - _ => fail + _ => die!() }; let typarms = if self.token == token::LT { diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 7bf4f2dc1d9..da0ac4e08ab 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -11,7 +11,7 @@ // A protocol compiler for Rust. use ast::ident; -use ast_util::dummy_sp; +use codemap::dummy_sp; use ext::base::ext_ctxt; use ext::pipes::ast_builder::{append_types, ext_ctxt_ast_builder, path}; use ext::pipes::ast_builder::{path_global}; diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 5c2dd82eb7f..6a1d9357694 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -34,8 +34,8 @@ pub impl direction : cmp::Eq { } pub impl direction: ToStr { - pure fn to_str() -> ~str { - match self { + pure fn to_str(&self) -> ~str { + match *self { send => ~"Send", recv => ~"Recv" } diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 7605e01fbf0..4a9a22de50f 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -184,7 +184,7 @@ pub mod rt { Some(ast) => ast, None => { error!("Parse error with ```\n%s\n```", s); - fail + die!() } } } @@ -399,7 +399,7 @@ fn mk_token(cx: ext_ctxt, sp: span, tok: token::Token) -> @ast::expr { ~[mk_ident(cx, sp, ident)]); } - INTERPOLATED(_) => fail ~"quote! with interpolated token", + INTERPOLATED(_) => die!(~"quote! with interpolated token"), _ => () } @@ -437,7 +437,7 @@ fn mk_token(cx: ext_ctxt, sp: span, tok: token::Token) -> @ast::expr { DOLLAR => "DOLLAR", UNDERSCORE => "UNDERSCORE", EOF => "EOF", - _ => fail + _ => die!() }; build::mk_path(cx, sp, ids_ext(cx, ~[name.to_owned()])) @@ -467,7 +467,7 @@ fn mk_tt(cx: ext_ctxt, sp: span, tt: &ast::token_tree) } ast::tt_delim(ref tts) => mk_tts(cx, sp, *tts), - ast::tt_seq(*) => fail ~"tt_seq in quote!", + ast::tt_seq(*) => die!(~"tt_seq in quote!"), ast::tt_nonterminal(sp, ident) => { diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 4c0550b3c3a..9548db70b94 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -10,8 +10,7 @@ // Earley-like parser for macros. use ast::{matcher, match_tok, match_seq, match_nonterminal, ident}; -use ast_util::mk_sp; -use codemap::BytePos; +use codemap::{BytePos, mk_sp}; use codemap; use parse::common::*; //resolve bug? use parse::lexer::*; //resolve bug? @@ -27,7 +26,7 @@ use core::option; use core::str; use core::uint; use core::vec; -use std::map::HashMap; +use std::oldmap::HashMap; /* This is an Earley-like parser, without support for in-grammar nonterminals, only by calling out to the main rust parser for named nonterminals (which it @@ -125,7 +124,7 @@ pub type matcher_pos = ~{ pub fn copy_up(&& mpu: matcher_pos_up) -> matcher_pos { match &mpu { &matcher_pos_up(Some(ref mp)) => copy (*mp), - _ => fail + _ => die!() } } @@ -189,16 +188,16 @@ pub fn nameize(p_s: parse_sess, ms: ~[matcher], res: ~[@named_match]) fn n_rec(p_s: parse_sess, m: matcher, res: ~[@named_match], ret_val: HashMap<ident, @named_match>) { match m { - ast::spanned {node: match_tok(_), _} => (), - ast::spanned {node: match_seq(ref more_ms, _, _, _, _), _} => { + codemap::spanned {node: match_tok(_), _} => (), + codemap::spanned {node: match_seq(ref more_ms, _, _, _, _), _} => { for (*more_ms).each() |next_m| { n_rec(p_s, *next_m, res, ret_val) }; } - ast::spanned { + codemap::spanned { node: match_nonterminal(bind_name, _, idx), span: sp } => { - if ret_val.contains_key(bind_name) { + if ret_val.contains_key_ref(&bind_name) { p_s.span_diagnostic.span_fatal(sp, ~"Duplicated bind name: "+ *p_s.interner.get(bind_name)) } @@ -239,7 +238,7 @@ pub fn parse(sess: parse_sess, let mut next_eis = ~[]; // or proceed normally let mut eof_eis = ~[]; - let {tok: tok, sp: sp} = rdr.peek(); + let TokenAndSpan {tok: tok, sp: sp} = rdr.peek(); /* we append new items to this while we go */ while cur_eis.len() > 0u { /* for each Earley Item */ @@ -362,7 +361,7 @@ pub fn parse(sess: parse_sess, fmt!("%s ('%s')", *sess.interner.get(name), *sess.interner.get(bind)) } - _ => fail + _ => die!() } }), ~" or "); return error(sp, fmt!( "Local ambiguity: multiple parsing options: \ @@ -387,7 +386,7 @@ pub fn parse(sess: parse_sess, parse_nt(rust_parser, *sess.interner.get(name)))); ei.idx += 1u; } - _ => fail + _ => die!() } cur_eis.push(move ei); diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index f7ef79db466..31172cbfa85 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -13,8 +13,7 @@ use core::prelude::*; use ast::{ident, matcher_, matcher, match_tok, match_nonterminal, match_seq}; use ast::{tt_delim}; use ast; -use ast_util::dummy_sp; -use codemap::span; +use codemap::{span, spanned, dummy_sp}; use ext::base::{ext_ctxt, MacResult, MRAny, MRDef, MacroDef, NormalTT}; use ext::base; use ext::tt::macro_parser::{error}; @@ -27,13 +26,13 @@ use parse::token::{FAT_ARROW, SEMI, LBRACE, RBRACE, nt_matchers, nt_tt}; use print; use core::io; -use std::map::HashMap; +use std::oldmap::HashMap; pub fn add_new_extension(cx: ext_ctxt, sp: span, name: ident, arg: ~[ast::token_tree]) -> base::MacResult { // these spans won't matter, anyways fn ms(m: matcher_) -> matcher { - ast::spanned { node: m, span: dummy_sp() } + spanned { node: m, span: dummy_sp() } } let lhs_nm = cx.parse_sess().interner.gensym(@~"lhs"); diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index b3b1e04976a..6bf90617a6e 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -13,15 +13,16 @@ use core::prelude::*; use ast; use ast::{token_tree, tt_delim, tt_tok, tt_seq, tt_nonterminal,ident}; use ast_util; -use codemap::span; +use codemap::{span, dummy_sp}; use diagnostic::span_handler; use ext::tt::macro_parser::{named_match, matched_seq, matched_nonterminal}; use parse::token::{EOF, INTERPOLATED, IDENT, Token, nt_ident, ident_interner}; +use parse::lexer::TokenAndSpan; use core::option; use core::vec; use std; -use std::map::HashMap; +use std::oldmap::HashMap; enum tt_frame_up { /* to break a circularity */ tt_frame_up(Option<tt_frame>) @@ -43,7 +44,7 @@ pub type tt_reader = @{ interner: @ident_interner, mut cur: tt_frame, /* for MBE-style macro transcription */ - interpolations: std::map::HashMap<ident, @named_match>, + interpolations: std::oldmap::HashMap<ident, @named_match>, mut repeat_idx: ~[uint], mut repeat_len: ~[uint], /* cached: */ @@ -55,21 +56,21 @@ pub type tt_reader = @{ * `src` contains no `tt_seq`s and `tt_nonterminal`s, `interp` can (and * should) be none. */ pub fn new_tt_reader(sp_diag: span_handler, itr: @ident_interner, - interp: Option<std::map::HashMap<ident,@named_match>>, + interp: Option<std::oldmap::HashMap<ident,@named_match>>, src: ~[ast::token_tree]) -> tt_reader { let r = @{sp_diag: sp_diag, interner: itr, mut cur: @{readme: src, mut idx: 0u, dotdotdoted: false, sep: None, up: tt_frame_up(option::None)}, interpolations: match interp { /* just a convienience */ - None => std::map::HashMap(), + None => std::oldmap::HashMap(), Some(x) => x }, mut repeat_idx: ~[], mut repeat_len: ~[], /* dummy values, never read: */ mut cur_tok: EOF, - mut cur_span: ast_util::dummy_sp() + mut cur_span: dummy_sp() }; tt_next_token(r); /* get cur_tok and cur_span set up */ return r; @@ -149,8 +150,8 @@ fn lockstep_iter_size(t: token_tree, r: tt_reader) -> lis { } -pub fn tt_next_token(&&r: tt_reader) -> {tok: Token, sp: span} { - let ret_val = { tok: r.cur_tok, sp: r.cur_span }; +pub fn tt_next_token(&&r: tt_reader) -> TokenAndSpan { + let ret_val = TokenAndSpan { tok: r.cur_tok, sp: r.cur_span }; while r.cur.idx >= r.cur.readme.len() { /* done with this set; pop or repeat? */ if ! r.cur.dotdotdoted diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 5c80a6664de..cfa8a3c1153 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -495,7 +495,6 @@ pub fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { expr_index(fld.fold_expr(el), fld.fold_expr(er)) } expr_path(pth) => expr_path(fld.fold_path(pth)), - expr_fail(e) => expr_fail(option::map(&e, |x| fld.fold_expr(*x))), expr_break(opt_ident) => expr_break(option::map(&opt_ident, |x| fld.fold_ident(*x))), expr_again(opt_ident) => diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 3ed31c0953c..e6ba543cf79 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -11,7 +11,7 @@ use core::prelude::*; use ast; -use ast_util::spanned; +use codemap::spanned; use codemap::BytePos; use parse::common::*; //resolve bug? use parse::token; diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index afe6823e76d..4ceb04c55d0 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -13,6 +13,7 @@ */ use ast; +use codemap; use ast_util::operator_prec; pub fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool { @@ -31,7 +32,8 @@ pub fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool { pub fn expr_is_simple_block(e: @ast::expr) -> bool { match e.node { ast::expr_block( - ast::spanned { node: ast::blk_ { rules: ast::default_blk, _ }, _ } + codemap::spanned { + node: ast::blk_ { rules: ast::default_blk, _ }, _ } ) => true, _ => false } diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 26de85548e1..d7640ce3a23 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -14,7 +14,7 @@ use ast; use codemap::{BytePos, CharPos, CodeMap, FileMap, Pos}; use diagnostic; use parse::lexer::{is_whitespace, get_str_from, reader}; -use parse::lexer::{string_reader, bump, is_eof, nextch}; +use parse::lexer::{string_reader, bump, is_eof, nextch, TokenAndSpan}; use parse::lexer; use parse::token; use parse; @@ -117,7 +117,7 @@ pub fn strip_doc_comment_decoration(comment: ~str) -> ~str { return str::connect(lines, ~"\n"); } - fail ~"not a doc-comment: " + comment; + die!(~"not a doc-comment: " + comment); } fn read_to_eol(rdr: string_reader) -> ~str { @@ -295,7 +295,7 @@ fn consume_comment(rdr: string_reader, code_to_the_left: bool, read_block_comment(rdr, code_to_the_left, comments); } else if rdr.curr == '#' && nextch(rdr) == '!' { read_shebang_comment(rdr, code_to_the_left, comments); - } else { fail; } + } else { die!(); } debug!("<<< consume comment"); } @@ -334,7 +334,7 @@ pub fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler, let bstart = rdr.pos; rdr.next_token(); //discard, and look ahead; we're working with internal state - let {tok: tok, sp: sp} = rdr.peek(); + let TokenAndSpan {tok: tok, sp: sp} = rdr.peek(); if token::is_lit(tok) { let s = get_str_from(rdr, bstart); literals.push({lit: s, pos: sp.lo}); diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index 583ad982000..d82a5a18039 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -11,15 +11,14 @@ use core::prelude::*; use ast; -use ast_util::spanned; -use codemap::BytePos; +use codemap::{BytePos, spanned}; use parse::lexer::reader; use parse::parser::Parser; use parse::token; use core::option::{None, Option, Some}; use core::option; -use std::map::HashMap; +use std::oldmap::HashMap; pub type seq_sep = { sep: Option<token::Token>, @@ -190,7 +189,9 @@ pub impl Parser { if self.token == token::GT { self.bump(); } else if self.token == token::BINOP(token::SHR) { - self.swap(token::GT, self.span.lo + BytePos(1u), self.span.hi); + self.replace_token(token::GT, + self.span.lo + BytePos(1u), + self.span.hi); } else { let mut s: ~str = ~"expected `"; s += token_to_str(self.reader, token::GT); @@ -229,7 +230,7 @@ pub impl Parser { } fn parse_seq_lt_gt<T: Copy>(sep: Option<token::Token>, - f: fn(Parser) -> T) -> ast::spanned<~[T]> { + f: fn(Parser) -> T) -> spanned<~[T]> { let lo = self.span.lo; self.expect(token::LT); let result = self.parse_seq_to_before_gt::<T>(sep, f); @@ -277,7 +278,7 @@ pub impl Parser { // NB: Do not use this function unless you actually plan to place the // spanned list in the AST. fn parse_seq<T: Copy>(bra: token::Token, ket: token::Token, sep: seq_sep, - f: fn(Parser) -> T) -> ast::spanned<~[T]> { + f: fn(Parser) -> T) -> spanned<~[T]> { let lo = self.span.lo; self.expect(bra); let result = self.parse_seq_to_before_end::<T>(ket, sep, f); diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs index caab03afb76..5decb2351e3 100644 --- a/src/libsyntax/parse/eval.rs +++ b/src/libsyntax/parse/eval.rs @@ -10,8 +10,7 @@ use parser::Parser; use attr::parser_attr; -use ast_util::mk_sp; -use codemap::span; +use codemap::{span, mk_sp}; type ctx = @{sess: parse::parse_sess, @@ -75,7 +74,7 @@ fn parse_companion_mod(cx: ctx, prefix: &Path, suffix: &Option<Path>) // XXX: Using a dummy span, but this code will go away soon let p0 = new_sub_parser_from_file(cx.sess, cx.cfg, modpath, - ast_util::dummy_sp()); + codemap::dummy_sp()); let inner_attrs = p0.parse_inner_attrs_and_next(); let m0 = p0.parse_mod_items(token::EOF, inner_attrs.next); return (m0.view_items, m0.items, inner_attrs.inner); diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index c3b94182cc2..381183e736c 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -30,14 +30,17 @@ use std; pub trait reader { fn is_eof() -> bool; - fn next_token() -> {tok: token::Token, sp: span}; + fn next_token() -> TokenAndSpan; fn fatal(~str) -> !; fn span_diag() -> span_handler; pure fn interner() -> @token::ident_interner; - fn peek() -> {tok: token::Token, sp: span}; + fn peek() -> TokenAndSpan; fn dup() -> reader; } +#[deriving_eq] +pub struct TokenAndSpan {tok: token::Token, sp: span} + pub type string_reader = @{ span_diagnostic: span_handler, src: @~str, @@ -79,11 +82,14 @@ pub fn new_low_level_string_reader(span_diagnostic: span_handler, filemap: filemap, interner: itr, /* dummy values; not read */ mut peek_tok: token::EOF, - mut peek_span: ast_util::dummy_sp()}; + mut peek_span: codemap::dummy_sp()}; bump(r); return r; } +// duplicating the string reader is probably a bad idea, in +// that using them will cause interleaved pushes of line +// offsets to the underlying filemap... fn dup_string_reader(&&r: string_reader) -> string_reader { @{span_diagnostic: r.span_diagnostic, src: r.src, mut pos: r.pos, @@ -95,8 +101,9 @@ fn dup_string_reader(&&r: string_reader) -> string_reader { impl string_reader: reader { fn is_eof() -> bool { is_eof(self) } - fn next_token() -> {tok: token::Token, sp: span} { - let ret_val = {tok: self.peek_tok, sp: self.peek_span}; + // return the next token. EFFECT: advances the string_reader. + fn next_token() -> TokenAndSpan { + let ret_val = TokenAndSpan {tok: self.peek_tok, sp: self.peek_span}; string_advance_token(self); return ret_val; } @@ -105,15 +112,15 @@ impl string_reader: reader { } fn span_diag() -> span_handler { self.span_diagnostic } pure fn interner() -> @token::ident_interner { self.interner } - fn peek() -> {tok: token::Token, sp: span} { - {tok: self.peek_tok, sp: self.peek_span} + fn peek() -> TokenAndSpan { + TokenAndSpan {tok: self.peek_tok, sp: self.peek_span} } fn dup() -> reader { dup_string_reader(self) as reader } } pub impl tt_reader: reader { fn is_eof() -> bool { self.cur_tok == token::EOF } - fn next_token() -> {tok: token::Token, sp: span} { + fn next_token() -> TokenAndSpan { /* weird resolve bug: if the following `if`, or any of its statements are removed, we get resolution errors */ if false { @@ -127,27 +134,29 @@ pub impl tt_reader: reader { } fn span_diag() -> span_handler { self.sp_diag } pure fn interner() -> @token::ident_interner { self.interner } - fn peek() -> {tok: token::Token, sp: span} { - { tok: self.cur_tok, sp: self.cur_span } + fn peek() -> TokenAndSpan { + TokenAndSpan { tok: self.cur_tok, sp: self.cur_span } } fn dup() -> reader { dup_tt_reader(self) as reader } } +// EFFECT: advance peek_tok and peek_span to refer to the next token. fn string_advance_token(&&r: string_reader) { - for consume_whitespace_and_comments(r).each |comment| { - r.peek_tok = comment.tok; - r.peek_span = comment.sp; - return; + match (consume_whitespace_and_comments(r)) { + Some(comment) => { + r.peek_tok = comment.tok; + r.peek_span = comment.sp; + }, + None => { + if is_eof(r) { + r.peek_tok = token::EOF; + } else { + let start_bytepos = r.last_pos; + r.peek_tok = next_token_inner(r); + r.peek_span = codemap::mk_sp(start_bytepos, r.last_pos); + }; + } } - - if is_eof(r) { - r.peek_tok = token::EOF; - } else { - let start_bytepos = r.last_pos; - r.peek_tok = next_token_inner(r); - r.peek_span = ast_util::mk_sp(start_bytepos, r.last_pos); - }; - } fn byte_offset(rdr: string_reader) -> BytePos { @@ -163,6 +172,8 @@ pub fn get_str_from(rdr: string_reader, start: BytePos) -> ~str { } } +// EFFECT: advance the StringReader by one character. If a newline is +// discovered, add it to the FileMap's list of line start offsets. pub fn bump(rdr: string_reader) { rdr.last_pos = rdr.pos; let current_byte_offset = byte_offset(rdr).to_uint();; @@ -203,7 +214,7 @@ fn hex_digit_val(c: char) -> int { if in_range(c, '0', '9') { return (c as int) - ('0' as int); } if in_range(c, 'a', 'f') { return (c as int) - ('a' as int) + 10; } if in_range(c, 'A', 'F') { return (c as int) - ('A' as int) + 10; } - fail; + die!(); } fn bin_digit_value(c: char) -> int { if c == '0' { return 0; } return 1; } @@ -233,16 +244,19 @@ fn is_hex_digit(c: char) -> bool { fn is_bin_digit(c: char) -> bool { return c == '0' || c == '1'; } -// might return a sugared-doc-attr +// EFFECT: eats whitespace and comments. +// returns a Some(sugared-doc-attr) if one exists, None otherwise. fn consume_whitespace_and_comments(rdr: string_reader) - -> Option<{tok: token::Token, sp: span}> { + -> Option<TokenAndSpan> { while is_whitespace(rdr.curr) { bump(rdr); } return consume_any_line_comment(rdr); } -// might return a sugared-doc-attr +// PRECONDITION: rdr.curr is not whitespace +// EFFECT: eats any kind of comment. +// returns a Some(sugared-doc-attr) if one exists, None otherwise fn consume_any_line_comment(rdr: string_reader) - -> Option<{tok: token::Token, sp: span}> { + -> Option<TokenAndSpan> { if rdr.curr == '/' { match nextch(rdr) { '/' => { @@ -256,9 +270,9 @@ fn consume_any_line_comment(rdr: string_reader) str::push_char(&mut acc, rdr.curr); bump(rdr); } - return Some({ + return Some(TokenAndSpan{ tok: token::DOC_COMMENT(rdr.interner.intern(@acc)), - sp: ast_util::mk_sp(start_bpos, rdr.pos) + sp: codemap::mk_sp(start_bpos, rdr.pos) }); } else { while rdr.curr != '\n' && !is_eof(rdr) { bump(rdr); } @@ -285,7 +299,7 @@ fn consume_any_line_comment(rdr: string_reader) // might return a sugared-doc-attr fn consume_block_comment(rdr: string_reader) - -> Option<{tok: token::Token, sp: span}> { + -> Option<TokenAndSpan> { // block comments starting with "/**" or "/*!" are doc-comments if rdr.curr == '*' || rdr.curr == '!' { @@ -301,9 +315,9 @@ fn consume_block_comment(rdr: string_reader) acc += ~"*/"; bump(rdr); bump(rdr); - return Some({ + return Some(TokenAndSpan{ tok: token::DOC_COMMENT(rdr.interner.intern(@acc)), - sp: ast_util::mk_sp(start_bpos, rdr.pos) + sp: codemap::mk_sp(start_bpos, rdr.pos) }); } } else { @@ -403,7 +417,7 @@ fn scan_number(c: char, rdr: string_reader) -> token::Token { if str::len(num_str) == 0u { rdr.fatal(~"no valid digits found for number"); } - let parsed = u64::from_str_radix(num_str, base as u64).get(); + let parsed = u64::from_str_radix(num_str, base as uint).get(); match tp { either::Left(t) => return token::LIT_INT(parsed as i64, t), either::Right(t) => return token::LIT_UINT(parsed, t) @@ -457,7 +471,7 @@ fn scan_number(c: char, rdr: string_reader) -> token::Token { if str::len(num_str) == 0u { rdr.fatal(~"no valid digits found for number"); } - let parsed = u64::from_str_radix(num_str, base as u64).get(); + let parsed = u64::from_str_radix(num_str, base as uint).get(); debug!("lexing %s as an unsuffixed integer literal", num_str); @@ -702,6 +716,41 @@ fn consume_whitespace(rdr: string_reader) { while is_whitespace(rdr.curr) && !is_eof(rdr) { bump(rdr); } } +#[cfg(test)] +pub mod test { + + use super::*; + use util::interner; + use diagnostic; + use util::testing::{check_equal, check_equal_ptr}; + #[test] fn t1 () { + let teststr = + @~"/* my source file */ +fn main() { io::println(~\"zebra\"); }\n"; + let cm = CodeMap::new(); + let fm = cm.new_filemap(~"zebra.rs",teststr); + let ident_interner = token::mk_ident_interner(); // interner::mk(); + let id = ident_interner.intern(@~"fn"); + let span_handler = + diagnostic::mk_span_handler(diagnostic::mk_handler(None),@cm); + let string_reader = new_string_reader(span_handler,fm,ident_interner); + let tok1 = string_reader.next_token(); + let tok2 = TokenAndSpan{ + tok:token::IDENT(id, false), + sp:span {lo:BytePos(21),hi:BytePos(23),expn_info: None}}; + check_equal (tok1,tok2); + // the 'main' id is already read: + check_equal (string_reader.last_pos,BytePos(28)); + // read another token: + let tok3 = string_reader.next_token(); + let tok4 = TokenAndSpan{ + tok:token::IDENT(ident_interner.intern (@~"main"), false), + sp:span {lo:BytePos(24),hi:BytePos(28),expn_info: None}}; + check_equal (tok3,tok4); + // the lparen is already read: + check_equal (string_reader.last_pos,BytePos(29)) + } +} // // Local Variables: diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index f9088bfd635..6169233c1b7 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -10,6 +10,7 @@ //! The main parser interface + use ast::node_id; use ast; use codemap::{span, CodeMap, FileMap, CharPos, BytePos}; @@ -33,6 +34,7 @@ pub mod token; pub mod comments; pub mod attr; + /// Common routines shared by parser mods pub mod common; @@ -215,3 +217,4 @@ pub fn new_parser_from_tts(sess: parse_sess, cfg: ast::crate_cfg, None, tts); return Parser(sess, cfg, trdr as reader) } + diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 7dad15f9dfc..cdde542bb1f 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -21,8 +21,7 @@ use core::prelude::*; use ast::{expr, expr_lit, lit_nil}; use ast; -use ast_util::{respan}; -use codemap::span; +use codemap::{span, respan}; use parse::parser::Parser; use parse::token::Token; use parse::token; @@ -138,7 +137,7 @@ pub impl Parser { desc: &str) { self.span_err(sp, fmt!("obsolete syntax: %s", kind_str)); - if !self.obsolete_set.contains_key(kind) { + if !self.obsolete_set.contains_key_ref(&kind) { self.sess.span_diagnostic.handler().note(fmt!("%s", desc)); self.obsolete_set.insert(kind, ()); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 48f38092f88..5cd78dd9049 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -20,7 +20,7 @@ use ast::{decl_local, default_blk, deref, div, enum_def, enum_variant_kind}; use ast::{expl, expr, expr_, expr_addr_of, expr_match, expr_again}; use ast::{expr_assert, expr_assign, expr_assign_op, expr_binary, expr_block}; use ast::{expr_break, expr_call, expr_cast, expr_copy, expr_do_body}; -use ast::{expr_fail, expr_field, expr_fn, expr_fn_block, expr_if, expr_index}; +use ast::{expr_field, expr_fn, expr_fn_block, expr_if, expr_index}; use ast::{expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac}; use ast::{expr_method_call, expr_paren, expr_path, expr_rec, expr_repeat}; use ast::{expr_ret, expr_swap, expr_struct, expr_tup, expr_unary}; @@ -55,15 +55,16 @@ use ast::{view_path, view_path_glob, view_path_list, view_path_simple}; use ast::{visibility, vstore, vstore_box, vstore_fixed, vstore_slice}; use ast::{vstore_uniq}; use ast; -use ast_util::{spanned, respan, mk_sp, ident_to_path, operator_prec}; +use ast_util::{ident_to_path, operator_prec}; use ast_util; use classify; -use codemap::{span,FssNone, BytePos}; +use codemap::{span,FssNone, BytePos, spanned, respan, mk_sp}; use codemap; use parse::attr::parser_attr; use parse::common::{seq_sep_none, token_to_str}; use parse::common::{seq_sep_trailing_disallowed, seq_sep_trailing_allowed}; use parse::lexer::reader; +use parse::lexer::TokenAndSpan; use parse::obsolete::{ObsoleteClassTraits, ObsoleteModeInFnType}; use parse::obsolete::{ObsoleteLet, ObsoleteFieldTerminator}; use parse::obsolete::{ObsoleteMoveInit, ObsoleteBinaryMove}; @@ -86,7 +87,7 @@ use core::either; use core::result::Result; use core::vec::push; use core::vec; -use std::map::HashMap; +use std::oldmap::HashMap; #[deriving_eq] enum restriction { @@ -193,7 +194,7 @@ pub fn Parser(sess: parse_sess, token: tok0.tok, span: span0, last_span: span0, - buffer: [mut {tok: tok0.tok, sp: span0}, ..4], + mut buffer: [TokenAndSpan {tok: tok0.tok, sp: span0}, ..4], buffer_start: 0, buffer_end: 0, tokens_consumed: 0u, @@ -213,7 +214,7 @@ pub struct Parser { mut token: token::Token, mut span: span, mut last_span: span, - mut buffer: [mut {tok: token::Token, sp: span} * 4], + mut buffer: [TokenAndSpan * 4], mut buffer_start: int, mut buffer_end: int, mut tokens_consumed: uint, @@ -234,6 +235,7 @@ pub struct Parser { } pub impl Parser { + // advance the parser by one token fn bump() { self.last_span = self.span; let next = if self.buffer_start == self.buffer_end { @@ -247,7 +249,8 @@ pub impl Parser { self.span = next.sp; self.tokens_consumed += 1u; } - fn swap(next: token::Token, +lo: BytePos, +hi: BytePos) { + // EFFECT: replace the current token and span with the given one + fn replace_token(next: token::Token, +lo: BytePos, +hi: BytePos) { self.token = next; self.span = mk_sp(lo, hi); } @@ -800,7 +803,7 @@ pub impl Parser { self.bump(); self.lit_from_token(tok) }; - ast::spanned { node: lit, span: mk_sp(lo, self.last_span.hi) } + codemap::spanned { node: lit, span: mk_sp(lo, self.last_span.hi) } } fn parse_path_without_tps() -> @path { @@ -875,7 +878,7 @@ pub impl Parser { self.parse_seq_lt_gt(Some(token::COMMA), |p| p.parse_ty(false)) } else { - ast::spanned {node: ~[], span: path.span} + codemap::spanned {node: ~[], span: path.span} } }; @@ -917,14 +920,14 @@ pub impl Parser { @expr { id: self.get_id(), callee_id: self.get_id(), - node: expr_mac(ast::spanned {node: m, span: mk_sp(lo, hi)}), + node: expr_mac(codemap::spanned {node: m, span: mk_sp(lo, hi)}), span: mk_sp(lo, hi), } } fn mk_lit_u32(i: u32) -> @expr { let span = self.span; - let lv_lit = @ast::spanned { node: lit_uint(i as u64, ty_u32), + let lv_lit = @codemap::spanned { node: lit_uint(i as u64, ty_u32), span: span }; @expr { @@ -1031,12 +1034,6 @@ pub impl Parser { } } hi = self.span.hi; - } else if self.eat_keyword(~"fail") { - if can_begin_expr(self.token) { - let e = self.parse_expr(); - hi = e.span.hi; - ex = expr_fail(Some(e)); - } else { ex = expr_fail(None); } } else if self.eat_keyword(~"log") { self.expect(token::LPAREN); let lvl = self.parse_expr(); @@ -1404,7 +1401,7 @@ pub impl Parser { hi = e.span.hi; // HACK: turn &[...] into a &-evec ex = match e.node { - expr_vec(*) | expr_lit(@ast::spanned { + expr_vec(*) | expr_lit(@codemap::spanned { node: lit_str(_), span: _ }) if m == m_imm => { @@ -1429,7 +1426,7 @@ pub impl Parser { expr_vec(*) if m == m_mutbl => expr_vstore(e, expr_vstore_mut_box), expr_vec(*) if m == m_imm => expr_vstore(e, expr_vstore_box), - expr_lit(@ast::spanned { + expr_lit(@codemap::spanned { node: lit_str(_), span: _}) if m == m_imm => expr_vstore(e, expr_vstore_box), _ => expr_unary(box(m), e) @@ -1442,7 +1439,7 @@ pub impl Parser { hi = e.span.hi; // HACK: turn ~[...] into a ~-evec ex = match e.node { - expr_vec(*) | expr_lit(@ast::spanned { + expr_vec(*) | expr_lit(@codemap::spanned { node: lit_str(_), span: _}) if m == m_imm => expr_vstore(e, expr_vstore_uniq), _ => expr_unary(uniq(m), e) @@ -1453,11 +1450,12 @@ pub impl Parser { return self.mk_expr(lo, hi, ex); } - + // parse an expression of binops fn parse_binops() -> @expr { - return self.parse_more_binops(self.parse_prefix_expr(), 0); + self.parse_more_binops(self.parse_prefix_expr(), 0) } + // parse an expression of binops of at least min_prec precedence fn parse_more_binops(lhs: @expr, min_prec: uint) -> @expr { if self.expr_is_complete(lhs) { return lhs; } @@ -1465,65 +1463,73 @@ pub impl Parser { if peeked == token::BINOP(token::OR) && (self.restriction == RESTRICT_NO_BAR_OP || self.restriction == RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) { - return lhs; - } - if peeked == token::OROR && + lhs + } else if peeked == token::OROR && self.restriction == RESTRICT_NO_BAR_OR_DOUBLEBAR_OP { - return lhs; - } - let cur_opt = token_to_binop(peeked); - match cur_opt { - Some(cur_op) => { - let cur_prec = operator_prec(cur_op); - if cur_prec > min_prec { - self.bump(); - let expr = self.parse_prefix_expr(); - let rhs = self.parse_more_binops(expr, cur_prec); - self.get_id(); // see ast_util::op_expr_callee_id - let bin = self.mk_expr(lhs.span.lo, rhs.span.hi, - expr_binary(cur_op, lhs, rhs)); - return self.parse_more_binops(bin, min_prec); + lhs + } else { + let cur_opt = token_to_binop(peeked); + match cur_opt { + Some(cur_op) => { + let cur_prec = operator_prec(cur_op); + if cur_prec > min_prec { + self.bump(); + let expr = self.parse_prefix_expr(); + let rhs = self.parse_more_binops(expr, cur_prec); + self.get_id(); // see ast_util::op_expr_callee_id + let bin = self.mk_expr(lhs.span.lo, rhs.span.hi, + expr_binary(cur_op, lhs, rhs)); + self.parse_more_binops(bin, min_prec) + } else { + lhs + } + } + None => { + if as_prec > min_prec && self.eat_keyword(~"as") { + let rhs = self.parse_ty(true); + let _as = self.mk_expr(lhs.span.lo, + rhs.span.hi, + expr_cast(lhs, rhs)); + self.parse_more_binops(_as, min_prec) + } else { + lhs + } + } } - } - _ => () - } - if as_prec > min_prec && self.eat_keyword(~"as") { - let rhs = self.parse_ty(true); - let _as = - self.mk_expr(lhs.span.lo, rhs.span.hi, expr_cast(lhs, rhs)); - return self.parse_more_binops(_as, min_prec); } - return lhs; } + // parse an assignment expression.... + // actually, this seems to be the main entry point for + // parsing an arbitrary expression. fn parse_assign_expr() -> @expr { let lo = self.span.lo; let lhs = self.parse_binops(); match copy self.token { - token::EQ => { - self.bump(); - let rhs = self.parse_expr(); - return self.mk_expr(lo, rhs.span.hi, expr_assign(lhs, rhs)); + token::EQ => { + self.bump(); + let rhs = self.parse_expr(); + self.mk_expr(lo, rhs.span.hi, expr_assign(lhs, rhs)) } token::BINOPEQ(op) => { - self.bump(); - let rhs = self.parse_expr(); - let mut aop; - match op { - token::PLUS => aop = add, - token::MINUS => aop = subtract, - token::STAR => aop = mul, - token::SLASH => aop = div, - token::PERCENT => aop = rem, - token::CARET => aop = bitxor, - token::AND => aop = bitand, - token::OR => aop = bitor, - token::SHL => aop = shl, - token::SHR => aop = shr - } - self.get_id(); // see ast_util::op_expr_callee_id - return self.mk_expr(lo, rhs.span.hi, - expr_assign_op(aop, lhs, rhs)); + self.bump(); + let rhs = self.parse_expr(); + let mut aop; + match op { + token::PLUS => aop = add, + token::MINUS => aop = subtract, + token::STAR => aop = mul, + token::SLASH => aop = div, + token::PERCENT => aop = rem, + token::CARET => aop = bitxor, + token::AND => aop = bitand, + token::OR => aop = bitor, + token::SHL => aop = shl, + token::SHR => aop = shr + } + self.get_id(); // see ast_util::op_expr_callee_id + self.mk_expr(lo, rhs.span.hi, + expr_assign_op(aop, lhs, rhs)) } token::LARROW => { self.obsolete(copy self.span, ObsoleteBinaryMove); @@ -1531,17 +1537,18 @@ pub impl Parser { self.bump(); // <- self.bump(); // rhs self.bump(); // ; - return self.mk_expr(lo, self.span.hi, - expr_break(None)); + self.mk_expr(lo, self.span.hi, + expr_break(None)) } token::DARROW => { self.bump(); let rhs = self.parse_expr(); - return self.mk_expr(lo, rhs.span.hi, expr_swap(lhs, rhs)); + self.mk_expr(lo, rhs.span.hi, expr_swap(lhs, rhs)) + } + _ => { + lhs } - _ => {/* fall through */ } } - return lhs; } fn parse_if_expr() -> @expr { @@ -1556,7 +1563,7 @@ pub impl Parser { hi = elexpr.span.hi; } let q = {cond: cond, then: thn, els: els, lo: lo, hi: hi}; - return self.mk_expr(q.lo, q.hi, expr_if(q.cond, q.then, q.els)); + self.mk_expr(q.lo, q.hi, expr_if(q.cond, q.then, q.els)) } fn parse_fn_expr(proto: Proto) -> @expr { @@ -1567,8 +1574,9 @@ pub impl Parser { let decl = self.parse_fn_decl(|p| p.parse_arg_or_capture_item()); let body = self.parse_block(); - return self.mk_expr(lo, body.span.hi, - expr_fn(proto, decl, body, @())); + + self.mk_expr(lo, body.span.hi, + expr_fn(proto, decl, body, @())) } // `|args| { ... }` like in `do` expressions @@ -1794,7 +1802,7 @@ pub impl Parser { self.eat(token::COMMA); } - let blk = ast::spanned { + let blk = codemap::spanned { node: ast::blk_ { view_items: ~[], stmts: ~[], @@ -1812,10 +1820,12 @@ pub impl Parser { return self.mk_expr(lo, hi, expr_match(discriminant, arms)); } + // parse an expression fn parse_expr() -> @expr { return self.parse_expr_res(UNRESTRICTED); } + // parse an expression, subject to the given restriction fn parse_expr_res(r: restriction) -> @expr { let old = self.restriction; self.restriction = r; @@ -1943,7 +1953,9 @@ pub impl Parser { // HACK: parse @"..." as a literal of a vstore @str pat = match sub.node { pat_lit(e@@expr { - node: expr_lit(@ast::spanned {node: lit_str(_), span: _}), _ + node: expr_lit(@codemap::spanned { + node: lit_str(_), + span: _}), _ }) => { let vst = @expr { id: self.get_id(), @@ -1963,7 +1975,9 @@ pub impl Parser { // HACK: parse ~"..." as a literal of a vstore ~str pat = match sub.node { pat_lit(e@@expr { - node: expr_lit(@ast::spanned {node: lit_str(_), span: _}), _ + node: expr_lit(@codemap::spanned { + node: lit_str(_), + span: _}), _ }) => { let vst = @expr { id: self.get_id(), @@ -1985,7 +1999,7 @@ pub impl Parser { // HACK: parse &"..." as a literal of a borrowed str pat = match sub.node { pat_lit(e@@expr { - node: expr_lit(@ast::spanned { + node: expr_lit(@codemap::spanned { node: lit_str(_), span: _}), _ }) => { let vst = @expr { @@ -2011,7 +2025,9 @@ pub impl Parser { if self.token == token::RPAREN { hi = self.span.hi; self.bump(); - let lit = @ast::spanned {node: lit_nil, span: mk_sp(lo, hi)}; + let lit = @codemap::spanned { + node: lit_nil, + span: mk_sp(lo, hi)}; let expr = self.mk_expr(lo, hi, expr_lit(lit)); pat = pat_lit(expr); } else { @@ -2381,7 +2397,7 @@ pub impl Parser { match self.token { token::SEMI => { self.bump(); - stmts.push(@ast::spanned { + stmts.push(@codemap::spanned { node: stmt_semi(e, stmt_id), .. *stmt}); } @@ -2406,7 +2422,7 @@ pub impl Parser { match self.token { token::SEMI => { self.bump(); - stmts.push(@ast::spanned { + stmts.push(@codemap::spanned { node: stmt_mac((*m), true), .. *stmt}); } @@ -2500,7 +2516,7 @@ pub impl Parser { _ => None } } - _ => fail + _ => die!() }; match maybe_bound { @@ -2940,7 +2956,7 @@ pub impl Parser { let actual_dtor = do the_dtor.map |dtor| { let (d_body, d_attrs, d_s) = *dtor; - ast::spanned { node: ast::struct_dtor_ { id: self.get_id(), + codemap::spanned { node: ast::struct_dtor_ { id: self.get_id(), attrs: d_attrs, self_id: self.get_id(), body: d_body}, @@ -3445,7 +3461,7 @@ pub impl Parser { self.bump(); let mut actual_dtor = do the_dtor.map |dtor| { let (d_body, d_attrs, d_s) = *dtor; - ast::spanned { node: ast::struct_dtor_ { id: self.get_id(), + codemap::spanned { node: ast::struct_dtor_ { id: self.get_id(), attrs: d_attrs, self_id: self.get_id(), body: d_body }, @@ -3737,7 +3753,7 @@ pub impl Parser { _ => self.fatal(~"expected open delimiter") }; let m = ast::mac_invoc_tt(pth, tts); - let m: ast::mac = ast::spanned { node: m, + let m: ast::mac = codemap::spanned { node: m, span: mk_sp(self.span.lo, self.span.hi) }; let item_ = item_mac(m); @@ -3892,7 +3908,7 @@ pub impl Parser { let metadata = self.parse_optional_meta(); view_item_use(ident, metadata, self.get_id()) } else { - fail; + die!(); }; self.expect(token::SEMI); @ast::view_item { node: node, diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 2093b5caebd..2770d823bf3 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -21,7 +21,7 @@ use core::char; use core::cmp; use core::str; use core::task; -use std::map::HashMap; +use std::oldmap::HashMap; #[auto_encode] #[auto_decode] @@ -209,7 +209,7 @@ pub fn to_str(in: @ident_interner, t: Token) -> ~str { nt_block(*) => ~"block", nt_stmt(*) => ~"statement", nt_pat(*) => ~"pattern", - nt_expr(*) => fail ~"should have been handled above", + nt_expr(*) => die!(~"should have been handled above"), nt_ty(*) => ~"type", nt_ident(*) => ~"identifier", nt_path(*) => ~"path", @@ -262,7 +262,7 @@ pub fn flip_delimiter(t: token::Token) -> token::Token { token::RPAREN => token::LPAREN, token::RBRACE => token::LBRACE, token::RBRACKET => token::LBRACKET, - _ => fail + _ => die!() } } @@ -454,13 +454,13 @@ pub fn mk_fake_ident_interner() -> @ident_interner { */ pub fn keyword_table() -> HashMap<~str, ()> { let keywords = HashMap(); - for temporary_keyword_table().each_key |word| { + for temporary_keyword_table().each_key_ref |&word| { keywords.insert(word, ()); } - for strict_keyword_table().each_key |word| { + for strict_keyword_table().each_key_ref |&word| { keywords.insert(word, ()); } - for reserved_keyword_table().each_key |word| { + for reserved_keyword_table().each_key_ref |&word| { keywords.insert(word, ()); } keywords @@ -487,7 +487,7 @@ pub fn strict_keyword_table() -> HashMap<~str, ()> { ~"const", ~"copy", ~"do", ~"drop", ~"else", ~"enum", ~"extern", - ~"fail", ~"false", ~"fn", ~"for", + ~"false", ~"fn", ~"for", ~"if", ~"impl", ~"let", ~"log", ~"loop", ~"match", ~"mod", ~"move", ~"mut", diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index d3487fa845f..34ba4526c47 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -119,7 +119,7 @@ pub fn tok_str(++t: token) -> ~str { } } -pub fn buf_str(toks: ~[mut token], szs: ~[mut int], left: uint, right: uint, +pub fn buf_str(toks: ~[token], szs: ~[int], left: uint, right: uint, lim: uint) -> ~str { let n = vec::len(toks); assert (n == vec::len(szs)); @@ -148,17 +148,17 @@ pub fn mk_printer(out: io::Writer, linewidth: uint) -> printer { // fall behind. let n: uint = 3 * linewidth; debug!("mk_printer %u", linewidth); - let token: ~[mut token] = vec::cast_to_mut(vec::from_elem(n, EOF)); - let size: ~[mut int] = vec::cast_to_mut(vec::from_elem(n, 0)); - let scan_stack: ~[mut uint] = vec::cast_to_mut(vec::from_elem(n, 0u)); + let mut token: ~[token] = vec::from_elem(n, EOF); + let mut size: ~[int] = vec::from_elem(n, 0); + let mut scan_stack: ~[uint] = vec::from_elem(n, 0u); printer_(@{out: out, buf_len: n, mut margin: linewidth as int, mut space: linewidth as int, mut left: 0, mut right: 0, - token: move token, - size: move size, + mut token: move token, + mut size: move size, mut left_total: 0, mut right_total: 0, mut scan_stack: move scan_stack, @@ -254,8 +254,8 @@ pub type printer_ = { mut space: int, // number of spaces left on line mut left: uint, // index of left side of input stream mut right: uint, // index of right side of input stream - token: ~[mut token], // ring-buffr stream goes through - size: ~[mut int], // ring-buffer of calculated sizes + mut token: ~[token], // ring-buffr stream goes through + mut size: ~[int], // ring-buffer of calculated sizes mut left_total: int, // running size of stream "...left" mut right_total: int, // running size of stream "...right" // pseudo-stack, really a ring too. Holds the @@ -264,7 +264,7 @@ pub type printer_ = { // BEGIN (if there is any) on top of it. Stuff is flushed off the // bottom as it becomes irrelevant due to the primary ring-buffer // advancing. - mut scan_stack: ~[mut uint], + mut scan_stack: ~[uint], mut scan_stack_empty: bool, // top==bottom disambiguator mut top: uint, // index of top of scan_stack mut bottom: uint, // index of bottom of scan_stack @@ -532,7 +532,7 @@ pub impl printer { } EOF => { // EOF should never get here. - fail; + die!(); } } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 6661f5e810a..5079766239b 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -422,10 +422,10 @@ pub fn print_type_ex(s: ps, &&ty: @ast::Ty, print_colons: bool) { word(s.s, ~"]"); } ast::ty_mac(_) => { - fail ~"print_type doesn't know how to print a ty_mac"; + die!(~"print_type doesn't know how to print a ty_mac"); } ast::ty_infer => { - fail ~"print_type shouldn't see a ty_infer"; + die!(~"print_type shouldn't see a ty_infer"); } } @@ -575,7 +575,7 @@ pub fn print_item(s: ps, &&item: @ast::item) { } bclose(s, item.span); } - ast::item_mac(ast::spanned { node: ast::mac_invoc_tt(pth, ref tts), + ast::item_mac(codemap::spanned { node: ast::mac_invoc_tt(pth, ref tts), _}) => { print_visibility(s, item.vis); print_path(s, pth, false); @@ -617,7 +617,7 @@ pub fn print_enum_def(s: ps, enum_definition: ast::enum_def, word_space(s, ~"="); match enum_definition.variants[0].node.kind { ast::tuple_variant_kind(args) => print_type(s, args[0].ty), - _ => fail ~"newtype syntax with struct?" + _ => die!(~"newtype syntax with struct?") } word(s.s, ~";"); end(s); @@ -686,7 +686,7 @@ pub fn print_struct(s: ps, } match field.node.kind { - ast::named_field(*) => fail ~"unexpected named field", + ast::named_field(*) => die!(~"unexpected named field"), ast::unnamed_field => { maybe_print_comment(s, field.span.lo); print_type(s, field.node.ty); @@ -709,7 +709,7 @@ pub fn print_struct(s: ps, for struct_def.fields.each |field| { match field.node.kind { - ast::unnamed_field => fail ~"unexpected unnamed field", + ast::unnamed_field => die!(~"unexpected unnamed field"), ast::named_field(ident, mutability, visibility) => { hardbreak_if_not_bol(s); maybe_print_comment(s, field.span.lo); @@ -995,7 +995,7 @@ pub fn print_if(s: ps, test: @ast::expr, blk: ast::blk, } // BLEAH, constraints would be great here _ => { - fail ~"print_if saw if with weird alternative"; + die!(~"print_if saw if with weird alternative"); } } } @@ -1296,7 +1296,7 @@ pub fn print_expr(s: ps, &&expr: @ast::expr) { } end(s); // close enclosing cbox } - None => fail + None => die!() } } else { // the block will close the pattern's ibox @@ -1393,13 +1393,6 @@ pub fn print_expr(s: ps, &&expr: @ast::expr) { word(s.s, ~"]"); } ast::expr_path(path) => print_path(s, path, true), - ast::expr_fail(maybe_fail_val) => { - word(s.s, ~"fail"); - match maybe_fail_val { - Some(expr) => { word(s.s, ~" "); print_expr(s, expr); } - _ => () - } - } ast::expr_break(opt_ident) => { word(s.s, ~"break"); space(s.s); @@ -2013,24 +2006,24 @@ pub fn print_literal(s: ps, &&lit: @ast::lit) { ast::lit_int(i, t) => { if i < 0_i64 { word(s.s, - ~"-" + u64::to_str(-i as u64, 10u) + ~"-" + u64::to_str_radix(-i as u64, 10u) + ast_util::int_ty_to_str(t)); } else { word(s.s, - u64::to_str(i as u64, 10u) + u64::to_str_radix(i as u64, 10u) + ast_util::int_ty_to_str(t)); } } ast::lit_uint(u, t) => { word(s.s, - u64::to_str(u, 10u) + u64::to_str_radix(u, 10u) + ast_util::uint_ty_to_str(t)); } ast::lit_int_unsuffixed(i) => { if i < 0_i64 { - word(s.s, ~"-" + u64::to_str(-i as u64, 10u)); + word(s.s, ~"-" + u64::to_str_radix(-i as u64, 10u)); } else { - word(s.s, u64::to_str(i as u64, 10u)); + word(s.s, u64::to_str_radix(i as u64, 10u)); } } ast::lit_float(f, t) => { @@ -2241,10 +2234,11 @@ pub mod test { use parse; use super::*; //use util; + use util::testing::check_equal; fn string_check<T : Eq> (given : &T, expected: &T) { if !(given == expected) { - fail (fmt!("given %?, expected %?",given,expected)); + die!(fmt!("given %?, expected %?",given,expected)); } } @@ -2257,11 +2251,11 @@ pub mod test { inputs: ~[], output: @ast::Ty {id: 0, node: ast::ty_nil, - span: ast_util::dummy_sp()}, + span: codemap::dummy_sp()}, cf: ast::return_val }; - assert fun_to_str(decl, abba_ident, ~[],mock_interner) - == ~"fn abba()"; + check_equal (&fun_to_str(decl, abba_ident, ~[],mock_interner), + &~"fn abba()"); } #[test] @@ -2269,7 +2263,7 @@ pub mod test { let mock_interner = parse::token::mk_fake_ident_interner(); let ident = mock_interner.intern(@~"principal_skinner"); - let var = ast_util::respan(ast_util::dummy_sp(), ast::variant_ { + let var = codemap::respan(codemap::dummy_sp(), ast::variant_ { name: ident, attrs: ~[], // making this up as I go.... ? @@ -2280,7 +2274,7 @@ pub mod test { }); let varstr = variant_to_str(var,mock_interner); - string_check(&varstr,&~"pub principal_skinner"); + check_equal(&varstr,&~"pub principal_skinner"); } } diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index dc5964e6a12..a6d50b9cf09 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -46,10 +46,11 @@ pub mod ast_map; pub mod visit; pub mod fold; pub mod util { - #[path = "interner.rs"] pub mod interner; + pub mod testing; } + #[path = "parse/mod.rs"] pub mod parse; @@ -86,3 +87,4 @@ pub mod ext { pub mod trace_macros; } + diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 23db470391a..19b938ccd68 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -15,13 +15,13 @@ use core::prelude::*; use core::dvec::DVec; -use std::map::HashMap; -use std::map; +use std::oldmap::HashMap; +use std::oldmap; pub type hash_interner<T> = {map: HashMap<T, uint>, vect: DVec<T>}; pub fn mk<T:Eq IterBytes Hash Const Copy>() -> Interner<T> { - let m = map::HashMap::<T, uint>(); + let m = oldmap::HashMap::<T, uint>(); let hi: hash_interner<T> = {map: m, vect: DVec()}; move ((move hi) as Interner::<T>) diff --git a/src/libsyntax/util/testing.rs b/src/libsyntax/util/testing.rs new file mode 100644 index 00000000000..39d3b003e66 --- /dev/null +++ b/src/libsyntax/util/testing.rs @@ -0,0 +1,24 @@ +// 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. + +// support for test cases. +use core::cmp; + +pub pure fn check_equal_ptr<T : cmp::Eq> (given : &T, expected: &T) { + if !((given == expected) && (expected == given )) { + die!(fmt!("given %?, expected %?",given,expected)); + } +} + +pub pure fn check_equal<T : cmp::Eq> (given : T, expected: T) { + if !((given == expected) && (expected == given )) { + die!(fmt!("given %?, expected %?",given,expected)); + } +} diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index a174ea47740..eea1a6906e4 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -485,7 +485,6 @@ pub fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) { (v.visit_expr)(b, e, v); } expr_path(p) => visit_path(p, e, v), - expr_fail(eo) => visit_expr_opt(eo, e, v), expr_break(_) => (), expr_again(_) => (), expr_ret(eo) => visit_expr_opt(eo, e, v), |
