1
- import std:: { str, vec, option} ;
1
+ import std:: { str, vec, option, int } ;
2
2
import option:: { some, none} ;
3
3
import std:: map:: hashmap;
4
4
@@ -16,22 +16,34 @@ import util::common::lit_eq;
16
16
17
17
import trans_common:: * ;
18
18
19
- // An option identifying a branch (either a literal or a tag variant)
19
+ // An option identifying a branch (either a literal, a tag variant or a range )
20
20
tag opt {
21
21
lit( @ast : : lit) ;
22
22
var ( /* variant id */ uint, /* variant dids */ { tg: def_id, var: def_id} ) ;
23
+ range ( @ast:: lit, @ast:: lit) ;
23
24
}
24
25
fn opt_eq ( a : opt , b : opt ) -> bool {
25
26
alt a {
26
27
lit( la) {
27
- ret alt b { lit( lb) { lit_eq ( la, lb) } var ( _ , _ ) { false } } ;
28
+ ret alt b { lit( lb) { lit_eq ( la, lb) } _ { false } } ;
28
29
}
29
30
var ( ida, _) {
30
- ret alt b { lit( _) { false } var ( idb, _) { ida == idb } } ;
31
+ ret alt b { var( idb, _) { ida == idb } _ { false } } ;
32
+ }
33
+ range ( la1, la2) {
34
+ ret alt b {
35
+ range( lb1, lb2) { lit_eq ( la1, lb1) && lit_eq ( la2, lb2) }
36
+ _ { false }
37
+ } ;
31
38
}
32
39
}
33
40
}
34
- fn trans_opt ( bcx : @block_ctxt , o : opt ) -> result {
41
+
42
+ tag opt_result {
43
+ single_result( result) ;
44
+ range_result ( result, result) ;
45
+ }
46
+ fn trans_opt ( bcx : @block_ctxt , o : opt ) -> opt_result {
35
47
alt o {
36
48
lit( l) {
37
49
alt l. node {
@@ -40,14 +52,22 @@ fn trans_opt(bcx: @block_ctxt, o: opt) -> result {
40
52
let { bcx, val: dst } = trans:: alloc_ty ( bcx, strty) ;
41
53
bcx = trans_vec:: trans_str ( bcx, s, trans:: save_in ( dst) ) ;
42
54
add_clean_temp ( bcx, dst, strty) ;
43
- ret rslt( bcx, dst) ;
55
+ ret single_result ( rslt ( bcx, dst) ) ;
44
56
}
45
57
_ {
46
- ret rslt( bcx, trans:: trans_crate_lit ( bcx_ccx ( bcx) , * l) ) ;
58
+ ret single_result(
59
+ rslt ( bcx, trans:: trans_crate_lit ( bcx_ccx ( bcx) , * l) ) ) ;
47
60
}
48
61
}
49
62
}
50
- var ( id, _) { ret rslt ( bcx, C_int ( id as int ) ) ; }
63
+ var ( id, _) { ret single_result ( rslt ( bcx, C_int ( id as int ) ) ) ; }
64
+ range ( l1, l2) {
65
+ let cell1 = trans:: empty_dest_cell ( ) ;
66
+ let cell2 = trans:: empty_dest_cell ( ) ;
67
+ let bcx = trans:: trans_lit ( bcx, * l1, trans:: by_val ( cell1) ) ;
68
+ let bcx = trans:: trans_lit ( bcx, * l2, trans:: by_val ( cell2) ) ;
69
+ ret range_result ( rslt ( bcx, * cell1) , rslt ( bcx, * cell2) ) ;
70
+ }
51
71
}
52
72
}
53
73
@@ -137,6 +157,9 @@ fn enter_opt(ccx: @crate_ctxt, m: match, opt: opt, col: uint, tag_size: uint,
137
157
ast:: pat_lit ( l) {
138
158
ret if opt_eq ( lit ( l) , opt) { some ( [ ] ) } else { none } ;
139
159
}
160
+ ast:: pat_range ( l1, l2) {
161
+ ret if opt_eq ( range ( l1, l2) , opt) { some ( [ ] ) } else { none } ;
162
+ }
140
163
_ { ret some( vec:: init_elt ( dummy, size) ) ; }
141
164
}
142
165
}
@@ -210,6 +233,9 @@ fn get_options(ccx: @crate_ctxt, m: match, col: uint) -> [opt] {
210
233
for br: match_branch in m {
211
234
alt br. pats [ col] . node {
212
235
ast:: pat_lit ( l) { add_to_set ( found, lit ( l) ) ; }
236
+ ast:: pat_range ( l1, l2) {
237
+ add_to_set ( found, range ( l1, l2) ) ;
238
+ }
213
239
ast:: pat_tag ( _, _) {
214
240
add_to_set ( found, variant_opt ( ccx, br. pats [ col] . id ) ) ;
215
241
}
@@ -296,7 +322,9 @@ fn pick_col(m: match) -> uint {
296
322
let i = 0 u;
297
323
for p: @ast:: pat in br. pats {
298
324
alt p. node {
299
- ast:: pat_lit ( _) | ast:: pat_tag ( _, _) { scores[ i] += 1 u; }
325
+ ast:: pat_lit ( _) | ast:: pat_tag ( _, _) | ast:: pat_range ( _, _) {
326
+ scores[ i] += 1 u;
327
+ }
300
328
_ { }
301
329
}
302
330
i += 1 u;
@@ -450,6 +478,16 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
450
478
_ { test_val = Load ( bcx, val) ; switch }
451
479
} ;
452
480
}
481
+ range ( _, _) {
482
+ test_val = Load ( bcx, val) ;
483
+ kind = compare;
484
+ }
485
+ }
486
+ }
487
+ for o: opt in opts {
488
+ alt o {
489
+ range( _, _) { kind = compare; break ; }
490
+ _ { }
453
491
}
454
492
}
455
493
let else_cx =
@@ -473,22 +511,44 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
473
511
alt kind {
474
512
single. { Br ( bcx, opt_cx. llbb ) ; }
475
513
switch. {
476
- let r = trans_opt ( bcx, opt) ;
477
- bcx = r. bcx ;
478
- AddCase ( sw, r. val , opt_cx. llbb ) ;
514
+ let res = trans_opt ( bcx, opt) ;
515
+ alt res {
516
+ single_result( r) {
517
+ llvm:: LLVMAddCase ( sw, r. val , opt_cx. llbb ) ;
518
+ bcx = r. bcx ;
519
+ }
520
+ }
479
521
}
480
522
compare. {
481
523
let compare_cx = new_scope_block_ctxt ( bcx, "compare_scope" ) ;
482
524
Br ( bcx, compare_cx. llbb ) ;
483
525
bcx = compare_cx;
484
- let r = trans_opt ( bcx, opt) ;
485
- bcx = r. bcx ;
486
526
let t = ty:: node_id_to_type ( ccx. tcx , pat_id) ;
487
- let eq =
488
- trans:: trans_compare ( bcx, ast:: eq, test_val, t, r. val , t) ;
489
- let cleanup_cx = trans:: trans_block_cleanups ( eq. bcx , compare_cx) ;
490
- bcx = new_sub_block_ctxt ( bcx, "compare_next" ) ;
491
- CondBr ( cleanup_cx, eq. val , opt_cx. llbb , bcx. llbb ) ;
527
+ let res = trans_opt ( bcx, opt) ;
528
+ alt res {
529
+ single_result( r) {
530
+ bcx = r. bcx ;
531
+ let eq =
532
+ trans:: trans_compare ( bcx, ast:: eq, test_val, t, r. val , t) ;
533
+ let cleanup_cx = trans:: trans_block_cleanups (
534
+ eq. bcx , compare_cx) ;
535
+ bcx = new_sub_block_ctxt ( bcx, "compare_next" ) ;
536
+ CondBr ( cleanup_cx, eq. val , opt_cx. llbb , bcx. llbb ) ;
537
+ }
538
+ range_result ( rbegin, rend) {
539
+ bcx = rend. bcx ;
540
+ let ge = trans:: trans_compare ( bcx, ast:: ge, test_val, t,
541
+ rbegin. val , t) ;
542
+ let le = trans:: trans_compare ( ge. bcx , ast:: le, test_val, t,
543
+ rend. val , t) ;
544
+ let in_range = rslt ( le. bcx , And ( le. bcx , ge. val , le. val ) ) ;
545
+ /*let*/ bcx = in_range. bcx ; //XXX uncomment for assertion
546
+ let cleanup_cx =
547
+ trans:: trans_block_cleanups ( bcx, compare_cx) ;
548
+ bcx = new_sub_block_ctxt ( bcx, "compare_next" ) ;
549
+ CondBr ( cleanup_cx, in_range. val , opt_cx. llbb , bcx. llbb ) ;
550
+ }
551
+ }
492
552
}
493
553
_ { }
494
554
}
@@ -501,7 +561,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
501
561
unpacked = args. vals ;
502
562
opt_cx = args. bcx ;
503
563
}
504
- lit ( _) { }
564
+ lit ( _) | range ( _ , _ ) { }
505
565
}
506
566
compile_submatch ( opt_cx, enter_opt ( ccx, m, opt, col, size, val) ,
507
567
unpacked + vals_left, f, exits) ;
@@ -673,12 +733,13 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
673
733
let val = Load ( bcx, val) ;
674
734
bcx = bind_irrefutable_pat ( bcx, inner, val, table, true ) ;
675
735
}
676
- ast:: pat_wild. | ast:: pat_lit ( _) { }
736
+ ast:: pat_wild. | ast:: pat_lit ( _) | ast :: pat_range ( _ , _ ) { }
677
737
}
678
738
ret bcx;
679
739
}
680
740
681
741
// Local Variables:
742
+ // mode: rust
682
743
// fill-column: 78;
683
744
// indent-tabs-mode: nil
684
745
// c-basic-offset: 4
0 commit comments