@self.read_to_vec(|| self.read_vtable_origin(xcx) )
}
+ #[cfg(stage0)]
fn read_vtable_origin(&self, xcx: @ExtendedDecodeContext)
-> typeck::vtable_origin {
do self.read_enum(~"vtable_origin") {
}
}
}
+
+ #[cfg(stage1)]
+ #[cfg(stage2)]
+ #[cfg(stage3)]
+ fn read_vtable_origin(&self, xcx: @ExtendedDecodeContext)
+ -> typeck::vtable_origin {
+ do self.read_enum("vtable_origin") {
+ do self.read_enum_variant(["vtable_static", "vtable_param"]) |i| {
+ match i {
+ 0 => {
+ typeck::vtable_static(
+ do self.read_enum_variant_arg(0u) {
+ self.read_def_id(xcx)
+ },
+ do self.read_enum_variant_arg(1u) {
+ self.read_tys(xcx)
+ },
+ do self.read_enum_variant_arg(2u) {
+ self.read_vtable_res(xcx)
+ }
+ )
+ }
+ 1 => {
+ typeck::vtable_param(
+ do self.read_enum_variant_arg(0u) {
+ self.read_uint()
+ },
+ do self.read_enum_variant_arg(1u) {
+ self.read_uint()
+ }
+ )
+ }
+ // hard to avoid - user input
+ _ => fail!(~"bad enum variant")
+ }
+ }
+ }
+ }
}
// ______________________________________________________________________
self.push_doc(self.next_doc(EsEnum), f)
}
+ #[cfg(stage0)]
fn read_enum_variant<T>(&self, f: &fn(uint) -> T) -> T {
debug!("read_enum_variant()");
let idx = self._next_uint(EsEnumVid);
}
}
+ #[cfg(stage1)]
+ #[cfg(stage2)]
+ #[cfg(stage3)]
+ fn read_enum_variant<T>(&self, _names: &[&str], f: &fn(uint) -> T) -> T {
+ debug!("read_enum_variant()");
+ let idx = self._next_uint(EsEnumVid);
+ debug!(" idx=%u", idx);
+ do self.push_doc(self.next_doc(EsEnumBody)) {
+ f(idx)
+ }
+ }
+
fn read_enum_variant_arg<T>(&self, idx: uint, f: &fn() -> T) -> T {
debug!("read_enum_variant_arg(idx=%u)", idx);
f()
f()
}
+ #[cfg(stage0)]
fn read_option<T>(&self, f: &fn() -> T) -> Option<T> {
debug!("read_option()");
do self.read_enum("Option") || {
}
}
}
+
+ #[cfg(stage1)]
+ #[cfg(stage2)]
+ #[cfg(stage3)]
+ fn read_option<T>(&self, f: &fn() -> T) -> Option<T> {
+ debug!("read_option()");
+ do self.read_enum("Option") || {
+ do self.read_enum_variant(["None", "Some"]) |idx| {
+ match idx {
+ 0 => None,
+ 1 => Some(f()),
+ _ => fail!(),
+ }
+ }
+ }
+ }
}
}
f()
}
+ #[cfg(stage0)]
fn read_enum_variant<T>(&self, f: &fn(uint) -> T) -> T {
debug!("read_enum_variant()");
let idx = match *self.peek() {
f(idx)
}
+ #[cfg(stage1)]
+ #[cfg(stage2)]
+ #[cfg(stage3)]
+ fn read_enum_variant<T>(&self, names: &[&str], f: &fn(uint) -> T) -> T {
+ debug!("read_enum_variant(names=%?)", names);
+ let name = match *self.peek() {
+ String(ref s) => s,
+ List([String(ref s), .. _]) => s,
+ json => fail!(fmt!("invalid variant: %?", json)),
+ };
+ let idx = match vec::position(names, |n| str::eq_slice(*n, *name)) {
+ Some(idx) => idx,
+ None => fail!(fmt!("Unknown variant name: %?", name)),
+ };
+ f(idx)
+ }
+
fn read_enum_variant_arg<T>(&self, idx: uint, f: &fn() -> T) -> T {
debug!("read_enum_variant_arg(idx=%u)", idx);
- if idx != 0 { fail!(~"unknown index") }
- f()
+ match *self.peek() {
+ List(ref list) => {
+ self.stack.push(&list[idx + 1]);
+ f()
+ }
+ ref json => fail!(fmt!("not a list: %?", json)),
+ }
}
fn read_owned_vec<T>(&self, f: &fn(uint) -> T) -> T {
// Compound types:
fn read_enum<T>(&self, name: &str, f: &fn() -> T) -> T;
+
+ #[cfg(stage0)]
fn read_enum_variant<T>(&self, f: &fn(uint) -> T) -> T;
+
+ #[cfg(stage1)]
+ #[cfg(stage2)]
+ #[cfg(stage3)]
+ fn read_enum_variant<T>(&self, names: &[&str], f: &fn(uint) -> T) -> T;
+
fn read_enum_variant_arg<T>(&self, idx: uint, f: &fn() -> T) -> T;
fn read_owned<T>(&self, f: &fn() -> T) -> T;
name: ast::ident,
variants: ~[ast::variant]
) -> @ast::expr {
+ let expr_arm_names = build::mk_base_vec_e(
+ ext_cx,
+ span,
+ do variants.map |variant| {
+ build::mk_base_str(
+ ext_cx,
+ span,
+ ext_cx.str_of(variant.node.name)
+ )
+ }
+ );
+
let mut arms = do variants.mapi |v_idx, variant| {
let body = match variant.node.kind {
ast::tuple_variant_kind(ref args) => {
)
);
- // ast for `__d.read_enum_variant($(expr_lambda))`
+ // ast for `__d.read_enum_variant($expr_arm_names, $(expr_lambda))`
let expr_lambda = ext_cx.lambda_expr(
ext_cx.expr_method_call(
span,
ext_cx.expr_var(span, ~"__d"),
ext_cx.ident_of(~"read_enum_variant"),
- ~[expr_lambda]
+ ~[expr_arm_names, expr_lambda]
)
);
)
}
-
#[cfg(test)]
mod test {
use core::option::{None, Some};