@@ -1958,10 +1958,66 @@ fn trans_unary(@block_ctxt cx, ast.unop op,
1958
1958
fail;
1959
1959
}
1960
1960
1961
- // FIXME: implement proper structural comparison.
1961
+ fn trans_compare( @block_ctxt cx, ast. binop op, @ty. t t,
1962
+ ValueRef lhs, ValueRef rhs) -> result {
1963
+
1964
+ if ( ty. type_is_scalar( t) ) {
1965
+ ret res( cx, trans_scalar_compare( cx, op, t, lhs, rhs) ) ;
1966
+
1967
+ } else if ( ty. type_is_structural( t) ) {
1968
+ auto scx = new_sub_block_ctxt( cx, "structural compare body" ) ;
1969
+ auto next = new_sub_block_ctxt( cx, "structural compare completion" ) ;
1970
+ cx. build. Br ( scx. llbb) ;
1971
+
1972
+ // Start with the assumptioin that our predicate holds.
1973
+ auto flag = scx. build. Alloca ( T_i1 ( ) ) ;
1974
+ scx. build. Store ( C_integral ( 1 , T_i1 ( ) ) , flag) ;
1975
+
1976
+ // Attempt to prove otherwise by inverting the sense of the comparison
1977
+ // on each inner element and bailing if any succeed.
1978
+
1979
+ // FIXME: finish this.
1980
+
1981
+ auto v = scx. build. Load ( flag) ;
1982
+ scx. build. Br ( next. llbb) ;
1983
+ ret res( next, v) ;
1984
+
1985
+ } else {
1986
+ // FIXME: compare vec, str, box?
1987
+ cx. fcx. ccx. sess. unimpl( "type in trans_compare" ) ;
1988
+ ret res( cx, C_bool ( false ) ) ;
1989
+ }
1990
+ }
1991
+
1992
+ fn trans_scalar_compare( @block_ctxt cx, ast. binop op, @ty. t t,
1993
+ ValueRef lhs, ValueRef rhs) -> ValueRef {
1994
+ if ( ty. type_is_fp( t) ) {
1995
+ ret trans_fp_compare( cx, op, t, lhs, rhs) ;
1996
+ } else {
1997
+ ret trans_integral_compare( cx, op, t, lhs, rhs) ;
1998
+ }
1999
+ }
2000
+
2001
+ fn trans_fp_compare( @block_ctxt cx, ast. binop op, @ty. t fptype,
2002
+ ValueRef lhs, ValueRef rhs) -> ValueRef {
1962
2003
1963
- fn trans_compare( @block_ctxt cx, ast. binop op, @ty. t intype,
1964
- ValueRef lhs, ValueRef rhs) -> ValueRef {
2004
+ auto cmp = lib. llvm. LLVMIntEQ ;
2005
+ alt ( op) {
2006
+ // FIXME: possibly use the unordered-or-< predicates here,
2007
+ // for now we're only going with ordered-and-< style (no NaNs).
2008
+ case ( ast. eq) { cmp = lib. llvm. LLVMRealOEQ; }
2009
+ case ( ast. ne) { cmp = lib. llvm. LLVMRealONE ; }
2010
+ case ( ast. lt) { cmp = lib. llvm. LLVMRealOLT ; }
2011
+ case ( ast. gt) { cmp = lib. llvm. LLVMRealOGT ; }
2012
+ case ( ast. le) { cmp = lib. llvm. LLVMRealOLE ; }
2013
+ case ( ast. ge) { cmp = lib. llvm. LLVMRealOGE ; }
2014
+ }
2015
+
2016
+ ret cx. build. FCmp ( cmp, lhs, rhs) ;
2017
+ }
2018
+
2019
+ fn trans_integral_compare( @block_ctxt cx, ast. binop op, @ty. t intype,
2020
+ ValueRef lhs, ValueRef rhs) -> ValueRef {
1965
2021
auto cmp = lib. llvm. LLVMIntEQ ;
1966
2022
alt ( op) {
1967
2023
case ( ast. eq) { cmp = lib. llvm. LLVMIntEQ ; }
@@ -2000,34 +2056,34 @@ fn trans_compare(@block_ctxt cx, ast.binop op, @ty.t intype,
2000
2056
}
2001
2057
2002
2058
fn trans_eager_binop( @block_ctxt cx, ast. binop op, @ty. t intype,
2003
- ValueRef lhs, ValueRef rhs) -> ValueRef {
2059
+ ValueRef lhs, ValueRef rhs) -> result {
2004
2060
2005
2061
alt ( op) {
2006
- case ( ast. add) { ret cx . build. Add ( lhs, rhs) ; }
2007
- case ( ast. sub) { ret cx . build. Sub ( lhs, rhs) ; }
2062
+ case ( ast. add) { ret res ( cx , cx . build. Add ( lhs, rhs) ) ; }
2063
+ case ( ast. sub) { ret res ( cx , cx . build. Sub ( lhs, rhs) ) ; }
2008
2064
2009
- case ( ast. mul) { ret cx . build. Mul ( lhs, rhs) ; }
2065
+ case ( ast. mul) { ret res ( cx , cx . build. Mul ( lhs, rhs) ) ; }
2010
2066
case ( ast. div) {
2011
2067
if ( ty. type_is_signed( intype) ) {
2012
- ret cx . build. SDiv ( lhs, rhs) ;
2068
+ ret res ( cx , cx . build. SDiv ( lhs, rhs) ) ;
2013
2069
} else {
2014
- ret cx . build. UDiv ( lhs, rhs) ;
2070
+ ret res ( cx , cx . build. UDiv ( lhs, rhs) ) ;
2015
2071
}
2016
2072
}
2017
2073
case ( ast. rem) {
2018
2074
if ( ty. type_is_signed( intype) ) {
2019
- ret cx . build. SRem ( lhs, rhs) ;
2075
+ ret res ( cx , cx . build. SRem ( lhs, rhs) ) ;
2020
2076
} else {
2021
- ret cx . build. URem ( lhs, rhs) ;
2077
+ ret res ( cx , cx . build. URem ( lhs, rhs) ) ;
2022
2078
}
2023
2079
}
2024
2080
2025
- case ( ast. bitor) { ret cx . build. Or ( lhs, rhs) ; }
2026
- case ( ast. bitand) { ret cx . build. And ( lhs, rhs) ; }
2027
- case ( ast. bitxor) { ret cx . build. Xor ( lhs, rhs) ; }
2028
- case ( ast. lsl) { ret cx . build. Shl ( lhs, rhs) ; }
2029
- case ( ast. lsr) { ret cx . build. LShr ( lhs, rhs) ; }
2030
- case ( ast. asr) { ret cx . build. AShr ( lhs, rhs) ; }
2081
+ case ( ast. bitor) { ret res ( cx , cx . build. Or ( lhs, rhs) ) ; }
2082
+ case ( ast. bitand) { ret res ( cx , cx . build. And ( lhs, rhs) ) ; }
2083
+ case ( ast. bitxor) { ret res ( cx , cx . build. Xor ( lhs, rhs) ) ; }
2084
+ case ( ast. lsl) { ret res ( cx , cx . build. Shl ( lhs, rhs) ) ; }
2085
+ case ( ast. lsr) { ret res ( cx , cx . build. LShr ( lhs, rhs) ) ; }
2086
+ case ( ast. asr) { ret res ( cx , cx . build. AShr ( lhs, rhs) ) ; }
2031
2087
case ( _) {
2032
2088
ret trans_compare( cx, op, intype, lhs, rhs) ;
2033
2089
}
@@ -2055,6 +2111,21 @@ fn autoderef(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
2055
2111
}
2056
2112
}
2057
2113
2114
+ fn autoderefed_ty( @ty. t t) -> @ty. t {
2115
+ let @ty. t t1 = t;
2116
+
2117
+ while ( true ) {
2118
+ alt ( t1. struct ) {
2119
+ case ( ty. ty_box( ?inner) ) {
2120
+ t1 = inner;
2121
+ }
2122
+ case ( _) {
2123
+ ret t1;
2124
+ }
2125
+ }
2126
+ }
2127
+ }
2128
+
2058
2129
fn trans_binary( @block_ctxt cx, ast. binop op,
2059
2130
@ast. expr a, @ast. expr b) -> result {
2060
2131
@@ -2109,8 +2180,9 @@ fn trans_binary(@block_ctxt cx, ast.binop op,
2109
2180
auto rhs = trans_expr( lhs. bcx, b) ;
2110
2181
auto rhty = ty. expr_ty( b) ;
2111
2182
rhs = autoderef( rhs. bcx, rhs. val, rhty) ;
2112
- ret res( rhs. bcx, trans_eager_binop( rhs. bcx, op, lhty,
2113
- lhs. val, rhs. val) ) ;
2183
+ ret trans_eager_binop( rhs. bcx, op,
2184
+ autoderefed_ty( lhty) ,
2185
+ lhs. val, rhs. val) ;
2114
2186
}
2115
2187
}
2116
2188
fail;
@@ -2399,8 +2471,8 @@ fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval,
2399
2471
auto lltype = ty. ann_to_type( ann) ;
2400
2472
auto lleq = trans_compare( cx, ast. eq, lltype, llval, lllit) ;
2401
2473
2402
- auto matched_cx = new_sub_block_ctxt( cx , "matched_cx") ;
2403
- cx . build. CondBr ( lleq, matched_cx. llbb, next_cx. llbb) ;
2474
+ auto matched_cx = new_sub_block_ctxt( lleq . bcx , "matched_cx") ;
2475
+ lleq . bcx . build. CondBr ( lleq. val , matched_cx. llbb, next_cx. llbb) ;
2404
2476
ret res( matched_cx, llval) ;
2405
2477
}
2406
2478
@@ -2656,8 +2728,9 @@ fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt,
2656
2728
fn trans_field( @block_ctxt cx, & ast. span sp, @ast. expr base,
2657
2729
& ast. ident field, & ast. ann ann) -> lval_result {
2658
2730
auto r = trans_expr( cx, base) ;
2659
- r = autoderef( r. bcx, r. val, ty. expr_ty( base) ) ;
2660
2731
auto t = ty. expr_ty( base) ;
2732
+ r = autoderef( r. bcx, r. val, t) ;
2733
+ t = autoderefed_ty( t) ;
2661
2734
alt ( t. struct ) {
2662
2735
case ( ty. ty_tup( ?fields) ) {
2663
2736
let uint ix = ty. field_num( cx. fcx. ccx. sess, sp, field) ;
@@ -3439,8 +3512,8 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
3439
3512
auto v = trans_eager_binop( rhs_res. bcx, op, t,
3440
3513
lhs_val, rhs_res. val) ;
3441
3514
// FIXME: calculate copy init-ness in typestate.
3442
- ret copy_ty( rhs_res . bcx, DROP_EXISTING ,
3443
- lhs_res. res. val, v, t) ;
3515
+ ret copy_ty( v . bcx, DROP_EXISTING ,
3516
+ lhs_res. res. val, v. val , t) ;
3444
3517
}
3445
3518
3446
3519
case ( ast. expr_bind( ?f, ?args, ?ann) ) {
0 commit comments