rust/src/comp/front/ast.rs

527 lines
13 KiB
Rust
Raw Normal View History

import std::option;
import std::str;
import std::vec;
import util::common::span;
import util::common::spanned;
import util::common::ty_mach;
import util::common::filename;
type ident = str;
type path_ = rec(vec[ident] idents, vec[@ty] types);
type path = spanned[path_];
type crate_num = int;
const crate_num local_crate = 0;
type def_num = int;
type def_id = tup(crate_num, def_num);
type ty_param = ident;
type ann = rec(uint id);
tag def {
def_fn(def_id);
2010-12-14 15:32:13 -08:00
def_obj(def_id);
2010-12-30 15:27:19 -08:00
def_obj_field(def_id);
def_mod(def_id);
2011-03-10 21:33:53 -05:00
def_native_mod(def_id);
def_const(def_id);
def_arg(def_id);
def_local(def_id);
2010-12-01 10:19:20 -08:00
def_variant(def_id /* tag */, def_id /* variant */);
def_ty(def_id);
def_ty_arg(uint);
2010-12-10 18:08:32 -08:00
def_binding(def_id);
def_use(def_id);
def_native_ty(def_id);
def_native_fn(def_id);
}
fn variant_def_ids(&def d) -> tup(def_id, def_id) {
alt (d) {
case (def_variant(?tag_id, ?var_id)) {
ret tup(tag_id, var_id);
}
}
}
fn def_id_of_def(def d) -> def_id {
alt (d) {
case (def_fn(?id)) { ret id; }
case (def_obj(?id)) { ret id; }
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; }
case (def_ty_arg(_)) { fail; }
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;
}
type crate = spanned[crate_];
type crate_ = rec(vec[@crate_directive] directives,
_mod module);
tag meta_visibility {
export_meta;
local_meta;
}
tag crate_directive_ {
cdir_expr(@expr);
// FIXME: cdir_let should be eliminated
// and redirected to the use of const stmt_decls inside
// crate directive blocks.
cdir_let(ident, @expr, vec[@crate_directive]);
cdir_src_mod(ident, option::t[filename]);
cdir_dir_mod(ident, option::t[filename], vec[@crate_directive]);
cdir_view_item(@view_item);
cdir_meta(meta_visibility, vec[@meta_item]);
cdir_syntax(path);
2011-04-19 13:35:49 -07:00
cdir_auth(path, _auth);
}
type crate_directive = spanned[crate_directive_];
2010-12-30 11:21:37 -05:00
type meta_item = spanned[meta_item_];
type meta_item_ = rec(ident name, str value);
type block = spanned[block_];
type block_ = rec(vec[@stmt] stmts,
option::t[@expr] expr,
2011-05-26 15:59:39 -07:00
ann a);
2010-11-24 14:42:01 -08:00
type pat = spanned[pat_];
tag pat_ {
2010-11-24 15:45:59 -08:00
pat_wild(ann);
2010-12-10 17:24:53 -08:00
pat_bind(ident, def_id, ann);
pat_lit(@lit, ann);
pat_tag(path, vec[@pat], ann);
2010-11-24 14:42:01 -08:00
}
tag mutability {
mut;
imm;
maybe_mut;
}
2010-12-03 18:03:28 -08:00
tag layer {
layer_value;
layer_state;
layer_gc;
}
2011-04-19 13:35:49 -07:00
tag _auth {
auth_unsafe;
2010-12-03 18:03:28 -08:00
}
tag proto {
proto_iter;
proto_fn;
}
tag binop {
2010-09-28 10:30:34 -07:00
add;
sub;
mul;
div;
rem;
and;
or;
bitxor;
bitand;
bitor;
lsl;
lsr;
asr;
eq;
lt;
le;
ne;
ge;
gt;
}
fn binop_to_str(binop op) -> str {
alt (op) {
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 ">";}
}
}
tag unop {
box(mutability);
2010-09-28 10:30:34 -07:00
deref;
bitnot;
not;
neg;
}
fn unop_to_str(unop op) -> str {
alt (op) {
case (box(?mt)) {
2011-06-01 13:12:12 -07:00
if (mt == mut) { ret "@mutable "; }
ret "@";
}
case (deref) {ret "*";}
case (bitnot) {ret "~";}
case (not) {ret "!";}
case (neg) {ret "-";}
}
}
2010-12-03 18:03:28 -08:00
tag mode {
val;
alias;
}
type stmt = spanned[stmt_];
tag stmt_ {
stmt_decl(@decl, ann);
stmt_expr(@expr, ann);
// These only exist in crate-level blocks.
stmt_crate_directive(@crate_directive);
}
tag init_op {
init_assign;
init_recv;
2011-05-31 15:41:08 -07:00
init_move;
}
type initializer = rec(init_op op,
@expr expr);
type local = rec(option::t[@ty] ty,
bool infer,
ident ident,
option::t[initializer] init,
def_id id,
ann ann);
type decl = spanned[decl_];
tag decl_ {
decl_local(@local);
decl_item(@item);
}
2011-05-11 15:26:36 +02:00
type arm = rec(@pat pat, block block);
2010-11-24 15:45:59 -08:00
type elt = rec(mutability mut, @expr expr);
type field_ = rec(mutability mut, ident ident, @expr expr);
type field = spanned[field_];
tag spawn_dom {
dom_implicit;
dom_thread;
}
type expr = spanned[expr_];
tag expr_ {
expr_vec(vec[@expr], mutability, ann);
expr_tup(vec[elt], ann);
expr_rec(vec[field], option::t[@expr], ann);
expr_call(@expr, vec[@expr], ann);
expr_self_method(ident, ann);
expr_bind(@expr, vec[option::t[@expr]], ann);
expr_spawn(spawn_dom, option::t[str], @expr, vec[@expr], ann);
expr_binary(binop, @expr, @expr, ann);
expr_unary(unop, @expr, ann);
expr_lit(@lit, ann);
expr_cast(@expr, @ty, ann);
expr_if(@expr, block, option::t[@expr], ann);
expr_while(@expr, block, ann);
expr_for(@decl, @expr, block, ann);
expr_for_each(@decl, @expr, block, ann);
expr_do_while(block, @expr, ann);
2010-11-24 14:42:01 -08:00
expr_alt(@expr, vec[arm], ann);
expr_block(block, ann);
expr_move(@expr /* TODO: @expr|is_lval */, @expr, ann);
expr_assign(@expr /* TODO: @expr|is_lval */, @expr, ann);
expr_assign_op(binop, @expr /* TODO: @expr|is_lval */, @expr, ann);
expr_send(@expr /* TODO: @expr|is_lval */, @expr, ann);
expr_recv(@expr /* TODO: @expr|is_lval */, @expr, ann);
expr_field(@expr, ident, ann);
expr_index(@expr, @expr, ann);
expr_path(path, ann);
expr_ext(path, vec[@expr], option::t[str], @expr, ann);
2011-06-08 03:58:52 -04:00
expr_fail(ann, option::t[str]);
expr_break(ann);
expr_cont(ann);
expr_ret(option::t[@expr], ann);
expr_put(option::t[@expr], ann);
expr_be(@expr, ann);
2011-04-19 11:21:23 +02:00
expr_log(int, @expr, ann);
/* just an assert, no significance to typestate */
expr_assert(@expr, ann);
/* preds that typestate is aware of */
expr_check(@expr, ann);
expr_port(ann);
expr_chan(@expr, ann);
expr_anon_obj(anon_obj, vec[ty_param], obj_def_ids, ann);
}
type lit = spanned[lit_];
tag lit_ {
lit_str(str);
lit_char(char);
lit_int(int);
lit_uint(uint);
lit_mach_int(ty_mach, int);
lit_float(str);
lit_mach_float(ty_mach, str);
lit_nil;
lit_bool(bool);
}
2010-11-03 16:43:12 -07:00
// NB: If you change this, you'll probably want to change the corresponding
// type structure in middle/ty.rs as well.
2010-12-03 18:03:28 -08:00
type mt = rec(@ty ty, mutability mut);
type ty_field_ = rec(ident ident, mt mt);
type ty_arg_ = rec(mode mode, @ty ty);
type ty_method_ = rec(proto proto, ident ident,
vec[ty_arg] inputs, @ty output,
controlflow cf);
type ty_field = spanned[ty_field_];
type ty_arg = spanned[ty_arg_];
type ty_method = spanned[ty_method_];
type ty = spanned[ty_];
tag ty_ {
ty_nil;
ty_bot; /* return type of ! functions and type of
ret/fail/break/cont. there is no syntax
for this type. */
/* 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. */
ty_bool;
ty_int;
ty_uint;
ty_float;
ty_machine(util::common::ty_mach);
ty_char;
ty_str;
ty_box(mt);
ty_vec(mt);
ty_ptr(mt);
ty_task;
ty_port(@ty);
ty_chan(@ty);
ty_tup(vec[mt]);
ty_rec(vec[ty_field]);
ty_fn(proto, vec[ty_arg], @ty, controlflow);
2010-12-14 17:42:12 -08:00
ty_obj(vec[ty_method]);
ty_path(path, ann);
2011-02-01 14:56:21 -08:00
ty_type;
ty_constr(@ty, vec[@constr]);
}
tag constr_arg_ {
carg_base;
carg_ident(ident);
2011-06-01 17:45:13 -07:00
carg_lit(@lit);
}
type constr_arg = spanned[constr_arg_];
type constr_ = rec(path path, vec[@constr_arg] args);
type constr = spanned[constr_];
type arg = rec(mode mode, @ty ty, ident ident, def_id id);
2011-04-19 13:35:49 -07:00
type fn_decl = rec(vec[arg] inputs,
@ty output,
purity purity,
controlflow cf);
tag purity {
pure_fn; // declared with "pred"
impure_fn; // declared with "fn"
}
tag controlflow {
noreturn; // functions with return type _|_ that always
// raise an error or exit (i.e. never return to the caller)
return; // everything else
}
2011-02-04 11:10:04 -05:00
type _fn = rec(fn_decl decl,
proto proto,
block body);
2010-12-16 18:34:04 -08:00
type method_ = rec(ident ident, _fn meth, def_id id, ann ann);
2010-12-14 15:32:13 -08:00
type method = spanned[method_];
2010-12-16 18:34:04 -08:00
type obj_field = rec(@ty ty, ident ident, def_id id, ann ann);
2010-12-14 15:32:13 -08:00
type _obj = rec(vec[obj_field] fields,
2011-03-01 17:32:16 -08:00
vec[@method] methods,
option::t[@method] dtor);
2010-12-14 15:32:13 -08:00
2011-05-10 11:55:32 -07:00
type anon_obj = rec(
// New fields and methods, if they exist.
2011-05-13 11:00:26 -07:00
option::t[vec[obj_field]] fields,
2011-05-10 11:55:32 -07:00
vec[@method] methods,
// with_obj: the original object being extended, if it exists.
2011-05-20 17:41:36 -07:00
option::t[@expr] with_obj);
type _mod = rec(vec[@view_item] view_items,
vec[@item] items);
2011-02-23 14:06:37 -05:00
tag native_abi {
native_abi_rust;
native_abi_cdecl;
native_abi_llvm;
native_abi_rust_intrinsic;
2011-02-23 14:06:37 -05:00
}
type native_mod = rec(str native_name,
2011-02-23 14:06:37 -05:00
native_abi abi,
2011-03-07 11:48:43 -08:00
vec[@view_item] view_items,
vec[@native_item] items);
type variant_arg = rec(@ty ty, def_id id);
type variant_ = rec(str name, vec[variant_arg] args, def_id id, ann ann);
type variant = spanned[variant_];
type view_item = spanned[view_item_];
tag view_item_ {
view_item_use(ident, vec[@meta_item], def_id, ann);
view_item_import(ident, vec[ident], def_id);
view_item_import_glob(vec[ident], def_id);
view_item_export(ident);
}
type obj_def_ids = rec(def_id ty, def_id ctor);
type item = spanned[item_];
tag item_ {
item_const(ident, @ty, @expr, def_id, ann);
2010-11-24 16:52:49 -08:00
item_fn(ident, _fn, vec[ty_param], def_id, ann);
item_mod(ident, _mod, def_id);
item_native_mod(ident, native_mod, def_id);
2010-11-24 17:36:22 -08:00
item_ty(ident, @ty, vec[ty_param], def_id, ann);
item_tag(ident, vec[variant], vec[ty_param], def_id, ann);
item_obj(ident, _obj, vec[ty_param], obj_def_ids, ann);
}
2011-05-11 15:10:24 +02:00
fn item_ident(@item it) -> ident {
ret alt (it.node) {
case (item_const(?ident, _, _, _, _)) { ident }
case (item_fn(?ident, _, _, _, _)) { ident }
case (item_mod(?ident, _, _)) { ident }
case (item_native_mod(?ident, _, _)) { ident }
case (item_ty(?ident, _, _, _, _)) { ident }
case (item_tag(?ident, _, _, _, _)) { ident }
case (item_obj(?ident, _, _, _, _)) { ident }
}
}
type native_item = spanned[native_item_];
tag native_item_ {
native_item_ty(ident, def_id);
native_item_fn(ident, option::t[str],
fn_decl, vec[ty_param], def_id, ann);
}
fn is_exported(ident i, _mod m) -> bool {
auto nonlocal = true;
for (@ast::item it in m.items) {
if (item_ident(it) == i) {
nonlocal = false;
}
alt (it.node) {
case (item_tag(_, ?variants, _, _, _)) {
for (variant v in variants) {
if (v.node.name == i) {
nonlocal = false;
}
}
}
case (_) {}
}
}
auto count = 0u;
for (@ast::view_item vi in m.view_items) {
alt (vi.node) {
case (ast::view_item_export(?id)) {
if (str::eq(i, id)) {
// even if it's nonlocal (since it's explicit)
ret true;
}
count += 1u;
}
case (_) { /* fall through */ }
}
}
// If there are no declared exports then
// everything not imported is exported
if (count == 0u && !nonlocal) {
ret true;
} else {
ret false;
}
}
fn is_call_expr(@expr e) -> bool {
alt (e.node) {
case (expr_call(_, _, _)) {
ret true;
}
case (_) {
ret false;
}
}
}
fn is_constraint_arg(@expr e) -> bool {
alt (e.node) {
case (expr_lit(_,_)) {
ret true;
}
case (expr_path(_, _)) {
ret true;
}
case (_) {
ret false;
}
}
}
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
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
2010-08-12 10:27:50 -07:00
// End:
//