Remove all remaining uses of objs from the compiler
This commit is contained in:
parent
7f62944559
commit
eb07fa4d3b
@ -545,7 +545,7 @@ fn mangle_internal_name_by_type_only(ccx: @crate_ctxt, t: ty::t, name: str) ->
|
||||
|
||||
fn mangle_internal_name_by_path_and_seq(ccx: @crate_ctxt, path: [str],
|
||||
flav: str) -> str {
|
||||
ret mangle(path + [ccx.names.next(flav)]);
|
||||
ret mangle(path + [ccx.names(flav)]);
|
||||
}
|
||||
|
||||
fn mangle_internal_name_by_path(_ccx: @crate_ctxt, path: [str]) -> str {
|
||||
@ -553,7 +553,7 @@ fn mangle_internal_name_by_path(_ccx: @crate_ctxt, path: [str]) -> str {
|
||||
}
|
||||
|
||||
fn mangle_internal_name_by_seq(ccx: @crate_ctxt, flav: str) -> str {
|
||||
ret ccx.names.next(flav);
|
||||
ret ccx.names(flav);
|
||||
}
|
||||
|
||||
// If the user wants an exe generated we need to invoke
|
||||
|
@ -898,37 +898,27 @@ native mod llvm {
|
||||
|
||||
/* Memory-managed object interface to type handles. */
|
||||
|
||||
obj type_names(type_names: std::map::hashmap<TypeRef, str>,
|
||||
named_types: std::map::hashmap<str, TypeRef>) {
|
||||
type type_names = @{type_names: std::map::hashmap<TypeRef, str>,
|
||||
named_types: std::map::hashmap<str, TypeRef>};
|
||||
|
||||
fn associate(s: str, t: TypeRef) {
|
||||
assert (!named_types.contains_key(s));
|
||||
assert (!type_names.contains_key(t));
|
||||
type_names.insert(t, s);
|
||||
named_types.insert(s, t);
|
||||
}
|
||||
fn associate_type(tn: type_names, s: str, t: TypeRef) {
|
||||
assert tn.type_names.insert(t, s);
|
||||
assert tn.named_types.insert(s, t);
|
||||
}
|
||||
|
||||
fn type_has_name(t: TypeRef) -> bool { ret type_names.contains_key(t); }
|
||||
fn type_has_name(tn: type_names, t: TypeRef) -> option::t<str> {
|
||||
ret tn.type_names.find(t);
|
||||
}
|
||||
|
||||
fn get_name(t: TypeRef) -> str { ret type_names.get(t); }
|
||||
|
||||
fn name_has_type(s: str) -> bool { ret named_types.contains_key(s); }
|
||||
|
||||
fn get_type(s: str) -> TypeRef { ret named_types.get(s); }
|
||||
fn name_has_type(tn: type_names, s: str) -> option::t<TypeRef> {
|
||||
ret tn.named_types.find(s);
|
||||
}
|
||||
|
||||
fn mk_type_names() -> type_names {
|
||||
let nt = std::map::new_str_hash::<TypeRef>();
|
||||
|
||||
fn hash(&&t: TypeRef) -> uint { ret t as uint; }
|
||||
|
||||
fn eq(&&a: TypeRef, &&b: TypeRef) -> bool { ret a as uint == b as uint; }
|
||||
|
||||
let hasher: std::map::hashfn<TypeRef> = hash;
|
||||
let eqer: std::map::eqfn<TypeRef> = eq;
|
||||
let tn = std::map::mk_hashmap::<TypeRef, str>(hasher, eqer);
|
||||
|
||||
ret type_names(tn, nt);
|
||||
@{type_names: std::map::mk_hashmap(hash, eq),
|
||||
named_types: std::map::new_str_hash()}
|
||||
}
|
||||
|
||||
fn type_to_str(names: type_names, ty: TypeRef) -> str {
|
||||
@ -937,8 +927,10 @@ fn type_to_str(names: type_names, ty: TypeRef) -> str {
|
||||
|
||||
fn type_to_str_inner(names: type_names, outer0: [TypeRef], ty: TypeRef) ->
|
||||
str {
|
||||
|
||||
if names.type_has_name(ty) { ret names.get_name(ty); }
|
||||
alt type_has_name(names, ty) {
|
||||
option::some(n) { ret n; }
|
||||
_ {}
|
||||
}
|
||||
|
||||
let outer = outer0 + [ty];
|
||||
|
||||
|
@ -394,7 +394,7 @@ fn create_record(cx: @crate_ctxt, t: ty::t, fields: [ast::ty_field],
|
||||
let fname = filename_from_span(cx, span);
|
||||
let file_node = create_file(cx, fname);
|
||||
let scx = create_structure(file_node,
|
||||
option::get(cx.dbg_cx).names.next("rec"),
|
||||
option::get(cx.dbg_cx).names("rec"),
|
||||
line_from_span(cx.sess.codemap,
|
||||
span) as int);
|
||||
for field in fields {
|
||||
@ -738,10 +738,10 @@ fn create_function(fcx: @fn_ctxt) -> @metadata<subprogram_md> {
|
||||
ast_map::node_expr(expr) {
|
||||
alt expr.node {
|
||||
ast::expr_fn(_, decl, _, _) {
|
||||
(dbg_cx.names.next("fn"), decl.output, expr.id)
|
||||
(dbg_cx.names("fn"), decl.output, expr.id)
|
||||
}
|
||||
ast::expr_fn_block(decl, _) {
|
||||
(dbg_cx.names.next("fn"), decl.output, expr.id)
|
||||
(dbg_cx.names("fn"), decl.output, expr.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4119,7 +4119,7 @@ fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind,
|
||||
let s = "";
|
||||
if cx.lcx.ccx.sess.opts.save_temps ||
|
||||
cx.lcx.ccx.sess.opts.debuginfo {
|
||||
s = cx.lcx.ccx.names.next(name);
|
||||
s = cx.lcx.ccx.names(name);
|
||||
}
|
||||
let llbb: BasicBlockRef =
|
||||
str::as_buf(s, {|buf| llvm::LLVMAppendBasicBlock(cx.llfn, buf) });
|
||||
@ -5665,13 +5665,13 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
|
||||
let float_type = T_float(targ_cfg);
|
||||
let task_type = T_task(targ_cfg);
|
||||
let taskptr_type = T_ptr(task_type);
|
||||
tn.associate("taskptr", taskptr_type);
|
||||
lib::llvm::associate_type(tn, "taskptr", taskptr_type);
|
||||
let tydesc_type = T_tydesc(targ_cfg);
|
||||
tn.associate("tydesc", tydesc_type);
|
||||
lib::llvm::associate_type(tn, "tydesc", tydesc_type);
|
||||
let crate_map = decl_crate_map(sess, link_meta.name, llmod);
|
||||
let dbg_cx = if sess.opts.debuginfo {
|
||||
option::some(@{llmetadata: map::new_int_hash(),
|
||||
names: namegen(0)})
|
||||
names: new_namegen()})
|
||||
} else {
|
||||
option::none
|
||||
};
|
||||
@ -5696,7 +5696,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
|
||||
dicts: map::mk_hashmap(hash_dict_id, {|a, b| a == b}),
|
||||
module_data: new_str_hash::<ValueRef>(),
|
||||
lltypes: ty::new_ty_hash(),
|
||||
names: namegen(0),
|
||||
names: new_namegen(),
|
||||
sha: sha,
|
||||
type_sha1s: ty::new_ty_hash(),
|
||||
type_short_names: ty::new_ty_hash(),
|
||||
|
@ -507,7 +507,7 @@ fn trans_expr_fn(bcx: @block_ctxt,
|
||||
let ccx = bcx_ccx(bcx), bcx = bcx;
|
||||
let fty = node_id_type(ccx, id);
|
||||
let llfnty = type_of_fn_from_ty(ccx, sp, fty, []);
|
||||
let sub_cx = extend_path(bcx.fcx.lcx, ccx.names.next("anon"));
|
||||
let sub_cx = extend_path(bcx.fcx.lcx, ccx.names("anon"));
|
||||
let s = mangle_internal_name_by_path(ccx, sub_cx.path);
|
||||
let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
|
||||
register_fn(ccx, sp, sub_cx.path, "anon fn", [], id);
|
||||
|
@ -14,7 +14,8 @@ import middle::{resolve, ty};
|
||||
import back::{link, abi, upcall};
|
||||
import util::common::*;
|
||||
import syntax::codemap::span;
|
||||
import lib::llvm::{llvm, target_data, type_names};
|
||||
import lib::llvm::{llvm, target_data, type_names, associate_type,
|
||||
name_has_type};
|
||||
import lib::llvm::llvm::{ModuleRef, ValueRef, TypeRef, BasicBlockRef};
|
||||
import lib::llvm::{True, False, Bool};
|
||||
import metadata::{csearch};
|
||||
@ -22,8 +23,10 @@ import metadata::{csearch};
|
||||
// FIXME: These should probably be pulled in here too.
|
||||
import trans::{type_of_fn, drop_ty};
|
||||
|
||||
obj namegen(mutable i: int) {
|
||||
fn next(prefix: str) -> str { i += 1; ret prefix + int::str(i); }
|
||||
type namegen = fn@(str) -> str;
|
||||
fn new_namegen() -> namegen {
|
||||
let i = @mutable 0;
|
||||
ret fn@(prefix: str) -> str { *i += 1; prefix + int::str(*i) };
|
||||
}
|
||||
|
||||
type derived_tydesc_info = {lltydesc: ValueRef, escapes: bool};
|
||||
@ -616,17 +619,17 @@ fn T_tydesc_field(cx: @crate_ctxt, field: int) -> TypeRef unsafe {
|
||||
|
||||
fn T_glue_fn(cx: @crate_ctxt) -> TypeRef {
|
||||
let s = "glue_fn";
|
||||
if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); }
|
||||
alt name_has_type(cx.tn, s) { some(t) { ret t; } _ {} }
|
||||
let t = T_tydesc_field(cx, abi::tydesc_field_drop_glue);
|
||||
cx.tn.associate(s, t);
|
||||
associate_type(cx.tn, s, t);
|
||||
ret t;
|
||||
}
|
||||
|
||||
fn T_cmp_glue_fn(cx: @crate_ctxt) -> TypeRef {
|
||||
let s = "cmp_glue_fn";
|
||||
if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); }
|
||||
alt name_has_type(cx.tn, s) { some(t) { ret t; } _ {} }
|
||||
let t = T_tydesc_field(cx, abi::tydesc_field_cmp_glue);
|
||||
cx.tn.associate(s, t);
|
||||
associate_type(cx.tn, s, t);
|
||||
ret t;
|
||||
}
|
||||
|
||||
@ -691,9 +694,9 @@ fn T_taskptr(cx: @crate_ctxt) -> TypeRef { ret T_ptr(cx.task_type); }
|
||||
// This type must never be used directly; it must always be cast away.
|
||||
fn T_typaram(tn: type_names) -> TypeRef {
|
||||
let s = "typaram";
|
||||
if tn.name_has_type(s) { ret tn.get_type(s); }
|
||||
alt name_has_type(tn, s) { some(t) { ret t; } _ {} }
|
||||
let t = T_i8();
|
||||
tn.associate(s, t);
|
||||
associate_type(tn, s, t);
|
||||
ret t;
|
||||
}
|
||||
|
||||
@ -701,13 +704,13 @@ fn T_typaram_ptr(tn: type_names) -> TypeRef { ret T_ptr(T_typaram(tn)); }
|
||||
|
||||
fn T_opaque_cbox_ptr(cx: @crate_ctxt) -> TypeRef {
|
||||
let s = "*cbox";
|
||||
if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); }
|
||||
alt name_has_type(cx.tn, s) { some(t) { ret t; } _ {} }
|
||||
let t = T_ptr(T_struct([cx.int_type,
|
||||
T_ptr(cx.tydesc_type),
|
||||
T_i8() /* represents closed over tydescs
|
||||
and data go here; see trans_closure.rs*/
|
||||
]));
|
||||
cx.tn.associate(s, t);
|
||||
associate_type(cx.tn, s, t);
|
||||
ret t;
|
||||
}
|
||||
|
||||
@ -717,20 +720,20 @@ fn T_tag_variant(cx: @crate_ctxt) -> TypeRef {
|
||||
|
||||
fn T_tag(cx: @crate_ctxt, size: uint) -> TypeRef {
|
||||
let s = "tag_" + uint::to_str(size, 10u);
|
||||
if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); }
|
||||
alt name_has_type(cx.tn, s) { some(t) { ret t; } _ {} }
|
||||
let t =
|
||||
if size == 0u {
|
||||
T_struct([T_tag_variant(cx)])
|
||||
} else { T_struct([T_tag_variant(cx), T_array(T_i8(), size)]) };
|
||||
cx.tn.associate(s, t);
|
||||
associate_type(cx.tn, s, t);
|
||||
ret t;
|
||||
}
|
||||
|
||||
fn T_opaque_tag(cx: @crate_ctxt) -> TypeRef {
|
||||
let s = "opaque_tag";
|
||||
if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); }
|
||||
alt name_has_type(cx.tn, s) { some(t) { ret t; } _ {} }
|
||||
let t = T_struct([T_tag_variant(cx), T_i8()]);
|
||||
cx.tn.associate(s, t);
|
||||
associate_type(cx.tn, s, t);
|
||||
ret t;
|
||||
}
|
||||
|
||||
@ -818,7 +821,7 @@ fn C_cstr(cx: @crate_ctxt, s: str) -> ValueRef {
|
||||
llvm::LLVMConstString(buf, str::byte_len(s), False)
|
||||
});
|
||||
let g =
|
||||
str::as_buf(cx.names.next("str"),
|
||||
str::as_buf(cx.names("str"),
|
||||
{|buf| llvm::LLVMAddGlobal(cx.llmod, val_ty(sc), buf) });
|
||||
llvm::LLVMSetInitializer(g, sc);
|
||||
llvm::LLVMSetGlobalConstant(g, True);
|
||||
@ -865,11 +868,9 @@ fn C_bytes(bytes: [u8]) -> ValueRef unsafe {
|
||||
|
||||
fn C_shape(ccx: @crate_ctxt, bytes: [u8]) -> ValueRef {
|
||||
let llshape = C_bytes(bytes);
|
||||
let llglobal =
|
||||
str::as_buf(ccx.names.next("shape"),
|
||||
{|buf|
|
||||
llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), buf)
|
||||
});
|
||||
let llglobal = str::as_buf(ccx.names("shape"), {|buf|
|
||||
llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), buf)
|
||||
});
|
||||
llvm::LLVMSetInitializer(llglobal, llshape);
|
||||
llvm::LLVMSetGlobalConstant(llglobal, True);
|
||||
llvm::LLVMSetLinkage(llglobal,
|
||||
|
@ -340,7 +340,7 @@ fn get_static_dict(bcx: @block_ctxt, origin: typeck::dict_origin)
|
||||
none. {}
|
||||
}
|
||||
let ptrs = C_struct(get_dict_ptrs(bcx, origin).ptrs);
|
||||
let name = ccx.names.next("dict");
|
||||
let name = ccx.names("dict");
|
||||
let gvar = str::as_buf(name, {|buf|
|
||||
llvm::LLVMAddGlobal(ccx.llmod, val_ty(ptrs), buf)
|
||||
});
|
||||
|
@ -33,54 +33,60 @@ fn syntax_expander_table() -> hashmap<str, syntax_extension> {
|
||||
ret syntax_expanders;
|
||||
}
|
||||
|
||||
obj ext_ctxt(sess: session,
|
||||
mutable backtrace: codemap::opt_span) {
|
||||
|
||||
fn session() -> session { ret sess; }
|
||||
|
||||
fn print_backtrace() { }
|
||||
|
||||
fn backtrace() -> codemap::opt_span { ret backtrace; }
|
||||
|
||||
fn bt_push(sp: span) {
|
||||
backtrace =
|
||||
codemap::os_some(@{lo: sp.lo,
|
||||
hi: sp.hi,
|
||||
expanded_from: backtrace});
|
||||
}
|
||||
fn bt_pop() {
|
||||
alt backtrace {
|
||||
codemap::os_some(@{expanded_from: pre, _}) {
|
||||
let tmp = pre;
|
||||
backtrace = tmp;
|
||||
}
|
||||
_ { self.bug("tried to pop without a push"); }
|
||||
}
|
||||
}
|
||||
|
||||
fn span_fatal(sp: span, msg: str) -> ! {
|
||||
self.print_backtrace();
|
||||
sess.span_fatal(sp, msg);
|
||||
}
|
||||
fn span_err(sp: span, msg: str) {
|
||||
self.print_backtrace();
|
||||
sess.span_err(sp, msg);
|
||||
}
|
||||
fn span_unimpl(sp: span, msg: str) -> ! {
|
||||
self.print_backtrace();
|
||||
sess.span_unimpl(sp, msg);
|
||||
}
|
||||
fn span_bug(sp: span, msg: str) -> ! {
|
||||
self.print_backtrace();
|
||||
sess.span_bug(sp, msg);
|
||||
}
|
||||
fn bug(msg: str) -> ! { self.print_backtrace(); sess.bug(msg); }
|
||||
fn next_id() -> ast::node_id { ret sess.next_node_id(); }
|
||||
|
||||
iface ext_ctxt {
|
||||
fn session() -> session;
|
||||
fn print_backtrace();
|
||||
fn backtrace() -> codemap::opt_span;
|
||||
fn bt_push(sp: span);
|
||||
fn bt_pop();
|
||||
fn span_fatal(sp: span, msg: str) -> !;
|
||||
fn span_err(sp: span, msg: str);
|
||||
fn span_unimpl(sp: span, msg: str) -> !;
|
||||
fn span_bug(sp: span, msg: str) -> !;
|
||||
fn bug(msg: str) -> !;
|
||||
fn next_id() -> ast::node_id;
|
||||
}
|
||||
|
||||
fn mk_ctxt(sess: session) -> ext_ctxt {
|
||||
ret ext_ctxt(sess, codemap::os_none);
|
||||
type ctxt_repr = {sess: session,
|
||||
mutable backtrace: codemap::opt_span};
|
||||
impl of ext_ctxt for ctxt_repr {
|
||||
fn session() -> session { self.sess }
|
||||
fn print_backtrace() { }
|
||||
fn backtrace() -> codemap::opt_span { self.backtrace }
|
||||
fn bt_push(sp: span) {
|
||||
self.backtrace = codemap::os_some(
|
||||
@{lo: sp.lo, hi: sp.hi, expanded_from: self.backtrace});
|
||||
}
|
||||
fn bt_pop() {
|
||||
alt self.backtrace {
|
||||
codemap::os_some(@{expanded_from: pre, _}) {
|
||||
let tmp = pre;
|
||||
self.backtrace = tmp;
|
||||
}
|
||||
_ { self.bug("tried to pop without a push"); }
|
||||
}
|
||||
}
|
||||
fn span_fatal(sp: span, msg: str) -> ! {
|
||||
self.print_backtrace();
|
||||
self.sess.span_fatal(sp, msg);
|
||||
}
|
||||
fn span_err(sp: span, msg: str) {
|
||||
self.print_backtrace();
|
||||
self.sess.span_err(sp, msg);
|
||||
}
|
||||
fn span_unimpl(sp: span, msg: str) -> ! {
|
||||
self.print_backtrace();
|
||||
self.sess.span_unimpl(sp, msg);
|
||||
}
|
||||
fn span_bug(sp: span, msg: str) -> ! {
|
||||
self.print_backtrace();
|
||||
self.sess.span_bug(sp, msg);
|
||||
}
|
||||
fn bug(msg: str) -> ! { self.print_backtrace(); self.sess.bug(msg); }
|
||||
fn next_id() -> ast::node_id { ret self.sess.next_node_id(); }
|
||||
}
|
||||
{sess: sess, mutable backtrace: codemap::os_none} as ext_ctxt
|
||||
}
|
||||
|
||||
fn expr_to_str(cx: ext_ctxt, expr: @ast::expr, error: str) -> str {
|
||||
|
@ -100,23 +100,28 @@ const size_infinity: int = 0xffff;
|
||||
fn mk_printer(out: io::writer, linewidth: uint) -> printer {
|
||||
// Yes 3, it makes the ring buffers big enough to never
|
||||
// fall behind.
|
||||
|
||||
let n: uint = 3u * linewidth;
|
||||
#debug("mk_printer %u", linewidth);
|
||||
let token: [mutable token] = vec::init_elt_mut(EOF, n);
|
||||
let size: [mutable int] = vec::init_elt_mut(0, n);
|
||||
let scan_stack: [mutable uint] = vec::init_elt_mut(0u, n);
|
||||
let print_stack: [print_stack_elt] = [];
|
||||
ret printer(out, n, linewidth as int, // margin
|
||||
linewidth as int, // space
|
||||
0u, // left
|
||||
0u, // right
|
||||
token, size, 0, // left_total
|
||||
0, // right_total
|
||||
scan_stack, true, // scan_stack_empty
|
||||
0u, // top
|
||||
0u, // bottom
|
||||
print_stack, 0);
|
||||
@{out: out,
|
||||
buf_len: n,
|
||||
mutable margin: linewidth as int,
|
||||
mutable space: linewidth as int,
|
||||
mutable left: 0u,
|
||||
mutable right: 0u,
|
||||
mutable token: token,
|
||||
mutable size: size,
|
||||
mutable left_total: 0,
|
||||
mutable right_total: 0,
|
||||
mutable scan_stack: scan_stack,
|
||||
mutable scan_stack_empty: true,
|
||||
mutable top: 0u,
|
||||
mutable bottom: 0u,
|
||||
mutable print_stack: print_stack,
|
||||
mutable pending_indentation: 0}
|
||||
}
|
||||
|
||||
|
||||
@ -197,108 +202,96 @@ fn mk_printer(out: io::writer, linewidth: uint) -> printer {
|
||||
* the method called 'pretty_print', and the 'PRINT' process is the method
|
||||
* called 'print'.
|
||||
*/
|
||||
obj printer(out: io::writer,
|
||||
buf_len: uint,
|
||||
mutable margin: int, // width of lines we're constrained to
|
||||
|
||||
mutable space: int, // number of spaces left on line
|
||||
|
||||
mutable left: uint, // index of left side of input stream
|
||||
|
||||
mutable right: uint, // index of right side of input stream
|
||||
|
||||
mutable token: [mutable token],
|
||||
|
||||
// ring-buffr stream goes through
|
||||
mutable size: [mutable int], // ring-buffer of calculated sizes
|
||||
|
||||
mutable left_total: int, // running size of stream "...left"
|
||||
|
||||
mutable right_total: int, // running size of stream "...right"
|
||||
|
||||
// pseudo-stack, really a ring too. Holds the
|
||||
// primary-ring-buffers index of the BEGIN that started the
|
||||
// current block, possibly with the most recent BREAK after that
|
||||
// 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.
|
||||
mutable scan_stack: [mutable uint],
|
||||
mutable scan_stack_empty: bool, // top==bottom disambiguator
|
||||
|
||||
mutable top: uint, // index of top of scan_stack
|
||||
|
||||
mutable bottom: uint, // index of bottom of scan_stack
|
||||
|
||||
// stack of blocks-in-progress being flushed by print
|
||||
mutable print_stack: [print_stack_elt],
|
||||
|
||||
|
||||
// buffered indentation to avoid writing trailing whitespace
|
||||
mutable pending_indentation: int) {
|
||||
|
||||
fn last_token() -> token { ret token[right]; }
|
||||
type printer = @{
|
||||
out: io::writer,
|
||||
buf_len: uint,
|
||||
mutable margin: int, // width of lines we're constrained to
|
||||
mutable space: int, // number of spaces left on line
|
||||
mutable left: uint, // index of left side of input stream
|
||||
mutable right: uint, // index of right side of input stream
|
||||
mutable token: [mutable token], // ring-buffr stream goes through
|
||||
mutable size: [mutable int], // ring-buffer of calculated sizes
|
||||
mutable left_total: int, // running size of stream "...left"
|
||||
mutable right_total: int, // running size of stream "...right"
|
||||
// pseudo-stack, really a ring too. Holds the
|
||||
// primary-ring-buffers index of the BEGIN that started the
|
||||
// current block, possibly with the most recent BREAK after that
|
||||
// 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.
|
||||
mutable scan_stack: [mutable uint],
|
||||
mutable scan_stack_empty: bool, // top==bottom disambiguator
|
||||
mutable top: uint, // index of top of scan_stack
|
||||
mutable bottom: uint, // index of bottom of scan_stack
|
||||
// stack of blocks-in-progress being flushed by print
|
||||
mutable print_stack: [print_stack_elt],
|
||||
// buffered indentation to avoid writing trailing whitespace
|
||||
mutable pending_indentation: int
|
||||
};
|
||||
|
||||
impl printer for printer {
|
||||
fn last_token() -> token { self.token[self.right] }
|
||||
// be very careful with this!
|
||||
fn replace_last_token(t: token) { token[right] = t; }
|
||||
|
||||
fn replace_last_token(t: token) { self.token[self.right] = t; }
|
||||
fn pretty_print(t: token) {
|
||||
#debug("pp [%u,%u]", left, right);
|
||||
#debug("pp [%u,%u]", self.left, self.right);
|
||||
alt t {
|
||||
EOF. {
|
||||
if !scan_stack_empty {
|
||||
if !self.scan_stack_empty {
|
||||
self.check_stack(0);
|
||||
self.advance_left(token[left], size[left]);
|
||||
self.advance_left(self.token[self.left],
|
||||
self.size[self.left]);
|
||||
}
|
||||
self.indent(0);
|
||||
}
|
||||
BEGIN(b) {
|
||||
if scan_stack_empty {
|
||||
left_total = 1;
|
||||
right_total = 1;
|
||||
left = 0u;
|
||||
right = 0u;
|
||||
if self.scan_stack_empty {
|
||||
self.left_total = 1;
|
||||
self.right_total = 1;
|
||||
self.left = 0u;
|
||||
self.right = 0u;
|
||||
} else { self.advance_right(); }
|
||||
#debug("pp BEGIN/buffer [%u,%u]", left, right);
|
||||
token[right] = t;
|
||||
size[right] = -right_total;
|
||||
self.scan_push(right);
|
||||
#debug("pp BEGIN/buffer [%u,%u]", self.left, self.right);
|
||||
self.token[self.right] = t;
|
||||
self.size[self.right] = -self.right_total;
|
||||
self.scan_push(self.right);
|
||||
}
|
||||
END. {
|
||||
if scan_stack_empty {
|
||||
#debug("pp END/print [%u,%u]", left, right);
|
||||
if self.scan_stack_empty {
|
||||
#debug("pp END/print [%u,%u]", self.left, self.right);
|
||||
self.print(t, 0);
|
||||
} else {
|
||||
#debug("pp END/buffer [%u,%u]", left, right);
|
||||
#debug("pp END/buffer [%u,%u]", self.left, self.right);
|
||||
self.advance_right();
|
||||
token[right] = t;
|
||||
size[right] = -1;
|
||||
self.scan_push(right);
|
||||
self.token[self.right] = t;
|
||||
self.size[self.right] = -1;
|
||||
self.scan_push(self.right);
|
||||
}
|
||||
}
|
||||
BREAK(b) {
|
||||
if scan_stack_empty {
|
||||
left_total = 1;
|
||||
right_total = 1;
|
||||
left = 0u;
|
||||
right = 0u;
|
||||
if self.scan_stack_empty {
|
||||
self.left_total = 1;
|
||||
self.right_total = 1;
|
||||
self.left = 0u;
|
||||
self.right = 0u;
|
||||
} else { self.advance_right(); }
|
||||
#debug("pp BREAK/buffer [%u,%u]", left, right);
|
||||
#debug("pp BREAK/buffer [%u,%u]", self.left, self.right);
|
||||
self.check_stack(0);
|
||||
self.scan_push(right);
|
||||
token[right] = t;
|
||||
size[right] = -right_total;
|
||||
right_total += b.blank_space;
|
||||
self.scan_push(self.right);
|
||||
self.token[self.right] = t;
|
||||
self.size[self.right] = -self.right_total;
|
||||
self.right_total += b.blank_space;
|
||||
}
|
||||
STRING(s, len) {
|
||||
if scan_stack_empty {
|
||||
#debug("pp STRING/print [%u,%u]", left, right);
|
||||
if self.scan_stack_empty {
|
||||
#debug("pp STRING/print [%u,%u]", self.left, self.right);
|
||||
self.print(t, len);
|
||||
} else {
|
||||
#debug("pp STRING/buffer [%u,%u]", left, right);
|
||||
#debug("pp STRING/buffer [%u,%u]", self.left, self.right);
|
||||
self.advance_right();
|
||||
token[right] = t;
|
||||
size[right] = len;
|
||||
right_total += len;
|
||||
self.token[self.right] = t;
|
||||
self.size[self.right] = len;
|
||||
self.right_total += len;
|
||||
self.check_stream();
|
||||
}
|
||||
}
|
||||
@ -306,83 +299,92 @@ obj printer(out: io::writer,
|
||||
}
|
||||
fn check_stream() {
|
||||
#debug("check_stream [%u, %u] with left_total=%d, right_total=%d",
|
||||
left, right, left_total, right_total);
|
||||
if right_total - left_total > space {
|
||||
self.left, self.right, self.left_total, self.right_total);
|
||||
if self.right_total - self.left_total > self.space {
|
||||
#debug("scan window is %d, longer than space on line (%d)",
|
||||
right_total - left_total, space);
|
||||
if !scan_stack_empty {
|
||||
if left == scan_stack[bottom] {
|
||||
#debug("setting %u to infinity and popping", left);
|
||||
size[self.scan_pop_bottom()] = size_infinity;
|
||||
self.right_total - self.left_total, self.space);
|
||||
if !self.scan_stack_empty {
|
||||
if self.left == self.scan_stack[self.bottom] {
|
||||
#debug("setting %u to infinity and popping", self.left);
|
||||
self.size[self.scan_pop_bottom()] = size_infinity;
|
||||
}
|
||||
}
|
||||
self.advance_left(token[left], size[left]);
|
||||
if left != right { self.check_stream(); }
|
||||
self.advance_left(self.token[self.left], self.size[self.left]);
|
||||
if self.left != self.right { self.check_stream(); }
|
||||
}
|
||||
}
|
||||
fn scan_push(x: uint) {
|
||||
#debug("scan_push %u", x);
|
||||
if scan_stack_empty {
|
||||
scan_stack_empty = false;
|
||||
} else { top += 1u; top %= buf_len; assert (top != bottom); }
|
||||
scan_stack[top] = x;
|
||||
if self.scan_stack_empty {
|
||||
self.scan_stack_empty = false;
|
||||
} else {
|
||||
self.top += 1u;
|
||||
self.top %= self.buf_len;
|
||||
assert (self.top != self.bottom);
|
||||
}
|
||||
self.scan_stack[self.top] = x;
|
||||
}
|
||||
fn scan_pop() -> uint {
|
||||
assert (!scan_stack_empty);
|
||||
let x = scan_stack[top];
|
||||
if top == bottom {
|
||||
scan_stack_empty = true;
|
||||
} else { top += buf_len - 1u; top %= buf_len; }
|
||||
assert (!self.scan_stack_empty);
|
||||
let x = self.scan_stack[self.top];
|
||||
if self.top == self.bottom {
|
||||
self.scan_stack_empty = true;
|
||||
} else { self.top += self.buf_len - 1u; self.top %= self.buf_len; }
|
||||
ret x;
|
||||
}
|
||||
fn scan_top() -> uint { assert (!scan_stack_empty); ret scan_stack[top]; }
|
||||
fn scan_top() -> uint {
|
||||
assert (!self.scan_stack_empty);
|
||||
ret self.scan_stack[self.top];
|
||||
}
|
||||
fn scan_pop_bottom() -> uint {
|
||||
assert (!scan_stack_empty);
|
||||
let x = scan_stack[bottom];
|
||||
if top == bottom {
|
||||
scan_stack_empty = true;
|
||||
} else { bottom += 1u; bottom %= buf_len; }
|
||||
assert (!self.scan_stack_empty);
|
||||
let x = self.scan_stack[self.bottom];
|
||||
if self.top == self.bottom {
|
||||
self.scan_stack_empty = true;
|
||||
} else { self.bottom += 1u; self.bottom %= self.buf_len; }
|
||||
ret x;
|
||||
}
|
||||
fn advance_right() {
|
||||
right += 1u;
|
||||
right %= buf_len;
|
||||
assert (right != left);
|
||||
self.right += 1u;
|
||||
self.right %= self.buf_len;
|
||||
assert (self.right != self.left);
|
||||
}
|
||||
fn advance_left(x: token, L: int) {
|
||||
#debug("advnce_left [%u,%u], sizeof(%u)=%d", left, right, left, L);
|
||||
#debug("advnce_left [%u,%u], sizeof(%u)=%d", self.left, self.right,
|
||||
self.left, L);
|
||||
if L >= 0 {
|
||||
self.print(x, L);
|
||||
alt x {
|
||||
BREAK(b) { left_total += b.blank_space; }
|
||||
STRING(_, len) { assert (len == L); left_total += len; }
|
||||
BREAK(b) { self.left_total += b.blank_space; }
|
||||
STRING(_, len) { assert (len == L); self.left_total += len; }
|
||||
_ { }
|
||||
}
|
||||
if left != right {
|
||||
left += 1u;
|
||||
left %= buf_len;
|
||||
self.advance_left(token[left], size[left]);
|
||||
if self.left != self.right {
|
||||
self.left += 1u;
|
||||
self.left %= self.buf_len;
|
||||
self.advance_left(self.token[self.left],
|
||||
self.size[self.left]);
|
||||
}
|
||||
}
|
||||
}
|
||||
fn check_stack(k: int) {
|
||||
if !scan_stack_empty {
|
||||
if !self.scan_stack_empty {
|
||||
let x = self.scan_top();
|
||||
alt token[x] {
|
||||
alt self.token[x] {
|
||||
BEGIN(b) {
|
||||
if k > 0 {
|
||||
size[self.scan_pop()] = size[x] + right_total;
|
||||
self.size[self.scan_pop()] = self.size[x] +
|
||||
self.right_total;
|
||||
self.check_stack(k - 1);
|
||||
}
|
||||
}
|
||||
END. {
|
||||
// paper says + not =, but that makes no sense.
|
||||
|
||||
size[self.scan_pop()] = 1;
|
||||
self.size[self.scan_pop()] = 1;
|
||||
self.check_stack(k + 1);
|
||||
}
|
||||
_ {
|
||||
size[self.scan_pop()] = size[x] + right_total;
|
||||
self.size[self.scan_pop()] = self.size[x] + self.right_total;
|
||||
if k > 0 { self.check_stack(k); }
|
||||
}
|
||||
}
|
||||
@ -390,69 +392,69 @@ obj printer(out: io::writer,
|
||||
}
|
||||
fn print_newline(amount: int) {
|
||||
#debug("NEWLINE %d", amount);
|
||||
out.write_str("\n");
|
||||
pending_indentation = 0;
|
||||
self.out.write_str("\n");
|
||||
self.pending_indentation = 0;
|
||||
self.indent(amount);
|
||||
}
|
||||
fn indent(amount: int) {
|
||||
#debug("INDENT %d", amount);
|
||||
pending_indentation += amount;
|
||||
self.pending_indentation += amount;
|
||||
}
|
||||
fn top() -> print_stack_elt {
|
||||
let n = vec::len(print_stack);
|
||||
fn get_top() -> print_stack_elt {
|
||||
let n = vec::len(self.print_stack);
|
||||
let top: print_stack_elt = {offset: 0, pbreak: broken(inconsistent)};
|
||||
if n != 0u { top = print_stack[n - 1u]; }
|
||||
if n != 0u { top = self.print_stack[n - 1u]; }
|
||||
ret top;
|
||||
}
|
||||
fn write_str(s: str) {
|
||||
while pending_indentation > 0 {
|
||||
out.write_str(" ");
|
||||
pending_indentation -= 1;
|
||||
while self.pending_indentation > 0 {
|
||||
self.out.write_str(" ");
|
||||
self.pending_indentation -= 1;
|
||||
}
|
||||
out.write_str(s);
|
||||
self.out.write_str(s);
|
||||
}
|
||||
fn print(x: token, L: int) {
|
||||
#debug("print %s %d (remaining line space=%d)", tok_str(x), L,
|
||||
space);
|
||||
log(debug, buf_str(token, size, left, right, 6u));
|
||||
self.space);
|
||||
log(debug, buf_str(self.token, self.size, self.left, self.right, 6u));
|
||||
alt x {
|
||||
BEGIN(b) {
|
||||
if L > space {
|
||||
let col = margin - space + b.offset;
|
||||
if L > self.space {
|
||||
let col = self.margin - self.space + b.offset;
|
||||
#debug("print BEGIN -> push broken block at col %d", col);
|
||||
print_stack += [{offset: col, pbreak: broken(b.breaks)}];
|
||||
self.print_stack += [{offset: col, pbreak: broken(b.breaks)}];
|
||||
} else {
|
||||
#debug("print BEGIN -> push fitting block");
|
||||
print_stack += [{offset: 0, pbreak: fits}];
|
||||
self.print_stack += [{offset: 0, pbreak: fits}];
|
||||
}
|
||||
}
|
||||
END. {
|
||||
#debug("print END -> pop END");
|
||||
assert (vec::len(print_stack) != 0u);
|
||||
vec::pop(print_stack);
|
||||
assert (vec::len(self.print_stack) != 0u);
|
||||
vec::pop(self.print_stack);
|
||||
}
|
||||
BREAK(b) {
|
||||
let top = self.top();
|
||||
let top = self.get_top();
|
||||
alt top.pbreak {
|
||||
fits. {
|
||||
#debug("print BREAK in fitting block");
|
||||
space -= b.blank_space;
|
||||
self.space -= b.blank_space;
|
||||
self.indent(b.blank_space);
|
||||
}
|
||||
broken(consistent.) {
|
||||
#debug("print BREAK in consistent block");
|
||||
self.print_newline(top.offset + b.offset);
|
||||
space = margin - (top.offset + b.offset);
|
||||
self.space = self.margin - (top.offset + b.offset);
|
||||
}
|
||||
broken(inconsistent.) {
|
||||
if L > space {
|
||||
if L > self.space {
|
||||
#debug("print BREAK w/ newline in inconsistent");
|
||||
self.print_newline(top.offset + b.offset);
|
||||
space = margin - (top.offset + b.offset);
|
||||
self.space = self.margin - (top.offset + b.offset);
|
||||
} else {
|
||||
#debug("print BREAK w/o newline in inconsistent");
|
||||
self.indent(b.blank_space);
|
||||
space -= b.blank_space;
|
||||
self.space -= b.blank_space;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -461,20 +463,17 @@ obj printer(out: io::writer,
|
||||
#debug("print STRING");
|
||||
assert (L == len);
|
||||
// assert L <= space;
|
||||
|
||||
space -= len;
|
||||
self.space -= len;
|
||||
self.write_str(s);
|
||||
}
|
||||
EOF. {
|
||||
// EOF should never get here.
|
||||
|
||||
fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Convenience functions to talk to the printer.
|
||||
fn box(p: printer, indent: uint, b: breaks) {
|
||||
p.pretty_print(BEGIN({offset: indent as int, breaks: b}));
|
||||
|
@ -6,7 +6,7 @@ import syntax::codemap::codemap;
|
||||
import ast;
|
||||
import ast_util;
|
||||
import option::{some, none};
|
||||
import pp::{break_offset, word,
|
||||
import pp::{break_offset, word, printer,
|
||||
space, zerobreak, hardbreak, breaks, consistent,
|
||||
inconsistent, eof};
|
||||
|
||||
|
@ -24,33 +24,32 @@ fn pick_file(file: fs::path, path: fs::path) -> option::t<fs::path> {
|
||||
else { option::none }
|
||||
}
|
||||
|
||||
type filesearch = obj {
|
||||
iface filesearch {
|
||||
fn sysroot() -> fs::path;
|
||||
fn lib_search_paths() -> [fs::path];
|
||||
fn get_target_lib_path() -> fs::path;
|
||||
fn get_target_lib_file_path(file: fs::path) -> fs::path;
|
||||
};
|
||||
}
|
||||
|
||||
fn mk_filesearch(maybe_sysroot: option::t<fs::path>,
|
||||
target_triple: str,
|
||||
addl_lib_search_paths: [fs::path]) -> filesearch {
|
||||
obj filesearch_impl(sysroot: fs::path,
|
||||
addl_lib_search_paths: [fs::path],
|
||||
target_triple: str) {
|
||||
fn sysroot() -> fs::path { sysroot }
|
||||
type filesearch_impl = {sysroot: fs::path,
|
||||
addl_lib_search_paths: [fs::path],
|
||||
target_triple: str};
|
||||
impl of filesearch for filesearch_impl {
|
||||
fn sysroot() -> fs::path { self.sysroot }
|
||||
fn lib_search_paths() -> [fs::path] {
|
||||
addl_lib_search_paths
|
||||
+ [make_target_lib_path(sysroot, target_triple)]
|
||||
self.addl_lib_search_paths
|
||||
+ [make_target_lib_path(self.sysroot, self.target_triple)]
|
||||
+ alt get_cargo_lib_path() {
|
||||
result::ok(p) { [p] }
|
||||
result::err(p) { [] }
|
||||
}
|
||||
}
|
||||
|
||||
fn get_target_lib_path() -> fs::path {
|
||||
make_target_lib_path(sysroot, target_triple)
|
||||
make_target_lib_path(self.sysroot, self.target_triple)
|
||||
}
|
||||
|
||||
fn get_target_lib_file_path(file: fs::path) -> fs::path {
|
||||
fs::connect(self.get_target_lib_path(), file)
|
||||
}
|
||||
@ -58,7 +57,9 @@ fn mk_filesearch(maybe_sysroot: option::t<fs::path>,
|
||||
|
||||
let sysroot = get_sysroot(maybe_sysroot);
|
||||
#debug("using sysroot = %s", sysroot);
|
||||
ret filesearch_impl(sysroot, addl_lib_search_paths, target_triple);
|
||||
{sysroot: sysroot,
|
||||
addl_lib_search_paths: addl_lib_search_paths,
|
||||
target_triple: target_triple} as filesearch
|
||||
}
|
||||
|
||||
// FIXME #1001: This can't be an obj method
|
||||
|
Loading…
x
Reference in New Issue
Block a user