aboutsummaryrefslogtreecommitdiff
path: root/src/comp/me/trans.rs
blob: 57213d9382b7d051bb18cdc8ff3ffdcec008f9a3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import std._str;
import std._vec;
import std._str.rustrt.sbuf;
import std._vec.rustrt.vbuf;

import fe.ast;
import driver.session;

import lib.llvm.llvm;
import lib.llvm.builder;
import lib.llvm.llvm.ModuleRef;
import lib.llvm.llvm.ValueRef;
import lib.llvm.llvm.TypeRef;
import lib.llvm.llvm.BuilderRef;
import lib.llvm.llvm.BasicBlockRef;

import lib.llvm.False;
import lib.llvm.True;

type trans_ctxt = rec(session.session sess,
                      ModuleRef llmod,
                      str path);

fn T_nil() -> TypeRef {
    ret llvm.LLVMVoidType();
}

fn T_int() -> TypeRef {
    ret llvm.LLVMInt32Type();
}

fn T_fn(vec[TypeRef] inputs, TypeRef output) -> TypeRef {
    ret llvm.LLVMFunctionType(output,
                              _vec.buf[TypeRef](inputs),
                              _vec.len[TypeRef](inputs),
                              False());
}

fn trans_log(&trans_ctxt cx, builder b, &ast.atom a) {
}

fn trans_stmt(&trans_ctxt cx, builder b, &ast.stmt s) {
    alt (s) {
        case (ast.stmt_log(?a)) {
            trans_log(cx, b, *a);
        }
        case (_) {
            cx.sess.unimpl("stmt variant");
        }
    }
}

fn trans_block(&trans_ctxt cx, ValueRef llfn, &ast.block b) {
    let BasicBlockRef llbb =
        llvm.LLVMAppendBasicBlock(llfn, _str.buf(""));
    let BuilderRef llbuild = llvm.LLVMCreateBuilder();
    llvm.LLVMPositionBuilderAtEnd(llbuild, llbb);
    auto bld = builder(llbuild);
    for (@ast.stmt s in b) {
        trans_stmt(cx, bld, *s);
    }
}

fn trans_fn(&trans_ctxt cx, &ast._fn f) {
    let vec[TypeRef] args = vec();
    let TypeRef llty = T_fn(args, T_nil());
    let ValueRef llfn =
        llvm.LLVMAddFunction(cx.llmod, _str.buf(cx.path), llty);
    trans_block(cx, llfn, f.body);
}

fn trans_item(&trans_ctxt cx, &str name, &ast.item item) {
    auto sub_cx = rec(path=cx.path + "." + name with cx);
    alt (item) {
        case (ast.item_fn(?f)) {
            trans_fn(sub_cx, *f);
        }
        case (ast.item_mod(?m)) {
            trans_mod(sub_cx, *m);
        }
    }
}

fn trans_mod(&trans_ctxt cx, &ast._mod m) {
    for each (tup(str, ast.item) pair in m.items()) {
        trans_item(cx, pair._0, pair._1);
    }
}

fn trans_crate(session.session sess, ast.crate crate) {
    auto llmod =
        llvm.LLVMModuleCreateWithNameInContext(_str.buf("rust_out"),
                                               llvm.LLVMGetGlobalContext());

    auto cx = rec(sess=sess, llmod=llmod, path="");
    trans_mod(cx, crate.module);

    llvm.LLVMWriteBitcodeToFile(llmod, _str.buf("rust_out.bc"));
    llvm.LLVMDisposeModule(llmod);
}

//
// 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:
//