Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wa-lang
wa
提交
d80d88bc
wa
项目概览
wa-lang
/
wa
11 个月 前同步成功
通知
68
Star
655
Fork
45
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
wa
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d80d88bc
编写于
11月 28, 2022
作者:
B
Ben Shi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
llvm: implement support of closure functions.
上级
cb393db0
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
74 addition
and
14 deletion
+74
-14
_examples/llvm/internal_function.wa
_examples/llvm/internal_function.wa
+17
-5
internal/backends/compiler_llvm/compile.go
internal/backends/compiler_llvm/compile.go
+14
-4
internal/backends/compiler_llvm/compile_function.go
internal/backends/compiler_llvm/compile_function.go
+9
-1
internal/backends/compiler_llvm/compile_value.go
internal/backends/compiler_llvm/compile_value.go
+34
-4
未找到文件。
_examples/llvm/internal_function.wa
浏览文件 @
d80d88bc
# Test the llvm backend.
# Test anonymous functions and closure functions.
type pair struct {
i :f32
j :f32
}
fn main() {
print("Hello, ")
fn() {
println("World!")
}()
var i: int
show := fn() {
println("i = ", i)
var i: int = 31
var j: [4]f32 = [4]f32{1, 2.2, 5.5, 9.8}
var k: pair = pair{3.14, 2.718}
show := fn(q: int) {
println(i, " + ", q, " = ", i+q)
println("{", j[0], ", ", j[1], ", ", j[2], ", ", j[3], "}")
println("{", k.i, ", ", k.j, "}")
}
for i = 0; i < 10; i++ {
show()
for i := int(0); i < 4; i++ {
j[i] += 1.0
k.i += 0.1
k.j -= 0.1
show(i)
}
}
internal/backends/compiler_llvm/compile.go
浏览文件 @
d80d88bc
...
...
@@ -16,12 +16,22 @@ type FmtStr struct {
size
int
}
type
Argument
struct
{
AType
string
AName
string
}
type
InnerFunc
struct
{
fn
*
ssa
.
Function
args
[]
Argument
}
type
Compiler
struct
{
target
string
output
strings
.
Builder
debug
bool
fmts
[]
FmtStr
anofn
[]
*
ssa
.
Function
anofn
[]
InnerFunc
}
func
New
(
target
string
,
debug
bool
)
*
Compiler
{
...
...
@@ -138,18 +148,18 @@ func (p *Compiler) compilePackage(pkg *ssa.Package) error {
// Generate LLVM-IR for each global function.
for
_
,
v
:=
range
fns
{
if
err
:=
p
.
compileFunction
(
v
);
err
!=
nil
{
if
err
:=
p
.
compileFunction
(
v
,
[]
Argument
{}
);
err
!=
nil
{
return
err
}
}
// Generate LLVM-IR for each internal function.
for
_
,
v
:=
range
p
.
anofn
{
if
err
:=
p
.
compileFunction
(
v
);
err
!=
nil
{
if
err
:=
p
.
compileFunction
(
v
.
fn
,
v
.
args
);
err
!=
nil
{
return
err
}
}
p
.
anofn
=
[]
*
ssa
.
Function
{}
p
.
anofn
=
[]
InnerFunc
{}
return
nil
}
...
...
internal/backends/compiler_llvm/compile_function.go
浏览文件 @
d80d88bc
...
...
@@ -11,7 +11,7 @@ import (
"github.com/wa-lang/wa/internal/types"
)
func
(
p
*
Compiler
)
compileFunction
(
fn
*
ssa
.
Function
)
error
{
func
(
p
*
Compiler
)
compileFunction
(
fn
*
ssa
.
Function
,
extraArgs
[]
Argument
)
error
{
if
isTargetBuiltin
(
fn
.
LinkName
(),
p
.
target
)
||
isTargetBuiltin
(
fn
.
Name
(),
p
.
target
)
{
return
nil
}
...
...
@@ -82,6 +82,14 @@ func (p *Compiler) compileFunction(fn *ssa.Function) error {
p
.
output
.
WriteString
(
", "
)
}
}
// Emit binded values as extra arguments for closure functions.
for
_
,
v
:=
range
extraArgs
{
p
.
output
.
WriteString
(
", "
)
p
.
output
.
WriteString
(
v
.
AType
)
p
.
output
.
WriteString
(
" "
)
p
.
output
.
WriteString
(
v
.
AName
)
}
// Finish emitting function header.
if
len
(
fn
.
Blocks
)
==
0
{
p
.
output
.
WriteString
(
")
\n\n
"
)
return
nil
...
...
internal/backends/compiler_llvm/compile_value.go
浏览文件 @
d80d88bc
...
...
@@ -114,6 +114,10 @@ func (p *Compiler) compileValue(val ssa.Value) error {
p
.
output
.
WriteString
(
fmt
.
Sprintf
(
"%d"
,
val
.
Index
))
p
.
output
.
WriteString
(
"
\n
"
)
case
*
ssa
.
MakeClosure
:
// We postpone the process of closure functions to the fist call of them.
break
default
:
p
.
output
.
WriteString
(
" ; "
+
val
.
Name
()
+
" = "
+
val
.
String
()
+
"
\n
"
)
// panic("unsupported Value '" + val.Name() + " = " + val.String() + "'")
...
...
@@ -359,7 +363,7 @@ func (p *Compiler) compileBinOp(val *ssa.BinOp) error {
func
(
p
*
Compiler
)
compileCall
(
val
*
ssa
.
Call
)
error
{
switch
val
.
Call
.
Value
.
(
type
)
{
case
*
ssa
.
Function
:
case
*
ssa
.
Function
,
*
ssa
.
MakeClosure
:
// Special process for float32 constants.
paf32
:=
map
[
int
]
string
{}
for
i
,
v
:=
range
val
.
Call
.
Args
{
...
...
@@ -389,16 +393,42 @@ func (p *Compiler) compileCall(val *ssa.Call) error {
callee
:=
val
.
Call
.
StaticCallee
()
// This callee is an internal function, whose body will be genereated later.
if
callee
.
Parent
()
!=
nil
{
p
.
anofn
=
append
(
p
.
anofn
,
callee
)
found
:=
false
for
_
,
f
:=
range
p
.
anofn
{
if
f
.
fn
==
callee
{
found
=
true
}
}
if
!
found
{
inner
:=
InnerFunc
{
callee
,
[]
Argument
{}}
// Collect all binded values for closure functions, then emit them as implicit arguments.
if
cl
,
ok
:=
val
.
Call
.
Value
.
(
*
ssa
.
MakeClosure
);
ok
{
for
_
,
v
:=
range
cl
.
Bindings
{
if
al
,
ok
:=
v
.
(
*
ssa
.
Alloc
);
ok
{
arg
:=
Argument
{
getTypeStr
(
v
.
Type
(),
p
.
target
),
"%"
+
al
.
Comment
}
inner
.
args
=
append
(
inner
.
args
,
arg
)
}
}
}
p
.
anofn
=
append
(
p
.
anofn
,
inner
)
}
}
// Emit link name for external functions.
if
len
(
callee
.
LinkName
())
>
0
{
p
.
output
.
WriteString
(
callee
.
LinkName
())
}
else
{
p
.
output
.
WriteString
(
getNormalName
(
callee
.
Pkg
.
Pkg
.
Path
()
+
"."
+
callee
.
Name
()))
}
p
.
output
.
WriteString
(
"("
)
// Collect all binded values for closure functions, then pass them as implicit parameters.
params
:=
val
.
Call
.
Args
[
0
:
]
if
cl
,
ok
:=
val
.
Call
.
Value
.
(
*
ssa
.
MakeClosure
);
ok
{
for
_
,
v
:=
range
cl
.
Bindings
{
params
=
append
(
params
,
v
)
}
}
// Emit parameters.
for
i
,
v
:=
range
val
.
Call
.
Arg
s
{
for
i
,
v
:=
range
param
s
{
ty
:=
getRealType
(
v
.
Type
())
tyStr
:=
getTypeStr
(
ty
,
p
.
target
)
switch
ty
.
(
type
)
{
...
...
@@ -414,7 +444,7 @@ func (p *Compiler) compileCall(val *ssa.Call) error {
}
else
{
p
.
output
.
WriteString
(
getValueStr
(
v
))
}
if
i
<
len
(
val
.
Call
.
Arg
s
)
-
1
{
if
i
<
len
(
param
s
)
-
1
{
p
.
output
.
WriteString
(
", "
)
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录