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)); } } }