2011-07-05 16:23:07 -07:00
|
|
|
// The Rust abstract syntax tree.
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-07-05 16:23:07 -07:00
|
|
|
import std::ivec;
|
2011-05-12 17:24:54 +02:00
|
|
|
import std::option;
|
2011-05-17 20:41:41 +02:00
|
|
|
import std::str;
|
2011-07-05 11:48:19 +02:00
|
|
|
import codemap::span;
|
|
|
|
import codemap::filename;
|
|
|
|
|
|
|
|
type spanned[T] = rec(T node, span span);
|
|
|
|
fn respan[T](&span sp, &T t) -> spanned[T] { ret rec(node=t, span=sp); }
|
2010-08-18 09:00:10 -07:00
|
|
|
|
|
|
|
type ident = str;
|
2011-06-24 15:11:22 -07:00
|
|
|
// Functions may or may not have names.
|
|
|
|
type fn_ident = option::t[ident];
|
2010-08-18 09:00:10 -07:00
|
|
|
|
2011-06-24 22:17:17 -07:00
|
|
|
// FIXME: with typestate constraint, could say
|
|
|
|
// idents and types are the same length, and are
|
|
|
|
// non-empty
|
2011-07-11 16:01:46 -07:00
|
|
|
type path_ = rec(bool global, ident[] idents, (@ty)[] types);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-01-13 17:42:28 -08:00
|
|
|
type path = spanned[path_];
|
2010-10-04 17:25:52 -07:00
|
|
|
|
2011-07-08 20:52:54 -07:00
|
|
|
fn path_name(&path p) -> str { path_name_i(p.node.idents) }
|
|
|
|
|
|
|
|
fn path_name_i(&ident[] idents) -> str { str::connect_ivec(idents, "::") }
|
A revised, improved alias-checker
The old system tried to ensure that the location an alias pointed at
would retain its type. That turned out to not be strong enough in the
face of aliases to the inside of tags.
The new system instead proves that values pointed to by aliases are
not replaced (or invalidated in some other way) at all. It knows of
two sufficient conditions for this, and tries to prove at least of
them:
A) The alias is 'immutably rooted' in a local, and this local is not
reassigned for the lifetime of the alias. Immutably rooted means
the alias refers to the local itself, or to something reachable
from the local through immutable dereferencing.
B) No value whose type might include the type of the 'inner mutable
element' of the thing the alias refers to (for example, the box in
rec(mutable x = @mutable int)) is from the outer scope is accessed
for the lifetime of the alias. This means for functions, no other
argument types may include the alias's inner mutable type. For alt,
for each, and for, it means the body does not refer to any locals
originating from outside their scope that include this type.
The lifetime of an alias in an alt, for each, or for body is defined
as the range from its definition to its last use, not to the point
where it goes out of scope. This makes working around these
restrictions somewhat less annoying. For example, you can assign to
your alt-ed value you don't refer to any bindings afterwards.
2011-06-07 11:20:51 +02:00
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
type crate_num = int;
|
2011-06-19 22:41:21 +02:00
|
|
|
type node_id = int;
|
|
|
|
type def_id = tup(crate_num, node_id);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-05-11 12:59:34 +02:00
|
|
|
const crate_num local_crate = 0;
|
2011-06-19 22:41:21 +02:00
|
|
|
fn local_def(node_id id) -> def_id {
|
|
|
|
ret tup(local_crate, id);
|
|
|
|
}
|
2010-10-18 16:15:25 -07:00
|
|
|
|
2011-04-12 15:09:50 -07:00
|
|
|
type ty_param = ident;
|
2010-11-24 18:01:20 -08:00
|
|
|
|
2010-10-18 16:15:25 -07:00
|
|
|
tag def {
|
2011-06-20 17:29:54 -07:00
|
|
|
def_fn(def_id, purity);
|
2010-12-30 15:27:19 -08:00
|
|
|
def_obj_field(def_id);
|
2010-10-18 16:15:25 -07:00
|
|
|
def_mod(def_id);
|
2011-03-10 21:33:53 -05:00
|
|
|
def_native_mod(def_id);
|
2010-10-18 16:15:25 -07:00
|
|
|
def_const(def_id);
|
|
|
|
def_arg(def_id);
|
|
|
|
def_local(def_id);
|
2011-06-15 11:19:50 -07:00
|
|
|
def_variant(def_id, /* tag */def_id);
|
|
|
|
|
|
|
|
/* variant */
|
2010-10-18 16:15:25 -07:00
|
|
|
def_ty(def_id);
|
2011-04-12 15:09:50 -07:00
|
|
|
def_ty_arg(uint);
|
2010-12-10 18:08:32 -08:00
|
|
|
def_binding(def_id);
|
2011-01-01 13:13:00 -05:00
|
|
|
def_use(def_id);
|
2011-02-07 15:07:27 -05:00
|
|
|
def_native_ty(def_id);
|
|
|
|
def_native_fn(def_id);
|
2010-10-05 18:21:44 -07:00
|
|
|
}
|
2010-10-04 17:25:52 -07:00
|
|
|
|
2011-05-12 13:25:18 +02:00
|
|
|
fn variant_def_ids(&def d) -> tup(def_id, def_id) {
|
|
|
|
alt (d) {
|
2011-06-15 11:19:50 -07:00
|
|
|
case (def_variant(?tag_id, ?var_id)) { ret tup(tag_id, var_id); }
|
2011-05-12 13:25:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-29 13:21:16 -07:00
|
|
|
fn def_id_of_def(def d) -> def_id {
|
|
|
|
alt (d) {
|
2011-06-20 17:29:54 -07:00
|
|
|
case (def_fn(?id,_)) { ret id; }
|
2011-03-29 13:21:16 -07:00
|
|
|
case (def_obj_field(?id)) { ret id; }
|
|
|
|
case (def_mod(?id)) { ret id; }
|
|
|
|
case (def_native_mod(?id)) { ret id; }
|
|
|
|
case (def_const(?id)) { ret id; }
|
|
|
|
case (def_arg(?id)) { ret id; }
|
|
|
|
case (def_local(?id)) { ret id; }
|
|
|
|
case (def_variant(_, ?id)) { ret id; }
|
|
|
|
case (def_ty(?id)) { ret id; }
|
2011-04-12 15:09:50 -07:00
|
|
|
case (def_ty_arg(_)) { fail; }
|
2011-03-29 13:21:16 -07:00
|
|
|
case (def_binding(?id)) { ret id; }
|
|
|
|
case (def_use(?id)) { ret id; }
|
|
|
|
case (def_native_ty(?id)) { ret id; }
|
|
|
|
case (def_native_fn(?id)) { ret id; }
|
|
|
|
}
|
|
|
|
fail;
|
|
|
|
}
|
|
|
|
|
2011-06-29 18:07:15 -07:00
|
|
|
// The set of meta_items that define the compilation environment of the crate,
|
|
|
|
// used to drive conditional compilation
|
2011-07-05 17:57:34 -07:00
|
|
|
type crate_cfg = (@meta_item)[];
|
2011-06-29 18:07:15 -07:00
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
type crate = spanned[crate_];
|
2010-08-18 09:00:10 -07:00
|
|
|
|
2011-07-05 17:50:14 -07:00
|
|
|
type crate_ = rec((@crate_directive)[] directives,
|
2011-06-16 16:38:23 -07:00
|
|
|
_mod module,
|
2011-07-05 17:02:51 -07:00
|
|
|
attribute[] attrs,
|
2011-06-29 18:07:15 -07:00
|
|
|
crate_cfg config);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-02-23 14:37:39 -08:00
|
|
|
tag crate_directive_ {
|
2011-07-05 17:02:51 -07:00
|
|
|
cdir_src_mod(ident, option::t[filename], attribute[]);
|
2011-06-28 18:15:39 -07:00
|
|
|
cdir_dir_mod(ident, option::t[filename],
|
2011-07-05 17:50:14 -07:00
|
|
|
(@crate_directive)[], attribute[]);
|
2011-02-23 14:37:39 -08:00
|
|
|
cdir_view_item(@view_item);
|
|
|
|
cdir_syntax(path);
|
2011-04-19 13:35:49 -07:00
|
|
|
cdir_auth(path, _auth);
|
2011-02-23 14:37:39 -08:00
|
|
|
}
|
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
type crate_directive = spanned[crate_directive_];
|
2011-02-23 14:37:39 -08:00
|
|
|
|
2010-12-30 11:21:37 -05:00
|
|
|
type meta_item = spanned[meta_item_];
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-06-21 14:23:16 -07:00
|
|
|
tag meta_item_ {
|
|
|
|
meta_word(ident);
|
2011-07-05 17:57:34 -07:00
|
|
|
meta_list(ident, (@meta_item)[]);
|
2011-07-05 17:01:23 -07:00
|
|
|
meta_name_value(ident, lit);
|
2011-06-21 14:23:16 -07:00
|
|
|
}
|
2010-12-30 11:21:37 -05:00
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
type block = spanned[block_];
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-07-06 19:00:00 -07:00
|
|
|
type block_ = rec((@stmt)[] stmts, option::t[@expr] expr, node_id id);
|
2010-08-18 09:00:10 -07:00
|
|
|
|
2011-07-04 21:53:33 +02:00
|
|
|
type pat = rec(node_id id,
|
|
|
|
pat_ node,
|
|
|
|
span span);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-07-11 14:13:20 +02:00
|
|
|
type field_pat = rec(ident ident, @pat pat);
|
|
|
|
|
2010-11-24 14:42:01 -08:00
|
|
|
tag pat_ {
|
2011-07-04 21:53:33 +02:00
|
|
|
pat_wild;
|
|
|
|
pat_bind(ident);
|
|
|
|
pat_lit(@lit);
|
2011-07-06 19:00:00 -07:00
|
|
|
pat_tag(path, (@pat)[]);
|
2011-07-11 14:13:20 +02:00
|
|
|
pat_rec(field_pat[], bool);
|
2011-07-13 10:50:16 +02:00
|
|
|
pat_box(@pat);
|
2010-11-24 14:42:01 -08:00
|
|
|
}
|
|
|
|
|
2011-07-08 16:27:55 +02:00
|
|
|
type pat_id_map = std::map::hashmap[str, ast::node_id];
|
|
|
|
|
|
|
|
// This is used because same-named variables in alternative patterns need to
|
|
|
|
// use the node_id of their namesake in the first pattern.
|
|
|
|
fn pat_id_map(&@pat pat) -> pat_id_map {
|
|
|
|
auto map = std::map::new_str_hash[node_id]();
|
|
|
|
fn walk(&pat_id_map map, &@pat pat) {
|
|
|
|
alt (pat.node) {
|
|
|
|
pat_bind(?name) { map.insert(name, pat.id); }
|
|
|
|
pat_tag(_, ?sub) {
|
|
|
|
for (@pat p in sub) { walk(map, p); }
|
|
|
|
}
|
2011-07-11 14:13:20 +02:00
|
|
|
pat_rec(?fields, _) {
|
|
|
|
for (field_pat f in fields) { walk(map, f.pat); }
|
|
|
|
}
|
2011-07-13 10:50:16 +02:00
|
|
|
pat_box(?inner) { walk(map, inner); }
|
2011-07-08 16:27:55 +02:00
|
|
|
_ {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
walk(map, pat);
|
|
|
|
ret map;
|
|
|
|
}
|
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
tag mutability { mut; imm; maybe_mut; }
|
2010-11-29 14:18:26 -08:00
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
tag layer { layer_value; layer_state; layer_gc; }
|
2010-12-03 18:03:28 -08:00
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
tag _auth { auth_unsafe; }
|
2010-12-03 18:03:28 -08:00
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
tag proto { proto_iter; proto_fn; }
|
2011-02-18 17:30:57 -08:00
|
|
|
|
2010-09-27 18:25:02 -07:00
|
|
|
tag binop {
|
2010-09-28 10:30:34 -07:00
|
|
|
add;
|
|
|
|
sub;
|
|
|
|
mul;
|
|
|
|
div;
|
|
|
|
rem;
|
|
|
|
and;
|
|
|
|
or;
|
|
|
|
bitxor;
|
2010-09-27 18:25:02 -07:00
|
|
|
bitand;
|
|
|
|
bitor;
|
|
|
|
lsl;
|
|
|
|
lsr;
|
|
|
|
asr;
|
|
|
|
eq;
|
|
|
|
lt;
|
|
|
|
le;
|
|
|
|
ne;
|
|
|
|
ge;
|
|
|
|
gt;
|
|
|
|
}
|
|
|
|
|
2011-03-04 07:22:43 +01:00
|
|
|
fn binop_to_str(binop op) -> str {
|
|
|
|
alt (op) {
|
2011-06-15 11:19:50 -07:00
|
|
|
case (add) { ret "+"; }
|
|
|
|
case (sub) { ret "-"; }
|
|
|
|
case (mul) { ret "*"; }
|
|
|
|
case (div) { ret "/"; }
|
|
|
|
case (rem) { ret "%"; }
|
|
|
|
case (and) { ret "&&"; }
|
|
|
|
case (or) { ret "||"; }
|
|
|
|
case (bitxor) { ret "^"; }
|
|
|
|
case (bitand) { ret "&"; }
|
|
|
|
case (bitor) { ret "|"; }
|
|
|
|
case (lsl) { ret "<<"; }
|
|
|
|
case (lsr) { ret ">>"; }
|
|
|
|
case (asr) { ret ">>>"; }
|
|
|
|
case (eq) { ret "=="; }
|
|
|
|
case (lt) { ret "<"; }
|
|
|
|
case (le) { ret "<="; }
|
|
|
|
case (ne) { ret "!="; }
|
|
|
|
case (ge) { ret ">="; }
|
|
|
|
case (gt) { ret ">"; }
|
2011-03-04 07:22:43 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-28 13:06:43 -07:00
|
|
|
pred lazy_binop(binop b) -> bool {
|
|
|
|
alt (b) {
|
|
|
|
case (and) { true }
|
|
|
|
case (or) { true }
|
|
|
|
case (_) { false }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
tag unop { box(mutability); deref; not; neg; }
|
2010-09-27 18:25:02 -07:00
|
|
|
|
2011-03-04 07:22:43 +01:00
|
|
|
fn unop_to_str(unop op) -> str {
|
|
|
|
alt (op) {
|
2011-06-15 11:19:50 -07:00
|
|
|
case (box(?mt)) { if (mt == mut) { ret "@mutable "; } ret "@"; }
|
|
|
|
case (deref) { ret "*"; }
|
|
|
|
case (not) { ret "!"; }
|
|
|
|
case (neg) { ret "-"; }
|
2011-03-04 07:22:43 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
tag mode { val; alias(bool); }
|
2010-12-03 18:03:28 -08:00
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
type stmt = spanned[stmt_];
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
tag stmt_ {
|
2011-06-19 22:41:21 +02:00
|
|
|
stmt_decl(@decl, node_id);
|
|
|
|
stmt_expr(@expr, node_id);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-02-24 15:54:55 -08:00
|
|
|
// These only exist in crate-level blocks.
|
|
|
|
stmt_crate_directive(@crate_directive);
|
2010-09-09 15:59:29 -07:00
|
|
|
}
|
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
tag init_op { init_assign; init_recv; init_move; }
|
|
|
|
|
|
|
|
type initializer = rec(init_op op, @expr expr);
|
2011-03-24 21:04:29 -04:00
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
type local_ =
|
|
|
|
rec(option::t[@ty] ty,
|
|
|
|
bool infer,
|
|
|
|
ident ident,
|
|
|
|
option::t[initializer] init,
|
2011-06-19 22:41:21 +02:00
|
|
|
node_id id);
|
2011-03-24 21:04:29 -04:00
|
|
|
|
2011-06-16 15:58:25 -07:00
|
|
|
type local = spanned[local_];
|
2010-10-18 18:19:16 -07:00
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
type decl = spanned[decl_];
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-06-16 15:58:25 -07:00
|
|
|
tag decl_ { decl_local(@local); decl_item(@item); }
|
2010-09-09 15:59:29 -07:00
|
|
|
|
2011-07-08 16:27:55 +02:00
|
|
|
type arm = rec((@pat)[] pats, block block);
|
2010-11-24 15:45:59 -08:00
|
|
|
|
2010-11-30 16:31:43 -08:00
|
|
|
type elt = rec(mutability mut, @expr expr);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-05-30 15:56:01 -07:00
|
|
|
type field_ = rec(mutability mut, ident ident, @expr expr);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-05-30 15:56:01 -07:00
|
|
|
type field = spanned[field_];
|
2010-11-30 16:31:43 -08:00
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
tag spawn_dom { dom_implicit; dom_thread; }
|
|
|
|
|
2011-06-28 16:29:37 -07:00
|
|
|
tag check_mode { checked; unchecked; }
|
2011-03-26 00:53:57 -04:00
|
|
|
|
2011-06-09 17:11:21 -07:00
|
|
|
// FIXME: temporary
|
2011-06-15 11:19:50 -07:00
|
|
|
tag seq_kind { sk_unique; sk_rc; }
|
2011-06-09 17:11:21 -07:00
|
|
|
|
2011-06-21 22:16:40 +02:00
|
|
|
type expr = rec(node_id id,
|
|
|
|
expr_ node,
|
|
|
|
span span);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
tag expr_ {
|
2011-07-06 19:00:00 -07:00
|
|
|
expr_vec((@expr)[], mutability, seq_kind);
|
|
|
|
expr_tup(elt[]);
|
|
|
|
expr_rec(field[], option::t[@expr]);
|
|
|
|
expr_call(@expr, (@expr)[]);
|
2011-06-21 22:16:40 +02:00
|
|
|
expr_self_method(ident);
|
2011-07-06 19:00:00 -07:00
|
|
|
expr_bind(@expr, (option::t[@expr])[]);
|
|
|
|
expr_spawn(spawn_dom, option::t[str], @expr, (@expr)[]);
|
2011-06-21 22:16:40 +02:00
|
|
|
expr_binary(binop, @expr, @expr);
|
|
|
|
expr_unary(unop, @expr);
|
|
|
|
expr_lit(@lit);
|
|
|
|
expr_cast(@expr, @ty);
|
|
|
|
expr_if(@expr, block, option::t[@expr]);
|
2011-06-23 15:15:50 -07:00
|
|
|
expr_ternary(@expr, @expr, @expr);
|
2011-06-21 22:16:40 +02:00
|
|
|
expr_while(@expr, block);
|
|
|
|
expr_for(@local, @expr, block);
|
|
|
|
expr_for_each(@local, @expr, block);
|
|
|
|
expr_do_while(block, @expr);
|
2011-07-06 19:00:00 -07:00
|
|
|
expr_alt(@expr, arm[]);
|
2011-06-21 22:16:40 +02:00
|
|
|
expr_fn(_fn);
|
|
|
|
expr_block(block);
|
2011-06-16 16:55:46 -07:00
|
|
|
/*
|
|
|
|
* FIXME: many of these @exprs should be constrained with
|
|
|
|
* is_lval once we have constrained types working.
|
|
|
|
*/
|
2011-06-21 22:16:40 +02:00
|
|
|
expr_move(@expr, @expr);
|
|
|
|
expr_assign(@expr,@expr);
|
|
|
|
expr_swap(@expr, @expr);
|
|
|
|
expr_assign_op(binop, @expr, @expr);
|
|
|
|
expr_send(@expr, @expr);
|
|
|
|
expr_recv(@expr, @expr);
|
|
|
|
expr_field(@expr, ident);
|
|
|
|
expr_index(@expr, @expr);
|
|
|
|
expr_path(path);
|
2011-07-01 14:33:15 -04:00
|
|
|
expr_fail(option::t[@expr]);
|
2011-06-21 22:16:40 +02:00
|
|
|
expr_break;
|
|
|
|
expr_cont;
|
|
|
|
expr_ret(option::t[@expr]);
|
|
|
|
expr_put(option::t[@expr]);
|
|
|
|
expr_be(@expr);
|
|
|
|
expr_log(int, @expr);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
|
|
|
/* just an assert, no significance to typestate */
|
2011-06-21 22:16:40 +02:00
|
|
|
expr_assert(@expr);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
|
|
|
/* preds that typestate is aware of */
|
2011-06-28 16:29:37 -07:00
|
|
|
expr_check(check_mode, @expr);
|
2011-06-16 11:56:34 -07:00
|
|
|
/* FIXME Would be nice if expr_check desugared
|
|
|
|
to expr_if_check. */
|
2011-06-21 22:16:40 +02:00
|
|
|
expr_if_check(@expr, block, option::t[@expr]);
|
2011-06-28 15:54:16 -07:00
|
|
|
expr_port(option::t[@ty]);
|
2011-07-08 16:35:09 -07:00
|
|
|
expr_chan(@expr);
|
2011-07-06 19:00:00 -07:00
|
|
|
expr_anon_obj(anon_obj, ty_param[]);
|
2011-07-08 16:35:09 -07:00
|
|
|
expr_mac(mac);
|
|
|
|
}
|
|
|
|
|
|
|
|
type mac = spanned[mac_];
|
|
|
|
|
|
|
|
tag mac_ {
|
|
|
|
mac_invoc(path, (@expr)[], option::t[str]);
|
|
|
|
mac_embed_type(@ty);
|
|
|
|
mac_embed_block(block);
|
2011-07-11 16:13:17 -07:00
|
|
|
mac_ellipsis;
|
2010-09-09 15:59:29 -07:00
|
|
|
}
|
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
type lit = spanned[lit_];
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
tag lit_ {
|
2011-06-09 17:11:21 -07:00
|
|
|
lit_str(str, seq_kind);
|
2010-09-09 15:59:29 -07:00
|
|
|
lit_char(char);
|
|
|
|
lit_int(int);
|
2010-09-21 16:22:32 -07:00
|
|
|
lit_uint(uint);
|
2010-11-22 17:41:26 -08:00
|
|
|
lit_mach_int(ty_mach, int);
|
2011-03-21 17:12:05 -07:00
|
|
|
lit_float(str);
|
2011-03-22 17:25:40 -07:00
|
|
|
lit_mach_float(ty_mach, str);
|
2010-09-20 23:56:43 -07:00
|
|
|
lit_nil;
|
2010-09-09 15:59:29 -07:00
|
|
|
lit_bool(bool);
|
|
|
|
}
|
|
|
|
|
2011-06-25 12:16:48 +02:00
|
|
|
fn is_path(&@expr e) -> bool {
|
|
|
|
ret alt (e.node) {
|
|
|
|
case (expr_path(_)) { true }
|
|
|
|
case (_) { false }
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2010-11-03 16:43:12 -07:00
|
|
|
// NB: If you change this, you'll probably want to change the corresponding
|
2010-12-21 12:13:51 -08:00
|
|
|
// type structure in middle/ty.rs as well.
|
2011-03-17 17:39:47 -07:00
|
|
|
type mt = rec(@ty ty, mutability mut);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-06-03 15:26:03 -07:00
|
|
|
type ty_field_ = rec(ident ident, mt mt);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-06-03 15:26:03 -07:00
|
|
|
type ty_arg_ = rec(mode mode, @ty ty);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
|
|
|
type ty_method_ =
|
|
|
|
rec(proto proto,
|
|
|
|
ident ident,
|
2011-07-06 16:01:47 -07:00
|
|
|
ty_arg[] inputs,
|
2011-06-15 11:19:50 -07:00
|
|
|
@ty output,
|
|
|
|
controlflow cf,
|
2011-07-06 16:12:39 -07:00
|
|
|
(@constr)[] constrs);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-06-03 15:26:03 -07:00
|
|
|
type ty_field = spanned[ty_field_];
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-06-03 15:26:03 -07:00
|
|
|
type ty_arg = spanned[ty_arg_];
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-06-03 15:26:03 -07:00
|
|
|
type ty_method = spanned[ty_method_];
|
|
|
|
|
2011-07-05 11:48:19 +02:00
|
|
|
tag ty_mach {
|
|
|
|
ty_i8;
|
|
|
|
ty_i16;
|
|
|
|
ty_i32;
|
|
|
|
ty_i64;
|
|
|
|
ty_u8;
|
|
|
|
ty_u16;
|
|
|
|
ty_u32;
|
|
|
|
ty_u64;
|
|
|
|
ty_f32;
|
|
|
|
ty_f64;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn ty_mach_to_str(ty_mach tm) -> str {
|
|
|
|
alt (tm) {
|
|
|
|
case (ty_u8) { ret "u8"; }
|
|
|
|
case (ty_u16) { ret "u16"; }
|
|
|
|
case (ty_u32) { ret "u32"; }
|
|
|
|
case (ty_u64) { ret "u64"; }
|
|
|
|
case (ty_i8) { ret "i8"; }
|
|
|
|
case (ty_i16) { ret "i16"; }
|
|
|
|
case (ty_i32) { ret "i32"; }
|
|
|
|
case (ty_i64) { ret "i64"; }
|
|
|
|
case (ty_f32) { ret "f32"; }
|
|
|
|
case (ty_f64) { ret "f64"; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
type ty = spanned[ty_];
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
tag ty_ {
|
2010-09-20 23:56:43 -07:00
|
|
|
ty_nil;
|
2011-05-14 19:02:30 -07:00
|
|
|
ty_bot; /* return type of ! functions and type of
|
|
|
|
ret/fail/break/cont. there is no syntax
|
|
|
|
for this type. */
|
2011-06-15 11:19:50 -07:00
|
|
|
|
|
|
|
/* bot represents the value of functions that don't return a value
|
|
|
|
locally to their context. in contrast, things like log that do
|
|
|
|
return, but don't return a meaningful value, have result type nil. */
|
2011-06-24 18:10:40 +02:00
|
|
|
ty_bool;
|
2010-09-20 23:56:43 -07:00
|
|
|
ty_int;
|
2010-09-21 16:22:32 -07:00
|
|
|
ty_uint;
|
2011-03-21 17:12:05 -07:00
|
|
|
ty_float;
|
2011-07-05 11:48:19 +02:00
|
|
|
ty_machine(ty_mach);
|
2010-09-20 23:56:43 -07:00
|
|
|
ty_char;
|
2010-09-21 16:22:32 -07:00
|
|
|
ty_str;
|
2011-06-15 11:19:50 -07:00
|
|
|
ty_istr; // interior string
|
|
|
|
|
2011-03-17 17:39:47 -07:00
|
|
|
ty_box(mt);
|
|
|
|
ty_vec(mt);
|
2011-06-15 11:19:50 -07:00
|
|
|
ty_ivec(mt); // interior vector
|
|
|
|
|
2011-06-03 14:34:19 -04:00
|
|
|
ty_ptr(mt);
|
2011-05-31 16:27:39 -07:00
|
|
|
ty_task;
|
2011-03-10 22:58:55 -05:00
|
|
|
ty_port(@ty);
|
|
|
|
ty_chan(@ty);
|
2011-07-06 15:53:47 -07:00
|
|
|
ty_tup(mt[]);
|
2011-07-06 16:01:47 -07:00
|
|
|
ty_rec(ty_field[]);
|
2011-07-06 16:12:39 -07:00
|
|
|
ty_fn(proto, ty_arg[], @ty, controlflow, (@constr)[]);
|
2011-07-06 16:01:47 -07:00
|
|
|
ty_obj(ty_method[]);
|
2011-06-19 22:41:21 +02:00
|
|
|
ty_path(path, node_id);
|
2011-02-01 14:56:21 -08:00
|
|
|
ty_type;
|
2011-07-06 16:12:39 -07:00
|
|
|
ty_constr(@ty, (@constr)[]);
|
2011-07-08 16:35:09 -07:00
|
|
|
ty_mac(mac);
|
2010-09-09 15:59:29 -07:00
|
|
|
}
|
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-06-10 19:12:42 -07:00
|
|
|
/*
|
|
|
|
A constraint arg that's a function argument is referred to by its position
|
|
|
|
rather than name. This is so we could have higher-order functions that have
|
|
|
|
constraints (potentially -- right now there's no way to write that), and also
|
|
|
|
so that the typestate pass doesn't have to map a function name onto its decl.
|
|
|
|
So, the constr_arg type is parameterized: it's instantiated with uint for
|
|
|
|
declarations, and ident for uses.
|
|
|
|
*/
|
2011-06-15 11:19:50 -07:00
|
|
|
tag constr_arg_general_[T] { carg_base; carg_ident(T); carg_lit(@lit); }
|
|
|
|
|
2011-06-10 19:12:42 -07:00
|
|
|
type constr_arg = constr_arg_general[uint];
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-06-10 19:12:42 -07:00
|
|
|
type constr_arg_general[T] = spanned[constr_arg_general_[T]];
|
|
|
|
|
2011-06-19 22:41:21 +02:00
|
|
|
type constr_ = rec(path path,
|
2011-07-06 16:19:19 -07:00
|
|
|
(@constr_arg_general[uint])[] args,
|
2011-06-19 22:41:21 +02:00
|
|
|
node_id id);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-06-15 15:14:30 -07:00
|
|
|
type constr = spanned[constr_];
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-06-16 16:55:46 -07:00
|
|
|
|
2011-06-15 15:14:30 -07:00
|
|
|
/* The parser generates ast::constrs; resolve generates
|
|
|
|
a mapping from each function to a list of ty::constr_defs,
|
|
|
|
corresponding to these. */
|
2011-06-19 22:41:21 +02:00
|
|
|
type arg = rec(mode mode, @ty ty, ident ident, node_id id);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
|
|
|
type fn_decl =
|
2011-07-06 19:00:00 -07:00
|
|
|
rec(arg[] inputs,
|
2011-06-15 11:19:50 -07:00
|
|
|
@ty output,
|
|
|
|
purity purity,
|
|
|
|
controlflow cf,
|
2011-07-06 16:12:39 -07:00
|
|
|
(@constr)[] constraints);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-05-04 11:28:13 -07:00
|
|
|
tag purity {
|
2011-06-15 11:19:50 -07:00
|
|
|
pure_fn; // declared with "pred"
|
|
|
|
|
2011-05-04 11:28:13 -07:00
|
|
|
impure_fn; // declared with "fn"
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-05-04 11:28:13 -07:00
|
|
|
}
|
|
|
|
|
2011-05-14 19:02:30 -07:00
|
|
|
tag controlflow {
|
|
|
|
noreturn; // functions with return type _|_ that always
|
|
|
|
// raise an error or exit (i.e. never return to the caller)
|
2011-06-15 11:19:50 -07:00
|
|
|
|
|
|
|
return; // everything else
|
|
|
|
|
2011-05-14 19:02:30 -07:00
|
|
|
}
|
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
type _fn = rec(fn_decl decl, proto proto, block body);
|
2010-08-18 09:00:10 -07:00
|
|
|
|
2011-06-19 22:41:21 +02:00
|
|
|
type method_ = rec(ident ident, _fn meth, node_id id);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2010-12-14 15:32:13 -08:00
|
|
|
type method = spanned[method_];
|
|
|
|
|
2011-06-19 22:41:21 +02:00
|
|
|
type obj_field = rec(mutability mut, @ty ty, ident ident, node_id id);
|
2011-06-16 17:33:31 -07:00
|
|
|
type anon_obj_field = rec(mutability mut, @ty ty, @expr expr, ident ident,
|
|
|
|
node_id id);
|
2010-12-14 15:32:13 -08:00
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
type _obj =
|
2011-07-06 19:00:00 -07:00
|
|
|
rec(obj_field[] fields, (@method)[] methods, option::t[@method] dtor);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
|
|
|
type anon_obj =
|
|
|
|
rec(
|
|
|
|
// New fields and methods, if they exist.
|
2011-07-06 19:00:00 -07:00
|
|
|
option::t[anon_obj_field[]] fields,
|
|
|
|
(@method)[] methods,
|
2011-05-06 17:08:41 -07:00
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
// with_obj: the original object being extended, if it exists.
|
|
|
|
option::t[@expr] with_obj);
|
|
|
|
|
2011-07-07 15:31:54 -07:00
|
|
|
type _mod = rec((@view_item)[] view_items, (@item)[] items);
|
2010-08-18 09:00:10 -07:00
|
|
|
|
2011-02-23 14:06:37 -05:00
|
|
|
tag native_abi {
|
|
|
|
native_abi_rust;
|
|
|
|
native_abi_cdecl;
|
2011-03-28 08:24:11 -07:00
|
|
|
native_abi_llvm;
|
2011-05-03 18:03:59 -07:00
|
|
|
native_abi_rust_intrinsic;
|
2011-02-23 14:06:37 -05:00
|
|
|
}
|
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
type native_mod =
|
|
|
|
rec(str native_name,
|
|
|
|
native_abi abi,
|
2011-07-07 15:31:54 -07:00
|
|
|
(@view_item)[] view_items,
|
|
|
|
(@native_item)[] items);
|
2011-02-01 13:40:04 -05:00
|
|
|
|
2011-06-19 22:41:21 +02:00
|
|
|
type variant_arg = rec(@ty ty, node_id id);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-07-07 15:31:54 -07:00
|
|
|
type variant_ = rec(str name, (variant_arg)[] args, node_id id);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-03-29 12:46:55 +02:00
|
|
|
type variant = spanned[variant_];
|
2010-11-24 11:36:35 -08:00
|
|
|
|
2011-01-01 12:55:18 -05:00
|
|
|
type view_item = spanned[view_item_];
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-01-01 12:55:18 -05:00
|
|
|
tag view_item_ {
|
2011-07-05 17:57:34 -07:00
|
|
|
view_item_use(ident, (@meta_item)[], node_id);
|
2011-07-07 15:31:54 -07:00
|
|
|
view_item_import(ident, ident[], node_id);
|
|
|
|
view_item_import_glob(ident[], node_id);
|
2011-06-19 22:41:21 +02:00
|
|
|
view_item_export(ident, node_id);
|
2011-01-01 12:55:18 -05:00
|
|
|
}
|
|
|
|
|
2011-06-19 22:41:21 +02:00
|
|
|
type obj_def_ids = rec(node_id ty, node_id ctor);
|
2011-03-30 17:23:25 -07:00
|
|
|
|
2011-06-14 16:13:19 -07:00
|
|
|
|
|
|
|
// Meta-data associated with an item
|
|
|
|
type attribute = spanned[attribute_];
|
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-06-14 16:13:19 -07:00
|
|
|
// Distinguishes between attributes that decorate items and attributes that
|
|
|
|
// are contained as statements within items. These two cases need to be
|
|
|
|
// distinguished for pretty-printing.
|
2011-06-15 11:19:50 -07:00
|
|
|
tag attr_style { attr_outer; attr_inner; }
|
2011-06-14 16:13:19 -07:00
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
type attribute_ = rec(attr_style style, meta_item value);
|
2011-06-14 16:13:19 -07:00
|
|
|
|
2011-06-19 22:41:21 +02:00
|
|
|
type item = rec(ident ident,
|
2011-07-05 17:02:51 -07:00
|
|
|
attribute[] attrs,
|
2011-06-24 18:10:40 +02:00
|
|
|
node_id id, // For objs and resources, this is the type def_id
|
2011-06-19 22:41:21 +02:00
|
|
|
item_ node,
|
|
|
|
span span);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
tag item_ {
|
2011-06-16 11:53:06 +02:00
|
|
|
item_const(@ty, @expr);
|
2011-07-06 19:00:00 -07:00
|
|
|
item_fn(_fn, ty_param[]);
|
2011-06-16 11:53:06 +02:00
|
|
|
item_mod(_mod);
|
|
|
|
item_native_mod(native_mod);
|
2011-07-06 19:00:00 -07:00
|
|
|
item_ty(@ty, ty_param[]);
|
|
|
|
item_tag(variant[], ty_param[]);
|
|
|
|
item_obj(_obj, ty_param[], node_id /* constructor id */);
|
2011-06-24 18:10:40 +02:00
|
|
|
item_res(_fn /* dtor */, node_id /* dtor id */,
|
2011-07-06 19:00:00 -07:00
|
|
|
ty_param[], node_id /* ctor id */);
|
2011-05-11 15:10:24 +02:00
|
|
|
}
|
|
|
|
|
2011-06-21 23:01:08 +02:00
|
|
|
type native_item = rec(ident ident,
|
2011-07-05 17:02:51 -07:00
|
|
|
attribute[] attrs,
|
2011-06-21 23:01:08 +02:00
|
|
|
native_item_ node,
|
|
|
|
node_id id,
|
|
|
|
span span);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-02-02 10:43:57 -05:00
|
|
|
tag native_item_ {
|
2011-06-21 23:01:08 +02:00
|
|
|
native_item_ty;
|
2011-07-06 19:00:00 -07:00
|
|
|
native_item_fn(option::t[str], fn_decl, ty_param[]);
|
2011-02-02 10:43:57 -05:00
|
|
|
}
|
|
|
|
|
2011-05-02 20:29:39 -04:00
|
|
|
fn is_exported(ident i, _mod m) -> bool {
|
2011-05-31 18:24:06 -07:00
|
|
|
auto nonlocal = true;
|
|
|
|
for (@ast::item it in m.items) {
|
2011-06-16 11:53:06 +02:00
|
|
|
if (it.ident == i) { nonlocal = false; }
|
2011-05-31 18:24:06 -07:00
|
|
|
alt (it.node) {
|
2011-06-16 11:53:06 +02:00
|
|
|
case (item_tag(?variants, _)) {
|
2011-05-31 18:24:06 -07:00
|
|
|
for (variant v in variants) {
|
2011-06-15 11:19:50 -07:00
|
|
|
if (v.node.name == i) { nonlocal = false; }
|
2011-05-31 18:24:06 -07:00
|
|
|
}
|
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
case (_) { }
|
2011-05-31 18:24:06 -07:00
|
|
|
}
|
2011-06-16 11:53:06 +02:00
|
|
|
if (!nonlocal) { break; }
|
2011-05-31 18:24:06 -07:00
|
|
|
}
|
|
|
|
auto count = 0u;
|
2011-05-12 17:24:54 +02:00
|
|
|
for (@ast::view_item vi in m.view_items) {
|
2011-05-02 20:29:39 -04:00
|
|
|
alt (vi.node) {
|
2011-06-19 22:41:21 +02:00
|
|
|
case (ast::view_item_export(?id, _)) {
|
2011-05-17 20:41:41 +02:00
|
|
|
if (str::eq(i, id)) {
|
2011-05-31 18:24:06 -07:00
|
|
|
// even if it's nonlocal (since it's explicit)
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-05-02 20:29:39 -04:00
|
|
|
ret true;
|
|
|
|
}
|
2011-05-31 18:24:06 -07:00
|
|
|
count += 1u;
|
2011-05-02 20:29:39 -04:00
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
case (_) {/* fall through */ }
|
2011-05-02 20:29:39 -04:00
|
|
|
}
|
|
|
|
}
|
2011-05-31 18:24:06 -07:00
|
|
|
// If there are no declared exports then
|
|
|
|
// everything not imported is exported
|
2011-06-16 16:55:46 -07:00
|
|
|
|
2011-06-16 11:53:06 +02:00
|
|
|
ret count == 0u && !nonlocal;
|
2011-05-02 20:29:39 -04:00
|
|
|
}
|
|
|
|
|
2011-02-09 22:36:37 -05:00
|
|
|
fn is_call_expr(@expr e) -> bool {
|
|
|
|
alt (e.node) {
|
2011-06-21 22:16:40 +02:00
|
|
|
case (expr_call(_, _)) { ret true; }
|
2011-06-15 11:19:50 -07:00
|
|
|
case (_) { ret false; }
|
2011-02-09 22:36:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-02 14:28:35 -07:00
|
|
|
fn is_constraint_arg(@expr e) -> bool {
|
|
|
|
alt (e.node) {
|
2011-06-21 22:16:40 +02:00
|
|
|
case (expr_lit(_)) { ret true; }
|
|
|
|
case (expr_path(_)) { ret true; }
|
2011-06-15 11:19:50 -07:00
|
|
|
case (_) { ret false; }
|
2011-05-02 14:28:35 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
fn eq_ty(&@ty a, &@ty b) -> bool { ret std::box::ptr_eq(a, b); }
|
2011-06-02 14:03:17 -07:00
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
fn hash_ty(&@ty t) -> uint { ret t.span.lo << 16u + t.span.hi; }
|
2011-06-23 15:15:50 -07:00
|
|
|
|
|
|
|
fn block_from_expr(@expr e) -> block {
|
|
|
|
let block_ blk_ =
|
2011-07-06 19:00:00 -07:00
|
|
|
rec(stmts=~[],
|
2011-06-23 15:15:50 -07:00
|
|
|
expr=option::some[@expr](e),
|
|
|
|
id=e.id);
|
|
|
|
ret rec(node=blk_, span=e.span);
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is a convenience function to transfor ternary expressions to if
|
|
|
|
// expressions so that they can be treated the same
|
|
|
|
fn ternary_to_if(&@expr e) -> @ast::expr {
|
|
|
|
alt (e.node) {
|
|
|
|
case (expr_ternary(?cond, ?then, ?els)) {
|
|
|
|
auto then_blk = block_from_expr(then);
|
|
|
|
auto els_blk = block_from_expr(els);
|
|
|
|
auto els_expr = @rec(id=els.id, node=expr_block(els_blk),
|
|
|
|
span=els.span);
|
|
|
|
ret @rec(id=e.id,
|
|
|
|
node=expr_if(cond, then_blk, option::some(els_expr)),
|
|
|
|
span=e.span);
|
|
|
|
}
|
|
|
|
case (_) { fail; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-01 17:10:33 -07:00
|
|
|
// Path stringification
|
|
|
|
fn path_to_str(&ast::path pth) -> str {
|
2011-07-05 16:23:07 -07:00
|
|
|
auto result = str::connect_ivec(pth.node.idents, "::");
|
|
|
|
if (ivec::len[@ast::ty](pth.node.types) > 0u) {
|
2011-07-05 11:48:19 +02:00
|
|
|
fn f(&@ast::ty t) -> str { ret print::pprust::ty_to_str(*t); }
|
2011-07-01 17:10:33 -07:00
|
|
|
result += "[";
|
2011-07-05 16:23:07 -07:00
|
|
|
result += str::connect_ivec(ivec::map(f, pth.node.types), ",");
|
2011-07-01 17:10:33 -07:00
|
|
|
result += "]";
|
|
|
|
}
|
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-12 10:27:50 -07:00
|
|
|
//
|
|
|
|
// Local Variables:
|
|
|
|
// mode: rust
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
2011-03-25 15:07:27 -07:00
|
|
|
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
2010-08-12 10:27:50 -07:00
|
|
|
// End:
|
|
|
|
//
|