aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2011-01-13 17:42:28 -0800
committerGraydon Hoare <[email protected]>2011-01-13 17:42:28 -0800
commitf3c3fc03537d9aca36b0ce5956ab8d5b760784b4 (patch)
tree802723cba8094d8aba500e9a8d6774c86ea2f54a
parentAdd or enable some tests. (diff)
downloadrust-f3c3fc03537d9aca36b0ce5956ab8d5b760784b4.tar.xz
rust-f3c3fc03537d9aca36b0ce5956ab8d5b760784b4.zip
Change single-ident expr_ident to greedy/fat multi-ident expr_path, to handle the module-path/value-indexing distinction.
-rw-r--r--src/comp/front/ast.rs7
-rw-r--r--src/comp/front/parser.rs102
-rw-r--r--src/comp/middle/fold.rs46
-rw-r--r--src/comp/middle/resolve.rs66
-rw-r--r--src/comp/middle/trans.rs8
-rw-r--r--src/comp/middle/ty.rs25
-rw-r--r--src/comp/middle/typeck.rs14
7 files changed, 170 insertions, 98 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index c8e36dde..1ee50c2a 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -8,9 +8,8 @@ import util.common.ty_mach;
type ident = str;
-type name_ = rec(ident ident, vec[@ty] types);
-type name = spanned[name_];
-type path = vec[name];
+type path_ = rec(vec[ident] idents, vec[@ty] types);
+type path = spanned[path_];
type crate_num = int;
type def_num = int;
@@ -158,7 +157,7 @@ tag expr_ {
expr_assign_op(binop, @expr /* TODO: @expr|is_lval */, @expr, ann);
expr_field(@expr, ident, ann);
expr_index(@expr, @expr, ann);
- expr_name(name, option.t[def], ann);
+ expr_path(path, option.t[def], ann);
}
type lit = spanned[lit_];
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 5428510d..c44da8f1 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -283,26 +283,7 @@ impure fn parse_ty(parser p) -> @ast.ty {
}
case (token.IDENT(_)) {
- let ast.path pth = vec();
- let bool more = true;
- while (more) {
- alt (p.peek()) {
- case (token.IDENT(?i)) {
- auto n = parse_name(p, i);
- hi = n.span;
- pth += n;
- if (p.peek() == token.DOT) {
- p.bump();
- } else {
- more = false;
- }
- }
- case (_) {
- more = false;
- }
- }
- }
- t = ast.ty_path(pth, none[ast.def]);
+ t = ast.ty_path(parse_path(p, true), none[ast.def]);
}
case (_) {
@@ -391,14 +372,46 @@ impure fn parse_lit(parser p) -> option.t[ast.lit] {
ret some(spanned(lo, lo, lit));
}
-impure fn parse_name(parser p, ast.ident id) -> ast.name {
+fn is_ident(token.token t) -> bool {
+ alt (t) {
+ case (token.IDENT(_)) { ret true; }
+ case (_) {}
+ }
+ ret false;
+}
+
+impure fn parse_path(parser p, bool greedy) -> ast.path {
auto lo = p.get_span();
+ auto hi = lo;
- p.bump();
+ let vec[ast.ident] ids = vec();
+ let bool more = true;
+ while (more) {
+ alt (p.peek()) {
+ case (token.IDENT(?i)) {
+ hi = p.get_span();
+ ids += i;
+ p.bump();
+ if (p.peek() == token.DOT) {
+ if (greedy) {
+ p.bump();
+ check (is_ident(p.peek()));
+ } else {
+ more = false;
+ }
+ } else {
+ more = false;
+ }
+ }
+ case (_) {
+ more = false;
+ }
+ }
+ }
let vec[@ast.ty] v = vec();
- let util.common.spanned[vec[@ast.ty]] tys = rec(node=v, span=lo);
+ let util.common.spanned[vec[@ast.ty]] tys = rec(node=v, span=hi);
alt (p.peek()) {
case (token.LBRACKET) {
@@ -411,7 +424,7 @@ impure fn parse_name(parser p, ast.ident id) -> ast.name {
case (_) {
}
}
- ret spanned(lo, tys.span, rec(ident=id, types=tys.node));
+ ret spanned(lo, tys.span, rec(idents=ids, types=tys.node));
}
impure fn parse_mutabliity(parser p) -> ast.mutability {
@@ -442,10 +455,10 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
alt (p.peek()) {
- case (token.IDENT(?i)) {
- auto n = parse_name(p, i);
- hi = n.span;
- ex = ast.expr_name(n, none[ast.def], ast.ann_none);
+ case (token.IDENT(_)) {
+ auto pth = parse_path(p, false);
+ hi = pth.span;
+ ex = ast.expr_path(pth, none[ast.def], ast.ann_none);
}
case (token.LPAREN) {
@@ -546,7 +559,29 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
ret @spanned(lo, hi, ex);
}
-impure fn parse_path_expr(parser p) -> @ast.expr {
+fn append_dot_ident_to_expr(span lo, span hi,
+ @ast.expr e, ast.ident i) -> @ast.expr {
+ auto e_ = e.node;
+ alt (e.node) {
+ case (ast.expr_path(?pth, ?def, ?ann)) {
+ if (_vec.len[@ast.ty](pth.node.types) == 0u) {
+ auto idents_ = pth.node.idents;
+ idents_ += i;
+ auto pth_ = rec(node=rec(idents=idents_ with pth.node)
+ with pth);
+ e_ = ast.expr_path(pth_, def, ann);
+ } else {
+ e_ = ast.expr_field(e, i, ann);
+ }
+ }
+ case (_) {
+ e_ = ast.expr_field(e, i, ast.ann_none);
+ }
+ }
+ ret @spanned(lo, hi, e_);
+}
+
+impure fn parse_dot_or_call_expr(parser p) -> @ast.expr {
auto lo = p.get_span();
auto e = parse_bottom_expr(p);
auto hi = e.span;
@@ -576,8 +611,7 @@ impure fn parse_path_expr(parser p) -> @ast.expr {
case (token.IDENT(?i)) {
hi = p.get_span();
p.bump();
- auto e_ = ast.expr_field(e, i, ast.ann_none);
- e = @spanned(lo, hi, e_);
+ e = append_dot_ident_to_expr(lo, hi, e, i);
}
case (token.LPAREN) {
@@ -645,7 +679,7 @@ impure fn parse_prefix_expr(parser p) -> @ast.expr {
}
case (_) {
- ret parse_path_expr(p);
+ ret parse_dot_or_call_expr(p);
}
}
}
@@ -658,7 +692,7 @@ impure fn parse_prefix_expr(parser p) -> @ast.expr {
}
case (_) {
- ret parse_path_expr(p);
+ ret parse_dot_or_call_expr(p);
}
}
ret @spanned(lo, hi, ex);
@@ -1254,7 +1288,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
{ ret true; }
case (ast.expr_field(_,_,_)) { ret true; }
case (ast.expr_index(_,_,_)) { ret true; }
- case (ast.expr_name(_,_,_)) { ret true; }
+ case (ast.expr_path(_,_,_)) { ret true; }
case (_) { fail; }
}
}
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 4adf5ff9..b96ca938 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -11,7 +11,6 @@ import util.common.append;
import front.ast;
import front.ast.ident;
-import front.ast.name;
import front.ast.path;
import front.ast.mutability;
import front.ast.ty;
@@ -34,8 +33,8 @@ import std._vec;
type ast_fold[ENV] =
@rec
(
- // Name fold.
- (fn(&ENV e, &span sp, ast.name_ n) -> name) fold_name,
+ // Path fold.
+ (fn(&ENV e, &span sp, ast.path_ p) -> path) fold_path,
// Type folds.
(fn(&ENV e, &span sp) -> @ty) fold_ty_nil,
@@ -137,9 +136,9 @@ type ast_fold[ENV] =
ann a) -> @expr) fold_expr_index,
(fn(&ENV e, &span sp,
- &name n,
+ &path p,
&option.t[def] d,
- ann a) -> @expr) fold_expr_name,
+ ann a) -> @expr) fold_expr_path,
// Decl folds.
(fn(&ENV e, &span sp,
@@ -249,13 +248,13 @@ type ast_fold[ENV] =
//// Fold drivers.
-fn fold_name[ENV](&ENV env, ast_fold[ENV] fld, &name n) -> name {
+fn fold_path[ENV](&ENV env, ast_fold[ENV] fld, &path p) -> path {
let vec[@ast.ty] tys_ = vec();
- for (@ast.ty t in n.node.types) {
+ for (@ast.ty t in p.node.types) {
append[@ast.ty](tys_, fold_ty(env, fld, t));
}
- let ast.name_ n_ = rec(ident=n.node.ident, types=tys_);
- ret fld.fold_name(env, n.span, n_);
+ let ast.path_ p_ = rec(idents=p.node.idents, types=tys_);
+ ret fld.fold_path(env, p.span, p_);
}
fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
@@ -321,11 +320,8 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
}
case (ast.ty_path(?pth, ?ref_opt)) {
- let vec[ast.name] path = vec();
- for (ast.name n in pth) {
- path += fold_name(env, fld, n);
- }
- ret fld.fold_ty_path(env_, t.span, path, ref_opt);
+ auto pth_ = fold_path(env, fld, pth);
+ ret fld.fold_ty_path(env_, t.span, pth_, ref_opt);
}
case (ast.ty_mutable(?ty)) {
@@ -550,9 +546,9 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
ret fld.fold_expr_index(env_, e.span, ee, iix, t);
}
- case (ast.expr_name(?n, ?r, ?t)) {
- auto n_ = fold_name(env_, fld, n);
- ret fld.fold_expr_name(env_, e.span, n_, r, t);
+ case (ast.expr_path(?p, ?r, ?t)) {
+ auto p_ = fold_path(env_, fld, p);
+ ret fld.fold_expr_path(env_, e.span, p_, r, t);
}
}
@@ -809,10 +805,10 @@ fn respan[T](&span sp, &T t) -> spanned[T] {
}
-// Name identity.
+// Path identity.
-fn identity_fold_name[ENV](&ENV env, &span sp, ast.name_ n) -> name {
- ret respan(sp, n);
+fn identity_fold_path[ENV](&ENV env, &span sp, ast.path_ p) -> path {
+ ret respan(sp, p);
}
// Type identities.
@@ -983,10 +979,10 @@ fn identity_fold_expr_index[ENV](&ENV env, &span sp,
ret @respan(sp, ast.expr_index(e, ix, a));
}
-fn identity_fold_expr_name[ENV](&ENV env, &span sp,
- &name n, &option.t[def] d,
+fn identity_fold_expr_path[ENV](&ENV env, &span sp,
+ &path p, &option.t[def] d,
ann a) -> @expr {
- ret @respan(sp, ast.expr_name(n, d, a));
+ ret @respan(sp, ast.expr_path(p, d, a));
}
@@ -1176,7 +1172,7 @@ fn always_keep_going[ENV](&ENV e) -> bool {
fn new_identity_fold[ENV]() -> ast_fold[ENV] {
ret @rec
(
- fold_name = bind identity_fold_name[ENV](_,_,_),
+ fold_path = bind identity_fold_path[ENV](_,_,_),
fold_ty_nil = bind identity_fold_ty_nil[ENV](_,_),
fold_ty_bool = bind identity_fold_ty_bool[ENV](_,_),
@@ -1214,7 +1210,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
= bind identity_fold_expr_assign_op[ENV](_,_,_,_,_,_),
fold_expr_field = bind identity_fold_expr_field[ENV](_,_,_,_,_),
fold_expr_index = bind identity_fold_expr_index[ENV](_,_,_,_,_),
- fold_expr_name = bind identity_fold_expr_name[ENV](_,_,_,_,_),
+ fold_expr_path = bind identity_fold_expr_path[ENV](_,_,_,_,_),
fold_decl_local = bind identity_fold_decl_local[ENV](_,_,_),
fold_decl_item = bind identity_fold_decl_item[ENV](_,_,_),
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index 700c0902..f7567590 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -295,25 +295,63 @@ fn fold_pat_tag(&env e, &span sp, import_map index, ident i,
ret @fold.respan[ast.pat_](sp, ast.pat_tag(i, args, new_def, a));
}
-fn fold_expr_name(&env e, &span sp, import_map index,
- &ast.name n, &option.t[def] d, ann a) -> @ast.expr {
-
- if (_vec.len[@ast.ty](n.node.types) > 0u) {
+// We received a path expression of the following form:
+//
+// a.b.c.d
+//
+// Somewhere along this path there might be a split from a path-expr
+// to a runtime field-expr. For example:
+//
+// 'a' could be the name of a variable in the local scope
+// and 'b.c.d' could be a field-sequence inside it.
+//
+// Or:
+//
+// 'a.b' could be a module path to a constant record, and 'c.d'
+// could be a field within it.
+//
+// Our job here is to figure out what the prefix of 'a.b.c.d' is that
+// corresponds to a static binding-name (a module or slot, with no type info)
+// and split that off as the 'primary' expr_path, with secondary expr_field
+// expressions tacked on the end.
+
+fn fold_expr_path(&env e, &span sp, import_map index,
+ &ast.path p, &option.t[def] d, ann a) -> @ast.expr {
+
+ if (_vec.len[@ast.ty](p.node.types) > 0u) {
e.sess.unimpl("resolving name expr with ty params");
}
- auto d_ = unwrap_def(lookup_name(e, some(index), n.node.ident));
+ auto n_idents = _vec.len[ast.ident](p.node.idents);
+
+ check (n_idents != 0u);
+ auto id0 = p.node.idents.(0);
+
+ auto d_ = unwrap_def(lookup_name(e, some(index), id0));
alt (d_) {
case (some[def](_)) {
// log "resolved name " + n.node.ident;
}
case (none[def]) {
- e.sess.span_err(sp, "unresolved name: " + n.node.ident);
+ e.sess.span_err(sp, "unresolved name: " + id0);
}
}
- ret @fold.respan[ast.expr_](sp, ast.expr_name(n, d_, a));
+ // FIXME: once espindola's modifications to lookup land, actually step
+ // through the path doing speculative lookup, and extend the maximal
+ // static prefix. For now we are always using the minimal prefix: first
+ // ident is static anchor, rest turn into fields.
+
+ auto p_ = rec(node=rec(idents = vec(id0) with p.node) with p);
+ auto ex = @fold.respan[ast.expr_](sp, ast.expr_path(p_, d_, a));
+ auto i = 1u;
+ while (i < n_idents) {
+ auto id = p.node.idents.(i);
+ ex = @fold.respan[ast.expr_](sp, ast.expr_field(ex, id, a));
+ i += 1u;
+ }
+ ret ex;
}
fn fold_view_item_import(&env e, &span sp,
@@ -339,26 +377,24 @@ fn fold_view_item_import(&env e, &span sp,
fn fold_ty_path(&env e, &span sp, import_map index, ast.path p,
&option.t[def] d) -> @ast.ty {
- let uint len = _vec.len[ast.name](p);
+ let uint len = _vec.len[ast.ident](p.node.idents);
check (len != 0u);
if (len > 1u) {
e.sess.unimpl("resolving path ty with >1 component");
}
- let ast.name n = p.(0);
-
- if (_vec.len[@ast.ty](n.node.types) > 0u) {
+ if (_vec.len[@ast.ty](p.node.types) > 0u) {
e.sess.unimpl("resolving path ty with ty params");
}
- auto d_ = unwrap_def(lookup_name(e, some(index), n.node.ident));
+ auto d_ = unwrap_def(lookup_name(e, some(index), p.node.idents.(0)));
alt (d_) {
- case (some[def](_)) {
+ case (some[def](?d)) {
// log "resolved name " + n.node.ident;
}
case (none[def]) {
- e.sess.span_err(sp, "unresolved name: " + n.node.ident);
+ e.sess.span_err(sp, "unresolved name: " + p.node.idents.(0));
}
}
@@ -387,7 +423,7 @@ fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate {
auto import_index = new_def_hash[def_wrap]();
fld = @rec( fold_pat_tag = bind fold_pat_tag(_,_,import_index,_,_,_,_),
- fold_expr_name = bind fold_expr_name(_,_,import_index,_,_,_),
+ fold_expr_path = bind fold_expr_path(_,_,import_index,_,_,_),
fold_view_item_import
= bind fold_view_item_import(_,_,import_index,_,_),
fold_ty_path = bind fold_ty_path(_,_,import_index,_,_),
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 09fa0a8d..594d7bc5 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -1772,7 +1772,7 @@ fn lval_val(@block_ctxt cx, ValueRef val) -> lval_result {
llobj=none[ValueRef]);
}
-fn trans_name(@block_ctxt cx, &ast.name n, &option.t[ast.def] dopt,
+fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt,
&ast.ann ann) -> lval_result {
alt (dopt) {
case (some[ast.def](?def)) {
@@ -1826,7 +1826,7 @@ fn trans_name(@block_ctxt cx, &ast.name n, &option.t[ast.def] dopt,
}
}
case (none[ast.def]) {
- cx.fcx.ccx.sess.err("unresolved expr_name in trans");
+ cx.fcx.ccx.sess.err("unresolved expr_path in trans");
}
}
fail;
@@ -1906,8 +1906,8 @@ impure fn trans_index(@block_ctxt cx, &ast.span sp, @ast.expr base,
impure fn trans_lval(@block_ctxt cx, @ast.expr e) -> lval_result {
alt (e.node) {
- case (ast.expr_name(?n, ?dopt, ?ann)) {
- ret trans_name(cx, n, dopt, ann);
+ case (ast.expr_path(?p, ?dopt, ?ann)) {
+ ret trans_path(cx, p, dopt, ann);
}
case (ast.expr_field(?base, ?ident, ?ann)) {
ret trans_field(cx, e.span, base, ident, ann);
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index ff54a0a1..b55e8be6 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -146,22 +146,17 @@ fn ast_ty_to_str(&@ast.ty ty) -> str {
ret s;
}
-fn name_to_str(&ast.name nm) -> str {
- auto result = nm.node.ident;
- if (_vec.len[@ast.ty](nm.node.types) > 0u) {
+fn path_to_str(&ast.path pth) -> str {
+ auto result = _str.connect(pth.node.idents, ".");
+ if (_vec.len[@ast.ty](pth.node.types) > 0u) {
auto f = ast_ty_to_str;
result += "[";
- result += _str.connect(_vec.map[@ast.ty,str](f, nm.node.types), ",");
+ result += _str.connect(_vec.map[@ast.ty,str](f, pth.node.types), ",");
result += "]";
}
ret result;
}
-fn path_to_str(&ast.path path) -> str {
- auto f = name_to_str;
- ret _str.connect(_vec.map[ast.name,str](f, path), ".");
-}
-
fn ty_to_str(&@t typ) -> str {
fn fn_input_to_str(&rec(ast.mode mode, @t ty) input) -> str {
@@ -632,7 +627,7 @@ fn expr_ty(@ast.expr expr) -> @t {
{ ret ann_to_type(ann); }
case (ast.expr_field(_, _, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_index(_, _, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_name(_, _, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_path(_, _, ?ann)) { ret ann_to_type(ann); }
}
fail;
}
@@ -697,7 +692,7 @@ fn is_lval(@ast.expr expr) -> bool {
alt (expr.node) {
case (ast.expr_field(_,_,_)) { ret true; }
case (ast.expr_index(_,_,_)) { ret true; }
- case (ast.expr_name(_,_,_)) { ret true; }
+ case (ast.expr_path(_,_,_)) { ret true; }
case (_) { ret false; }
}
}
@@ -1238,3 +1233,11 @@ fn resolve_ty_params(@ast.item item, @t monoty) -> vec[@t] {
ret result_tys;
}
+// Local Variables:
+// mode: rust
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
+// End:
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index d1e34e7a..d159c76f 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -753,9 +753,9 @@ fn demand_expr(&@fn_ctxt fcx, @ty.t expected, @ast.expr e) -> @ast.expr {
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
e_1 = ast.expr_index(base, index, ast.ann_type(t));
}
- case (ast.expr_name(?name, ?d, ?ann)) {
+ case (ast.expr_path(?pth, ?d, ?ann)) {
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
- e_1 = ast.expr_name(name, d, ast.ann_type(t));
+ e_1 = ast.expr_path(pth, d, ast.ann_type(t));
}
case (_) {
fail;
@@ -941,7 +941,7 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
ast.ann_type(oper_t)));
}
- case (ast.expr_name(?name, ?defopt, _)) {
+ case (ast.expr_path(?pth, ?defopt, _)) {
auto t = plain_ty(ty.ty_nil);
check (defopt != none[ast.def]);
alt (option.get[ast.def](defopt)) {
@@ -980,16 +980,20 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
t = generalize_ty(fcx.ccx, fcx.ccx.item_types.get(id));
}
+ case (ast.def_mod(_)) {
+ // Hopefully part of a path.
+ }
+
case (_) {
// FIXME: handle other names.
fcx.ccx.sess.unimpl("definition variant for: "
- + name.node.ident);
+ + _str.connect(pth.node.idents, "."));
fail;
}
}
ret @fold.respan[ast.expr_](expr.span,
- ast.expr_name(name, defopt,
+ ast.expr_path(pth, defopt,
ast.ann_type(t)));
}