提交 f3c3fc03 编写于 作者: G Graydon Hoare

Change single-ident expr_ident to greedy/fat multi-ident expr_path, to handle...

Change single-ident expr_ident to greedy/fat multi-ident expr_path, to handle the module-path/value-indexing distinction.
上级 3722326c
......@@ -8,9 +8,8 @@
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 @@
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_];
......
......@@ -283,26 +283,7 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
}
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 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
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 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
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 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
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 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
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 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
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 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
}
case (_) {
ret parse_path_expr(p);
ret parse_dot_or_call_expr(p);
}
}
}
......@@ -658,7 +692,7 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
}
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; }
}
}
......
......@@ -11,7 +11,6 @@
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 @@
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 @@
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 @@
//// 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](_,_,_),
......
......@@ -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,_,_),
......
......@@ -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 @@ fn trans_name(@block_ctxt cx, &ast.name n, &option.t[ast.def] dopt,
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);
......
......@@ -146,22 +146,17 @@ fn ast_ty_field_to_str(&ast.ty_field f) -> 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 unify_actual_param(ast.def_id id, @t expected, @t actual)
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:
......@@ -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)));
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册