aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/comp/front/ast.rs2
-rw-r--r--src/comp/front/parser.rs4
-rw-r--r--src/comp/middle/fold.rs14
-rw-r--r--src/comp/middle/resolve.rs21
-rw-r--r--src/comp/middle/trans.rs132
-rw-r--r--src/comp/util/common.rs19
6 files changed, 174 insertions, 18 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index e2dcf159..2135a97d 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -78,7 +78,7 @@ type local = rec(option[@ty] ty,
type decl = spanned[decl_];
tag decl_ {
- decl_local(local);
+ decl_local(@local);
decl_item(@item);
}
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index acf64c1b..68603e4a 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -629,7 +629,7 @@ io fn parse_let(parser p) -> @ast.decl {
init = init,
id = p.next_def_id());
- ret @spanned(lo, hi, ast.decl_local(local));
+ ret @spanned(lo, hi, ast.decl_local(@local));
}
io fn parse_auto(parser p) -> @ast.decl {
@@ -648,7 +648,7 @@ io fn parse_auto(parser p) -> @ast.decl {
init = init,
id = p.next_def_id());
- ret @spanned(lo, hi, ast.decl_local(local));
+ ret @spanned(lo, hi, ast.decl_local(@local));
}
io fn parse_stmt(parser p) -> @ast.stmt {
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 81bbffeb..4dd10871 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -103,7 +103,7 @@ type ast_fold[ENV] =
// Decl folds.
(fn(&ENV e, &span sp,
- &ast.local local) -> @decl) fold_decl_local,
+ @ast.local local) -> @decl) fold_decl_local,
(fn(&ENV e, &span sp,
@item item) -> @decl) fold_decl_item,
@@ -238,7 +238,7 @@ fn fold_decl[ENV](&ENV env, ast_fold[ENV] fld, @decl d) -> @decl {
init_ = some[@ast.expr](fold_expr(env, fld, e));
}
}
- let ast.local local_ = rec(ty=ty_, init=init_ with local);
+ let @ast.local local_ = @rec(ty=ty_, init=init_ with *local);
ret fld.fold_decl_local(env_, d.span, local_);
}
@@ -356,7 +356,7 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
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);
+ ret fld.fold_expr_name(env_, e.span, n_, r, t);
}
}
@@ -375,7 +375,7 @@ fn fold_stmt[ENV](&ENV env, ast_fold[ENV] fld, &@stmt s) -> @stmt {
alt (s.node) {
case (ast.stmt_decl(?d)) {
auto dd = fold_decl(env_, fld, d);
- ret fld.fold_stmt_decl(env_, s.span, d);
+ ret fld.fold_stmt_decl(env_, s.span, dd);
}
case (ast.stmt_ret(?oe)) {
@@ -390,12 +390,12 @@ fn fold_stmt[ENV](&ENV env, ast_fold[ENV] fld, &@stmt s) -> @stmt {
case (ast.stmt_log(?e)) {
auto ee = fold_expr(env_, fld, e);
- ret fld.fold_stmt_log(env_, s.span, e);
+ ret fld.fold_stmt_log(env_, s.span, ee);
}
case (ast.stmt_expr(?e)) {
auto ee = fold_expr(env_, fld, e);
- ret fld.fold_stmt_expr(env_, s.span, e);
+ ret fld.fold_stmt_expr(env_, s.span, ee);
}
}
ret s;
@@ -621,7 +621,7 @@ fn identity_fold_expr_name[ENV](&ENV env, &span sp,
// Decl identities.
fn identity_fold_decl_local[ENV](&ENV e, &span sp,
- &ast.local local) -> @decl {
+ @ast.local local) -> @decl {
ret @respan(sp, ast.decl_local(local));
}
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index 08b2e588..7951ec85 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -18,7 +18,8 @@ tag scope {
scope_block(ast.block);
}
-type env = list[scope];
+type env = rec(list[scope] scopes,
+ session.session sess);
fn lookup_name(&env e, ast.ident i) -> option[def] {
@@ -97,7 +98,7 @@ fn lookup_name(&env e, ast.ident i) -> option[def] {
ret none[def];
}
- ret std.list.find[scope,def](e, bind in_scope(i, _));
+ ret std.list.find[scope,def](e.scopes, bind in_scope(i, _));
}
fn fold_expr_name(&env e, &span sp, &ast.name n,
@@ -110,7 +111,7 @@ fn fold_expr_name(&env e, &span sp, &ast.name n,
log "resolved name " + n.node.ident;
}
case (none[def]) {
- log "unresolved name " + n.node.ident;
+ e.sess.err("unresolved name: " + n.node.ident);
}
}
@@ -118,25 +119,31 @@ fn fold_expr_name(&env e, &span sp, &ast.name n,
}
fn update_env_for_crate(&env e, @ast.crate c) -> env {
- ret cons[scope](scope_crate(c), @e);
+ ret rec(scopes = cons[scope](scope_crate(c), @e.scopes) with e);
}
fn update_env_for_item(&env e, @ast.item i) -> env {
- ret cons[scope](scope_item(i), @e);
+ ret rec(scopes = cons[scope](scope_item(i), @e.scopes) with e);
}
fn update_env_for_block(&env e, &ast.block b) -> env {
- ret cons[scope](scope_block(b), @e);
+ ret rec(scopes = cons[scope](scope_block(b), @e.scopes) with e);
}
fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate {
+
let fold.ast_fold[env] fld = fold.new_identity_fold[env]();
+
fld = @rec( fold_expr_name = bind fold_expr_name(_,_,_,_,_),
update_env_for_crate = bind update_env_for_crate(_,_),
update_env_for_item = bind update_env_for_item(_,_),
update_env_for_block = bind update_env_for_block(_,_)
with *fld );
- ret fold.fold_crate[env](nil[scope], fld, crate);
+
+ auto e = rec(scopes = nil[scope],
+ sess = sess);
+
+ ret fold.fold_crate[env](e, fld, crate);
}
// Local Variables:
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index dd7ac62e..c0f718fb 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -12,7 +12,9 @@ import driver.session;
import back.x86;
import back.abi;
+import util.common;
import util.common.istr;
+import util.common.new_def_hash;
import util.common.new_str_hash;
import lib.llvm.llvm;
@@ -49,6 +51,7 @@ state type trans_ctxt = rec(session.session sess,
state type fn_ctxt = rec(ValueRef llfn,
ValueRef lloutptr,
ValueRef lltaskptr,
+ hashmap[ast.def_id, ValueRef] lllocals,
@trans_ctxt tcx);
type terminator = fn(@fn_ctxt cx, builder build);
@@ -126,11 +129,23 @@ fn T_i64() -> TypeRef {
ret llvm.LLVMInt64Type();
}
+fn T_f32() -> TypeRef {
+ ret llvm.LLVMFloatType();
+}
+
+fn T_f64() -> TypeRef {
+ ret llvm.LLVMDoubleType();
+}
+
fn T_int() -> TypeRef {
// FIXME: switch on target type.
ret T_i32();
}
+fn T_char() -> TypeRef {
+ ret T_i32();
+}
+
fn T_fn(vec[TypeRef] inputs, TypeRef output) -> TypeRef {
ret llvm.LLVMFunctionType(output,
_vec.buf[TypeRef](inputs),
@@ -180,6 +195,10 @@ fn T_str(uint n) -> TypeRef {
ret T_vec(T_i8(), n);
}
+fn T_box(TypeRef t) -> TypeRef {
+ ret T_struct(vec(T_int(), t));
+}
+
fn T_crate() -> TypeRef {
ret T_struct(vec(T_int(), // ptrdiff_t image_base_off
T_int(), // uintptr_t self_addr
@@ -206,6 +225,49 @@ fn T_taskptr() -> TypeRef {
ret T_ptr(T_task());
}
+fn type_of(@trans_ctxt cx, @ast.ty t) -> TypeRef {
+ alt (t.node) {
+ case (ast.ty_nil) { ret T_nil(); }
+ case (ast.ty_bool) { ret T_i1(); }
+ case (ast.ty_int) { ret T_int(); }
+ case (ast.ty_uint) { ret T_int(); }
+ case (ast.ty_machine(?tm)) {
+ alt (tm) {
+ case (common.ty_i8) { ret T_i8(); }
+ case (common.ty_u8) { ret T_i8(); }
+ case (common.ty_i16) { ret T_i16(); }
+ case (common.ty_u16) { ret T_i16(); }
+ case (common.ty_i32) { ret T_i32(); }
+ case (common.ty_u32) { ret T_i32(); }
+ case (common.ty_i64) { ret T_i64(); }
+ case (common.ty_u64) { ret T_i64(); }
+ case (common.ty_f32) { ret T_f32(); }
+ case (common.ty_f64) { ret T_f64(); }
+ }
+ }
+ case (ast.ty_char) { ret T_char(); }
+ case (ast.ty_str) { ret T_str(0u); }
+ case (ast.ty_box(?t)) {
+ ret T_ptr(T_box(type_of(cx, t)));
+ }
+ case (ast.ty_vec(?t)) {
+ ret T_ptr(T_vec(type_of(cx, t), 0u));
+ }
+ case (ast.ty_tup(?elts)) {
+ let vec[TypeRef] tys = vec();
+ for (tup(bool, @ast.ty) elt in elts) {
+ tys += type_of(cx, elt._1);
+ }
+ ret T_struct(tys);
+ }
+ case (ast.ty_path(?pth, ?def)) {
+ // FIXME: implement.
+ cx.sess.unimpl("ty_path in trans.type_of");
+ }
+ }
+ fail;
+}
+
// LLVM constant constructors.
fn C_null(TypeRef t) -> ValueRef {
@@ -356,7 +418,7 @@ fn trans_lit(@block_ctxt cx, &ast.lit lit) -> result {
ret res(cx, C_int(u as int));
}
case (ast.lit_char(?c)) {
- ret res(cx, C_integral(c as int, T_i32()));
+ ret res(cx, C_integral(c as int, T_char()));
}
case (ast.lit_bool(?b)) {
ret res(cx, C_bool(b));
@@ -572,6 +634,25 @@ fn trans_expr(@block_ctxt cx, &ast.expr e) -> result {
ret res(next_cx, sub.val);
}
+
+ case (ast.expr_name(?n, ?dopt, _)) {
+ alt (dopt) {
+ case (some[ast.def](?def)) {
+ alt (def) {
+ case (ast.def_local(?did)) {
+ auto llptr = cx.fcx.lllocals.get(did);
+ ret res(cx, cx.build.Load(llptr));
+ }
+ case (_) {
+ cx.fcx.tcx.sess.unimpl("def variant in trans");
+ }
+ }
+ }
+ case (none[ast.def]) {
+ cx.fcx.tcx.sess.err("unresolved expr_name in trans");
+ }
+ }
+ }
}
cx.fcx.tcx.sess.unimpl("expr variant in trans_expr");
fail;
@@ -616,6 +697,20 @@ fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result {
sub.bcx = trans_expr(cx, *e).bcx;
}
+ case (ast.stmt_decl(?d)) {
+ alt (d.node) {
+ case (ast.decl_local(?local)) {
+ alt (local.init) {
+ case (some[@ast.expr](?e)) {
+ log "storing init of local " + local.ident;
+ auto llptr = cx.fcx.lllocals.get(local.id);
+ sub = trans_expr(cx, *e);
+ sub.val = sub.bcx.build.Store(sub.val, llptr);
+ }
+ }
+ }
+ }
+ }
case (_) {
cx.fcx.tcx.sess.unimpl("stmt variant");
}
@@ -685,9 +780,41 @@ fn trans_block_cleanups(@block_ctxt cx) -> @block_ctxt {
ret bcx;
}
+iter block_locals(&ast.block b) -> @ast.local {
+ // FIXME: putting from inside an iter block doesn't work, so we can't
+ // use the index here.
+ for (@ast.stmt s in b.node.stmts) {
+ alt (s.node) {
+ case (ast.stmt_decl(?d)) {
+ alt (d.node) {
+ case (ast.decl_local(?local)) {
+ put local;
+ }
+ }
+ }
+ }
+ }
+}
+
fn trans_block(@block_ctxt cx, &ast.block b) -> result {
auto bcx = cx;
+ for each (@ast.local local in block_locals(b)) {
+ log "declaring local " + local.ident;
+ auto ty = T_nil();
+ alt (local.ty) {
+ case (some[@ast.ty](?t)) {
+ ty = type_of(cx.fcx.tcx, t);
+ }
+ case (none[@ast.ty]) {
+ cx.fcx.tcx.sess.err("missing type for local " + local.ident);
+ }
+ }
+ auto val = bcx.build.Alloca(ty);
+ log "built alloca: " + val_str(val);
+ cx.fcx.lllocals.insert(local.id, val);
+ }
+
for (@ast.stmt s in b.node.stmts) {
bcx = trans_stmt(bcx, *s).bcx;
}
@@ -709,9 +836,11 @@ fn new_fn_ctxt(@trans_ctxt cx,
cx.fns.insert(cx.path, llfn);
let ValueRef lloutptr = llvm.LLVMGetParam(llfn, 0u);
let ValueRef lltaskptr = llvm.LLVMGetParam(llfn, 1u);
+ let hashmap[ast.def_id, ValueRef] lllocals = new_def_hash[ValueRef]();
ret @rec(llfn=llfn,
lloutptr=lloutptr,
lltaskptr=lltaskptr,
+ lllocals=lllocals,
tcx=cx);
}
@@ -758,6 +887,7 @@ fn trans_exit_task_glue(@trans_ctxt cx) {
auto fcx = @rec(llfn=llfn,
lloutptr=lloutptr,
lltaskptr=lltaskptr,
+ lllocals=new_def_hash[ValueRef](),
tcx=cx);
auto bcx = new_top_block_ctxt(fcx);
diff --git a/src/comp/util/common.rs b/src/comp/util/common.rs
index a5b77c0e..20bff22d 100644
--- a/src/comp/util/common.rs
+++ b/src/comp/util/common.rs
@@ -1,5 +1,6 @@
import std._uint;
import std._int;
+import front.ast;
type pos = rec(uint line, uint col);
type span = rec(str filename, pos lo, pos hi);
@@ -43,6 +44,24 @@ fn new_str_hash[V]() -> std.map.hashmap[str,V] {
ret std.map.mk_hashmap[str,V](hasher, eqer);
}
+fn new_def_hash[V]() -> std.map.hashmap[ast.def_id,V] {
+
+ fn hash(&ast.def_id d) -> uint {
+ let uint u = d._0 as uint;
+ u <<= 16u;
+ u |= d._1 as uint;
+ ret u;
+ }
+
+ fn eq(&ast.def_id a, &ast.def_id b) -> bool {
+ ret a._0 == b._0 && a._1 == b._1;
+ }
+
+ let std.map.hashfn[ast.def_id] hasher = hash;
+ let std.map.eqfn[ast.def_id] eqer = eq;
+ ret std.map.mk_hashmap[ast.def_id,V](hasher, eqer);
+}
+
fn istr(int i) -> str {
ret _int.to_str(i, 10u);
}