about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2010-09-28 14:01:21 -0700
committerGraydon Hoare <graydon@mozilla.com>2010-09-28 14:01:21 -0700
commit5a4cb3ef36bc0610284c5e67c239363d3757df71 (patch)
treea1648adb11d18d0d3767a5ebf0b6b52d75ca8ed8 /src/comp
parent11e72fd4e0a2e46afd9021b8ab4fb071ffb6ee89 (diff)
downloadrust-5a4cb3ef36bc0610284c5e67c239363d3757df71.tar.gz
rust-5a4cb3ef36bc0610284c5e67c239363d3757df71.zip
Translate a modest selection of easy binops.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/parser.rs20
-rw-r--r--src/comp/lib/llvm.rs19
-rw-r--r--src/comp/middle/trans.rs174
3 files changed, 176 insertions, 37 deletions
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 9596f7144fa..98cb7e1ee95 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -250,11 +250,13 @@ state fn parse_prefix_expr(parser p) -> @ast.expr {
     alt (p.peek()) {
 
         case (token.NOT) {
+            p.bump();
             auto e = parse_prefix_expr(p);
             ret @ast.expr_unary(ast.not, e);
         }
 
         case (token.TILDE) {
+            p.bump();
             auto e = parse_prefix_expr(p);
             ret @ast.expr_unary(ast.bitnot, e);
         }
@@ -263,11 +265,13 @@ state fn parse_prefix_expr(parser p) -> @ast.expr {
             alt (b) {
 
                 case (token.MINUS) {
+                    p.bump();
                     auto e = parse_prefix_expr(p);
                     ret @ast.expr_unary(ast.neg, e);
                 }
 
                 case (token.STAR) {
+                    p.bump();
                     auto e = parse_prefix_expr(p);
                     ret @ast.expr_unary(ast.deref, e);
                 }
@@ -298,19 +302,16 @@ state fn parse_binops(parser p,
     auto more = true;
     while (more) {
         more = false;
-        auto t = p.peek();
-        alt (t) {
-            case (token.BINOP(?op)) {
-                for (tup(token.binop, ast.binop) pair in ops) {
+        for (tup(token.binop, ast.binop) pair in ops) {
+            alt (p.peek()) {
+                case (token.BINOP(?op)) {
                     if (pair._0 == op) {
+                        p.bump();
                         e = @ast.expr_binary(pair._1, e, sub(p));
                         more = true;
-                        t = p.peek();
                     }
                 }
             }
-            case (_) {
-            }
         }
     }
     ret e;
@@ -324,12 +325,11 @@ state fn parse_binary_exprs(parser p,
     auto more = true;
     while (more) {
         more = false;
-        auto t = p.peek();
         for (tup(token.token, ast.binop) pair in ops) {
-            if (pair._0 == t) {
+            if (pair._0 == p.peek()) {
+                p.bump();
                 e = @ast.expr_binary(pair._1, e, sub(p));
                 more = true;
-                t = p.peek();
             }
         }
     }
diff --git a/src/comp/lib/llvm.rs b/src/comp/lib/llvm.rs
index ac8dd76f3d9..f0cb65a2082 100644
--- a/src/comp/lib/llvm.rs
+++ b/src/comp/lib/llvm.rs
@@ -41,6 +41,21 @@ const uint LLVMColdCallConv = 9u;
 const uint LLVMX86StdcallCallConv = 64u;
 const uint LLVMX86FastcallCallConv = 65u;
 
+// Consts for the LLVM IntPredicate type, pre-cast to uint.
+// FIXME: as above.
+
+const uint LLVMIntEQ = 32;
+const uint LLVMIntNE = 33;
+const uint LLVMIntUGT = 34;
+const uint LLVMIntUGE = 35;
+const uint LLVMIntULT = 36;
+const uint LLVMIntULE = 37;
+const uint LLVMIntSGT = 38;
+const uint LLVMIntSGE = 39;
+const uint LLVMIntSLT = 40;
+const uint LLVMIntSLE = 41;
+
+
 native mod llvm = llvm_lib {
 
     type ModuleRef;
@@ -626,7 +641,7 @@ native mod llvm = llvm_lib {
                        TypeRef DestTy, sbuf Name) -> ValueRef;
 
     /* Comparisons */
-    fn LLVMBuildICmp(BuilderRef B, IntPredicate Op,
+    fn LLVMBuildICmp(BuilderRef B, uint Op,
                      ValueRef LHS, ValueRef RHS,
                      sbuf Name) -> ValueRef;
     fn LLVMBuildFCmp(BuilderRef B, RealPredicate Op,
@@ -981,7 +996,7 @@ obj builder(BuilderRef B) {
 
 
     /* Comparisons */
-    fn ICmp(IntPredicate Op, ValueRef LHS, ValueRef RHS) -> ValueRef {
+    fn ICmp(uint Op, ValueRef LHS, ValueRef RHS) -> ValueRef {
         ret llvm.LLVMBuildICmp(B, Op, LHS, RHS, _str.buf(""));
     }
 
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 9da370d779b..1fbee72b12f 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -159,6 +159,14 @@ fn C_integral(int i, TypeRef t) -> ValueRef {
     ret llvm.LLVMConstIntOfString(t, _str.buf(istr(i)), 10);
 }
 
+fn C_bool(bool b) -> ValueRef {
+    if (b) {
+        ret C_integral(1, T_i8());
+    } else {
+        ret C_integral(0, T_i8());
+    }
+}
+
 fn C_int(int i) -> ValueRef {
     ret C_integral(i, T_int());
 }
@@ -237,33 +245,148 @@ fn trans_upcall(@block_ctxt cx, str name, vec[ValueRef] args) -> ValueRef {
     ret cx.build.Call(llglue, call_args);
 }
 
+fn trans_lit(@block_ctxt cx, &ast.lit lit) -> ValueRef {
+    alt (lit) {
+        case (ast.lit_int(?i)) {
+            ret C_int(i);
+        }
+        case (ast.lit_uint(?u)) {
+            ret C_int(u as int);
+        }
+        case (ast.lit_char(?c)) {
+            ret C_integral(c as int, T_i32());
+        }
+        case (ast.lit_bool(?b)) {
+            ret C_bool(b);
+        }
+        case (ast.lit_str(?s)) {
+            auto len = (_str.byte_len(s) as int) + 1;
+            ret trans_upcall(cx, "upcall_new_str",
+                             vec(p2i(C_str(cx.fcx.tcx, s)),
+                                 C_int(len)));
+        }
+    }
+}
+
+fn trans_unary(@block_ctxt cx, ast.unop op, &ast.expr e) -> ValueRef {
+    alt (op) {
+        case (ast.bitnot) {
+            ret cx.build.Not(trans_expr(cx, e));
+        }
+        case (ast.not) {
+            ret cx.build.And(C_bool(true),
+                             cx.build.Not(trans_expr(cx, e)));
+        }
+        case (ast.neg) {
+            // FIXME: switch by signedness.
+            ret cx.build.Neg(trans_expr(cx, e));
+        }
+
+    }
+    cx.fcx.tcx.sess.unimpl("expr variant in trans_unary");
+    fail;
+}
+
+fn trans_binary(@block_ctxt cx, ast.binop op,
+                &ast.expr a, &ast.expr b) -> ValueRef {
+    alt (op) {
+        case (ast.add) {
+            ret cx.build.Add(trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.sub) {
+            ret cx.build.Sub(trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.mul) {
+            // FIXME: switch by signedness.
+            ret cx.build.Mul(trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.div) {
+            // FIXME: switch by signedness.
+            ret cx.build.SDiv(trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.rem) {
+            // FIXME: switch by signedness.
+            ret cx.build.SRem(trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.bitor) {
+            ret cx.build.Or(trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.bitand) {
+            ret cx.build.And(trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.bitxor) {
+            ret cx.build.Xor(trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.lsl) {
+            ret cx.build.Shl(trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.lsr) {
+            ret cx.build.LShr(trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.asr) {
+            ret cx.build.AShr(trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.eq) {
+            ret cx.build.ICmp(lib.llvm.LLVMIntEQ,
+                              trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.ne) {
+            ret cx.build.ICmp(lib.llvm.LLVMIntNE,
+                              trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.lt) {
+            // FIXME: switch by signedness.
+            ret cx.build.ICmp(lib.llvm.LLVMIntSLT,
+                              trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.le) {
+            // FIXME: switch by signedness.
+            ret cx.build.ICmp(lib.llvm.LLVMIntSLE,
+                              trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.ge) {
+            // FIXME: switch by signedness.
+            ret cx.build.ICmp(lib.llvm.LLVMIntSGE,
+                              trans_expr(cx, a), trans_expr(cx, b));
+        }
+
+        case (ast.gt) {
+            // FIXME: switch by signedness.
+            ret cx.build.ICmp(lib.llvm.LLVMIntSGT,
+                              trans_expr(cx, a), trans_expr(cx, b));
+        }
+    }
+    cx.fcx.tcx.sess.unimpl("expr variant in trans_binary");
+    fail;
+}
+
 fn trans_expr(@block_ctxt cx, &ast.expr e) -> ValueRef {
     alt (e) {
         case (ast.expr_lit(?lit)) {
-            alt (*lit) {
-                case (ast.lit_int(?i)) {
-                    ret C_int(i);
-                }
-                case (ast.lit_uint(?u)) {
-                    ret C_int(u as int);
-                }
-                case (ast.lit_char(?c)) {
-                    ret C_integral(c as int, T_i32());
-                }
-                case (ast.lit_bool(?b)) {
-                    if (b) {
-                        ret C_integral(1, T_i8());
-                    } else {
-                        ret C_integral(0, T_i8());
-                    }
-                }
-                case (ast.lit_str(?s)) {
-                    auto len = (_str.byte_len(s) as int) + 1;
-                    ret trans_upcall(cx, "upcall_new_str",
-                                     vec(p2i(C_str(cx.fcx.tcx, s)),
-                                         C_int(len)));
-                }
-            }
+            ret trans_lit(cx, *lit);
+        }
+
+        case (ast.expr_unary(?op, ?x)) {
+            ret trans_unary(cx, op, *x);
+        }
+
+        case (ast.expr_binary(?op, ?x, ?y)) {
+            ret trans_binary(cx, op, *x, *y);
         }
     }
     cx.fcx.tcx.sess.unimpl("expr variant in trans_expr");
@@ -285,7 +408,8 @@ fn trans_log(@block_ctxt cx, &ast.expr e) {
             }
         }
         case (_) {
-            cx.fcx.tcx.sess.unimpl("expr variant in trans_log");
+            auto v = trans_expr(cx, e);
+            trans_upcall(cx, "upcall_log_int", vec(v));
         }
     }
 }