Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
e17806e1
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,发现更多精彩内容 >>
提交
e17806e1
编写于
12月 15, 2010
作者:
P
Patrick Walton
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc: Translate pattern matching
上级
cd55b7ed
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
155 addition
and
1 deletion
+155
-1
src/comp/middle/trans.rs
src/comp/middle/trans.rs
+155
-1
未找到文件。
src/comp/middle/trans.rs
浏览文件 @
e17806e1
...
...
@@ -15,6 +15,8 @@
import
back
.x86
;
import
back
.abi
;
import
middle
.typeck.pat_ty
;
import
util
.common
;
import
util
.common.istr
;
import
util
.common.new_def_hash
;
...
...
@@ -950,6 +952,7 @@ fn build_memcpy(@block_ctxt cx,
// lib.llvm.llvm.LLVMAlignOf(llty);
// but this makes it upset because it's not a constant.
log
"building memcpy"
;
auto
volatile
=
C_integral
(
0
,
T_i1
());
ret
res
(
cx
,
cx
.build
.Call
(
memcpy
,
vec
(
dst_ptr
,
src_ptr
,
...
...
@@ -1320,6 +1323,150 @@ fn join_results(@block_ctxt parent_cx,
ret
res
(
next_cx
,
body_res
.val
);
}
// Pattern matching translation
// Returns a pointer to the union part of the LLVM representation of a tag
// type, cast to the appropriate type.
fn
get_pat_union_ptr
(
@
block_ctxt
cx
,
vec
[
@
ast
.pat
]
subpats
,
ValueRef
llval
)
->
ValueRef
{
auto
llblobptr
=
cx
.build
.GEP
(
llval
,
vec
(
C_int
(
0
),
C_int
(
1
)));
// Generate the union type.
let
vec
[
TypeRef
]
llsubpattys
=
vec
();
for
(
@
ast
.pat
subpat
in
subpats
)
{
llsubpattys
+=
vec
(
type_of
(
cx
.fcx.ccx
,
pat_ty
(
subpat
)));
}
// Recursively check subpatterns.
auto
llunionty
=
T_struct
(
llsubpattys
);
ret
cx
.build
.TruncOrBitCast
(
llblobptr
,
T_ptr
(
llunionty
));
}
impure
fn
trans_pat_match
(
@
block_ctxt
cx
,
@
ast
.pat
pat
,
ValueRef
llval
,
@
block_ctxt
next_cx
)
->
result
{
alt
(
pat
.node
)
{
case
(
ast
.pat_wild
(
_
))
{
ret
res
(
cx
,
llval
);
}
case
(
ast
.pat_bind
(
_
,
_
,
_
))
{
ret
res
(
cx
,
llval
);
}
case
(
ast
.pat_tag
(
?
id
,
?
subpats
,
?
vdef_opt
,
?
ann
))
{
auto
lltagptr
=
cx
.build
.GEP
(
llval
,
vec
(
C_int
(
0
),
C_int
(
0
)));
auto
lltag
=
cx
.build
.Load
(
lltagptr
);
auto
vdef
=
option
.get
[
ast
.variant_def
](
vdef_opt
);
auto
variant_id
=
vdef
._1
;
auto
tinfo
=
cx
.fcx.ccx.tags
.get
(
vdef
._0
);
auto
variant_tag
=
0
;
auto
i
=
0
;
for
(
tup
(
ast
.def_id
,
arity
)
vinfo
in
tinfo
.variants
)
{
auto
this_variant_id
=
vinfo
._0
;
if
(
variant_id
._0
==
this_variant_id
._0
&&
variant_id
._1
==
this_variant_id
._1
)
{
variant_tag
=
i
;
}
i
+=
1
;
}
auto
matched_cx
=
new_sub_block_ctxt
(
cx
,
"matched_cx"
);
auto
lleq
=
cx
.build
.ICmp
(
lib
.llvm.LLVMIntEQ
,
lltag
,
C_int
(
variant_tag
));
cx
.build
.CondBr
(
lleq
,
matched_cx
.llbb
,
next_cx
.llbb
);
if
(
_
vec
.len
[
@
ast
.pat
](
subpats
)
>
0u
)
{
auto
llunionptr
=
get_pat_union_ptr
(
matched_cx
,
subpats
,
llval
);
auto
i
=
0
;
for
(
@
ast
.pat
subpat
in
subpats
)
{
auto
llsubvalptr
=
matched_cx
.build
.GEP
(
llunionptr
,
vec
(
C_int
(
0
),
C_int
(
i
)));
auto
llsubval
=
load_non_structural
(
matched_cx
,
llsubvalptr
,
pat_ty
(
subpat
));
auto
subpat_res
=
trans_pat_match
(
matched_cx
,
subpat
,
llsubval
,
next_cx
);
matched_cx
=
subpat_res
.bcx
;
}
}
ret
res
(
matched_cx
,
llval
);
}
}
fail
;
}
impure
fn
trans_pat_binding
(
@
block_ctxt
cx
,
@
ast
.pat
pat
,
ValueRef
llval
)
->
result
{
alt
(
pat
.node
)
{
case
(
ast
.pat_wild
(
_
))
{
ret
res
(
cx
,
llval
);
}
case
(
ast
.pat_bind
(
?
id
,
?
def_id
,
?
ann
))
{
auto
ty
=
node_ann_type
(
cx
.fcx.ccx
,
ann
);
auto
llty
=
type_of
(
cx
.fcx.ccx
,
ty
);
auto
dst
=
cx
.build
.Alloca
(
llty
);
llvm
.LLVMSetValueName
(
dst
,
_
str
.buf
(
id
));
cx
.fcx.lllocals
.insert
(
def_id
,
dst
);
cx
.cleanups
+=
clean
(
bind
drop_slot
(
_
,
dst
,
ty
));
ret
copy_ty
(
cx
,
true
,
dst
,
llval
,
ty
);
}
case
(
ast
.pat_tag
(
_
,
?
subpats
,
_
,
_
))
{
if
(
_
vec
.len
[
@
ast
.pat
](
subpats
)
==
0u
)
{
ret
res
(
cx
,
llval
);
}
auto
llunionptr
=
get_pat_union_ptr
(
cx
,
subpats
,
llval
);
auto
this_cx
=
cx
;
auto
i
=
0
;
for
(
@
ast
.pat
subpat
in
subpats
)
{
auto
llsubvalptr
=
this_cx
.build
.GEP
(
llunionptr
,
vec
(
C_int
(
0
),
C_int
(
i
)));
auto
llsubval
=
load_non_structural
(
this_cx
,
llsubvalptr
,
pat_ty
(
subpat
));
auto
subpat_res
=
trans_pat_binding
(
this_cx
,
subpat
,
llsubval
);
this_cx
=
subpat_res
.bcx
;
}
ret
res
(
this_cx
,
llval
);
}
}
}
impure
fn
trans_alt
(
@
block_ctxt
cx
,
@
ast
.expr
expr
,
vec
[
ast
.arm
]
arms
)
->
result
{
auto
expr_res
=
trans_expr
(
cx
,
expr
);
auto
last_cx
=
new_sub_block_ctxt
(
expr_res
.bcx
,
"last"
);
auto
this_cx
=
expr_res
.bcx
;
for
(
ast
.arm
arm
in
arms
)
{
auto
next_cx
=
new_sub_block_ctxt
(
expr_res
.bcx
,
"next"
);
auto
match_res
=
trans_pat_match
(
this_cx
,
arm
.pat
,
expr_res
.val
,
next_cx
);
auto
binding_cx
=
new_scope_block_ctxt
(
match_res
.bcx
,
"binding"
);
match_res
.bcx.build
.Br
(
binding_cx
.llbb
);
auto
binding_res
=
trans_pat_binding
(
binding_cx
,
arm
.pat
,
expr_res
.val
);
auto
block_res
=
trans_block
(
binding_res
.bcx
,
arm
.block
);
if
(
!
is_terminated
(
block_res
.bcx
))
{
block_res
.bcx.build
.Br
(
last_cx
.llbb
);
}
this_cx
=
next_cx
;
}
// FIXME: This is executed when none of the patterns match; it should fail
// instead!
this_cx
.build
.Br
(
last_cx
.llbb
);
// FIXME: This is very wrong; we should phi together all the arm blocks,
// since this is an expression.
ret
res
(
last_cx
,
C_nil
());
}
// The additional bool returned indicates whether it's mem (that is
// represented as an alloca or heap, hence needs a 'load' to be used as an
// immediate).
...
...
@@ -1339,6 +1486,10 @@ fn trans_name(@block_ctxt cx, &ast.name n, &option.t[ast.def] dopt)
ret
tup
(
res
(
cx
,
cx
.fcx.lllocals
.get
(
did
)),
true
);
}
case
(
ast
.def_binding
(
?
did
))
{
check
(
cx
.fcx.lllocals
.contains_key
(
did
));
ret
tup
(
res
(
cx
,
cx
.fcx.lllocals
.get
(
did
)),
true
);
}
case
(
ast
.def_fn
(
?
did
))
{
check
(
cx
.fcx.ccx.item_ids
.contains_key
(
did
));
ret
tup
(
res
(
cx
,
cx
.fcx.ccx.item_ids
.get
(
did
)),
...
...
@@ -1666,6 +1817,10 @@ fn trans_lval(@block_ctxt cx, @ast.expr e) -> tup(result, bool) {
ret
trans_do_while
(
cx
,
body
,
cond
);
}
case
(
ast
.expr_alt
(
?
expr
,
?
arms
,
_
))
{
ret
trans_alt
(
cx
,
expr
,
arms
);
}
case
(
ast
.expr_block
(
?
blk
,
_
))
{
auto
sub_cx
=
new_scope_block_ctxt
(
cx
,
"block-expr body"
);
auto
next_cx
=
new_sub_block_ctxt
(
cx
,
"next"
);
...
...
@@ -2461,7 +2616,6 @@ fn trans_main_fn(@crate_ctxt cx, ValueRef llcrate) {
auto
start_args
=
vec
(
p2i
(
llrust_main
),
p2i
(
llcrate
),
llargc
,
llargv
);
b
.Ret
(
b
.Call
(
llrust_start
,
start_args
));
}
fn
declare_intrinsics
(
ModuleRef
llmod
)
->
hashmap
[
str
,
ValueRef
]
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录