Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
ce0f054f
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ce0f054f
编写于
9月 21, 2011
作者:
J
Josh Matthews
提交者:
Marijn Haverbeke
9月 21, 2011
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement pattern ranges for all numeric types.
上级
e6a84f25
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
451 addition
and
25 deletion
+451
-25
src/comp/middle/alias.rs
src/comp/middle/alias.rs
+1
-1
src/comp/middle/check_alt.rs
src/comp/middle/check_alt.rs
+17
-1
src/comp/middle/trans_alt.rs
src/comp/middle/trans_alt.rs
+78
-20
src/comp/middle/typeck.rs
src/comp/middle/typeck.rs
+55
-0
src/comp/syntax/ast.rs
src/comp/syntax/ast.rs
+1
-0
src/comp/syntax/ast_util.rs
src/comp/syntax/ast_util.rs
+2
-1
src/comp/syntax/fold.rs
src/comp/syntax/fold.rs
+1
-0
src/comp/syntax/parse/parser.rs
src/comp/syntax/parse/parser.rs
+8
-2
src/comp/syntax/print/pprust.rs
src/comp/syntax/print/pprust.rs
+6
-0
src/comp/util/common.rs
src/comp/util/common.rs
+172
-0
src/lib/int.rs
src/lib/int.rs
+23
-0
src/test/compile-fail/alt-range-fail-dominate.rs
src/test/compile-fail/alt-range-fail-dominate.rs
+38
-0
src/test/compile-fail/alt-range-fail.rs
src/test/compile-fail/alt-range-fail.rs
+19
-0
src/test/run-pass/alt-range.rs
src/test/run-pass/alt-range.rs
+30
-0
未找到文件。
src/comp/middle/alias.rs
浏览文件 @
ce0f054f
...
...
@@ -645,7 +645,7 @@ fn pattern_roots(tcx: ty::ctxt, mut: option::t<unsafe_ty>, pat: @ast::pat)
fn
walk
(
tcx
:
ty
::
ctxt
,
mut
:
option
::
t
<
unsafe_ty
>
,
pat
:
@
ast
::
pat
,
&
set
:
[
pattern_root
])
{
alt
pat
.node
{
ast
::
pat_wild
.
|
ast
::
pat_lit
(
_
)
{}
ast
::
pat_wild
.
|
ast
::
pat_lit
(
_
)
|
ast
::
pat_range
(
_
,
_
)
{}
ast
::
pat_bind
(
nm
)
{
set
+=
[{
id
:
pat
.id
,
name
:
nm
,
mut
:
mut
,
span
:
pat
.span
}];
}
...
...
src/comp/middle/check_alt.rs
浏览文件 @
ce0f054f
...
...
@@ -62,12 +62,15 @@ fn field_patterns_supersede(tcx: ty::ctxt, fas: [field_pat],
ret
true
;
}
alt
a
.node
{
pat_wild
.
|
pat_bind
(
_
)
{
ret
true
;
}
pat_lit
(
la
)
{
alt
b
.node
{
pat_lit
(
lb
)
{
ret
util
::
common
::
lit_eq
(
la
,
lb
);
}
pat_range
(
beginb
,
endb
)
{
ret
util
::
common
::
lit_type_eq
(
la
,
beginb
)
&&
util
::
common
::
lit_in_range
(
la
,
beginb
,
endb
);
}
_
{
ret
false
;
}
}
}
...
...
@@ -98,6 +101,19 @@ fn field_patterns_supersede(tcx: ty::ctxt, fas: [field_pat],
_
{
ret
pattern_supersedes
(
tcx
,
suba
,
b
);
}
}
}
pat_range
(
begina
,
enda
)
{
alt
b
.node
{
pat_lit
(
lb
)
{
ret
util
::
common
::
lit_type_eq
(
lb
,
begina
)
&&
util
::
common
::
lit_in_range
(
lb
,
begina
,
enda
);
}
pat_range
(
beginb
,
endb
)
{
ret
util
::
common
::
lit_type_eq
(
begina
,
beginb
)
&&
util
::
common
::
lit_ranges_overlap
(
begina
,
enda
,
beginb
,
endb
);
}
_
{
ret
false
;
}
}
}
}
}
...
...
src/comp/middle/trans_alt.rs
浏览文件 @
ce0f054f
import
std
::{
str
,
vec
,
option
};
import
std
::{
str
,
vec
,
option
,
int
};
import
option
::{
some
,
none
};
import
std
::
map
::
hashmap
;
...
...
@@ -16,25 +16,42 @@
import
trans_common
::
*
;
// An option identifying a branch (either a literal
or a tag variant
)
// An option identifying a branch (either a literal
, a tag variant or a range
)
tag
opt
{
lit
(
@
ast
::
lit
);
var
(
/* variant id */
uint
,
/* variant dids */
{
tg
:
def_id
,
var
:
def_id
});
range
(
@
ast
::
lit
,
@
ast
::
lit
);
}
fn
opt_eq
(
a
:
opt
,
b
:
opt
)
->
bool
{
alt
a
{
lit
(
la
)
{
ret
alt
b
{
lit
(
lb
)
{
lit_eq
(
la
,
lb
)
}
var
(
_
,
_
)
{
false
}
};
ret
alt
b
{
lit
(
lb
)
{
lit_eq
(
la
,
lb
)
}
_
{
false
}
};
}
var
(
ida
,
_
)
{
ret
alt
b
{
lit
(
_
)
{
false
}
var
(
idb
,
_
)
{
ida
==
idb
}
};
ret
alt
b
{
var
(
idb
,
_
)
{
ida
==
idb
}
_
{
false
}
};
}
range
(
la1
,
la2
)
{
ret
alt
b
{
range
(
lb1
,
lb2
)
{
lit_eq
(
la1
,
lb1
)
&&
lit_eq
(
la2
,
lb2
)
}
_
{
false
}
};
}
}
}
fn
trans_opt
(
bcx
:
@
block_ctxt
,
o
:
opt
)
->
result
{
tag
opt_result
{
single_result
(
result
);
range_result
(
result
,
result
);
}
fn
trans_opt
(
bcx
:
@
block_ctxt
,
o
:
opt
)
->
opt_result
{
alt
o
{
lit
(
l
)
{
ret
trans
::
trans_lit
(
bcx
,
*
l
);
}
var
(
id
,
_
)
{
ret
rslt
(
bcx
,
C_int
(
id
as
int
));
}
lit
(
l
)
{
ret
single_result
(
trans
::
trans_lit
(
bcx
,
*
l
));
}
var
(
id
,
_
)
{
ret
single_result
(
rslt
(
bcx
,
C_int
(
id
as
int
)));
}
range
(
l1
,
l2
)
{
let
r1
=
trans
::
trans_lit
(
bcx
,
*
l1
);
let
r2
=
trans
::
trans_lit
(
r1
.bcx
,
*
l2
);
ret
range_result
(
r1
,
r2
);
}
}
}
...
...
@@ -124,6 +141,9 @@ fn e(ccx: @crate_ctxt, dummy: @ast::pat, opt: opt, size: uint,
ast
::
pat_lit
(
l
)
{
ret
if
opt_eq
(
lit
(
l
),
opt
)
{
some
([])
}
else
{
none
};
}
ast
::
pat_range
(
l1
,
l2
)
{
ret
if
opt_eq
(
range
(
l1
,
l2
),
opt
)
{
some
([])
}
else
{
none
};
}
_
{
ret
some
(
vec
::
init_elt
(
dummy
,
size
));
}
}
}
...
...
@@ -186,6 +206,9 @@ fn add_to_set(&set: [opt], val: opt) {
for
br
:
match_branch
in
m
{
alt
br
.pats
[
col
]
.node
{
ast
::
pat_lit
(
l
)
{
add_to_set
(
found
,
lit
(
l
));
}
ast
::
pat_range
(
l1
,
l2
)
{
add_to_set
(
found
,
range
(
l1
,
l2
));
}
ast
::
pat_tag
(
_
,
_
)
{
add_to_set
(
found
,
variant_opt
(
ccx
,
br
.pats
[
col
]
.id
));
}
...
...
@@ -265,7 +288,9 @@ fn pick_col(m: match) -> uint {
let
i
=
0u
;
for
p
:
@
ast
::
pat
in
br
.pats
{
alt
p
.node
{
ast
::
pat_lit
(
_
)
|
ast
::
pat_tag
(
_
,
_
)
{
scores
[
i
]
+=
1u
;
}
ast
::
pat_lit
(
_
)
|
ast
::
pat_tag
(
_
,
_
)
|
ast
::
pat_range
(
_
,
_
)
{
scores
[
i
]
+=
1u
;
}
_
{
}
}
i
+=
1u
;
...
...
@@ -410,6 +435,16 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
_
{
test_val
=
Load
(
bcx
,
val
);
switch
}
};
}
range
(
_
,
_
)
{
test_val
=
Load
(
bcx
,
val
);
kind
=
compare
;
}
}
}
for
o
:
opt
in
opts
{
alt
o
{
range
(
_
,
_
)
{
kind
=
compare
;
break
;
}
_
{
}
}
}
let
else_cx
=
...
...
@@ -428,22 +463,44 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
alt
kind
{
single
.
{
Br
(
bcx
,
opt_cx
.llbb
);
}
switch
.
{
let
r
=
trans_opt
(
bcx
,
opt
);
bcx
=
r
.bcx
;
llvm
::
LLVMAddCase
(
sw
,
r
.val
,
opt_cx
.llbb
);
let
res
=
trans_opt
(
bcx
,
opt
);
alt
res
{
single_result
(
r
)
{
llvm
::
LLVMAddCase
(
sw
,
r
.val
,
opt_cx
.llbb
);
bcx
=
r
.bcx
;
}
}
}
compare
.
{
let
compare_cx
=
new_scope_block_ctxt
(
bcx
,
"compare_scope"
);
Br
(
bcx
,
compare_cx
.llbb
);
bcx
=
compare_cx
;
let
r
=
trans_opt
(
bcx
,
opt
);
bcx
=
r
.bcx
;
let
t
=
ty
::
node_id_to_type
(
ccx
.tcx
,
pat_id
);
let
eq
=
trans
::
trans_compare
(
bcx
,
ast
::
eq
,
test_val
,
t
,
r
.val
,
t
);
let
cleanup_cx
=
trans
::
trans_block_cleanups
(
bcx
,
compare_cx
);
bcx
=
new_sub_block_ctxt
(
bcx
,
"compare_next"
);
CondBr
(
cleanup_cx
,
eq
.val
,
opt_cx
.llbb
,
bcx
.llbb
);
let
res
=
trans_opt
(
bcx
,
opt
);
alt
res
{
single_result
(
r
)
{
bcx
=
r
.bcx
;
let
eq
=
trans
::
trans_compare
(
bcx
,
ast
::
eq
,
test_val
,
t
,
r
.val
,
t
);
/*let*/
bcx
=
eq
.bcx
;
//XXX uncomment for assertion
let
cleanup_cx
=
trans
::
trans_block_cleanups
(
bcx
,
compare_cx
);
bcx
=
new_sub_block_ctxt
(
bcx
,
"compare_next"
);
CondBr
(
cleanup_cx
,
eq
.val
,
opt_cx
.llbb
,
bcx
.llbb
);
}
range_result
(
rbegin
,
rend
)
{
bcx
=
rend
.bcx
;
let
ge
=
trans
::
trans_compare
(
bcx
,
ast
::
ge
,
test_val
,
t
,
rbegin
.val
,
t
);
let
le
=
trans
::
trans_compare
(
ge
.bcx
,
ast
::
le
,
test_val
,
t
,
rend
.val
,
t
);
let
in_range
=
rslt
(
le
.bcx
,
And
(
le
.bcx
,
ge
.val
,
le
.val
));
/*let*/
bcx
=
in_range
.bcx
;
//XXX uncomment for assertion
let
cleanup_cx
=
trans
::
trans_block_cleanups
(
bcx
,
compare_cx
);
bcx
=
new_sub_block_ctxt
(
bcx
,
"compare_next"
);
CondBr
(
cleanup_cx
,
in_range
.val
,
opt_cx
.llbb
,
bcx
.llbb
);
}
}
}
_
{
}
}
...
...
@@ -456,7 +513,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
unpacked
=
args
.vals
;
opt_cx
=
args
.bcx
;
}
lit
(
_
)
{
}
lit
(
_
)
|
range
(
_
,
_
)
{
}
}
compile_submatch
(
opt_cx
,
enter_opt
(
ccx
,
m
,
opt
,
col
,
size
,
val
),
unpacked
+
vals_left
,
f
,
exits
);
...
...
@@ -631,12 +688,13 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
[
C_int
(
0
),
C_int
(
back
::
abi
::
box_rc_field_body
)]);
bcx
=
bind_irrefutable_pat
(
bcx
,
inner
,
unboxed
,
table
,
true
);
}
ast
::
pat_wild
.
|
ast
::
pat_lit
(
_
)
{
}
ast
::
pat_wild
.
|
ast
::
pat_lit
(
_
)
|
ast
::
pat_range
(
_
,
_
)
{
}
}
ret
bcx
;
}
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
...
...
src/comp/middle/typeck.rs
浏览文件 @
ce0f054f
...
...
@@ -1266,6 +1266,44 @@ fn check_lit(ccx: @crate_ctxt, lit: @ast::lit) -> ty::t {
}
}
fn
lit_as_uint
(
l
:
@
ast
::
lit
)
->
uint
{
alt
l
.node
{
ast
::
lit_uint
(
u
)
{
u
}
ast
::
lit_char
(
c
)
{
c
as
uint
}
}
}
fn
lit_as_int
(
l
:
@
ast
::
lit
)
->
int
{
alt
l
.node
{
ast
::
lit_int
(
i
)
|
ast
::
lit_mach_int
(
_
,
i
)
{
i
}
}
}
fn
lit_as_float
(
l
:
@
ast
::
lit
)
->
str
{
alt
l
.node
{
ast
::
lit_float
(
f
)
|
ast
::
lit_mach_float
(
_
,
f
)
{
f
}
}
}
fn
valid_range_bounds
(
l1
:
@
ast
::
lit
,
l2
:
@
ast
::
lit
)
->
bool
{
alt
l1
.node
{
ast
::
lit_float
(
s1
)
|
ast
::
lit_mach_float
(
_
,
s1
)
{
let
s2
=
lit_as_float
(
l2
);
let
f1
=
util
::
common
::
str_to_float
(
s1
);
let
f2
=
util
::
common
::
str_to_float
(
s2
);
ret
*
util
::
common
::
min
(
f1
,
f2
)
==
f1
}
ast
::
lit_uint
(
_
)
|
ast
::
lit_char
(
_
)
{
let
u1
=
lit_as_uint
(
l1
);
let
u2
=
lit_as_uint
(
l2
);
ret
*
util
::
common
::
min
(
u1
,
u2
)
==
u1
}
_
{
let
i1
=
lit_as_int
(
l1
);
let
i2
=
lit_as_int
(
l2
);
ret
*
util
::
common
::
min
(
i1
,
i2
)
==
i1
}
}
}
// Pattern checking is top-down rather than bottom-up so that bindings get
// their types immediately.
fn
check_pat
(
fcx
:
@
fn_ctxt
,
map
:
ast_util
::
pat_id_map
,
pat
:
@
ast
::
pat
,
...
...
@@ -1277,6 +1315,23 @@ fn check_pat(fcx: @fn_ctxt, map: ast_util::pat_id_map, pat: @ast::pat,
typ
=
demand
::
simple
(
fcx
,
pat
.span
,
expected
,
typ
);
write
::
ty_only_fixup
(
fcx
,
pat
.id
,
typ
);
}
ast
::
pat_range
(
begin
,
end
)
{
if
!
util
::
common
::
lit_is_numeric
(
begin
)
||
!
util
::
common
::
lit_is_numeric
(
end
)
{
fcx
.ccx.tcx.sess
.span_err
(
pat
.span
,
"non-numeric type used in range"
);
}
else
if
!
valid_range_bounds
(
begin
,
end
)
{
fcx
.ccx.tcx.sess
.span_err
(
begin
.span
,
"lower range bound must be less
\
than upper"
);
}
let
typ1
=
check_lit
(
fcx
.ccx
,
begin
);
typ1
=
demand
::
simple
(
fcx
,
pat
.span
,
expected
,
typ1
);
write
::
ty_only_fixup
(
fcx
,
pat
.id
,
typ1
);
let
typ2
=
check_lit
(
fcx
.ccx
,
end
);
typ2
=
demand
::
simple
(
fcx
,
pat
.span
,
typ1
,
typ2
);
write
::
ty_only_fixup
(
fcx
,
pat
.id
,
typ2
);
}
ast
::
pat_bind
(
name
)
{
let
vid
=
lookup_local
(
fcx
,
pat
.span
,
pat
.id
);
let
typ
=
ty
::
mk_var
(
fcx
.ccx.tcx
,
vid
);
...
...
src/comp/syntax/ast.rs
浏览文件 @
ce0f054f
...
...
@@ -92,6 +92,7 @@
pat_rec
([
field_pat
],
bool
);
pat_tup
([
@
pat
]);
pat_box
(
@
pat
);
pat_range
(
@
lit
,
@
lit
);
}
tag
mutability
{
mut
;
imm
;
maybe_mut
;
}
...
...
src/comp/syntax/ast_util.rs
浏览文件 @
ce0f054f
...
...
@@ -69,7 +69,7 @@ fn pat_id_map(pat: @pat) -> pat_id_map {
for
elt
in
elts
{
for
each
b
in
pat_bindings
(
elt
)
{
put
b
;
}
}
}
pat_box
(
sub
)
{
for
each
b
in
pat_bindings
(
sub
)
{
put
b
;
}
}
pat_wild
.
|
pat_lit
(
_
)
{
}
pat_wild
.
|
pat_lit
(
_
)
|
pat_range
(
_
,
_
)
{
}
}
}
...
...
@@ -229,3 +229,4 @@ fn ret_by_ref(style: ret_style) -> bool {
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
src/comp/syntax/fold.rs
浏览文件 @
ce0f054f
...
...
@@ -291,6 +291,7 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ {
}
pat_tup
(
elts
)
{
pat_tup
(
vec
::
map
(
fld
.fold_pat
,
elts
))
}
pat_box
(
inner
)
{
pat_box
(
fld
.fold_pat
(
inner
))
}
pat_range
(
_
,
_
)
{
p
}
};
}
...
...
src/comp/syntax/parse/parser.rs
浏览文件 @
ce0f054f
...
...
@@ -1494,8 +1494,14 @@ fn parse_pat(p: parser) -> @ast::pat {
tok
{
if
!
is_ident
(
tok
)
||
is_word
(
p
,
"true"
)
||
is_word
(
p
,
"false"
)
{
let
lit
=
parse_lit
(
p
);
hi
=
lit
.span.hi
;
pat
=
ast
::
pat_lit
(
@
lit
);
if
eat_word
(
p
,
"to"
)
{
let
end
=
parse_lit
(
p
);
hi
=
end
.span.hi
;
pat
=
ast
::
pat_range
(
@
lit
,
@
end
);
}
else
{
hi
=
lit
.span.hi
;
pat
=
ast
::
pat_lit
(
@
lit
);
}
}
else
if
is_plain_ident
(
p
)
&&
alt
p
.look_ahead
(
1u
)
{
token
::
DOT
.
|
token
::
LPAREN
.
|
token
::
LBRACKET
.
{
...
...
src/comp/syntax/print/pprust.rs
浏览文件 @
ce0f054f
...
...
@@ -1113,6 +1113,12 @@ fn print_field(s: ps, f: ast::field_pat) {
pclose
(
s
);
}
ast
::
pat_box
(
inner
)
{
word
(
s
.s
,
"@"
);
print_pat
(
s
,
inner
);
}
ast
::
pat_range
(
begin
,
end
)
{
print_literal
(
s
,
begin
);
space
(
s
.s
);
word_space
(
s
,
"to"
);
print_literal
(
s
,
end
);
}
}
s
.ann
.post
(
ann_node
);
}
...
...
src/comp/util/common.rs
浏览文件 @
ce0f054f
...
...
@@ -84,6 +84,162 @@ fn local_rhs_span(l: @ast::local, def: span) -> span {
alt
l
.node.init
{
some
(
i
)
{
ret
i
.expr.span
;
}
_
{
ret
def
;
}
}
}
fn
lit_is_numeric
(
l
:
@
ast
::
lit
)
->
bool
{
alt
l
.node
{
ast
::
lit_int
(
_
)
|
ast
::
lit_char
(
_
)
|
ast
::
lit_uint
(
_
)
|
ast
::
lit_mach_int
(
_
,
_
)
|
ast
::
lit_float
(
_
)
|
ast
::
lit_mach_float
(
_
,
_
)
{
true
}
_
{
false
}
}
}
fn
lit_type_eq
(
l
:
@
ast
::
lit
,
m
:
@
ast
::
lit
)
->
bool
{
alt
l
.node
{
ast
::
lit_str
(
_
)
{
alt
m
.node
{
ast
::
lit_str
(
_
)
{
true
}
_
{
false
}
}
}
ast
::
lit_char
(
_
)
{
alt
m
.node
{
ast
::
lit_char
(
_
)
{
true
}
_
{
false
}
}
}
ast
::
lit_int
(
_
)
{
alt
m
.node
{
ast
::
lit_int
(
_
)
{
true
}
_
{
false
}
}
}
ast
::
lit_uint
(
_
)
{
alt
m
.node
{
ast
::
lit_uint
(
_
)
{
true
}
_
{
false
}
}
}
ast
::
lit_mach_int
(
_
,
_
)
{
alt
m
.node
{
ast
::
lit_mach_int
(
_
,
_
)
{
true
}
_
{
false
}
}
}
ast
::
lit_float
(
_
)
{
alt
m
.node
{
ast
::
lit_float
(
_
)
{
true
}
_
{
false
}
}
}
ast
::
lit_mach_float
(
_
,
_
)
{
alt
m
.node
{
ast
::
lit_mach_float
(
_
,
_
)
{
true
}
_
{
false
}
}
}
ast
::
lit_nil
.
{
alt
m
.node
{
ast
::
lit_nil
.
{
true
}
_
{
false
}
}
}
ast
::
lit_bool
(
_
)
{
alt
m
.node
{
ast
::
lit_bool
(
_
)
{
true
}
_
{
false
}
}
}
}
}
fn
lit_in_range
(
l
:
@
ast
::
lit
,
m1
:
@
ast
::
lit
,
m2
:
@
ast
::
lit
)
->
bool
{
alt
lits_to_range
(
m1
,
m2
)
{
irange
(
i1
,
i2
)
{
alt
l
.node
{
ast
::
lit_int
(
i3
)
|
ast
::
lit_mach_int
(
_
,
i3
)
{
i3
>=
*
min
(
i1
,
i2
)
&&
i3
<=
*
max
(
i1
,
i2
)
}
_
{
fail
}
}
}
urange
(
u1
,
u2
)
{
alt
l
.node
{
ast
::
lit_uint
(
u3
)
{
u3
>=
*
min
(
u1
,
u2
)
&&
u3
<=
*
max
(
u1
,
u2
)
}
_
{
fail
}
}
}
crange
(
c1
,
c2
)
{
alt
l
.node
{
ast
::
lit_char
(
c3
)
{
(
c3
as
uint
)
>=
*
min
(
c1
as
uint
,
c2
as
uint
)
&&
(
c3
as
uint
)
<=
*
max
(
c1
as
uint
,
c2
as
uint
)
}
_
{
fail
}
}
}
frange
(
f1
,
f2
)
{
alt
l
.node
{
ast
::
lit_float
(
f3
)
|
ast
::
lit_mach_float
(
_
,
f3
)
{
str_to_float
(
f3
)
>=
*
min
(
f1
,
f2
)
&&
str_to_float
(
f3
)
<=
*
max
(
f1
,
f2
)
}
_
{
fail
}
}
}
}
}
fn
min
<
T
>
(
x
:
T
,
y
:
T
)
->
@
T
{
ret
@
(
if
x
>
y
{
y
}
else
{
x
});
}
fn
max
<
T
>
(
x
:
T
,
y
:
T
)
->
@
T
{
ret
@
(
if
x
>
y
{
x
}
else
{
y
});
}
fn
ranges_overlap
<
T
>
(
a1
:
T
,
a2
:
T
,
b1
:
T
,
b2
:
T
)
->
bool
{
let
min1
=
*
min
(
a1
,
a2
);
let
max1
=
*
max
(
a1
,
a2
);
let
min2
=
*
min
(
b1
,
b2
);
let
max2
=
*
max
(
b1
,
b2
);
ret
(
min1
>=
min2
&&
max1
<=
max2
)
||
(
min1
<=
min2
&&
max1
>=
min2
)
||
(
min1
>=
min2
&&
min1
<=
max2
)
||
(
max1
>=
min2
&&
max1
<=
max2
);
}
fn
lit_ranges_overlap
(
a1
:
@
ast
::
lit
,
a2
:
@
ast
::
lit
,
b1
:
@
ast
::
lit
,
b2
:
@
ast
::
lit
)
->
bool
{
alt
lits_to_range
(
a1
,
a2
)
{
irange
(
i1
,
i2
)
{
alt
lits_to_range
(
b1
,
b2
)
{
irange
(
i3
,
i4
)
{
ranges_overlap
(
i1
,
i2
,
i3
,
i4
)
}
_
{
fail
}
}
}
urange
(
u1
,
u2
)
{
alt
lits_to_range
(
b1
,
b2
)
{
urange
(
u3
,
u4
)
{
ranges_overlap
(
u1
,
u2
,
u3
,
u4
)
}
_
{
fail
}
}
}
crange
(
c1
,
c2
)
{
alt
lits_to_range
(
b1
,
b2
)
{
crange
(
c3
,
c4
)
{
ranges_overlap
(
c1
,
c2
,
c3
,
c4
)
}
_
{
fail
}
}
}
frange
(
f1
,
f2
)
{
alt
lits_to_range
(
b1
,
b2
)
{
frange
(
f3
,
f4
)
{
ranges_overlap
(
f1
,
f2
,
f3
,
f4
)
}
_
{
fail
}
}
}
}
}
tag
range
{
irange
(
int
,
int
);
urange
(
uint
,
uint
);
crange
(
char
,
char
);
frange
(
float
,
float
);
}
fn
lits_to_range
(
l
:
@
ast
::
lit
,
r
:
@
ast
::
lit
)
->
range
{
alt
l
.node
{
ast
::
lit_int
(
i1
)
|
ast
::
lit_mach_int
(
_
,
i1
)
{
alt
r
.node
{
ast
::
lit_int
(
i2
)
{
irange
(
i1
,
i2
)
}
_
{
fail
}
}
}
ast
::
lit_uint
(
u1
)
{
alt
r
.node
{
ast
::
lit_uint
(
u2
)
{
urange
(
u1
,
u2
)
}
_
{
fail
}
}
}
ast
::
lit_char
(
c1
)
{
alt
r
.node
{
ast
::
lit_char
(
c2
)
{
crange
(
c1
,
c2
)
}
_
{
fail
}
}
}
ast
::
lit_float
(
f1
)
|
ast
::
lit_mach_float
(
_
,
f1
)
{
alt
r
.node
{
ast
::
lit_float
(
f2
)
|
ast
::
lit_mach_float
(
_
,
f2
)
{
frange
(
str_to_float
(
f1
),
str_to_float
(
f2
))
}
_
{
fail
}
}
}
_
{
fail
}
}
}
fn
lit_eq
(
l
:
@
ast
::
lit
,
m
:
@
ast
::
lit
)
->
bool
{
alt
l
.node
{
ast
::
lit_str
(
s
)
{
...
...
@@ -156,6 +312,22 @@ fn float_to_str(num: float, digits: uint) -> str {
ret
accum
;
}
fn
str_to_float
(
num
:
str
)
->
float
{
let
digits
=
str
::
split
(
num
,
'.'
as
u8
);
let
total
=
int
::
from_str
(
digits
[
0
])
as
float
;
fn
dec_val
(
c
:
char
)
->
int
{
ret
(
c
as
int
)
-
(
'0'
as
int
);
}
let
right
=
digits
[
1
];
let
len
=
str
::
char_len
(
digits
[
1
]);
let
i
=
1u
;
while
(
i
<
len
)
{
total
+=
dec_val
(
str
::
pop_char
(
right
))
as
float
/
(
int
::
pow
(
10
,
i
)
as
float
);
i
+=
1u
;
}
ret
total
;
}
//
// Local Variables:
...
...
src/lib/int.rs
浏览文件 @
ce0f054f
...
...
@@ -41,6 +41,29 @@
while
lo_
<
hi
{
put
lo_
;
lo_
+=
1
;
}
}
fn
parse_buf
(
buf
:
[
u8
],
radix
:
uint
)
->
int
{
if
vec
::
len
::
<
u8
>
(
buf
)
==
0u
{
log_err
"parse_buf(): buf is empty"
;
fail
;
}
let
i
=
vec
::
len
::
<
u8
>
(
buf
)
-
1u
;
let
power
=
1
;
if
buf
[
0
]
==
(
'-'
as
u8
)
{
power
=
-
1
;
i
-=
1u
;
}
let
n
=
0
;
while
true
{
n
+=
(
buf
[
i
]
-
(
'0'
as
u8
)
as
int
)
*
power
;
power
*=
radix
as
int
;
if
i
==
0u
{
ret
n
;
}
i
-=
1u
;
}
fail
;
}
fn
from_str
(
s
:
str
)
->
int
{
parse_buf
(
str
::
bytes
(
s
),
10u
)
}
fn
to_str
(
n
:
int
,
radix
:
uint
)
->
str
{
assert
(
0u
<
radix
&&
radix
<=
16u
);
ret
if
n
<
0
{
...
...
src/test/compile-fail/alt-range-fail-dominate.rs
0 → 100644
浏览文件 @
ce0f054f
//error-pattern: unreachable
//error-pattern: unreachable
//error-pattern: unreachable
//error-pattern: unreachable
//error-pattern: unreachable
//error-pattern: unreachable
fn
main
()
{
alt
5u
{
1u
to
10u
{
}
5u
to
6u
{
}
};
alt
5u
{
4u
to
6u
{
}
3u
to
5u
{
}
};
alt
5u
{
4u
to
6u
{
}
5u
to
7u
{
}
};
alt
'c'
{
'A'
to
'z'
{}
'a'
to
'z'
{}
};
alt
1.0
{
-
5.0
to
5.0
{}
0.0
to
6.5
{}
};
alt
1.0
{
0.02
{}
0.01
to
6.5
{}
};
}
\ No newline at end of file
src/test/compile-fail/alt-range-fail.rs
0 → 100644
浏览文件 @
ce0f054f
//error-pattern: lower range bound
//error-pattern: non-numeric
//error-pattern: mismatched types
fn
main
()
{
alt
5u
{
6u
to
1u
{
}
_
{
}
};
alt
"wow"
{
"wow"
to
"woow"
{
}
};
alt
5u
{
'c'
to
100u
{
}
_
{
}
};
}
\ No newline at end of file
src/test/run-pass/alt-range.rs
0 → 100644
浏览文件 @
ce0f054f
fn
main
()
{
alt
5u
{
1u
to
5u
{}
_
{
fail
"should match range"
;
}
}
alt
5u
{
6u
to
7u
{
fail
"shouldn't match range"
;
}
_
{}
}
alt
5u
{
1u
{
fail
"should match non-first range"
;
}
2u
to
6u
{}
}
alt
'c'
{
'a'
to
'z'
{}
_
{
fail
"should suppport char ranges"
;
}
}
alt
-
3
{
-
7
to
5
{}
_
{
fail
"should match signed range"
;
}
}
alt
3.0
{
1.0
to
5.0
{}
_
{
fail
"should match float range"
;
}
}
alt
-
1.5
{
-
3.6
to
3.6
{}
_
{
fail
"should match negative float range"
;
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录