Support path as array length
Fixes #29.
diff --git a/src/expr.rs b/src/expr.rs
index 821e264..20e0555 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -352,11 +352,13 @@
named!(pub expr -> Expr, do_parse!(
mut e: alt!(
- expr_lit // needs to be before expr_struct
+ expr_lit // must be before expr_struct
|
- expr_struct // needs to be before expr_path
+ expr_struct // must be before expr_path
|
- expr_paren // needs to be before expr_tup
+ expr_paren // must be before expr_tup
+ |
+ expr_mac // must be before expr_path
|
expr_box
|
@@ -390,8 +392,6 @@
|
expr_ret
|
- expr_mac
- |
expr_repeat
) >>
many0!(alt!(
diff --git a/src/ty.rs b/src/ty.rs
index dd81fac..b8aee5a 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -6,7 +6,7 @@
/// A variable-length array (`[T]`)
Slice(Box<Ty>),
/// A fixed length array (`[T; n]`)
- Array(Box<Ty>, usize),
+ Array(Box<Ty>, ArrayLen),
/// A raw pointer (`*const T` or `*mut T`)
Ptr(Box<MutTy>),
/// A reference (`&'a T` or `&'a mut T`)
@@ -36,6 +36,15 @@
}
#[derive(Debug, Clone, Eq, PartialEq)]
+pub enum ArrayLen {
+ /// As in `[T; 0]`.
+ Usize(usize),
+ /// As in `[T; LEN]` or `[T; helper::LEN as usize]`. The boolean indicates
+ /// whether the path is followed by `as usize`.
+ Path(Path, bool),
+}
+
+#[derive(Debug, Clone, Eq, PartialEq)]
pub struct MutTy {
pub ty: Ty,
pub mutability: Mutability,
@@ -203,7 +212,7 @@
named!(pub ty -> Ty, alt!(
ty_vec
|
- ty_fixed_length_vec
+ ty_array
|
ty_ptr
|
@@ -229,13 +238,23 @@
(Ty::Slice(Box::new(elem)))
));
- named!(ty_fixed_length_vec -> Ty, do_parse!(
+ named!(ty_array -> Ty, do_parse!(
punct!("[") >>
elem: ty >>
punct!(";") >>
- len: int >>
+ len: array_len >>
punct!("]") >>
- (Ty::Array(Box::new(elem), len.0 as usize))
+ (Ty::Array(Box::new(elem), len))
+ ));
+
+ named!(array_len -> ArrayLen, alt!(
+ map!(int, |(i, _)| ArrayLen::Usize(i as usize))
+ |
+ do_parse!(
+ path: path >>
+ as_usize: option!(tuple!(keyword!("as"), keyword!("usize"))) >>
+ (ArrayLen::Path(path, as_usize.is_some()))
+ )
));
named!(ty_ptr -> Ty, do_parse!(
@@ -431,11 +450,11 @@
inner.to_tokens(tokens);
tokens.append("]");
}
- Ty::Array(ref inner, len) => {
+ Ty::Array(ref inner, ref len) => {
tokens.append("[");
inner.to_tokens(tokens);
tokens.append(";");
- tokens.append(&len.to_string());
+ len.to_tokens(tokens);
tokens.append("]");
}
Ty::Ptr(ref target) => {
@@ -508,6 +527,21 @@
}
}
+ impl ToTokens for ArrayLen {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ match *self {
+ ArrayLen::Usize(len) => tokens.append(&len.to_string()),
+ ArrayLen::Path(ref path, as_usize) => {
+ path.to_tokens(tokens);
+ if as_usize {
+ tokens.append("as");
+ tokens.append("usize");
+ }
+ }
+ }
+ }
+ }
+
impl ToTokens for Mutability {
fn to_tokens(&self, tokens: &mut Tokens) {
if let Mutability::Mutable = *self {